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:
parent
430dc3256d
commit
b8768dc407
5 changed files with 18 additions and 54 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Add table
Reference in a new issue