From 84b7057fe3a83b32b69da4beb26d3f9d81a75213 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Thu, 16 Oct 2025 11:06:08 +0200 Subject: [PATCH] realtek: dsa: rtl931x: Fix port L2 table flushing The DSA driver must flush the HW FDB when a port changes from learning/forwarding to disabled/blocking/listening. But the implementation for RTL931x was writing the port information starting at bit 11 (bit 11 of the second 32-bit L2_TBL_FLUSH_CTRL register). But this offset is the AGG_VID and not the port. The actual position is 43 (bit 11 of the first register). As result, the FDB was always only flushed for the port 0 and not for the selected port. Fixes: 9ed609705481 ("realtek: Add HW support for RTL931X for PIE, L2 and STP aging") Signed-off-by: Sven Eckelmann Link: https://github.com/openwrt/openwrt/pull/20422 Signed-off-by: Robert Marko --- .../files-6.12/drivers/net/dsa/rtl83xx/dsa.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) 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 3e698683bd0..9e274f357b4 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 @@ -1709,15 +1709,20 @@ void rtl83xx_fast_age(struct dsa_switch *ds, int port) mutex_unlock(&priv->reg_mutex); } -static void rtl931x_fast_age(struct dsa_switch *ds, int port) +static void rtldsa_931x_fast_age(struct dsa_switch *ds, int port) { struct rtl838x_switch_priv *priv = ds->priv; + u32 val; - pr_info("%s port %d\n", __func__, port); mutex_lock(&priv->reg_mutex); - sw_w32(port << 11, RTL931X_L2_TBL_FLUSH_CTRL + 4); - sw_w32(BIT(24) | BIT(28), RTL931X_L2_TBL_FLUSH_CTRL); + sw_w32(0, RTL931X_L2_TBL_FLUSH_CTRL + 4); + + val = 0; + val |= port << 11; + val |= BIT(24); /* compare port id */ + 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)); @@ -1729,7 +1734,7 @@ static void rtl930x_fast_age(struct dsa_switch *ds, int port) struct rtl838x_switch_priv *priv = ds->priv; if (priv->family_id == RTL9310_FAMILY_ID) - return rtl931x_fast_age(ds, port); + return rtldsa_931x_fast_age(ds, port); pr_debug("FAST AGE port %d\n", port); mutex_lock(&priv->reg_mutex); -- 2.47.3