mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-12 21:44:06 +08:00
net: bonding: convert to ndo_hwtstamp_get() / ndo_hwtstamp_set()
bonding is one of the stackable net devices which pass the hardware timestamping ops to the real device through ndo_eth_ioctl(). This prevents converting any device driver to the new hwtimestamping API without regressions. Remove that limitation in bonding by using the newly introduced helpers for timestamping through lower devices, that handle both the new and the old driver API. Signed-off-by: Maxim Georgiev <glipus@gmail.com> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Reviewed-by: Jacob Keller <jacob.e.keller@intel.com> Link: https://lore.kernel.org/r/20230801142824.1772134-6-vladimir.oltean@nxp.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
0bca3f7f9a
commit
c0dabeb4c6
@ -4446,11 +4446,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);
|
||||
|
||||
@ -4477,44 +4472,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)
|
||||
@ -5688,6 +5650,67 @@ static u32 bond_mode_bcast_speed(struct slave *slave, u32 speed)
|
||||
return speed;
|
||||
}
|
||||
|
||||
/* Set the BOND_PHC_INDEX flag to notify user space */
|
||||
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->copied_to_user) {
|
||||
/* Lower device has a legacy implementation */
|
||||
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 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);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return bond_set_phc_index_flag(cfg);
|
||||
}
|
||||
|
||||
static int bond_hwtstamp_set(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;
|
||||
|
||||
if (!(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, cfg, extack);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return bond_set_phc_index_flag(cfg);
|
||||
}
|
||||
|
||||
static int bond_ethtool_get_link_ksettings(struct net_device *bond_dev,
|
||||
struct ethtool_link_ksettings *cmd)
|
||||
{
|
||||
@ -5836,6 +5859,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 = {
|
||||
|
Loading…
Reference in New Issue
Block a user