The driver implemented SIOCSHWTSTAMP ioctl command only, but at the same time it has configuration stored in a private structure. Implement both ndo_hwtstamp_set and ndo_hwtstamp_get callback using stored info. Reviewed-by: Kory Maincent Signed-off-by: Vadim Fedorenko --- .../net/ethernet/broadcom/bnx2x/bnx2x_main.c | 53 +++++++++++-------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index f0f05d7315ac..289b1f6b42d0 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -308,8 +308,11 @@ static int bnx2x_set_storm_rx_mode(struct bnx2x *bp); /**************************************************************************** * General service functions ****************************************************************************/ - -static int bnx2x_hwtstamp_ioctl(struct bnx2x *bp, struct ifreq *ifr); +static int bnx2x_hwtstamp_set(struct net_device *dev, + struct kernel_hwtstamp_config *config, + struct netlink_ext_ack *extack); +static int bnx2x_hwtstamp_get(struct net_device *dev, + struct kernel_hwtstamp_config *config); static void __storm_memset_dma_mapping(struct bnx2x *bp, u32 addr, dma_addr_t mapping) @@ -12813,14 +12816,9 @@ static int bnx2x_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) if (!netif_running(dev)) return -EAGAIN; - switch (cmd) { - case SIOCSHWTSTAMP: - return bnx2x_hwtstamp_ioctl(bp, ifr); - default: - DP(NETIF_MSG_LINK, "ioctl: phy id 0x%x, reg 0x%x, val_in 0x%x\n", - mdio->phy_id, mdio->reg_num, mdio->val_in); - return mdio_mii_ioctl(&bp->mdio, mdio, cmd); - } + DP(NETIF_MSG_LINK, "ioctl: phy id 0x%x, reg 0x%x, val_in 0x%x\n", + mdio->phy_id, mdio->reg_num, mdio->val_in); + return mdio_mii_ioctl(&bp->mdio, mdio, cmd); } static int bnx2x_validate_addr(struct net_device *dev) @@ -13036,6 +13034,8 @@ static const struct net_device_ops bnx2x_netdev_ops = { .ndo_get_phys_port_id = bnx2x_get_phys_port_id, .ndo_set_vf_link_state = bnx2x_set_vf_link_state, .ndo_features_check = bnx2x_features_check, + .ndo_hwtstamp_get = bnx2x_hwtstamp_get, + .ndo_hwtstamp_set = bnx2x_hwtstamp_set, }; static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev, @@ -15350,31 +15350,40 @@ int bnx2x_configure_ptp_filters(struct bnx2x *bp) return 0; } -static int bnx2x_hwtstamp_ioctl(struct bnx2x *bp, struct ifreq *ifr) +static int bnx2x_hwtstamp_set(struct net_device *dev, + struct kernel_hwtstamp_config *config, + struct netlink_ext_ack *extack) { - struct hwtstamp_config config; + struct bnx2x *bp = netdev_priv(dev); int rc; - DP(BNX2X_MSG_PTP, "HWTSTAMP IOCTL called\n"); - - if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) - return -EFAULT; + DP(BNX2X_MSG_PTP, "HWTSTAMP SET called\n"); DP(BNX2X_MSG_PTP, "Requested tx_type: %d, requested rx_filters = %d\n", - config.tx_type, config.rx_filter); + config->tx_type, config->rx_filter); bp->hwtstamp_ioctl_called = true; - bp->tx_type = config.tx_type; - bp->rx_filter = config.rx_filter; + bp->tx_type = config->tx_type; + bp->rx_filter = config->rx_filter; rc = bnx2x_configure_ptp_filters(bp); if (rc) return rc; - config.rx_filter = bp->rx_filter; + config->rx_filter = bp->rx_filter; + + return 0; +} - return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? - -EFAULT : 0; +static int bnx2x_hwtstamp_get(struct net_device *dev, + struct kernel_hwtstamp_config *config) +{ + struct bnx2x *bp = netdev_priv(dev); + + config->rx_filter = bp->rx_filter; + config->tx_type = bp->tx_type; + + return 0; } /* Configures HW for PTP */ -- 2.47.3 The driver implemented SIOCSHWTSTAMP ioctl command only, but there is a way to get configured status. Implement both ndo_hwtstamp_set and ndo_hwtstamp_get callbacks. Reviewed-by: Kory Maincent Signed-off-by: Vadim Fedorenko --- .../net/ethernet/cavium/liquidio/lio_main.c | 50 ++++++++----------- 1 file changed, 20 insertions(+), 30 deletions(-) diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c index 8e2fcec26ea1..0732440eeacd 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_main.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c @@ -2107,20 +2107,16 @@ liquidio_get_stats64(struct net_device *netdev, lstats->tx_fifo_errors; } -/** - * hwtstamp_ioctl - Handler for SIOCSHWTSTAMP ioctl - * @netdev: network device - * @ifr: interface request - */ -static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr) +static int liquidio_hwtstamp_set(struct net_device *netdev, + struct kernel_hwtstamp_config *conf, + struct netlink_ext_ack *extack) { - struct hwtstamp_config conf; struct lio *lio = GET_LIO(netdev); - if (copy_from_user(&conf, ifr->ifr_data, sizeof(conf))) - return -EFAULT; + if (!lio->oct_dev->ptp_enable) + return -EOPNOTSUPP; - switch (conf.tx_type) { + switch (conf->tx_type) { case HWTSTAMP_TX_ON: case HWTSTAMP_TX_OFF: break; @@ -2128,7 +2124,7 @@ static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr) return -ERANGE; } - switch (conf.rx_filter) { + switch (conf->rx_filter) { case HWTSTAMP_FILTER_NONE: break; case HWTSTAMP_FILTER_ALL: @@ -2146,39 +2142,32 @@ static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr) case HWTSTAMP_FILTER_PTP_V2_SYNC: case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: case HWTSTAMP_FILTER_NTP_ALL: - conf.rx_filter = HWTSTAMP_FILTER_ALL; + conf->rx_filter = HWTSTAMP_FILTER_ALL; break; default: return -ERANGE; } - if (conf.rx_filter == HWTSTAMP_FILTER_ALL) + if (conf->rx_filter == HWTSTAMP_FILTER_ALL) ifstate_set(lio, LIO_IFSTATE_RX_TIMESTAMP_ENABLED); else ifstate_reset(lio, LIO_IFSTATE_RX_TIMESTAMP_ENABLED); - return copy_to_user(ifr->ifr_data, &conf, sizeof(conf)) ? -EFAULT : 0; + return 0; } -/** - * liquidio_ioctl - ioctl handler - * @netdev: network device - * @ifr: interface request - * @cmd: command - */ -static int liquidio_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) +static int liquidio_hwtstamp_get(struct net_device *netdev, + struct kernel_hwtstamp_config *conf) { struct lio *lio = GET_LIO(netdev); - switch (cmd) { - case SIOCSHWTSTAMP: - if (lio->oct_dev->ptp_enable) - return hwtstamp_ioctl(netdev, ifr); - fallthrough; - default: - return -EOPNOTSUPP; - } + /* TX timestamping is technically always on */ + conf->tx_type = HWTSTAMP_TX_ON; + conf->rx_filter = ifstate_check(lio, LIO_IFSTATE_RX_TIMESTAMP_ENABLED) ? + HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE; + + return 0; } /** @@ -3227,7 +3216,6 @@ static const struct net_device_ops lionetdevops = { .ndo_vlan_rx_add_vid = liquidio_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = liquidio_vlan_rx_kill_vid, .ndo_change_mtu = liquidio_change_mtu, - .ndo_eth_ioctl = liquidio_ioctl, .ndo_fix_features = liquidio_fix_features, .ndo_set_features = liquidio_set_features, .ndo_set_vf_mac = liquidio_set_vf_mac, @@ -3238,6 +3226,8 @@ static const struct net_device_ops lionetdevops = { .ndo_set_vf_link_state = liquidio_set_vf_link_state, .ndo_get_vf_stats = liquidio_get_vf_stats, .ndo_get_port_parent_id = liquidio_get_port_parent_id, + .ndo_hwtstamp_get = liquidio_hwtstamp_get, + .ndo_hwtstamp_set = liquidio_hwtstamp_set, }; /** -- 2.47.3 The driver implemented SIOCSHWTSTAMP ioctl command only, but there is a way to get configuration back. Implement both ndo_hwtstamp_set and ndo_hwtstamp_set callbacks. Reviewed-by: Kory Maincent Signed-off-by: Vadim Fedorenko --- .../ethernet/cavium/liquidio/lio_vf_main.c | 48 ++++++++----------- 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c index 3230dff5ba05..e02942dbbcce 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c @@ -1236,20 +1236,13 @@ liquidio_get_stats64(struct net_device *netdev, lstats->tx_carrier_errors; } -/** - * hwtstamp_ioctl - Handler for SIOCSHWTSTAMP ioctl - * @netdev: network device - * @ifr: interface request - */ -static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr) +static int liquidio_hwtstamp_set(struct net_device *netdev, + struct kernel_hwtstamp_config *conf, + struct netlink_ext_ack *extack) { struct lio *lio = GET_LIO(netdev); - struct hwtstamp_config conf; - - if (copy_from_user(&conf, ifr->ifr_data, sizeof(conf))) - return -EFAULT; - switch (conf.tx_type) { + switch (conf->tx_type) { case HWTSTAMP_TX_ON: case HWTSTAMP_TX_OFF: break; @@ -1257,7 +1250,7 @@ static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr) return -ERANGE; } - switch (conf.rx_filter) { + switch (conf->rx_filter) { case HWTSTAMP_FILTER_NONE: break; case HWTSTAMP_FILTER_ALL: @@ -1275,35 +1268,31 @@ static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr) case HWTSTAMP_FILTER_PTP_V2_SYNC: case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: case HWTSTAMP_FILTER_NTP_ALL: - conf.rx_filter = HWTSTAMP_FILTER_ALL; + conf->rx_filter = HWTSTAMP_FILTER_ALL; break; default: return -ERANGE; } - if (conf.rx_filter == HWTSTAMP_FILTER_ALL) + if (conf->rx_filter == HWTSTAMP_FILTER_ALL) ifstate_set(lio, LIO_IFSTATE_RX_TIMESTAMP_ENABLED); else ifstate_reset(lio, LIO_IFSTATE_RX_TIMESTAMP_ENABLED); - return copy_to_user(ifr->ifr_data, &conf, sizeof(conf)) ? -EFAULT : 0; + return 0; } -/** - * liquidio_ioctl - ioctl handler - * @netdev: network device - * @ifr: interface request - * @cmd: command - */ -static int liquidio_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) +static int liquidio_hwtstamp_get(struct net_device *netdev, + struct kernel_hwtstamp_config *conf) { - switch (cmd) { - case SIOCSHWTSTAMP: - return hwtstamp_ioctl(netdev, ifr); - default: - return -EOPNOTSUPP; - } + struct lio *lio = GET_LIO(netdev); + + /* TX timestamping is techically always on */ + conf->tx_type = HWTSTAMP_TX_ON; + conf->rx_filter = ifstate_check(lio, LIO_IFSTATE_RX_TIMESTAMP_ENABLED) ? + HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE; + return 0; } static void handle_timestamp(struct octeon_device *oct, u32 status, void *buf) @@ -1881,9 +1870,10 @@ static const struct net_device_ops lionetdevops = { .ndo_vlan_rx_add_vid = liquidio_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = liquidio_vlan_rx_kill_vid, .ndo_change_mtu = liquidio_change_mtu, - .ndo_eth_ioctl = liquidio_ioctl, .ndo_fix_features = liquidio_fix_features, .ndo_set_features = liquidio_set_features, + .ndo_hwtstamp_get = liquidio_hwtstamp_get, + .ndo_hwtstamp_set = liquidio_hwtstamp_set, }; static int lio_nic_info(struct octeon_recv_info *recv_info, void *buf) -- 2.47.3 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 The driver implemented SIOCSHWTSTAMP ioctl command only, but it also stores configuration in private data, so it's possible to report it back to users. Implement both ndo_hwtstamp_set and ndo_hwtstamp_get callbacks. Reviewed-by: Kory Maincent Signed-off-by: Vadim Fedorenko --- .../net/ethernet/cavium/thunder/nicvf_main.c | 45 ++++++++++--------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c index 1be2dc40a1a6..0b6e30a8feb0 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c +++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c @@ -1899,18 +1899,18 @@ static int nicvf_xdp(struct net_device *netdev, struct netdev_bpf *xdp) } } -static int nicvf_config_hwtstamp(struct net_device *netdev, struct ifreq *ifr) +static int nicvf_hwtstamp_set(struct net_device *netdev, + struct kernel_hwtstamp_config *config, + struct netlink_ext_ack *extack) { - struct hwtstamp_config config; struct nicvf *nic = netdev_priv(netdev); - if (!nic->ptp_clock) + if (!nic->ptp_clock) { + NL_SET_ERR_MSG_MOD(extack, "HW timestamping is not supported"); return -ENODEV; + } - if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) - return -EFAULT; - - switch (config.tx_type) { + switch (config->tx_type) { case HWTSTAMP_TX_OFF: case HWTSTAMP_TX_ON: break; @@ -1918,7 +1918,7 @@ static int nicvf_config_hwtstamp(struct net_device *netdev, struct ifreq *ifr) return -ERANGE; } - switch (config.rx_filter) { + switch (config->rx_filter) { case HWTSTAMP_FILTER_NONE: nic->hw_rx_tstamp = false; break; @@ -1937,7 +1937,7 @@ static int nicvf_config_hwtstamp(struct net_device *netdev, struct ifreq *ifr) case HWTSTAMP_FILTER_PTP_V2_SYNC: case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: nic->hw_rx_tstamp = true; - config.rx_filter = HWTSTAMP_FILTER_ALL; + config->rx_filter = HWTSTAMP_FILTER_ALL; break; default: return -ERANGE; @@ -1946,20 +1946,24 @@ static int nicvf_config_hwtstamp(struct net_device *netdev, struct ifreq *ifr) if (netif_running(netdev)) nicvf_config_hw_rx_tstamp(nic, nic->hw_rx_tstamp); - if (copy_to_user(ifr->ifr_data, &config, sizeof(config))) - return -EFAULT; - return 0; } -static int nicvf_ioctl(struct net_device *netdev, struct ifreq *req, int cmd) +static int nicvf_hwtstamp_get(struct net_device *netdev, + struct kernel_hwtstamp_config *config) { - switch (cmd) { - case SIOCSHWTSTAMP: - return nicvf_config_hwtstamp(netdev, req); - default: - return -EOPNOTSUPP; - } + struct nicvf *nic = netdev_priv(netdev); + + if (!nic->ptp_clock) + return -ENODEV; + + /* TX timestamping is technically always on */ + config->tx_type = HWTSTAMP_TX_ON; + config->rx_filter = nic->hw_rx_tstamp ? + HWTSTAMP_FILTER_ALL : + HWTSTAMP_FILTER_NONE; + + return 0; } static void __nicvf_set_rx_mode_task(u8 mode, struct xcast_addr_list *mc_addrs, @@ -2081,8 +2085,9 @@ static const struct net_device_ops nicvf_netdev_ops = { .ndo_fix_features = nicvf_fix_features, .ndo_set_features = nicvf_set_features, .ndo_bpf = nicvf_xdp, - .ndo_eth_ioctl = nicvf_ioctl, .ndo_set_rx_mode = nicvf_set_rx_mode, + .ndo_hwtstamp_get = nicvf_hwtstamp_get, + .ndo_hwtstamp_set = nicvf_hwtstamp_set, }; static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -- 2.47.3 The driver implemented SIOCSHWTSTAMP ioctl command only, but it stores configuration in the private data, so it is possible to report it back to users. Implement both ndo_hwtstamp_set and ndo_hwtstamp_get callbacks. To properly report RX filter type, store it in hwts_rx_en instead of using this field as a simple flag. The logic didn't change because receive path used this field as boolean flag. Signed-off-by: Vadim Fedorenko --- .../ethernet/oki-semi/pch_gbe/pch_gbe_main.c | 38 +++++++++++-------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c index e5a6f59af0b6..62f05f4569b1 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c @@ -198,23 +198,21 @@ pch_tx_timestamp(struct pch_gbe_adapter *adapter, struct sk_buff *skb) pch_ch_event_write(pdev, TX_SNAPSHOT_LOCKED); } -static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) +static int pch_gbe_hwtstamp_set(struct net_device *netdev, + struct kernel_hwtstamp_config *cfg, + struct netlink_ext_ack *extack) { - struct hwtstamp_config cfg; struct pch_gbe_adapter *adapter = netdev_priv(netdev); struct pci_dev *pdev; u8 station[20]; - if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) - return -EFAULT; - /* Get ieee1588's dev information */ pdev = adapter->ptp_pdev; - if (cfg.tx_type != HWTSTAMP_TX_OFF && cfg.tx_type != HWTSTAMP_TX_ON) + if (cfg->tx_type != HWTSTAMP_TX_OFF && cfg->tx_type != HWTSTAMP_TX_ON) return -ERANGE; - switch (cfg.rx_filter) { + switch (cfg->rx_filter) { case HWTSTAMP_FILTER_NONE: adapter->hwts_rx_en = 0; break; @@ -223,17 +221,17 @@ static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) pch_ch_control_write(pdev, SLAVE_MODE | CAP_MODE0); break; case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: - adapter->hwts_rx_en = 1; + adapter->hwts_rx_en = cfg->rx_filter; pch_ch_control_write(pdev, MASTER_MODE | CAP_MODE0); break; case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: - adapter->hwts_rx_en = 1; + adapter->hwts_rx_en = cfg->rx_filter; pch_ch_control_write(pdev, V2_MODE | CAP_MODE2); strcpy(station, PTP_L4_MULTICAST_SA); pch_set_station_address(station, pdev); break; case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: - adapter->hwts_rx_en = 1; + adapter->hwts_rx_en = cfg->rx_filter; pch_ch_control_write(pdev, V2_MODE | CAP_MODE2); strcpy(station, PTP_L2_MULTICAST_SA); pch_set_station_address(station, pdev); @@ -242,12 +240,23 @@ static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) return -ERANGE; } - adapter->hwts_tx_en = cfg.tx_type == HWTSTAMP_TX_ON; + adapter->hwts_tx_en = cfg->tx_type == HWTSTAMP_TX_ON; /* Clear out any old time stamps. */ pch_ch_event_write(pdev, TX_SNAPSHOT_LOCKED | RX_SNAPSHOT_LOCKED); - return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; + return 0; +} + +static int pch_gbe_hwtstamp_get(struct net_device *netdev, + struct kernel_hwtstamp_config *cfg) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + + cfg->tx_type = adapter->hwts_tx_en ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF; + cfg->rx_filter = adapter->hwts_rx_en; + + return 0; } static inline void pch_gbe_mac_load_mac_addr(struct pch_gbe_hw *hw) @@ -2234,9 +2243,6 @@ static int pch_gbe_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) netdev_dbg(netdev, "cmd : 0x%04x\n", cmd); - if (cmd == SIOCSHWTSTAMP) - return hwtstamp_ioctl(netdev, ifr, cmd); - return generic_mii_ioctl(&adapter->mii, if_mii(ifr), cmd, NULL); } @@ -2328,6 +2334,8 @@ static const struct net_device_ops pch_gbe_netdev_ops = { #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = pch_gbe_netpoll, #endif + .ndo_hwtstamp_get = pch_gbe_hwtstamp_get, + .ndo_hwtstamp_set = pch_gbe_hwtstamp_set, }; static pci_ers_result_t pch_gbe_io_error_detected(struct pci_dev *pdev, -- 2.47.3 The driver implemented SIOCSHWTSTAMP ioctl cmd only, but it stores configuration in private structure, so it can be reported back to users. Implement both ndo_hwtstamp_set and ndo_hwtstamp_set callbacks. Reviewed-by: Kory Maincent Signed-off-by: Vadim Fedorenko --- drivers/net/ethernet/qlogic/qede/qede_main.c | 22 +-------- drivers/net/ethernet/qlogic/qede/qede_ptp.c | 47 ++++++++++++++------ drivers/net/ethernet/qlogic/qede/qede_ptp.h | 6 ++- 3 files changed, 40 insertions(+), 35 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c index b5d744d2586f..66ab1b9d65a1 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_main.c +++ b/drivers/net/ethernet/qlogic/qede/qede_main.c @@ -506,25 +506,6 @@ static int qede_set_vf_trust(struct net_device *dev, int vfidx, bool setting) } #endif -static int qede_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -{ - struct qede_dev *edev = netdev_priv(dev); - - if (!netif_running(dev)) - return -EAGAIN; - - switch (cmd) { - case SIOCSHWTSTAMP: - return qede_ptp_hw_ts(edev, ifr); - default: - DP_VERBOSE(edev, QED_MSG_DEBUG, - "default IOCTL cmd 0x%x\n", cmd); - return -EOPNOTSUPP; - } - - return 0; -} - static void qede_fp_sb_dump(struct qede_dev *edev, struct qede_fastpath *fp) { char *p_sb = (char *)fp->sb_info->sb_virt; @@ -717,7 +698,6 @@ static const struct net_device_ops qede_netdev_ops = { .ndo_set_mac_address = qede_set_mac_addr, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = qede_change_mtu, - .ndo_eth_ioctl = qede_ioctl, .ndo_tx_timeout = qede_tx_timeout, #ifdef CONFIG_QED_SRIOV .ndo_set_vf_mac = qede_set_vf_mac, @@ -742,6 +722,8 @@ static const struct net_device_ops qede_netdev_ops = { #endif .ndo_xdp_xmit = qede_xdp_transmit, .ndo_setup_tc = qede_setup_tc_offload, + .ndo_hwtstamp_get = qede_hwtstamp_get, + .ndo_hwtstamp_set = qede_hwtstamp_set, }; static const struct net_device_ops qede_netdev_vf_ops = { diff --git a/drivers/net/ethernet/qlogic/qede/qede_ptp.c b/drivers/net/ethernet/qlogic/qede/qede_ptp.c index a38f1e72c62b..b65e9f46ac52 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_ptp.c +++ b/drivers/net/ethernet/qlogic/qede/qede_ptp.c @@ -290,35 +290,54 @@ static int qede_ptp_cfg_filters(struct qede_dev *edev) return 0; } -int qede_ptp_hw_ts(struct qede_dev *edev, struct ifreq *ifr) +int qede_hwtstamp_set(struct net_device *netdev, + struct kernel_hwtstamp_config *config, + struct netlink_ext_ack *extack) { - struct hwtstamp_config config; + struct qede_dev *edev = netdev_priv(netdev); struct qede_ptp *ptp; int rc; ptp = edev->ptp; - if (!ptp) + if (!ptp) { + NL_SET_ERR_MSG_MOD(extack, "HW timestamping is not supported"); return -EIO; - - if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) - return -EFAULT; + } DP_VERBOSE(edev, QED_MSG_DEBUG, - "HWTSTAMP IOCTL: Requested tx_type = %d, requested rx_filters = %d\n", - config.tx_type, config.rx_filter); + "HWTSTAMP SET: Requested tx_type = %d, requested rx_filters = %d\n", + config->tx_type, config->rx_filter); ptp->hw_ts_ioctl_called = 1; - ptp->tx_type = config.tx_type; - ptp->rx_filter = config.rx_filter; + ptp->tx_type = config->tx_type; + ptp->rx_filter = config->rx_filter; rc = qede_ptp_cfg_filters(edev); - if (rc) + if (rc) { + NL_SET_ERR_MSG_MOD(extack, + "One-step timestamping is not supported"); return rc; + } + + config->rx_filter = ptp->rx_filter; - config.rx_filter = ptp->rx_filter; + return 0; +} - return copy_to_user(ifr->ifr_data, &config, - sizeof(config)) ? -EFAULT : 0; +int qede_hwtstamp_get(struct net_device *netdev, + struct kernel_hwtstamp_config *config) +{ + struct qede_dev *edev = netdev_priv(netdev); + struct qede_ptp *ptp; + + ptp = edev->ptp; + if (!ptp) + return -EIO; + + config->tx_type = ptp->tx_type; + config->rx_filter = ptp->rx_filter; + + return 0; } int qede_ptp_get_ts_info(struct qede_dev *edev, struct kernel_ethtool_ts_info *info) diff --git a/drivers/net/ethernet/qlogic/qede/qede_ptp.h b/drivers/net/ethernet/qlogic/qede/qede_ptp.h index adafc894797e..88f168395812 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_ptp.h +++ b/drivers/net/ethernet/qlogic/qede/qede_ptp.h @@ -14,7 +14,11 @@ void qede_ptp_rx_ts(struct qede_dev *edev, struct sk_buff *skb); void qede_ptp_tx_ts(struct qede_dev *edev, struct sk_buff *skb); -int qede_ptp_hw_ts(struct qede_dev *edev, struct ifreq *req); +int qede_hwtstamp_get(struct net_device *netdev, + struct kernel_hwtstamp_config *config); +int qede_hwtstamp_set(struct net_device *netdev, + struct kernel_hwtstamp_config *config, + struct netlink_ext_ack *extack); void qede_ptp_disable(struct qede_dev *edev); int qede_ptp_enable(struct qede_dev *edev); int qede_ptp_get_ts_info(struct qede_dev *edev, struct kernel_ethtool_ts_info *ts); -- 2.47.3