1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00

net: ethtool: Refactor identical get_ts_info implementations.

The vlan, macvlan and the bonding drivers call their "real" device driver
in order to report the time stamping capabilities.  Provide a core
ethtool helper function to avoid copy/paste in the stack.

Signed-off-by: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Reviewed-by: Jay Vosburgh <jay.vosburgh@canonical.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Richard Cochran 2023-11-14 12:28:31 +01:00 committed by David S. Miller
parent 430dc3256d
commit b8768dc407
5 changed files with 18 additions and 54 deletions

View file

@ -5755,10 +5755,8 @@ static int bond_ethtool_get_ts_info(struct net_device *bond_dev,
{ {
struct bonding *bond = netdev_priv(bond_dev); struct bonding *bond = netdev_priv(bond_dev);
struct ethtool_ts_info ts_info; struct ethtool_ts_info ts_info;
const struct ethtool_ops *ops;
struct net_device *real_dev; struct net_device *real_dev;
bool sw_tx_support = false; bool sw_tx_support = false;
struct phy_device *phydev;
struct list_head *iter; struct list_head *iter;
struct slave *slave; struct slave *slave;
int ret = 0; int ret = 0;
@ -5769,29 +5767,12 @@ static int bond_ethtool_get_ts_info(struct net_device *bond_dev,
rcu_read_unlock(); rcu_read_unlock();
if (real_dev) { if (real_dev) {
ops = real_dev->ethtool_ops; ret = ethtool_get_ts_info_by_layer(real_dev, info);
phydev = real_dev->phydev;
if (phy_has_tsinfo(phydev)) {
ret = phy_ts_info(phydev, info);
goto out;
} else if (ops->get_ts_info) {
ret = ops->get_ts_info(real_dev, info);
goto out;
}
} else { } else {
/* Check if all slaves support software tx timestamping */ /* Check if all slaves support software tx timestamping */
rcu_read_lock(); rcu_read_lock();
bond_for_each_slave_rcu(bond, slave, iter) { bond_for_each_slave_rcu(bond, slave, iter) {
ret = -1; ret = ethtool_get_ts_info_by_layer(slave->dev, &ts_info);
ops = slave->dev->ethtool_ops;
phydev = slave->dev->phydev;
if (phy_has_tsinfo(phydev))
ret = phy_ts_info(phydev, &ts_info);
else if (ops->get_ts_info)
ret = ops->get_ts_info(slave->dev, &ts_info);
if (!ret && (ts_info.so_timestamping & SOF_TIMESTAMPING_TX_SOFTWARE)) { if (!ret && (ts_info.so_timestamping & SOF_TIMESTAMPING_TX_SOFTWARE)) {
sw_tx_support = true; sw_tx_support = true;
continue; continue;
@ -5803,15 +5784,9 @@ static int bond_ethtool_get_ts_info(struct net_device *bond_dev,
rcu_read_unlock(); rcu_read_unlock();
} }
ret = 0;
info->so_timestamping = SOF_TIMESTAMPING_RX_SOFTWARE |
SOF_TIMESTAMPING_SOFTWARE;
if (sw_tx_support) if (sw_tx_support)
info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE; info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE;
info->phc_index = -1;
out:
dev_put(real_dev); dev_put(real_dev);
return ret; return ret;
} }

View file

@ -1086,20 +1086,8 @@ static int macvlan_ethtool_get_ts_info(struct net_device *dev,
struct ethtool_ts_info *info) struct ethtool_ts_info *info)
{ {
struct net_device *real_dev = macvlan_dev_real_dev(dev); struct net_device *real_dev = macvlan_dev_real_dev(dev);
const struct ethtool_ops *ops = real_dev->ethtool_ops;
struct phy_device *phydev = real_dev->phydev;
if (phy_has_tsinfo(phydev)) { return ethtool_get_ts_info_by_layer(real_dev, info);
return phy_ts_info(phydev, info);
} else if (ops->get_ts_info) {
return ops->get_ts_info(real_dev, info);
} else {
info->so_timestamping = SOF_TIMESTAMPING_RX_SOFTWARE |
SOF_TIMESTAMPING_SOFTWARE;
info->phc_index = -1;
}
return 0;
} }
static netdev_features_t macvlan_fix_features(struct net_device *dev, static netdev_features_t macvlan_fix_features(struct net_device *dev,

View file

@ -1043,6 +1043,14 @@ static inline int ethtool_mm_frag_size_min_to_add(u32 val_min, u32 *val_add,
return -EINVAL; return -EINVAL;
} }
/**
* ethtool_get_ts_info_by_layer - Obtains time stamping capabilities from the MAC or PHY layer.
* @dev: pointer to net_device structure
* @info: buffer to hold the result
* Returns zero on success, non-zero otherwise.
*/
int ethtool_get_ts_info_by_layer(struct net_device *dev, struct ethtool_ts_info *info);
/** /**
* ethtool_sprintf - Write formatted string to ethtool string data * ethtool_sprintf - Write formatted string to ethtool string data
* @data: Pointer to a pointer to the start of string to update * @data: Pointer to a pointer to the start of string to update

View file

@ -702,20 +702,7 @@ static int vlan_ethtool_get_ts_info(struct net_device *dev,
struct ethtool_ts_info *info) struct ethtool_ts_info *info)
{ {
const struct vlan_dev_priv *vlan = vlan_dev_priv(dev); const struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
const struct ethtool_ops *ops = vlan->real_dev->ethtool_ops; return ethtool_get_ts_info_by_layer(vlan->real_dev, info);
struct phy_device *phydev = vlan->real_dev->phydev;
if (phy_has_tsinfo(phydev)) {
return phy_ts_info(phydev, info);
} else if (ops->get_ts_info) {
return ops->get_ts_info(vlan->real_dev, info);
} else {
info->so_timestamping = SOF_TIMESTAMPING_RX_SOFTWARE |
SOF_TIMESTAMPING_SOFTWARE;
info->phc_index = -1;
}
return 0;
} }
static void vlan_dev_get_stats64(struct net_device *dev, static void vlan_dev_get_stats64(struct net_device *dev,

View file

@ -661,6 +661,12 @@ int ethtool_get_phc_vclocks(struct net_device *dev, int **vclock_index)
} }
EXPORT_SYMBOL(ethtool_get_phc_vclocks); EXPORT_SYMBOL(ethtool_get_phc_vclocks);
int ethtool_get_ts_info_by_layer(struct net_device *dev, struct ethtool_ts_info *info)
{
return __ethtool_get_ts_info(dev, info);
}
EXPORT_SYMBOL(ethtool_get_ts_info_by_layer);
const struct ethtool_phy_ops *ethtool_phy_ops; const struct ethtool_phy_ops *ethtool_phy_ops;
void ethtool_set_ethtool_phy_ops(const struct ethtool_phy_ops *ops) void ethtool_set_ethtool_phy_ops(const struct ethtool_phy_ops *ops)