Commit 15ab7906 authored by Linus Walleij's avatar Linus Walleij Committed by David S. Miller

net: dsa: rtl8366: Fix VLAN semantics

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: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Fixes: d8652956 ("net: dsa: realtek-smi: Add Realtek SMI driver")
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b9aaec8f
...@@ -43,18 +43,26 @@ int rtl8366_set_vlan(struct realtek_smi *smi, int vid, u32 member, ...@@ -43,18 +43,26 @@ int rtl8366_set_vlan(struct realtek_smi *smi, int vid, u32 member,
int ret; int ret;
int i; int i;
dev_dbg(smi->dev,
"setting VLAN%d 4k members: 0x%02x, untagged: 0x%02x\n",
vid, member, untag);
/* Update the 4K table */ /* Update the 4K table */
ret = smi->ops->get_vlan_4k(smi, vid, &vlan4k); ret = smi->ops->get_vlan_4k(smi, vid, &vlan4k);
if (ret) if (ret)
return ret; return ret;
vlan4k.member = member; vlan4k.member |= member;
vlan4k.untag = untag; vlan4k.untag |= untag;
vlan4k.fid = fid; vlan4k.fid = fid;
ret = smi->ops->set_vlan_4k(smi, &vlan4k); ret = smi->ops->set_vlan_4k(smi, &vlan4k);
if (ret) if (ret)
return 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 */ /* Try to find an existing MC entry for this VID */
for (i = 0; i < smi->num_vlan_mc; i++) { for (i = 0; i < smi->num_vlan_mc; i++) {
struct rtl8366_vlan_mc vlanmc; struct rtl8366_vlan_mc vlanmc;
...@@ -65,11 +73,16 @@ int rtl8366_set_vlan(struct realtek_smi *smi, int vid, u32 member, ...@@ -65,11 +73,16 @@ int rtl8366_set_vlan(struct realtek_smi *smi, int vid, u32 member,
if (vid == vlanmc.vid) { if (vid == vlanmc.vid) {
/* update the MC entry */ /* update the MC entry */
vlanmc.member = member; vlanmc.member |= member;
vlanmc.untag = untag; vlanmc.untag |= untag;
vlanmc.fid = fid; vlanmc.fid = fid;
ret = smi->ops->set_vlan_mc(smi, i, &vlanmc); 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; break;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment