net: dsa: allow reporting of standard ethtool stats for slave devices
authorAlvin Šipraga <alsi@bang-olufsen.dk>
Mon, 18 Oct 2021 09:37:57 +0000 (11:37 +0200)
committerDavid S. Miller <davem@davemloft.net>
Mon, 18 Oct 2021 13:02:55 +0000 (14:02 +0100)
Jakub pointed out that we have a new ethtool API for reporting device
statistics in a standardized way, via .get_eth_{phy,mac,ctrl}_stats.
Add a small amount of plumbing to allow DSA drivers to take advantage of
this when exposing statistics.

Suggested-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Alvin Šipraga <alsi@bang-olufsen.dk>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/dsa.h
net/dsa/slave.c

index d784e76..8fefd58 100644 (file)
@@ -645,6 +645,12 @@ struct dsa_switch_ops {
        int     (*get_sset_count)(struct dsa_switch *ds, int port, int sset);
        void    (*get_ethtool_phy_stats)(struct dsa_switch *ds,
                                         int port, uint64_t *data);
+       void    (*get_eth_phy_stats)(struct dsa_switch *ds, int port,
+                                    struct ethtool_eth_phy_stats *phy_stats);
+       void    (*get_eth_mac_stats)(struct dsa_switch *ds, int port,
+                                    struct ethtool_eth_mac_stats *mac_stats);
+       void    (*get_eth_ctrl_stats)(struct dsa_switch *ds, int port,
+                                     struct ethtool_eth_ctrl_stats *ctrl_stats);
        void    (*get_stats64)(struct dsa_switch *ds, int port,
                                   struct rtnl_link_stats64 *s);
        void    (*self_test)(struct dsa_switch *ds, int port,
index 11ec9e6..499f8d1 100644 (file)
@@ -789,6 +789,37 @@ static int dsa_slave_get_sset_count(struct net_device *dev, int sset)
        return -EOPNOTSUPP;
 }
 
+static void dsa_slave_get_eth_phy_stats(struct net_device *dev,
+                                       struct ethtool_eth_phy_stats *phy_stats)
+{
+       struct dsa_port *dp = dsa_slave_to_port(dev);
+       struct dsa_switch *ds = dp->ds;
+
+       if (ds->ops->get_eth_phy_stats)
+               ds->ops->get_eth_phy_stats(ds, dp->index, phy_stats);
+}
+
+static void dsa_slave_get_eth_mac_stats(struct net_device *dev,
+                                       struct ethtool_eth_mac_stats *mac_stats)
+{
+       struct dsa_port *dp = dsa_slave_to_port(dev);
+       struct dsa_switch *ds = dp->ds;
+
+       if (ds->ops->get_eth_mac_stats)
+               ds->ops->get_eth_mac_stats(ds, dp->index, mac_stats);
+}
+
+static void
+dsa_slave_get_eth_ctrl_stats(struct net_device *dev,
+                            struct ethtool_eth_ctrl_stats *ctrl_stats)
+{
+       struct dsa_port *dp = dsa_slave_to_port(dev);
+       struct dsa_switch *ds = dp->ds;
+
+       if (ds->ops->get_eth_ctrl_stats)
+               ds->ops->get_eth_ctrl_stats(ds, dp->index, ctrl_stats);
+}
+
 static void dsa_slave_net_selftest(struct net_device *ndev,
                                   struct ethtool_test *etest, u64 *buf)
 {
@@ -1695,6 +1726,9 @@ static const struct ethtool_ops dsa_slave_ethtool_ops = {
        .get_strings            = dsa_slave_get_strings,
        .get_ethtool_stats      = dsa_slave_get_ethtool_stats,
        .get_sset_count         = dsa_slave_get_sset_count,
+       .get_eth_phy_stats      = dsa_slave_get_eth_phy_stats,
+       .get_eth_mac_stats      = dsa_slave_get_eth_mac_stats,
+       .get_eth_ctrl_stats     = dsa_slave_get_eth_ctrl_stats,
        .set_wol                = dsa_slave_set_wol,
        .get_wol                = dsa_slave_get_wol,
        .set_eee                = dsa_slave_set_eee,