The driver implemented SIOCSHWTSTAMP ioctl command only. But it stores timestamping configuration, so it is possible to report it to users. Implement both ndo_hwtstamp_set and ndo_hwtstamp_get callbacks. After this the ndo_eth_ioctl effectively becomes phy_do_ioctl - adjust callback accordingly. Reviewed-by: Kory Maincent Signed-off-by: Vadim Fedorenko --- .../net/ethernet/cavium/octeon/octeon_mgmt.c | 62 ++++++++++--------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/drivers/net/ethernet/cavium/octeon/octeon_mgmt.c b/drivers/net/ethernet/cavium/octeon/octeon_mgmt.c index 393b9951490a..c190fc6538d4 100644 --- a/drivers/net/ethernet/cavium/octeon/octeon_mgmt.c +++ b/drivers/net/ethernet/cavium/octeon/octeon_mgmt.c @@ -690,19 +690,16 @@ static irqreturn_t octeon_mgmt_interrupt(int cpl, void *dev_id) return IRQ_HANDLED; } -static int octeon_mgmt_ioctl_hwtstamp(struct net_device *netdev, - struct ifreq *rq, int cmd) +static int octeon_mgmt_hwtstamp_set(struct net_device *netdev, + struct kernel_hwtstamp_config *config, + struct netlink_ext_ack *extack) { struct octeon_mgmt *p = netdev_priv(netdev); - struct hwtstamp_config config; - union cvmx_mio_ptp_clock_cfg ptp; union cvmx_agl_gmx_rxx_frm_ctl rxx_frm_ctl; + union cvmx_mio_ptp_clock_cfg ptp; bool have_hw_timestamps = false; - if (copy_from_user(&config, rq->ifr_data, sizeof(config))) - return -EFAULT; - - /* Check the status of hardware for tiemstamps */ + /* Check the status of hardware for timestamps */ if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) { /* Get the current state of the PTP clock */ ptp.u64 = cvmx_read_csr(CVMX_MIO_PTP_CLOCK_CFG); @@ -733,10 +730,12 @@ static int octeon_mgmt_ioctl_hwtstamp(struct net_device *netdev, have_hw_timestamps = true; } - if (!have_hw_timestamps) + if (!have_hw_timestamps) { + NL_SET_ERR_MSG_MOD(extack, "HW doesn't support timestamping"); return -EINVAL; + } - switch (config.tx_type) { + switch (config->tx_type) { case HWTSTAMP_TX_OFF: case HWTSTAMP_TX_ON: break; @@ -744,7 +743,7 @@ static int octeon_mgmt_ioctl_hwtstamp(struct net_device *netdev, return -ERANGE; } - switch (config.rx_filter) { + switch (config->rx_filter) { case HWTSTAMP_FILTER_NONE: p->has_rx_tstamp = false; rxx_frm_ctl.u64 = cvmx_read_csr(p->agl + AGL_GMX_RX_FRM_CTL); @@ -766,33 +765,34 @@ static int octeon_mgmt_ioctl_hwtstamp(struct net_device *netdev, case HWTSTAMP_FILTER_PTP_V2_SYNC: case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: case HWTSTAMP_FILTER_NTP_ALL: - p->has_rx_tstamp = have_hw_timestamps; - config.rx_filter = HWTSTAMP_FILTER_ALL; - if (p->has_rx_tstamp) { - rxx_frm_ctl.u64 = cvmx_read_csr(p->agl + AGL_GMX_RX_FRM_CTL); - rxx_frm_ctl.s.ptp_mode = 1; - cvmx_write_csr(p->agl + AGL_GMX_RX_FRM_CTL, rxx_frm_ctl.u64); - } + p->has_rx_tstamp = true; + config->rx_filter = HWTSTAMP_FILTER_ALL; + rxx_frm_ctl.u64 = cvmx_read_csr(p->agl + AGL_GMX_RX_FRM_CTL); + rxx_frm_ctl.s.ptp_mode = 1; + cvmx_write_csr(p->agl + AGL_GMX_RX_FRM_CTL, rxx_frm_ctl.u64); break; default: return -ERANGE; } - if (copy_to_user(rq->ifr_data, &config, sizeof(config))) - return -EFAULT; - return 0; } -static int octeon_mgmt_ioctl(struct net_device *netdev, - struct ifreq *rq, int cmd) +static int octeon_mgmt_hwtstamp_get(struct net_device *netdev, + struct kernel_hwtstamp_config *config) { - switch (cmd) { - case SIOCSHWTSTAMP: - return octeon_mgmt_ioctl_hwtstamp(netdev, rq, cmd); - default: - return phy_do_ioctl(netdev, rq, cmd); - } + struct octeon_mgmt *p = netdev_priv(netdev); + + /* Check the status of hardware for timestamps */ + if (!OCTEON_IS_MODEL(OCTEON_CN6XXX)) + return -EINVAL; + + config->tx_type = HWTSTAMP_TX_ON; + config->rx_filter = p->has_rx_tstamp ? + HWTSTAMP_FILTER_ALL : + HWTSTAMP_FILTER_NONE; + + return 0; } static void octeon_mgmt_disable_link(struct octeon_mgmt *p) @@ -1370,11 +1370,13 @@ static const struct net_device_ops octeon_mgmt_ops = { .ndo_start_xmit = octeon_mgmt_xmit, .ndo_set_rx_mode = octeon_mgmt_set_rx_filtering, .ndo_set_mac_address = octeon_mgmt_set_mac_address, - .ndo_eth_ioctl = octeon_mgmt_ioctl, + .ndo_eth_ioctl = phy_do_ioctl, .ndo_change_mtu = octeon_mgmt_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = octeon_mgmt_poll_controller, #endif + .ndo_hwtstamp_get = octeon_mgmt_hwtstamp_get, + .ndo_hwtstamp_set = octeon_mgmt_hwtstamp_set, }; static int octeon_mgmt_probe(struct platform_device *pdev) -- 2.47.3