From bfa4bbfd37127b28415da97b28e7a7306c9bb803 Mon Sep 17 00:00:00 2001 From: Harshal Gohel Date: Wed, 26 Aug 2026 14:59:54 +0200 Subject: [PATCH] realtek: dsa: support multiple flood_type with enable_flood() enable_flood() took a bool, which can only select between forwarding and dropping. The hardware supports more actions per port and the upcoming BR_PORT_LOCKED support needs trap-to-CPU, so replace the bool with an enum matching the hardware encoding of the L2 learning constraint action field. On RTL93xx also program the unknown unicast flood port mask, which is what BR_FLOOD actually controls. No functional change for RTL83xx, where the field is only two bits wide. Signed-off-by: Harshal Gohel Link: https://github.com/openwrt/openwrt/pull/21775 Signed-off-by: Markus Stockhausen --- .../files-6.18/drivers/net/dsa/rtl83xx/dsa.c | 4 +++- .../drivers/net/dsa/rtl83xx/rtl-otto.h | 12 +++++++++- .../drivers/net/dsa/rtl83xx/rtl838x.c | 4 ++-- .../drivers/net/dsa/rtl83xx/rtl839x.c | 4 ++-- .../drivers/net/dsa/rtl83xx/rtl930x.c | 20 +++++++++-------- .../drivers/net/dsa/rtl83xx/rtl931x.c | 22 +++++++++++-------- 6 files changed, 42 insertions(+), 24 deletions(-) diff --git a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/dsa.c b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/dsa.c index fff009447e6..74d5145255e 100644 --- a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/dsa.c +++ b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/dsa.c @@ -2348,7 +2348,9 @@ static int rtldsa_port_bridge_flags(struct dsa_switch *ds, int port, priv->r->enable_learning(port, !!(flags.val & BR_LEARNING)); if (priv->r->enable_flood && (flags.mask & BR_FLOOD)) - priv->r->enable_flood(port, !!(flags.val & BR_FLOOD)); + priv->r->enable_flood(port, (flags.val & BR_FLOOD) ? + RTLDSA_FLOOD_TYPE_FORWARD : + RTLDSA_FLOOD_TYPE_DROP); if (priv->r->enable_mcast_flood && (flags.mask & BR_MCAST_FLOOD)) priv->r->enable_mcast_flood(port, !!(flags.val & BR_MCAST_FLOOD)); diff --git a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl-otto.h b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl-otto.h index 4ff7bb50c30..3d8c5873cce 100644 --- a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl-otto.h +++ b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl-otto.h @@ -642,6 +642,15 @@ typedef enum { COPY2CPU, } action_type_t; +enum rtldsa_flood_type { + RTLDSA_FLOOD_TYPE_FORWARD = 0, + RTLDSA_FLOOD_TYPE_DROP, + RTLDSA_FLOOD_TYPE_TRAP2CPU, + RTLDSA_FLOOD_TYPE_COPY2CPU, + RTLDSA_FLOOD_TYPE_TRAP2MASTER, + RTLDSA_FLOOD_TYPE_COPY2MASTER, +}; + #define RTL838X_RMA_BPDU_CTRL (0x4330) #define RTL839X_RMA_BPDU_CTRL (0x122C) #define RTL930X_RMA_BPDU_CTRL (0x9E7C) @@ -1002,6 +1011,7 @@ struct rtldsa_port { bool eee_enabled; bool has_pcs; int led_set; + enum rtldsa_flood_type flood_type; int leds_on_this_port; struct rtldsa_counter_state counters; const struct dsa_port *dp; @@ -1359,7 +1369,7 @@ struct rtldsa_config { 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); - void (*enable_flood)(int port, bool enable); + void (*enable_flood)(int port, enum rtldsa_flood_type flood_type); void (*enable_mcast_flood)(int port, bool enable); void (*enable_bcast_flood)(int port, bool enable); void (*set_static_move_action)(int port, bool forward); diff --git a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl838x.c b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl838x.c index d614dcb3a62..52cbee98a22 100644 --- a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl838x.c +++ b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl838x.c @@ -614,14 +614,14 @@ static void rtl838x_enable_learning(int port, bool enable) RTL838X_L2_PORT_LRN_CONSTRT + (port << 2)); } -static void rtl838x_enable_flood(int port, bool enable) +static void rtl838x_enable_flood(int port, enum rtldsa_flood_type mode) { /* 0: Forward * 1: Disable * 2: to CPU * 3: Copy to CPU */ - sw_w32_mask(0x3, enable ? 0 : 1, + sw_w32_mask(0x3, mode, RTL838X_L2_PORT_LRN_CONSTRT + (port << 2)); } diff --git a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl839x.c b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl839x.c index 27959172d8d..e31bc54a2e1 100644 --- a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl839x.c +++ b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl839x.c @@ -664,14 +664,14 @@ static void rtl839x_enable_learning(int port, bool enable) RTL839X_L2_PORT_LRN_CONSTRT + (port << 2)); } -static void rtl839x_enable_flood(int port, bool enable) +static void rtl839x_enable_flood(int port, enum rtldsa_flood_type mode) { /* 0: Forward * 1: Disable * 2: to CPU * 3: Copy to CPU */ - sw_w32_mask(0x3, enable ? 0 : 1, + sw_w32_mask(0x3, mode, RTL839X_L2_PORT_LRN_CONSTRT + (port << 2)); } diff --git a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl930x.c b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl930x.c index ad2f48af6c3..a450f3fcd28 100644 --- a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl930x.c +++ b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl930x.c @@ -508,17 +508,19 @@ static void rtldsa_930x_enable_learning(int port, bool enable) RTL930X_L2_LRN_PORT_CONSTRT_CTRL + port * 4); } -static void rtldsa_930x_enable_flood(int port, bool enable) +static void rtldsa_930x_enable_flood(int port, enum rtldsa_flood_type mode) { - /* 0: forward - * 1: drop - * 2: trap to local CPU - * 3: copy to local CPU - * 4: trap to master CPU - * 5: copy to master CPU - */ - sw_w32_mask(GENMASK(2, 0), enable ? 0 : 1, + u32 port_mask = BIT(port); + u32 val; + + val = (mode == RTLDSA_FLOOD_TYPE_FORWARD) ? port_mask : 0; + + sw_w32_mask(GENMASK(2, 0), mode, RTL930X_L2_LRN_PORT_CONSTRT_CTRL + port * 4); + + sw_w32_mask(port_mask, + val, + RTL930X_L2_UNKN_UC_FLD_PMSK); } static void rtldsa_930x_lag_set_port2group(int group, int port, bool valid) diff --git a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl931x.c b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl931x.c index dc3b70da5c7..e9d07daae25 100644 --- a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl931x.c +++ b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl931x.c @@ -908,17 +908,21 @@ static void rtldsa_931x_enable_learning(int port, bool enable) RTL931X_L2_LRN_PORT_CONSTRT_CTRL + port * 4); } -static void rtldsa_931x_enable_flood(int port, bool enable) +static void rtldsa_931x_enable_flood(int port, enum rtldsa_flood_type mode) { - /* 0: forward - * 1: drop - * 2: trap to local CPU - * 3: copy to local CPU - * 4: trap to master CPU - * 5: copy to master CPU - */ - sw_w32_mask(GENMASK(2, 0), enable ? 0 : 1, + /* RTL931X_L2_UNKN_UC_FLD_PMSK is big-endian */ + u32 port_offset = ((63 - port) / 32) * 4; + u32 port_mask = BIT(port % 32); + u32 val; + + val = (mode == RTLDSA_FLOOD_TYPE_FORWARD) ? port_mask : 0; + + sw_w32_mask(GENMASK(2, 0), mode, RTL931X_L2_LRN_PORT_CONSTRT_CTRL + port * 4); + + sw_w32_mask(port_mask, + val, + RTL931X_L2_UNKN_UC_FLD_PMSK + port_offset); } static u64 rtl931x_read_mcast_pmask(int idx)