diff options
author | Jakub Kicinski <kuba@kernel.org> | 2022-06-29 20:17:14 -0700 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2022-06-29 20:19:15 -0700 |
commit | 2a832912dba29f30f8df58b682ab0535c89682b5 (patch) | |
tree | c5d8a31a4873c1057ea6b37471ccc970705e2381 | |
parent | 702e70143291b09e6245deb8ab904d1c18ed4f47 (diff) | |
parent | 961d6c70d886ecc057f6e501db5879feb55db3b3 (diff) | |
download | lwn-2a832912dba29f30f8df58b682ab0535c89682b5.tar.gz lwn-2a832912dba29f30f8df58b682ab0535c89682b5.zip |
Merge branch 'net-dsa-add-pause-stats-support'
Oleksij Rempel says:
====================
net: dsa: add pause stats support
====================
Link: https://lore.kernel.org/r/20220628085155.2591201-1-o.rempel@pengutronix.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r-- | drivers/net/dsa/microchip/ksz_common.c | 25 | ||||
-rw-r--r-- | drivers/net/dsa/microchip/ksz_common.h | 1 | ||||
-rw-r--r-- | drivers/net/dsa/qca/ar9331.c | 17 | ||||
-rw-r--r-- | include/net/dsa.h | 2 | ||||
-rw-r--r-- | net/dsa/slave.c | 11 |
5 files changed, 54 insertions, 2 deletions
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index 1354804171a1..29b42b3b39c9 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -671,18 +671,22 @@ static void ksz_phylink_get_caps(struct dsa_switch *ds, int port, void ksz_r_mib_stats64(struct ksz_device *dev, int port) { + struct ethtool_pause_stats *pstats; struct rtnl_link_stats64 *stats; struct ksz_stats_raw *raw; struct ksz_port_mib *mib; mib = &dev->ports[port].mib; stats = &mib->stats64; + pstats = &mib->pause_stats; raw = (struct ksz_stats_raw *)mib->counters; spin_lock(&mib->stats64_lock); - stats->rx_packets = raw->rx_bcast + raw->rx_mcast + raw->rx_ucast; - stats->tx_packets = raw->tx_bcast + raw->tx_mcast + raw->tx_ucast; + stats->rx_packets = raw->rx_bcast + raw->rx_mcast + raw->rx_ucast + + raw->rx_pause; + stats->tx_packets = raw->tx_bcast + raw->tx_mcast + raw->tx_ucast + + raw->tx_pause; /* HW counters are counting bytes + FCS which is not acceptable * for rtnl_link_stats64 interface @@ -708,6 +712,9 @@ void ksz_r_mib_stats64(struct ksz_device *dev, int port) stats->multicast = raw->rx_mcast; stats->collisions = raw->tx_total_col; + pstats->tx_pause_frames = raw->tx_pause; + pstats->rx_pause_frames = raw->rx_pause; + spin_unlock(&mib->stats64_lock); } @@ -724,6 +731,19 @@ static void ksz_get_stats64(struct dsa_switch *ds, int port, spin_unlock(&mib->stats64_lock); } +static void ksz_get_pause_stats(struct dsa_switch *ds, int port, + struct ethtool_pause_stats *pause_stats) +{ + struct ksz_device *dev = ds->priv; + struct ksz_port_mib *mib; + + mib = &dev->ports[port].mib; + + spin_lock(&mib->stats64_lock); + memcpy(pause_stats, &mib->pause_stats, sizeof(*pause_stats)); + spin_unlock(&mib->stats64_lock); +} + static void ksz_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *buf) { @@ -1336,6 +1356,7 @@ static const struct dsa_switch_ops ksz_switch_ops = { .port_mirror_add = ksz_port_mirror_add, .port_mirror_del = ksz_port_mirror_del, .get_stats64 = ksz_get_stats64, + .get_pause_stats = ksz_get_pause_stats, .port_change_mtu = ksz_change_mtu, .port_max_mtu = ksz_max_mtu, }; diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h index 91fbb3b62536..b61e569a9949 100644 --- a/drivers/net/dsa/microchip/ksz_common.h +++ b/drivers/net/dsa/microchip/ksz_common.h @@ -25,6 +25,7 @@ struct ksz_port_mib { u8 cnt_ptr; u64 *counters; struct rtnl_link_stats64 stats64; + struct ethtool_pause_stats pause_stats; struct spinlock stats64_lock; }; diff --git a/drivers/net/dsa/qca/ar9331.c b/drivers/net/dsa/qca/ar9331.c index f23ce56fa591..0796b7cf8cae 100644 --- a/drivers/net/dsa/qca/ar9331.c +++ b/drivers/net/dsa/qca/ar9331.c @@ -231,6 +231,7 @@ struct ar9331_sw_port { int idx; struct delayed_work mib_read; struct rtnl_link_stats64 stats; + struct ethtool_pause_stats pause_stats; struct spinlock stats_lock; }; @@ -604,6 +605,7 @@ static void ar9331_sw_phylink_mac_link_up(struct dsa_switch *ds, int port, static void ar9331_read_stats(struct ar9331_sw_port *port) { struct ar9331_sw_priv *priv = ar9331_sw_port_to_priv(port); + struct ethtool_pause_stats *pstats = &port->pause_stats; struct rtnl_link_stats64 *stats = &port->stats; struct ar9331_sw_stats_raw raw; int ret; @@ -644,6 +646,9 @@ static void ar9331_read_stats(struct ar9331_sw_port *port) stats->multicast += raw.rxmulti; stats->collisions += raw.txcollision; + pstats->tx_pause_frames += raw.txpause; + pstats->rx_pause_frames += raw.rxpause; + spin_unlock(&port->stats_lock); } @@ -668,6 +673,17 @@ static void ar9331_get_stats64(struct dsa_switch *ds, int port, spin_unlock(&p->stats_lock); } +static void ar9331_get_pause_stats(struct dsa_switch *ds, int port, + struct ethtool_pause_stats *pause_stats) +{ + struct ar9331_sw_priv *priv = (struct ar9331_sw_priv *)ds->priv; + struct ar9331_sw_port *p = &priv->port[port]; + + spin_lock(&p->stats_lock); + memcpy(pause_stats, &p->pause_stats, sizeof(*pause_stats)); + spin_unlock(&p->stats_lock); +} + static const struct dsa_switch_ops ar9331_sw_ops = { .get_tag_protocol = ar9331_sw_get_tag_protocol, .setup = ar9331_sw_setup, @@ -677,6 +693,7 @@ static const struct dsa_switch_ops ar9331_sw_ops = { .phylink_mac_link_down = ar9331_sw_phylink_mac_link_down, .phylink_mac_link_up = ar9331_sw_phylink_mac_link_up, .get_stats64 = ar9331_get_stats64, + .get_pause_stats = ar9331_get_pause_stats, }; static irqreturn_t ar9331_sw_irq(int irq, void *data) diff --git a/include/net/dsa.h b/include/net/dsa.h index 33283eeda697..ea7bf007f34f 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -895,6 +895,8 @@ struct dsa_switch_ops { const struct ethtool_rmon_hist_range **ranges); void (*get_stats64)(struct dsa_switch *ds, int port, struct rtnl_link_stats64 *s); + void (*get_pause_stats)(struct dsa_switch *ds, int port, + struct ethtool_pause_stats *pause_stats); void (*self_test)(struct dsa_switch *ds, int port, struct ethtool_test *etest, u64 *data); diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 760ca58307a3..ad6a6663feeb 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -1109,6 +1109,16 @@ static int dsa_slave_set_link_ksettings(struct net_device *dev, return phylink_ethtool_ksettings_set(dp->pl, cmd); } +static void dsa_slave_get_pause_stats(struct net_device *dev, + struct ethtool_pause_stats *pause_stats) +{ + struct dsa_port *dp = dsa_slave_to_port(dev); + struct dsa_switch *ds = dp->ds; + + if (ds->ops->get_pause_stats) + ds->ops->get_pause_stats(ds, dp->index, pause_stats); +} + static void dsa_slave_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *pause) { @@ -2100,6 +2110,7 @@ static const struct ethtool_ops dsa_slave_ethtool_ops = { .get_eee = dsa_slave_get_eee, .get_link_ksettings = dsa_slave_get_link_ksettings, .set_link_ksettings = dsa_slave_set_link_ksettings, + .get_pause_stats = dsa_slave_get_pause_stats, .get_pauseparam = dsa_slave_get_pauseparam, .set_pauseparam = dsa_slave_set_pauseparam, .get_rxnfc = dsa_slave_get_rxnfc, |