summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Marangi <ansuelsmth@gmail.com>2025-04-10 18:30:14 +0200
committerPaolo Abeni <pabeni@redhat.com>2025-04-15 12:10:21 +0200
commit88c810f35ed543dc3ddc3e4d888d89f9e8ecd7cb (patch)
tree04e2b87840b91e3a2325710c85f66154639469be
parentc3b904c6dd814507c70c2c5c24b3ba359ff41d0a (diff)
net: dsa: mt7530: implement .get_stats64
It was reported that the internally calculated counter might differ from the real one from the Switch MIB. This can happen if the switch directly forward packets between the ports or offload small packets like ARP request. In such case, the kernel counter will desync compared to the real one transmitted and received by the Switch. To correctly provide the real info to the kernel, implement .get_stats64 that will directly read the current MIB counter from the switch register. Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> Link: https://patch.msgid.link/20250410163022.3695-7-ansuelsmth@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-rw-r--r--drivers/net/dsa/mt7530.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index fdceefb2083c..0a33ca1dd7ca 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -906,6 +906,51 @@ static void mt7530_get_rmon_stats(struct dsa_switch *ds, int port,
*ranges = mt7530_rmon_ranges;
}
+static void mt7530_get_stats64(struct dsa_switch *ds, int port,
+ struct rtnl_link_stats64 *storage)
+{
+ struct mt7530_priv *priv = ds->priv;
+ uint64_t data;
+
+ /* MIB counter doesn't provide a FramesTransmittedOK but instead
+ * provide stats for Unicast, Broadcast and Multicast frames separately.
+ * To simulate a global frame counter, read Unicast and addition Multicast
+ * and Broadcast later
+ */
+ mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_UNICAST, 1,
+ &storage->rx_packets);
+ mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_MULTICAST, 1,
+ &storage->multicast);
+ storage->rx_packets += storage->multicast;
+ mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_BROADCAST, 1,
+ &data);
+ storage->rx_packets += data;
+
+ mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_UNICAST, 1,
+ &storage->tx_packets);
+ mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_MULTICAST, 1,
+ &data);
+ storage->tx_packets += data;
+ mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_BROADCAST, 1,
+ &data);
+ storage->tx_packets += data;
+
+ mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_BYTES, 2,
+ &storage->rx_bytes);
+
+ mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_BYTES, 2,
+ &storage->tx_bytes);
+
+ mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_DROP, 1,
+ &storage->rx_dropped);
+
+ mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_DROP, 1,
+ &storage->tx_dropped);
+
+ mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_CRC_ERR, 1,
+ &storage->rx_crc_errors);
+}
+
static void mt7530_get_eth_ctrl_stats(struct dsa_switch *ds, int port,
struct ethtool_eth_ctrl_stats *ctrl_stats)
{
@@ -3207,6 +3252,7 @@ const struct dsa_switch_ops mt7530_switch_ops = {
.get_eth_mac_stats = mt7530_get_eth_mac_stats,
.get_rmon_stats = mt7530_get_rmon_stats,
.get_eth_ctrl_stats = mt7530_get_eth_ctrl_stats,
+ .get_stats64 = mt7530_get_stats64,
.set_ageing_time = mt7530_set_ageing_time,
.port_enable = mt7530_port_enable,
.port_disable = mt7530_port_disable,