[RFC PATCH net-next v6 4/5] bond: Add ndo_hwtstamp_get/set support to bond driver
From: Maxim Georgiev <hidden>
Date: 2023-05-02 04:32:15
Subsystem:
bonding driver, networking drivers, the rest · Maintainers:
Jay Vosburgh, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
This patch changes bonding net driver to use the newly introduced ndo_hwtstamp_get/set API to pass hw timestamp requests to underlying NIC drivers in case if these drivers implement ndo_hwtstamp_get/set functions. Otherwise Bonding subsystem falls back to calling ndo_eth_ioctl. Suggested-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: Maxim Georgiev <redacted> --- Notes: Changes in v6: - Patch title was updated. No code changes. --- drivers/net/bonding/bond_main.c | 106 ++++++++++++++++++++------------ 1 file changed, 66 insertions(+), 40 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 710548dbd0c1..21969afff2a9 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c@@ -4408,11 +4408,6 @@ static int bond_eth_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cm { struct bonding *bond = netdev_priv(bond_dev); struct mii_ioctl_data *mii = NULL; - const struct net_device_ops *ops; - struct net_device *real_dev; - struct hwtstamp_config cfg; - struct ifreq ifrr; - int res = 0; netdev_dbg(bond_dev, "bond_eth_ioctl: cmd=%d\n", cmd);
@@ -4439,44 +4434,11 @@ static int bond_eth_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cm } break; - case SIOCSHWTSTAMP: - if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) - return -EFAULT; - - if (!(cfg.flags & HWTSTAMP_FLAG_BONDED_PHC_INDEX)) - return -EOPNOTSUPP; - - fallthrough; - case SIOCGHWTSTAMP: - real_dev = bond_option_active_slave_get_rcu(bond); - if (!real_dev) - return -EOPNOTSUPP; - - strscpy_pad(ifrr.ifr_name, real_dev->name, IFNAMSIZ); - ifrr.ifr_ifru = ifr->ifr_ifru; - - ops = real_dev->netdev_ops; - if (netif_device_present(real_dev) && ops->ndo_eth_ioctl) { - res = ops->ndo_eth_ioctl(real_dev, &ifrr, cmd); - if (res) - return res; - - ifr->ifr_ifru = ifrr.ifr_ifru; - if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) - return -EFAULT; - - /* Set the BOND_PHC_INDEX flag to notify user space */ - cfg.flags |= HWTSTAMP_FLAG_BONDED_PHC_INDEX; - - return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? - -EFAULT : 0; - } - fallthrough; default: - res = -EOPNOTSUPP; + return -EOPNOTSUPP; } - return res; + return 0; } static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd)
@@ -5650,6 +5612,68 @@ static u32 bond_mode_bcast_speed(struct slave *slave, u32 speed) return speed; } +static int bond_set_phc_index_flag(struct kernel_hwtstamp_config *kernel_cfg) +{ + struct ifreq *ifr = kernel_cfg->ifr; + struct hwtstamp_config cfg; + + if (kernel_cfg->kernel_flags & KERNEL_HWTSTAMP_FLAG_IFR_RESULT) { + if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) + return -EFAULT; + + cfg.flags |= HWTSTAMP_FLAG_BONDED_PHC_INDEX; + if (copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg))) + return -EFAULT; + } else { + kernel_cfg->flags |= HWTSTAMP_FLAG_BONDED_PHC_INDEX; + } + + return 0; +} + +static int bond_hwtstamp_get(struct net_device *dev, + struct kernel_hwtstamp_config *cfg, + struct netlink_ext_ack *extack) +{ + struct bonding *bond = netdev_priv(dev); + struct net_device *real_dev; + int err; + + real_dev = bond_option_active_slave_get_rcu(bond); + if (!real_dev) + return -EOPNOTSUPP; + + err = generic_hwtstamp_get_lower(real_dev, cfg, extack); + if (err) + return err; + + /* Set the BOND_PHC_INDEX flag to notify user space */ + return bond_set_phc_index_flag(cfg); +} + +static int bond_hwtstamp_set(struct net_device *dev, + struct kernel_hwtstamp_config *kernel_cfg, + struct netlink_ext_ack *extack) +{ + struct bonding *bond = netdev_priv(dev); + struct net_device *real_dev; + int err; + + if (!(kernel_cfg->flags & HWTSTAMP_FLAG_BONDED_PHC_INDEX)) + return -EOPNOTSUPP; + + real_dev = bond_option_active_slave_get_rcu(bond); + if (!real_dev) + return -EOPNOTSUPP; + + err = generic_hwtstamp_set_lower(real_dev, kernel_cfg, extack); + if (err) + return err; + + /* Set the BOND_PHC_INDEX flag to notify user space */ + return bond_set_phc_index_flag(kernel_cfg); +} + static int bond_ethtool_get_link_ksettings(struct net_device *bond_dev, struct ethtool_link_ksettings *cmd) {
@@ -5798,6 +5822,8 @@ static const struct net_device_ops bond_netdev_ops = { .ndo_bpf = bond_xdp, .ndo_xdp_xmit = bond_xdp_xmit, .ndo_xdp_get_xmit_slave = bond_xdp_get_xmit_slave, + .ndo_hwtstamp_get = bond_hwtstamp_get, + .ndo_hwtstamp_set = bond_hwtstamp_set, }; static const struct device_type bond_type = {
--
2.40.1