in ptp_ines.c [331:397]
static int ines_hwtstamp(struct mii_timestamper *mii_ts, struct ifreq *ifr)
{
struct ines_port *port = container_of(mii_ts, struct ines_port, mii_ts);
u32 cm_one_step = 0, port_conf, ts_stat_rx, ts_stat_tx;
struct hwtstamp_config cfg;
unsigned long flags;
if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
return -EFAULT;
switch (cfg.tx_type) {
case HWTSTAMP_TX_OFF:
ts_stat_tx = 0;
break;
case HWTSTAMP_TX_ON:
ts_stat_tx = TS_ENABLE;
break;
case HWTSTAMP_TX_ONESTEP_P2P:
ts_stat_tx = TS_ENABLE;
cm_one_step = CM_ONE_STEP;
break;
default:
return -ERANGE;
}
switch (cfg.rx_filter) {
case HWTSTAMP_FILTER_NONE:
ts_stat_rx = 0;
break;
case HWTSTAMP_FILTER_ALL:
case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
return -ERANGE;
case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
case HWTSTAMP_FILTER_PTP_V2_EVENT:
case HWTSTAMP_FILTER_PTP_V2_SYNC:
case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
ts_stat_rx = TS_ENABLE;
cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
break;
default:
return -ERANGE;
}
spin_lock_irqsave(&port->lock, flags);
port_conf = ines_read32(port, port_conf);
port_conf &= ~CM_ONE_STEP;
port_conf |= cm_one_step;
ines_write32(port, port_conf, port_conf);
ines_write32(port, ts_stat_rx, ts_stat_rx);
ines_write32(port, ts_stat_tx, ts_stat_tx);
port->rxts_enabled = ts_stat_rx == TS_ENABLE;
port->txts_enabled = ts_stat_tx == TS_ENABLE;
spin_unlock_irqrestore(&port->lock, flags);
return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
}