[openwrt/openwrt] realtek: dsa: Adjust MSTP states after joining/leaving bridge
LEDE Commits
lede-commits at lists.infradead.org
Sat Nov 15 07:22:11 PST 2025
hauke pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/5d36445dc117e7b636a17e4b6f457df6145ce441
commit 5d36445dc117e7b636a17e4b6f457df6145ce441
Author: Sven Eckelmann <se at simonwunderlich.de>
AuthorDate: Tue Oct 28 08:55:38 2025 +0100
realtek: dsa: Adjust MSTP states after joining/leaving bridge
When joining a bridge or leaving a bridge, the CIST state will
automatically be adjusted by DSA using .port_stp_state_set(). But MSTIs are
completely unhandled.
If a port is joining a bridge, the default state must be disabled. The MSTP
daemon is then responsible for adjusting the state.
If the bridge is left, the forwarding state must be enforced because VLANs
(and with this also the MSTIs assigned to them) are shared between bridged
and non-bridged ports. An unbridged port must therefore not be left in an
blocked/disabled state for a VLAN (MSTI).
Suggested-by: Jonas Gorski <jonas.gorski at gmail.com>
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>
---
.../files-6.12/drivers/net/dsa/rtl83xx/dsa.c | 31 +++++++++++++++++-----
1 file changed, 24 insertions(+), 7 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 1a950fff55..0312ee413d 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
@@ -27,6 +27,8 @@ static const u8 ipv6_all_hosts_mcast_addr_mask[ETH_ALEN] =
extern struct rtl83xx_soc_info soc_info;
static void rtldsa_init_counters(struct rtl838x_switch_priv *priv);
+static void rtldsa_port_xstp_state_set(struct rtl838x_switch_priv *priv, int port,
+ u8 state, u16 mst_slot);
static void rtl83xx_init_stats(struct rtl838x_switch_priv *priv)
{
@@ -1497,6 +1499,7 @@ static int rtldsa_port_bridge_join(struct dsa_switch *ds, int port, struct dsa_b
bool *tx_fwd_offload, struct netlink_ext_ack *extack)
{
struct rtl838x_switch_priv *priv = ds->priv;
+ unsigned int i;
pr_debug("%s %x: %d", __func__, (u32)priv, port);
@@ -1510,6 +1513,10 @@ static int rtldsa_port_bridge_join(struct dsa_switch *ds, int port, struct dsa_b
if (priv->r->set_static_move_action)
priv->r->set_static_move_action(port, false);
+ /* Set to disabled in all MSTs, common code will take care of CIST */
+ for (i = 1; i < priv->n_mst; i++)
+ rtldsa_port_xstp_state_set(priv, port, BR_STATE_DISABLED, i);
+
mutex_unlock(&priv->reg_mutex);
return 0;
@@ -1518,6 +1525,7 @@ static int rtldsa_port_bridge_join(struct dsa_switch *ds, int port, struct dsa_b
static void rtldsa_port_bridge_leave(struct dsa_switch *ds, int port, struct dsa_bridge bridge)
{
struct rtl838x_switch_priv *priv = ds->priv;
+ unsigned int i;
pr_debug("%s %x: %d", __func__, (u32)priv, port);
@@ -1528,24 +1536,26 @@ static void rtldsa_port_bridge_leave(struct dsa_switch *ds, int port, struct dsa
if (priv->r->set_static_move_action)
priv->r->set_static_move_action(port, true);
+ /* Set to forwarding in all MSTs, common code will take care of CIST */
+ for (i = 1; i < priv->n_mst; i++)
+ rtldsa_port_xstp_state_set(priv, port, BR_STATE_FORWARDING, i);
+
mutex_unlock(&priv->reg_mutex);
}
-void rtl83xx_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
+static void rtldsa_port_xstp_state_set(struct rtl838x_switch_priv *priv, int port,
+ u8 state, u16 mst_slot)
+ __must_hold(&priv->reg_mutex)
{
- u32 msti = 0;
u32 port_state[4];
int index, bit;
int pos = port;
- struct rtl838x_switch_priv *priv = ds->priv;
int n = priv->port_width << 1;
/* Ports above or equal CPU port can never be configured */
if (port >= priv->cpu_port)
return;
- mutex_lock(&priv->reg_mutex);
-
/* For the RTL839x and following, the bits are left-aligned, 838x and 930x
* have 64 bit fields, 839x and 931x have 128 bit fields
*/
@@ -1559,7 +1569,7 @@ void rtl83xx_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
index = n - (pos >> 4) - 1;
bit = (pos << 1) % 32;
- priv->r->stp_get(priv, msti, port_state);
+ priv->r->stp_get(priv, mst_slot, port_state);
pr_debug("Current state, port %d: %d\n", port, (port_state[index] >> bit) & 3);
port_state[index] &= ~(3 << bit);
@@ -1581,8 +1591,15 @@ void rtl83xx_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
break;
}
- priv->r->stp_set(priv, msti, port_state);
+ priv->r->stp_set(priv, mst_slot, port_state);
+}
+
+void rtl83xx_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+ mutex_lock(&priv->reg_mutex);
+ rtldsa_port_xstp_state_set(priv, port, state, 0);
mutex_unlock(&priv->reg_mutex);
}
More information about the lede-commits
mailing list