net: dsa: fix error code getting shifted with 4 in dsa_slave_get_sset_count
authorVladimir Oltean <vladimir.oltean@nxp.com>
Sun, 9 May 2021 19:33:38 +0000 (22:33 +0300)
committerDavid S. Miller <davem@davemloft.net>
Mon, 10 May 2021 21:36:59 +0000 (14:36 -0700)
DSA implements a bunch of 'standardized' ethtool statistics counters,
namely tx_packets, tx_bytes, rx_packets, rx_bytes. So whatever the
hardware driver returns in .get_sset_count(), we need to add 4 to that.

That is ok, except that .get_sset_count() can return a negative error
code, for example:

b53_get_sset_count
-> phy_ethtool_get_sset_count
   -> return -EIO

-EIO is -5, and with 4 added to it, it becomes -1, aka -EPERM. One can
imagine that certain error codes may even become positive, although
based on code inspection I did not see instances of that.

Check the error code first, if it is negative return it as-is.

Based on a similar patch for dsa_master_get_strings from Dan Carpenter:
https://patchwork.kernel.org/project/netdevbpf/patch/YJaSe3RPgn7gKxZv@mwanda/

Fixes: 91da11f870f0 ("net: Distributed Switch Architecture protocol support")
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/dsa/slave.c

index 8c0f3c6..d4756b9 100644 (file)
@@ -776,13 +776,15 @@ static int dsa_slave_get_sset_count(struct net_device *dev, int sset)
        struct dsa_switch *ds = dp->ds;
 
        if (sset == ETH_SS_STATS) {
-               int count;
+               int count = 0;
 
-               count = 4;
-               if (ds->ops->get_sset_count)
-                       count += ds->ops->get_sset_count(ds, dp->index, sset);
+               if (ds->ops->get_sset_count) {
+                       count = ds->ops->get_sset_count(ds, dp->index, sset);
+                       if (count < 0)
+                               return count;
+               }
 
-               return count;
+               return count + 4;
        } else if (sset ==  ETH_SS_TEST) {
                return net_selftest_get_count();
        }