[PATCH 1/4] realtek: properly update port masks when port leaves bridge
Jan Hoffmann
jan at 3e8.eu
Sun Mar 12 15:57:27 PDT 2023
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.
Signed-off-by: Jan Hoffmann <jan at 3e8.eu>
---
I originally wanted to put a proper Fixes tag here, but I'm not sure
which commit to choose. This bug seems to have existed since this target
was introduced, and survived through multiple refactorings. It looks
like the incorrect update to the pm field was even fixed in 2b88563ee5aa
("realtek: update the tree to the latest refactored version"), but then
27029277f98d ("realtek: add switch driver support for the RTL93XX based
switches") reintroduced the issue.
.../realtek/files-5.10/drivers/net/dsa/rtl83xx/dsa.c | 10 +++++-----
.../realtek/files-5.15/drivers/net/dsa/rtl83xx/dsa.c | 10 +++++-----
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/dsa.c b/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/dsa.c
index 63461ff57348..220f1d5d281d 100644
--- a/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/dsa.c
+++ b/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/dsa.c
@@ -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;
diff --git a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/dsa.c b/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/dsa.c
index 83a0441ce27c..7eebb2107f84 100644
--- a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/dsa.c
+++ b/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/dsa.c
@@ -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;
--
2.39.1
More information about the openwrt-devel
mailing list