net: ethtool: Refactor identical get_ts_info implementations.
authorRichard Cochran <richardcochran@gmail.com>
Tue, 14 Nov 2023 11:28:31 +0000 (12:28 +0100)
committerDavid S. Miller <davem@davemloft.net>
Sat, 18 Nov 2023 14:52:57 +0000 (14:52 +0000)
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>
drivers/net/bonding/bond_main.c
drivers/net/macvlan.c
include/linux/ethtool.h
net/8021q/vlan_dev.c
net/ethtool/common.c

index 8e6cc0e..4e0600c 100644 (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 ethtool_ts_info ts_info;
-       const struct ethtool_ops *ops;
        struct net_device *real_dev;
        bool sw_tx_support = false;
-       struct phy_device *phydev;
        struct list_head *iter;
        struct slave *slave;
        int ret = 0;
@@ -5769,29 +5767,12 @@ static int bond_ethtool_get_ts_info(struct net_device *bond_dev,
        rcu_read_unlock();
 
        if (real_dev) {
-               ops = real_dev->ethtool_ops;
-               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;
-               }
+               ret = ethtool_get_ts_info_by_layer(real_dev, info);
        } else {
                /* Check if all slaves support software tx timestamping */
                rcu_read_lock();
                bond_for_each_slave_rcu(bond, slave, iter) {
-                       ret = -1;
-                       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);
-
+                       ret = ethtool_get_ts_info_by_layer(slave->dev, &ts_info);
                        if (!ret && (ts_info.so_timestamping & SOF_TIMESTAMPING_TX_SOFTWARE)) {
                                sw_tx_support = true;
                                continue;
@@ -5803,15 +5784,9 @@ static int bond_ethtool_get_ts_info(struct net_device *bond_dev,
                rcu_read_unlock();
        }
 
-       ret = 0;
-       info->so_timestamping = SOF_TIMESTAMPING_RX_SOFTWARE |
-                               SOF_TIMESTAMPING_SOFTWARE;
        if (sw_tx_support)
                info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE;
 
-       info->phc_index = -1;
-
-out:
        dev_put(real_dev);
        return ret;
 }
index c8da94a..88dd8a2 100644 (file)
@@ -1086,20 +1086,8 @@ static int macvlan_ethtool_get_ts_info(struct net_device *dev,
                                       struct ethtool_ts_info *info)
 {
        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 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;
+       return ethtool_get_ts_info_by_layer(real_dev, info);
 }
 
 static netdev_features_t macvlan_fix_features(struct net_device *dev,
index 6890282..c2bb741 100644 (file)
@@ -1043,6 +1043,14 @@ static inline int ethtool_mm_frag_size_min_to_add(u32 val_min, u32 *val_add,
        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
  * @data: Pointer to a pointer to the start of string to update
index 2a7f1b1..407b233 100644 (file)
@@ -702,20 +702,7 @@ static int vlan_ethtool_get_ts_info(struct net_device *dev,
                                    struct ethtool_ts_info *info)
 {
        const struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
-       const struct ethtool_ops *ops = vlan->real_dev->ethtool_ops;
-       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;
+       return ethtool_get_ts_info_by_layer(vlan->real_dev, info);
 }
 
 static void vlan_dev_get_stats64(struct net_device *dev,
index b4419fb..11d8797 100644 (file)
@@ -661,6 +661,12 @@ int ethtool_get_phc_vclocks(struct net_device *dev, int **vclock_index)
 }
 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;
 
 void ethtool_set_ethtool_phy_ops(const struct ethtool_phy_ops *ops)