| From 9ac0cb82a2181b2cea3391dbc2002b43f2989972 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 27 Jul 2020 01:34:39 +0200 |
| Subject: net: dsa: rtl8366: Fix VLAN semantics |
| |
| From: Linus Walleij <linus.walleij@linaro.org> |
| |
| [ Upstream commit 15ab7906cc9290afb006df1bb1074907fbcc7061 ] |
| |
| The RTL8366 would not handle adding new members (ports) to |
| a VLAN: the code assumed that ->port_vlan_add() was only |
| called once for a single port. When intializing the |
| switch with .configure_vlan_while_not_filtering set to |
| true, the function is called numerous times for adding |
| all ports to VLAN1, which was something the code could |
| not handle. |
| |
| Alter rtl8366_set_vlan() to just |= new members and |
| untagged flags to 4k and MC VLAN table entries alike. |
| This makes it possible to just add new ports to a |
| VLAN. |
| |
| Put in some helpful debug code that can be used to find |
| any further bugs here. |
| |
| Cc: DENG Qingfang <dqfext@gmail.com> |
| Cc: Mauri Sandberg <sandberg@mailfence.com> |
| Reviewed-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: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/net/dsa/rtl8366.c | 21 +++++++++++++++++---- |
| 1 file changed, 17 insertions(+), 4 deletions(-) |
| |
| diff --git a/drivers/net/dsa/rtl8366.c b/drivers/net/dsa/rtl8366.c |
| index ac88caca5ad4d..a75dcd6698b8a 100644 |
| --- a/drivers/net/dsa/rtl8366.c |
| +++ b/drivers/net/dsa/rtl8366.c |
| @@ -43,18 +43,26 @@ int rtl8366_set_vlan(struct realtek_smi *smi, int vid, u32 member, |
| int ret; |
| int i; |
| |
| + dev_dbg(smi->dev, |
| + "setting VLAN%d 4k members: 0x%02x, untagged: 0x%02x\n", |
| + vid, member, untag); |
| + |
| /* Update the 4K table */ |
| ret = smi->ops->get_vlan_4k(smi, vid, &vlan4k); |
| if (ret) |
| return ret; |
| |
| - vlan4k.member = member; |
| - vlan4k.untag = untag; |
| + vlan4k.member |= member; |
| + vlan4k.untag |= untag; |
| vlan4k.fid = fid; |
| ret = smi->ops->set_vlan_4k(smi, &vlan4k); |
| if (ret) |
| return ret; |
| |
| + dev_dbg(smi->dev, |
| + "resulting VLAN%d 4k members: 0x%02x, untagged: 0x%02x\n", |
| + vid, vlan4k.member, vlan4k.untag); |
| + |
| /* Try to find an existing MC entry for this VID */ |
| for (i = 0; i < smi->num_vlan_mc; i++) { |
| struct rtl8366_vlan_mc vlanmc; |
| @@ -65,11 +73,16 @@ int rtl8366_set_vlan(struct realtek_smi *smi, int vid, u32 member, |
| |
| if (vid == vlanmc.vid) { |
| /* update the MC entry */ |
| - vlanmc.member = member; |
| - vlanmc.untag = untag; |
| + vlanmc.member |= member; |
| + vlanmc.untag |= untag; |
| vlanmc.fid = fid; |
| |
| ret = smi->ops->set_vlan_mc(smi, i, &vlanmc); |
| + |
| + dev_dbg(smi->dev, |
| + "resulting VLAN%d MC members: 0x%02x, untagged: 0x%02x\n", |
| + vid, vlanmc.member, vlanmc.untag); |
| + |
| break; |
| } |
| } |
| -- |
| 2.25.1 |
| |