Skip to content

Commit 3d00827

Browse files
sss-secomeadavem330
authored andcommitted
net: dsa: microchip: fix bridging with more than two member ports
Commit b3612cc ("net: dsa: microchip: implement multi-bridge support") plugged a packet leak between ports that were members of different bridges. Unfortunately, this broke another use case, namely that of more than two ports that are members of the same bridge. After that commit, when a port is added to a bridge, hardware bridging between other member ports of that bridge will be cleared, preventing packet exchange between them. Fix by ensuring that the Port VLAN Membership bitmap includes any existing ports in the bridge, not just the port being added. Fixes: b3612cc ("net: dsa: microchip: implement multi-bridge support") Signed-off-by: Svenning Sørensen <[email protected]> Tested-by: Oleksij Rempel <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 5486f5b commit 3d00827

File tree

1 file changed

+23
-3
lines changed

1 file changed

+23
-3
lines changed

drivers/net/dsa/microchip/ksz_common.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ void ksz_update_port_member(struct ksz_device *dev, int port)
2626
struct dsa_switch *ds = dev->ds;
2727
u8 port_member = 0, cpu_port;
2828
const struct dsa_port *dp;
29-
int i;
29+
int i, j;
3030

3131
if (!dsa_is_user_port(ds, port))
3232
return;
@@ -45,13 +45,33 @@ void ksz_update_port_member(struct ksz_device *dev, int port)
4545
continue;
4646
if (!dsa_port_bridge_same(dp, other_dp))
4747
continue;
48+
if (other_p->stp_state != BR_STATE_FORWARDING)
49+
continue;
4850

49-
if (other_p->stp_state == BR_STATE_FORWARDING &&
50-
p->stp_state == BR_STATE_FORWARDING) {
51+
if (p->stp_state == BR_STATE_FORWARDING) {
5152
val |= BIT(port);
5253
port_member |= BIT(i);
5354
}
5455

56+
/* Retain port [i]'s relationship to other ports than [port] */
57+
for (j = 0; j < ds->num_ports; j++) {
58+
const struct dsa_port *third_dp;
59+
struct ksz_port *third_p;
60+
61+
if (j == i)
62+
continue;
63+
if (j == port)
64+
continue;
65+
if (!dsa_is_user_port(ds, j))
66+
continue;
67+
third_p = &dev->ports[j];
68+
if (third_p->stp_state != BR_STATE_FORWARDING)
69+
continue;
70+
third_dp = dsa_to_port(ds, j);
71+
if (dsa_port_bridge_same(other_dp, third_dp))
72+
val |= BIT(j);
73+
}
74+
5575
dev->dev_ops->cfg_port_member(dev, i, val | cpu_port);
5676
}
5777

0 commit comments

Comments
 (0)