summaryrefslogtreecommitdiffstats
path: root/drivers/net/dsa
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2020-09-05 12:32:33 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-09-26 18:01:29 +0200
commit76fde30cf12ccf3f6d0e731972d15da174159b71 (patch)
tree61a92713dcdd17b1547fadc17c12fa6bdfdc332d /drivers/net/dsa
parentd0c2f72526c6cf7ad090ee3a85226d3da8e62458 (diff)
downloadlinux-stable-76fde30cf12ccf3f6d0e731972d15da174159b71.tar.gz
linux-stable-76fde30cf12ccf3f6d0e731972d15da174159b71.tar.bz2
linux-stable-76fde30cf12ccf3f6d0e731972d15da174159b71.zip
net: dsa: rtl8366: Properly clear member config
[ Upstream commit 4ddcaf1ebb5e4e99240f29d531ee69d4244fe416 ] When removing a port from a VLAN we are just erasing the member config for the VLAN, which is wrong: other ports can be using it. Just mask off the port and only zero out the rest of the member config once ports using of the VLAN are removed from it. Reported-by: Florian Fainelli <f.fainelli@gmail.com> Fixes: d8652956cf37 ("net: dsa: realtek-smi: Add Realtek SMI driver") Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/net/dsa')
-rw-r--r--drivers/net/dsa/rtl8366.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/drivers/net/dsa/rtl8366.c b/drivers/net/dsa/rtl8366.c
index 7e27c9aff9b7..430988f79722 100644
--- a/drivers/net/dsa/rtl8366.c
+++ b/drivers/net/dsa/rtl8366.c
@@ -452,13 +452,19 @@ int rtl8366_vlan_del(struct dsa_switch *ds, int port,
return ret;
if (vid == vlanmc.vid) {
- /* clear VLAN member configurations */
- vlanmc.vid = 0;
- vlanmc.priority = 0;
- vlanmc.member = 0;
- vlanmc.untag = 0;
- vlanmc.fid = 0;
-
+ /* Remove this port from the VLAN */
+ vlanmc.member &= ~BIT(port);
+ vlanmc.untag &= ~BIT(port);
+ /*
+ * If no ports are members of this VLAN
+ * anymore then clear the whole member
+ * config so it can be reused.
+ */
+ if (!vlanmc.member && vlanmc.untag) {
+ vlanmc.vid = 0;
+ vlanmc.priority = 0;
+ vlanmc.fid = 0;
+ }
ret = smi->ops->set_vlan_mc(smi, i, &vlanmc);
if (ret) {
dev_err(smi->dev,