summaryrefslogtreecommitdiff
path: root/drivers/net/dsa/microchip/ksz_common.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2022-02-28 14:57:14 +1000
committerDave Airlie <airlied@redhat.com>2022-02-28 14:57:14 +1000
commit6c64ae228f0826859c56711ce133aff037d6205f (patch)
tree831f7b3c5a4eb3a5ab932edb6ca27780a316e714 /drivers/net/dsa/microchip/ksz_common.c
parent6d09e5cbc9633fa4df88544952614e9137d274af (diff)
parent7e57714cd0ad2d5bb90e50b5096a0e671dec1ef3 (diff)
downloadlinux-6c64ae228f0826859c56711ce133aff037d6205f.tar.gz
linux-6c64ae228f0826859c56711ce133aff037d6205f.tar.bz2
linux-6c64ae228f0826859c56711ce133aff037d6205f.zip
Backmerge tag 'v5.17-rc6' into drm-next
This backmerges v5.17-rc6 so I can merge some amdgpu and some tegra changes on top. Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/net/dsa/microchip/ksz_common.c')
-rw-r--r--drivers/net/dsa/microchip/ksz_common.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 55dbda04ea62..243f8ad6d06e 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -26,7 +26,7 @@ void ksz_update_port_member(struct ksz_device *dev, int port)
struct dsa_switch *ds = dev->ds;
u8 port_member = 0, cpu_port;
const struct dsa_port *dp;
- int i;
+ int i, j;
if (!dsa_is_user_port(ds, port))
return;
@@ -45,13 +45,33 @@ void ksz_update_port_member(struct ksz_device *dev, int port)
continue;
if (!dsa_port_bridge_same(dp, other_dp))
continue;
+ if (other_p->stp_state != BR_STATE_FORWARDING)
+ continue;
- if (other_p->stp_state == BR_STATE_FORWARDING &&
- p->stp_state == BR_STATE_FORWARDING) {
+ if (p->stp_state == BR_STATE_FORWARDING) {
val |= BIT(port);
port_member |= BIT(i);
}
+ /* Retain port [i]'s relationship to other ports than [port] */
+ for (j = 0; j < ds->num_ports; j++) {
+ const struct dsa_port *third_dp;
+ struct ksz_port *third_p;
+
+ if (j == i)
+ continue;
+ if (j == port)
+ continue;
+ if (!dsa_is_user_port(ds, j))
+ continue;
+ third_p = &dev->ports[j];
+ if (third_p->stp_state != BR_STATE_FORWARDING)
+ continue;
+ third_dp = dsa_to_port(ds, j);
+ if (dsa_port_bridge_same(other_dp, third_dp))
+ val |= BIT(j);
+ }
+
dev->dev_ops->cfg_port_member(dev, i, val | cpu_port);
}