net: Move PHY statistics code into PHY library helpers
authorFlorian Fainelli <f.fainelli@gmail.com>
Wed, 25 Apr 2018 19:12:47 +0000 (12:12 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 27 Apr 2018 15:53:02 +0000 (11:53 -0400)
In order to make it possible for network device drivers that do not
necessarily have a phy_device attached, but still report PHY statistics,
have a preliminary refactoring consisting in creating helper functions
that encapsulate the PHY device driver knowledge within PHYLIB.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/phy/phy.c
include/linux/phy.h
net/core/ethtool.c

index 05c1e8e..a98ed12 100644 (file)
@@ -1277,3 +1277,51 @@ int phy_ethtool_nway_reset(struct net_device *ndev)
        return phy_restart_aneg(phydev);
 }
 EXPORT_SYMBOL(phy_ethtool_nway_reset);
+
+int phy_ethtool_get_strings(struct phy_device *phydev, u8 *data)
+{
+       if (!phydev->drv)
+               return -EIO;
+
+       mutex_lock(&phydev->lock);
+       phydev->drv->get_strings(phydev, data);
+       mutex_unlock(&phydev->lock);
+
+       return 0;
+}
+EXPORT_SYMBOL(phy_ethtool_get_strings);
+
+int phy_ethtool_get_sset_count(struct phy_device *phydev)
+{
+       int ret;
+
+       if (!phydev->drv)
+               return -EIO;
+
+       if (phydev->drv->get_sset_count &&
+           phydev->drv->get_strings &&
+           phydev->drv->get_stats) {
+               mutex_lock(&phydev->lock);
+               ret = phydev->drv->get_sset_count(phydev);
+               mutex_unlock(&phydev->lock);
+
+               return ret;
+       }
+
+       return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(phy_ethtool_get_sset_count);
+
+int phy_ethtool_get_stats(struct phy_device *phydev,
+                         struct ethtool_stats *stats, u64 *data)
+{
+       if (!phydev->drv)
+               return -EIO;
+
+       mutex_lock(&phydev->lock);
+       phydev->drv->get_stats(phydev, stats, data);
+       mutex_unlock(&phydev->lock);
+
+       return 0;
+}
+EXPORT_SYMBOL(phy_ethtool_get_stats);
index f0b5870..6ca8139 100644 (file)
@@ -1066,6 +1066,26 @@ int phy_ethtool_nway_reset(struct net_device *ndev);
 #if IS_ENABLED(CONFIG_PHYLIB)
 int __init mdio_bus_init(void);
 void mdio_bus_exit(void);
+int phy_ethtool_get_strings(struct phy_device *phydev, u8 *data);
+int phy_ethtool_get_sset_count(struct phy_device *phydev);
+int phy_ethtool_get_stats(struct phy_device *phydev,
+                         struct ethtool_stats *stats, u64 *data);
+#else
+int phy_ethtool_get_strings(struct phy_device *phydev, u8 *data)
+{
+       return -EOPNOTSUPP;
+}
+
+int phy_ethtool_get_sset_count(struct phy_device *phydev)
+{
+       return -EOPNOTSUPP;
+}
+
+int phy_ethtool_get_stats(struct phy_device *phydev,
+                         struct ethtool_stats *stats, u64 *data)
+{
+       return -EOPNOTSUPP;
+}
 #endif
 
 extern struct bus_type mdio_bus_type;
index 4650fd6..efcd8e6 100644 (file)
@@ -211,23 +211,6 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
        return ret;
 }
 
-static int phy_get_sset_count(struct phy_device *phydev)
-{
-       int ret;
-
-       if (phydev->drv->get_sset_count &&
-           phydev->drv->get_strings &&
-           phydev->drv->get_stats) {
-               mutex_lock(&phydev->lock);
-               ret = phydev->drv->get_sset_count(phydev);
-               mutex_unlock(&phydev->lock);
-
-               return ret;
-       }
-
-       return -EOPNOTSUPP;
-}
-
 static int __ethtool_get_sset_count(struct net_device *dev, int sset)
 {
        const struct ethtool_ops *ops = dev->ethtool_ops;
@@ -246,7 +229,7 @@ static int __ethtool_get_sset_count(struct net_device *dev, int sset)
 
        if (sset == ETH_SS_PHY_STATS) {
                if (dev->phydev)
-                       return phy_get_sset_count(dev->phydev);
+                       return phy_ethtool_get_sset_count(dev->phydev);
                else
                        return -EOPNOTSUPP;
        }
@@ -273,15 +256,10 @@ static void __ethtool_get_strings(struct net_device *dev,
        else if (stringset == ETH_SS_PHY_TUNABLES)
                memcpy(data, phy_tunable_strings, sizeof(phy_tunable_strings));
        else if (stringset == ETH_SS_PHY_STATS) {
-               struct phy_device *phydev = dev->phydev;
-
-               if (phydev) {
-                       mutex_lock(&phydev->lock);
-                       phydev->drv->get_strings(phydev, data);
-                       mutex_unlock(&phydev->lock);
-               } else {
+               if (dev->phydev)
+                       phy_ethtool_get_strings(dev->phydev, data);
+               else
                        return;
-               }
        } else
                /* ops->get_strings is valid because checked earlier */
                ops->get_strings(dev, stringset, data);
@@ -2002,7 +1980,7 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
        if (!phydev)
                return -EOPNOTSUPP;
 
-       n_stats = phy_get_sset_count(phydev);
+       n_stats = phy_ethtool_get_sset_count(dev->phydev);
        if (n_stats < 0)
                return n_stats;
        if (n_stats > S32_MAX / sizeof(u64))
@@ -2017,9 +1995,9 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
        if (n_stats && !data)
                return -ENOMEM;
 
-       mutex_lock(&phydev->lock);
-       phydev->drv->get_stats(phydev, &stats, data);
-       mutex_unlock(&phydev->lock);
+       ret = phy_ethtool_get_stats(dev->phydev, &stats, data);
+       if (ret < 0)
+               return ret;
 
        ret = -EFAULT;
        if (copy_to_user(useraddr, &stats, sizeof(stats)))