realtek: properly update port masks when port leaves bridge
authorJan Hoffmann <jan@3e8.eu>
Sat, 6 May 2023 17:28:52 +0000 (19:28 +0200)
committerSander Vanheule <sander@svanheule.net>
Sun, 7 May 2023 17:07:34 +0000 (19:07 +0200)
Correctly update the isolation mask of the port being configured. The
port_bitmap variable should contain all other bridge members and needs
to be actually removed from the isolation mask instead of added to it.

Also actually remove the port being configured from the pm field of the
other ports, so that any other ports that are currently disabled will be
configured correctly when they are enabled.

Fixes: df8e6be59a1f ("rtl838x: add new architecture")
[fixed updating pm field of other ports]
Fixes: 2b88563ee5aa ("realtek: update the tree to the latest refactored version")
[reintroduced incorrect pm field update]
Fixes: 27029277f98d ("realtek: add switch driver support for the RTL93XX based switches")
Signed-off-by: Jan Hoffmann <jan@3e8.eu>
target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/dsa.c
target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/dsa.c

index 63461ff573488717e3ff0c063ec957f10babe684..220f1d5d281d9e6d86f566852421c7addf986931 100644 (file)
@@ -1227,7 +1227,7 @@ static void rtl83xx_port_bridge_leave(struct dsa_switch *ds, int port,
                                        struct net_device *bridge)
 {
        struct rtl838x_switch_priv *priv = ds->priv;
-       u64 port_bitmap = BIT_ULL(priv->cpu_port), v;
+       u64 port_bitmap = 0, v;
        int i;
 
        pr_debug("%s %x: %d", __func__, (u32)priv, port);
@@ -1245,16 +1245,16 @@ static void rtl83xx_port_bridge_leave(struct dsa_switch *ds, int port,
                        if (priv->ports[i].enable)
                                priv->r->traffic_disable(i, port);
 
-                       priv->ports[i].pm |= BIT_ULL(port);
-                       port_bitmap &= ~BIT_ULL(i);
+                       priv->ports[i].pm &= ~BIT_ULL(port);
+                       port_bitmap |= BIT_ULL(i);
                }
        }
        store_mcgroups(priv, port);
 
-       /* Add all other ports to this port matrix. */
+       /* Remove all other ports from this port matrix. */
        if (priv->ports[port].enable) {
                v = priv->r->traffic_get(port);
-               v |= port_bitmap;
+               v &= ~port_bitmap;
                priv->r->traffic_set(port, v);
        }
        priv->ports[port].pm &= ~port_bitmap;
index 83a0441ce27c88d5af9ae94226b957dd86afc23a..7eebb2107f848d548aa1fb658f1920f0473a5987 100644 (file)
@@ -1212,7 +1212,7 @@ static void rtl83xx_port_bridge_leave(struct dsa_switch *ds, int port,
                                        struct net_device *bridge)
 {
        struct rtl838x_switch_priv *priv = ds->priv;
-       u64 port_bitmap = BIT_ULL(priv->cpu_port), v;
+       u64 port_bitmap = 0, v;
 
        pr_debug("%s %x: %d", __func__, (u32)priv, port);
        mutex_lock(&priv->reg_mutex);
@@ -1229,16 +1229,16 @@ static void rtl83xx_port_bridge_leave(struct dsa_switch *ds, int port,
                        if (priv->ports[i].enable)
                                priv->r->traffic_disable(i, port);
 
-                       priv->ports[i].pm |= BIT_ULL(port);
-                       port_bitmap &= ~BIT_ULL(i);
+                       priv->ports[i].pm &= ~BIT_ULL(port);
+                       port_bitmap |= BIT_ULL(i);
                }
        }
        store_mcgroups(priv, port);
 
-       /* Add all other ports to this port matrix. */
+       /* Remove all other ports from this port matrix. */
        if (priv->ports[port].enable) {
                v = priv->r->traffic_get(port);
-               v |= port_bitmap;
+               v &= ~port_bitmap;
                priv->r->traffic_set(port, v);
        }
        priv->ports[port].pm &= ~port_bitmap;