From: Issam Hamdi Date: Tue, 15 Jul 2025 18:22:26 +0000 (+0200) Subject: realtek: dsa: rtl93xx: Support multi spanning tree states X-Git-Url: http://git.openwrt.org/?a=commitdiff_plain;h=6c15c5d5eb7c3c58107573c6341581559acb812f;p=openwrt%2Fstaging%2Fxback.git realtek: dsa: rtl93xx: Support multi spanning tree states The MSTP support (usually implemented by mstpd) requires from the kernel that a VLAN can associated with an MSTI. At the moment, all these VLANs just get the msti 0 harcoded on creation. But the vlan_tables_read()+vlan_tables_write() helper already allow the modification of the MSTI and only require a minimal hook to expose this functionality. It is also necessary to adjust the (M)STP states per MSTI and not only per port (or for the CIST). The rtl83xx_port_stp_state_set() function was in theory already capable to modify other MSTIs than CIST - if the msti would not have been hardcoded to 0. The userspace can trigger these modifications using netlink: * (Re)associating VLANs with an MSTI: bridge vlan global set dev
vid msti * Setting the port state in a given MSTI: bridge mst set dev msti state Signed-off-by: Issam Hamdi Co-developed-by: Sven Eckelmann Signed-off-by: Sven Eckelmann Link: https://github.com/openwrt/openwrt/pull/20421 Signed-off-by: Hauke Mehrtens --- 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 e595df93ba..cc29fd1ba6 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 @@ -1677,6 +1677,18 @@ static void rtl930x_fast_age(struct dsa_switch *ds, int port) mutex_unlock(&priv->reg_mutex); } +static int rtldsa_port_mst_state_set(struct dsa_switch *ds, int port, + const struct switchdev_mst_state *st) +{ + struct rtl838x_switch_priv *priv = ds->priv; + + mutex_lock(&priv->reg_mutex); + rtldsa_port_xstp_state_set(priv, port, st->state, st->msti); + mutex_unlock(&priv->reg_mutex); + + return 0; +} + static int rtl83xx_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, struct netlink_ext_ack *extack) @@ -1877,6 +1889,23 @@ static int rtldsa_port_vlan_fast_age(struct dsa_switch *ds, int port, u16 vid) return ret; } +static int rtldsa_vlan_msti_set(struct dsa_switch *ds, struct dsa_bridge bridge, + const struct switchdev_vlan_msti *msti) +{ + struct rtl838x_switch_priv *priv = ds->priv; + struct rtl838x_vlan_info info; + int mst_slot = msti->msti; + + if (mst_slot >= priv->n_mst) + return -EINVAL; + + priv->r->vlan_tables_read(msti->vid, &info); + info.fid = mst_slot; + priv->r->vlan_set_tagged(msti->vid, &info); + + return 0; +} + static void rtl83xx_setup_l2_uc_entry(struct rtl838x_l2_entry *e, int port, int vid, u64 mac) { memset(e, 0, sizeof(*e)); @@ -2666,10 +2695,12 @@ const struct dsa_switch_ops rtl83xx_switch_ops = { .port_bridge_leave = rtldsa_port_bridge_leave, .port_stp_state_set = rtl83xx_port_stp_state_set, .port_fast_age = rtl83xx_fast_age, + .port_mst_state_set = rtldsa_port_mst_state_set, .port_vlan_filtering = rtl83xx_vlan_filtering, .port_vlan_add = rtl83xx_vlan_add, .port_vlan_del = rtl83xx_vlan_del, + .vlan_msti_set = rtldsa_vlan_msti_set, .port_fdb_add = rtl83xx_port_fdb_add, .port_fdb_del = rtl83xx_port_fdb_del, @@ -2723,11 +2754,13 @@ const struct dsa_switch_ops rtl93xx_switch_ops = { .port_bridge_leave = rtldsa_port_bridge_leave, .port_stp_state_set = rtl83xx_port_stp_state_set, .port_fast_age = rtl930x_fast_age, + .port_mst_state_set = rtldsa_port_mst_state_set, .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, + .vlan_msti_set = rtldsa_vlan_msti_set, .port_fdb_add = rtl83xx_port_fdb_add, .port_fdb_del = rtl83xx_port_fdb_del,