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 <hg@simonwunderlich.de>
Link: https://github.com/openwrt/openwrt/pull/21775
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
This commit is contained in:
Harshal Gohel authored and Markus Stockhausen committed 2026-08-27 16:36:55 +02:00
1 parent 4f7269c4db
commit bfa4bbfd37
6 files changed
+42 -24

No files matched your search

@@ -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));
@@ -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);
@@ -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));
}
@@ -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));
}
@@ -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)
@@ -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)