[openwrt/openwrt] realtek: dsa: rtl93xx: Implement vlan fast age flushing

LEDE Commits lede-commits at lists.infradead.org
Sat Nov 15 07:22:08 PST 2025


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

commit 9c2e8d6cef08b63ff95ffe9ddba4f9f11da0ed0a
Author: Issam Hamdi <ih at simonwunderlich.de>
AuthorDate: Tue Jul 15 19:41:13 2025 +0200

    realtek: dsa: rtl93xx: Implement vlan fast age flushing
    
    The DSA port code is trying to flush associated VLANs whenever the MST
    state is changed. This functionality is available on a per port+vid based
    using the L2_TBL_FLUSH_CTRL which is already used for the .port_fast_age
    callbacks.
    
    Signed-off-by: Issam Hamdi <ih at simonwunderlich.de>
    Co-developed-by: Sven Eckelmann <se at simonwunderlich.de>
    Signed-off-by: Sven Eckelmann <se at simonwunderlich.de>
    Link: https://github.com/openwrt/openwrt/pull/20421
    Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
---
 .../realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c  | 16 ++++++++++++++++
 .../files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h      |  1 +
 .../files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c      | 19 +++++++++++++++++++
 .../files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c      | 19 +++++++++++++++++++
 4 files changed, 55 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 bfdbbf6db6..f83ac7bd26 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
@@ -1830,6 +1830,21 @@ static int rtl83xx_vlan_del(struct dsa_switch *ds, int port,
 	return 0;
 }
 
+static int rtldsa_port_vlan_fast_age(struct dsa_switch *ds, int port, u16 vid)
+{
+	struct rtl838x_switch_priv *priv = ds->priv;
+	int ret;
+
+	if (!priv->r->vlan_port_fast_age)
+		return -EOPNOTSUPP;
+
+	mutex_lock(&priv->reg_mutex);
+	ret = priv->r->vlan_port_fast_age(priv, port, vid);
+	mutex_unlock(&priv->reg_mutex);
+
+	return ret;
+}
+
 static void rtl83xx_setup_l2_uc_entry(struct rtl838x_l2_entry *e, int port, int vid, u64 mac)
 {
 	memset(e, 0, sizeof(*e));
@@ -2680,6 +2695,7 @@ const struct dsa_switch_ops rtl93xx_switch_ops = {
 	.port_vlan_filtering	= rtl83xx_vlan_filtering,
 	.port_vlan_add		= rtl83xx_vlan_add,
 	.port_vlan_del		= rtl83xx_vlan_del,
+	.port_vlan_fast_age	= rtldsa_port_vlan_fast_age,
 
 	.port_fdb_add		= rtl83xx_port_fdb_add,
 	.port_fdb_del		= rtl83xx_port_fdb_del,
diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h
index b2cdd224ad..8a5c8ce4fd 100644
--- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h
+++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h
@@ -1132,6 +1132,7 @@ struct rtl838x_reg {
 	void (*vlan_port_pvidmode_set)(int port, enum pbvlan_type type, enum pbvlan_mode mode);
 	void (*vlan_port_pvid_set)(int port, enum pbvlan_type type, int pvid);
 	void (*vlan_port_keep_tag_set)(int port, bool keep_outer, bool keep_inner);
+	int (*vlan_port_fast_age)(struct rtl838x_switch_priv *priv, int port, u16 vid);
 	void (*set_vlan_igr_filter)(int port, enum igr_filter state);
 	void (*set_vlan_egr_filter)(int port, enum egr_filter state);
 	void (*enable_learning)(int port, bool enable);
diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c
index 224d5a9aaa..babb014a90 100644
--- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c
+++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c
@@ -2329,6 +2329,24 @@ static void rtl930x_vlan_port_pvid_set(int port, enum pbvlan_type type, int pvid
 		sw_w32_mask(0xfff << 16, pvid << 16, RTL930X_VLAN_PORT_PB_VLAN + (port << 2));
 }
 
+static int rtldsa_930x_vlan_port_fast_age(struct rtl838x_switch_priv *priv, int port, u16 vid)
+{
+	u32 val;
+
+	sw_w32(port << 11, RTL930X_L2_TBL_FLUSH_CTRL + 4);
+
+	val = 0;
+	val |= vid << 12;
+	val |= BIT(26); /* compare port id */
+	val |= BIT(28); /* compare VID */
+	val |= BIT(30); /* status - trigger flush */
+	sw_w32(val, RTL930X_L2_TBL_FLUSH_CTRL);
+
+	do { } while (sw_r32(priv->r->l2_tbl_flush_ctrl) & BIT(30));
+
+	return 0;
+}
+
 static int rtl930x_set_ageing_time(unsigned long msec)
 {
 	int t = sw_r32(RTL930X_L2_AGE_CTRL);
@@ -2638,6 +2656,7 @@ const struct rtl838x_reg rtl930x_reg = {
 	.vlan_port_keep_tag_set = rtl930x_vlan_port_keep_tag_set,
 	.vlan_port_pvidmode_set = rtl930x_vlan_port_pvidmode_set,
 	.vlan_port_pvid_set = rtl930x_vlan_port_pvid_set,
+	.vlan_port_fast_age = rtldsa_930x_vlan_port_fast_age,
 	.trk_mbr_ctr = rtl930x_trk_mbr_ctr,
 	.rma_bpdu_fld_pmask = RTL930X_RMA_BPDU_FLD_PMSK,
 	.init_eee = rtl930x_init_eee,
diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c
index 1b959eb946..ba939103f7 100644
--- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c
+++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c
@@ -1471,6 +1471,24 @@ static void rtl931x_vlan_port_pvid_set(int port, enum pbvlan_type type, int pvid
 		sw_w32_mask(0xfff << 14, pvid << 14, RTL931X_VLAN_PORT_IGR_CTRL + (port << 2));
 }
 
+static int rtldsa_931x_vlan_port_fast_age(struct rtl838x_switch_priv *priv, int port, u16 vid)
+{
+	u32 val;
+
+	sw_w32(vid << 20, RTL931X_L2_TBL_FLUSH_CTRL + 4);
+
+	val = 0;
+	val |= port << 11;
+	val |= BIT(24); /* compare port id */
+	val |= BIT(26); /* compare VID */
+	val |= BIT(28); /* status - trigger flush */
+	sw_w32(val, RTL931X_L2_TBL_FLUSH_CTRL);
+
+	do { } while (sw_r32(RTL931X_L2_TBL_FLUSH_CTRL) & BIT (28));
+
+	return 0;
+}
+
 static void rtl931x_set_igr_filter(int port, enum igr_filter state)
 {
 	sw_w32_mask(0x3 << ((port & 0xf)<<1), state << ((port & 0xf)<<1),
@@ -1765,6 +1783,7 @@ const struct rtl838x_reg rtl931x_reg = {
 	.vlan_port_keep_tag_set = rtl931x_vlan_port_keep_tag_set,
 	.vlan_port_pvidmode_set = rtl931x_vlan_port_pvidmode_set,
 	.vlan_port_pvid_set = rtl931x_vlan_port_pvid_set,
+	.vlan_port_fast_age = rtldsa_931x_vlan_port_fast_age,
 	.trk_mbr_ctr = rtldsa_931x_trk_mbr_ctr,
 	.rma_bpdu_fld_pmask = RTL931X_RMA_BPDU_FLD_PMSK,
 	.set_vlan_igr_filter = rtl931x_set_igr_filter,




More information about the lede-commits mailing list