[openwrt/openwrt] realtek: implement get_stats64

LEDE Commits lede-commits at lists.infradead.org
Sun Jul 27 07:47:11 PDT 2025


hauke pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/fa63a5365ed905396bdae3bd91c35df6999a08ac

commit fa63a5365ed905396bdae3bd91c35df6999a08ac
Author: Jan Hoffmann <jan at 3e8.eu>
AuthorDate: Fri Apr 25 20:18:52 2025 +0200

    realtek: implement get_stats64
    
    By default, the network interface stats are based on software counters,
    which only consider traffic from and to the CPU. Implementing the
    get_stats64 method allows to report the full hardware counters instead.
    
    Signed-off-by: Jan Hoffmann <jan at 3e8.eu>
    Link: https://github.com/openwrt/openwrt/pull/18415
    Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
---
 .../files-6.12/drivers/net/dsa/rtl83xx/dsa.c       | 59 ++++++++++++++++++++++
 .../files-6.12/drivers/net/dsa/rtl83xx/rtl83xx.h   |  4 ++
 2 files changed, 63 insertions(+)

diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c
index adeb81591c..0823334f42 100644
--- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c
+++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c
@@ -79,6 +79,7 @@ const struct rtldsa_mib_desc rtldsa_838x_mib = {
 	.if_out_ucast_pkts = MIB_ITEM(MIB_REG_STD, 0xdc, 1),
 	.if_out_mcast_pkts = MIB_ITEM(MIB_REG_STD, 0xd8, 1),
 	.if_out_bcast_pkts = MIB_ITEM(MIB_REG_STD, 0xd4, 1),
+	.if_out_discards = MIB_ITEM(MIB_REG_STD, 0xd0, 1),
 	.single_collisions = MIB_ITEM(MIB_REG_STD, 0xcc, 1),
 	.multiple_collisions = MIB_ITEM(MIB_REG_STD, 0xc8, 1),
 	.deferred_transmissions = MIB_ITEM(MIB_REG_STD, 0xc4, 1),
@@ -121,6 +122,9 @@ const struct rtldsa_mib_desc rtldsa_838x_mib = {
 		{ 1519, 10000 }
 	},
 
+	.drop_events = MIB_ITEM(MIB_REG_STD, 0xa8, 1),
+	.collisions = MIB_ITEM(MIB_REG_STD, 0x7c, 1),
+
 	.rx_pause_frames = MIB_ITEM(MIB_REG_STD, 0xb0, 1),
 	.tx_pause_frames = MIB_ITEM(MIB_REG_STD, 0xac, 1),
 
@@ -159,6 +163,7 @@ const struct rtldsa_mib_desc rtldsa_839x_mib = {
 	.if_out_ucast_pkts = MIB_ITEM(MIB_REG_STD, 0xe0, 1),
 	.if_out_mcast_pkts = MIB_ITEM(MIB_REG_STD, 0xdc, 1),
 	.if_out_bcast_pkts = MIB_ITEM(MIB_REG_STD, 0xd8, 1),
+	.if_out_discards = MIB_ITEM(MIB_REG_STD, 0xd4, 1),
 	.single_collisions = MIB_ITEM(MIB_REG_STD, 0xcc, 1),
 	.multiple_collisions = MIB_ITEM(MIB_REG_STD, 0xc8, 1),
 	.deferred_transmissions = MIB_ITEM(MIB_REG_STD, 0xc4, 1),
@@ -201,6 +206,9 @@ const struct rtldsa_mib_desc rtldsa_839x_mib = {
 		{ 1519, 12288 }
 	},
 
+	.drop_events = MIB_ITEM(MIB_REG_STD, 0xa8, 1),
+	.collisions = MIB_ITEM(MIB_REG_STD, 0x7c, 1),
+
 	.rx_pause_frames = MIB_ITEM(MIB_REG_STD, 0xb0, 1),
 	.tx_pause_frames = MIB_ITEM(MIB_REG_STD, 0xac, 1),
 
@@ -249,6 +257,7 @@ const struct rtldsa_mib_desc rtldsa_930x_mib = {
 	.if_out_ucast_pkts = MIB_ITEM(MIB_REG_STD, 0xd0, 2),
 	.if_out_mcast_pkts = MIB_ITEM(MIB_REG_STD, 0xc8, 2),
 	.if_out_bcast_pkts = MIB_ITEM(MIB_REG_STD, 0xc0, 2),
+	.if_out_discards = MIB_ITEM(MIB_REG_STD, 0xbc, 1),
 	.single_collisions = MIB_ITEM(MIB_REG_STD, 0xb4, 1),
 	.multiple_collisions = MIB_ITEM(MIB_REG_STD, 0xb0, 1),
 	.deferred_transmissions = MIB_ITEM(MIB_REG_STD, 0xac, 1),
@@ -294,6 +303,9 @@ const struct rtldsa_mib_desc rtldsa_930x_mib = {
 		{ 12289, 65535 }
 	},
 
+	.drop_events = MIB_ITEM(MIB_REG_STD, 0x90, 1),
+	.collisions = MIB_ITEM(MIB_REG_STD, 0x5c, 1),
+
 	.rx_pause_frames = MIB_ITEM(MIB_REG_STD, 0x98, 1),
 	.tx_pause_frames = MIB_ITEM(MIB_REG_STD, 0x94, 1),
 
@@ -1279,6 +1291,51 @@ static void rtldsa_get_rmon_stats(struct dsa_switch *ds, int port,
 	*ranges = mib_desc->rmon_ranges;
 }
 
+static void rtldsa_get_stats64(struct dsa_switch *ds, int port,
+			       struct rtnl_link_stats64 *s)
+{
+	struct rtl838x_switch_priv *priv = ds->priv;
+	const struct rtldsa_mib_desc *mib_desc;
+	uint64_t val;
+
+	if (port < 0 || port >= priv->cpu_port)
+		return;
+
+	mib_desc = rtldsa_get_mib_desc(priv);
+	if (!mib_desc) {
+		dev_get_tstats64(dsa_to_port(ds, port)->user, s);
+		return;
+	}
+
+	rtldsa_read_mib_item(priv, port, &mib_desc->if_in_ucast_pkts, &s->rx_packets);
+	if (rtldsa_read_mib_item(priv, port, &mib_desc->if_in_mcast_pkts, &s->multicast))
+		s->rx_packets += s->multicast;
+	if (rtldsa_read_mib_item(priv, port, &mib_desc->if_in_bcast_pkts, &val))
+		s->rx_packets += val;
+
+	rtldsa_read_mib_item(priv, port, &mib_desc->if_out_ucast_pkts, &s->tx_packets);
+	if (rtldsa_read_mib_item(priv, port, &mib_desc->if_out_mcast_pkts, &val))
+		s->tx_packets += val;
+	if (rtldsa_read_mib_item(priv, port, &mib_desc->if_out_bcast_pkts, &val))
+		s->tx_packets += val;
+
+	/* Ideally, we should subtract the FCS for each packet here */
+	rtldsa_read_mib_item(priv, port, &mib_desc->if_in_octets, &s->rx_bytes);
+	rtldsa_read_mib_item(priv, port, &mib_desc->if_out_octets, &s->tx_bytes);
+
+	rtldsa_read_mib_item(priv, port, &mib_desc->collisions, &s->collisions);
+
+	rtldsa_read_mib_item(priv, port, &mib_desc->drop_events, &s->rx_dropped);
+	rtldsa_read_mib_item(priv, port, &mib_desc->if_out_discards, &s->tx_dropped);
+
+	rtldsa_read_mib_item(priv, port, &mib_desc->crc_align_errors, &s->rx_crc_errors);
+	s->rx_errors = s->rx_crc_errors;
+
+	rtldsa_read_mib_item(priv, port, &mib_desc->excessive_collisions, &s->tx_aborted_errors);
+	rtldsa_read_mib_item(priv, port, &mib_desc->late_collisions, &s->tx_window_errors);
+	s->tx_errors = s->tx_aborted_errors + s->tx_window_errors;
+}
+
 static void rtldsa_get_pause_stats(struct dsa_switch *ds, int port,
 				   struct ethtool_pause_stats *pause_stats)
 {
@@ -2501,6 +2558,7 @@ const struct dsa_switch_ops rtl83xx_switch_ops = {
 	.get_eth_mac_stats	= rtldsa_get_eth_mac_stats,
 	.get_eth_ctrl_stats	= rtldsa_get_eth_ctrl_stats,
 	.get_rmon_stats		= rtldsa_get_rmon_stats,
+	.get_stats64		= rtldsa_get_stats64,
 	.get_pause_stats	= rtldsa_get_pause_stats,
 
 	.port_enable		= rtl83xx_port_enable,
@@ -2563,6 +2621,7 @@ const struct dsa_switch_ops rtl930x_switch_ops = {
 	.get_eth_mac_stats	= rtldsa_get_eth_mac_stats,
 	.get_eth_ctrl_stats	= rtldsa_get_eth_ctrl_stats,
 	.get_rmon_stats		= rtldsa_get_rmon_stats,
+	.get_stats64		= rtldsa_get_stats64,
 	.get_pause_stats	= rtldsa_get_pause_stats,
 
 	.port_enable		= rtl83xx_port_enable,
diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl83xx.h b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl83xx.h
index 79d9d9a018..bc89f514c7 100644
--- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl83xx.h
+++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl83xx.h
@@ -51,6 +51,7 @@ struct rtldsa_mib_desc {
 	struct rtldsa_mib_item if_out_ucast_pkts;
 	struct rtldsa_mib_item if_out_mcast_pkts;
 	struct rtldsa_mib_item if_out_bcast_pkts;
+	struct rtldsa_mib_item if_out_discards;
 	struct rtldsa_mib_item single_collisions;
 	struct rtldsa_mib_item multiple_collisions;
 	struct rtldsa_mib_item deferred_transmissions;
@@ -69,6 +70,9 @@ struct rtldsa_mib_desc {
 	struct rtldsa_mib_item rx_pkts[ETHTOOL_RMON_HIST_MAX];
 	struct ethtool_rmon_hist_range rmon_ranges[ETHTOOL_RMON_HIST_MAX];
 
+	struct rtldsa_mib_item drop_events;
+	struct rtldsa_mib_item collisions;
+
 	struct rtldsa_mib_item rx_pause_frames;
 	struct rtldsa_mib_item tx_pause_frames;
 




More information about the lede-commits mailing list