realtek: dsa: add table-based statistics infrastructure
authorSharadanand Karanjkar <[email protected]>
Thu, 14 Aug 2025 15:48:14 +0000 (15:48 +0000)
committerHauke Mehrtens <[email protected]>
Sat, 15 Nov 2025 23:10:56 +0000 (00:10 +0100)
Some Realtek SoCs such as the RTL931X store MIB counters in tables rather
than registers. Unlike register reads, table access requires programming
the table control register, setting the command field to determine read or
write, and then polling for completion. This makes it necessary to
implement a separate path for table-based statistics.

Like register-based MIBs, the table-based MIBs also come in two types: STD
and PRIV which will require slightly different implementations.

Signed-off-by: Sharadanand Karanjkar <[email protected]>
Signed-off-by: Sven Eckelmann <[email protected]>
Link: https://github.com/openwrt/openwrt/pull/20631
Signed-off-by: Hauke Mehrtens <[email protected]>
target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c
target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h
target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl83xx.h

index 6468f9a48355e3589d490bba78a0afe2f5d0b79c..6d2dcbe609aeaf33af9d84d52f0933680f3cf3c9 100644 (file)
@@ -880,6 +880,15 @@ static bool rtldsa_read_mib_item(struct rtl838x_switch_priv *priv, int port,
                reg = priv->r->stat_port_prv_mib;
                reg_offset = 128;
                break;
+       case MIB_TBL_STD:
+       case MIB_TBL_PRV:
+               if (!priv->r->stat_port_table_read)
+                       return false;
+
+               *data = priv->r->stat_port_table_read(port, mib_item->size, mib_item->offset,
+                                                     mib_item->reg == MIB_TBL_PRV);
+
+               return true;
        default:
                return false;
        }
index 4120f5ff48a6dd3914db463386ef83b68f21c23a..e3f894ad6d482f75f50816c53f30f0ae3bf29463 100644 (file)
@@ -1121,6 +1121,7 @@ struct rtl838x_reg {
        int stat_rst;
        int stat_port_std_mib;
        int stat_port_prv_mib;
+       u64 (*stat_port_table_read)(int port, unsigned int mib_size, unsigned int offset, bool is_pvt);
        int (*port_iso_ctrl)(int p);
        void (*traffic_enable)(int source, int dest);
        void (*traffic_disable)(int source, int dest);
index 5b98c85848fcfa79c05c559532209259f3dcb1e7..1b04c657088c7a0d75a2173eb915ab6064905016 100644 (file)
@@ -20,7 +20,9 @@ struct fdb_update_work {
 enum mib_reg {
        MIB_REG_INVALID = 0,
        MIB_REG_STD,
-       MIB_REG_PRV
+       MIB_REG_PRV,
+       MIB_TBL_STD,
+       MIB_TBL_PRV,
 };
 
 #define MIB_ITEM(_reg, _offset, _size) \