Skip to content

Commit bd110b1

Browse files
KanjiMonsterSasha Levin
authored andcommitted
net: dsa: b53: fix toggling vlan_filtering
[ Upstream commit 2dc2bd5 ] To allow runtime switching between vlan aware and vlan non-aware mode, we need to properly keep track of any bridge VLAN configuration. Likewise, we need to know when we actually switch between both modes, to not have to rewrite the full VLAN table every time we update the VLANs. So keep track of the current vlan_filtering mode, and on changes, apply the appropriate VLAN configuration. Fixes: 0ee2af4 ("net: dsa: set configure_vlan_while_not_filtering to true by default") Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> Tested-by: Florian Fainelli <florian.fainelli@broadcom.com> Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com> Link: https://patch.msgid.link/20250429201710.330937-10-jonas.gorski@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 4b81329 commit bd110b1

File tree

2 files changed

+75
-31
lines changed

2 files changed

+75
-31
lines changed

drivers/net/dsa/b53/b53_common.c

Lines changed: 73 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,22 @@ static bool b53_vlan_port_needs_forced_tagged(struct dsa_switch *ds, int port)
763763
return dev->tag_protocol == DSA_TAG_PROTO_NONE && dsa_is_cpu_port(ds, port);
764764
}
765765

766+
static bool b53_vlan_port_may_join_untagged(struct dsa_switch *ds, int port)
767+
{
768+
struct b53_device *dev = ds->priv;
769+
struct dsa_port *dp;
770+
771+
if (!dev->vlan_filtering)
772+
return true;
773+
774+
dp = dsa_to_port(ds, port);
775+
776+
if (dsa_port_is_cpu(dp))
777+
return true;
778+
779+
return dp->bridge == NULL;
780+
}
781+
766782
int b53_configure_vlan(struct dsa_switch *ds)
767783
{
768784
struct b53_device *dev = ds->priv;
@@ -781,34 +797,47 @@ int b53_configure_vlan(struct dsa_switch *ds)
781797
b53_do_vlan_op(dev, VTA_CMD_CLEAR);
782798
}
783799

784-
b53_enable_vlan(dev, -1, dev->vlan_enabled, ds->vlan_filtering);
800+
b53_enable_vlan(dev, -1, dev->vlan_enabled, dev->vlan_filtering);
785801

786802
/* Create an untagged VLAN entry for the default PVID in case
787803
* CONFIG_VLAN_8021Q is disabled and there are no calls to
788804
* dsa_user_vlan_rx_add_vid() to create the default VLAN
789805
* entry. Do this only when the tagging protocol is not
790806
* DSA_TAG_PROTO_NONE
791807
*/
808+
v = &dev->vlans[def_vid];
792809
b53_for_each_port(dev, i) {
793-
v = &dev->vlans[def_vid];
794-
v->members |= BIT(i);
810+
if (!b53_vlan_port_may_join_untagged(ds, i))
811+
continue;
812+
813+
vl.members |= BIT(i);
795814
if (!b53_vlan_port_needs_forced_tagged(ds, i))
796-
v->untag = v->members;
797-
b53_write16(dev, B53_VLAN_PAGE,
798-
B53_VLAN_PORT_DEF_TAG(i), def_vid);
815+
vl.untag = vl.members;
816+
b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(i),
817+
def_vid);
799818
}
819+
b53_set_vlan_entry(dev, def_vid, &vl);
800820

801-
/* Upon initial call we have not set-up any VLANs, but upon
802-
* system resume, we need to restore all VLAN entries.
803-
*/
804-
for (vid = def_vid; vid < dev->num_vlans; vid++) {
805-
v = &dev->vlans[vid];
821+
if (dev->vlan_filtering) {
822+
/* Upon initial call we have not set-up any VLANs, but upon
823+
* system resume, we need to restore all VLAN entries.
824+
*/
825+
for (vid = def_vid + 1; vid < dev->num_vlans; vid++) {
826+
v = &dev->vlans[vid];
806827

807-
if (!v->members)
808-
continue;
828+
if (!v->members)
829+
continue;
830+
831+
b53_set_vlan_entry(dev, vid, v);
832+
b53_fast_age_vlan(dev, vid);
833+
}
809834

810-
b53_set_vlan_entry(dev, vid, v);
811-
b53_fast_age_vlan(dev, vid);
835+
b53_for_each_port(dev, i) {
836+
if (!dsa_is_cpu_port(ds, i))
837+
b53_write16(dev, B53_VLAN_PAGE,
838+
B53_VLAN_PORT_DEF_TAG(i),
839+
dev->ports[i].pvid);
840+
}
812841
}
813842

814843
return 0;
@@ -1128,7 +1157,9 @@ EXPORT_SYMBOL(b53_setup_devlink_resources);
11281157
static int b53_setup(struct dsa_switch *ds)
11291158
{
11301159
struct b53_device *dev = ds->priv;
1160+
struct b53_vlan *vl;
11311161
unsigned int port;
1162+
u16 pvid;
11321163
int ret;
11331164

11341165
/* Request bridge PVID untagged when DSA_TAG_PROTO_NONE is set
@@ -1147,6 +1178,15 @@ static int b53_setup(struct dsa_switch *ds)
11471178
return ret;
11481179
}
11491180

1181+
/* setup default vlan for filtering mode */
1182+
pvid = b53_default_pvid(dev);
1183+
vl = &dev->vlans[pvid];
1184+
b53_for_each_port(dev, port) {
1185+
vl->members |= BIT(port);
1186+
if (!b53_vlan_port_needs_forced_tagged(ds, port))
1187+
vl->untag |= BIT(port);
1188+
}
1189+
11501190
b53_reset_mib(dev);
11511191

11521192
ret = b53_apply_config(dev);
@@ -1500,7 +1540,10 @@ int b53_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
15001540
{
15011541
struct b53_device *dev = ds->priv;
15021542

1503-
b53_enable_vlan(dev, port, dev->vlan_enabled, vlan_filtering);
1543+
if (dev->vlan_filtering != vlan_filtering) {
1544+
dev->vlan_filtering = vlan_filtering;
1545+
b53_apply_config(dev);
1546+
}
15041547

15051548
return 0;
15061549
}
@@ -1525,7 +1568,7 @@ static int b53_vlan_prepare(struct dsa_switch *ds, int port,
15251568
if (vlan->vid >= dev->num_vlans)
15261569
return -ERANGE;
15271570

1528-
b53_enable_vlan(dev, port, true, ds->vlan_filtering);
1571+
b53_enable_vlan(dev, port, true, dev->vlan_filtering);
15291572

15301573
return 0;
15311574
}
@@ -1548,21 +1591,17 @@ int b53_vlan_add(struct dsa_switch *ds, int port,
15481591
if (vlan->vid == 0)
15491592
return 0;
15501593

1551-
if (!ds->vlan_filtering)
1552-
return 0;
1553-
1554-
b53_read16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port), &old_pvid);
1594+
old_pvid = dev->ports[port].pvid;
15551595
if (pvid)
15561596
new_pvid = vlan->vid;
15571597
else if (!pvid && vlan->vid == old_pvid)
15581598
new_pvid = b53_default_pvid(dev);
15591599
else
15601600
new_pvid = old_pvid;
1601+
dev->ports[port].pvid = new_pvid;
15611602

15621603
vl = &dev->vlans[vlan->vid];
15631604

1564-
b53_get_vlan_entry(dev, vlan->vid, vl);
1565-
15661605
if (dsa_is_cpu_port(ds, port))
15671606
untagged = false;
15681607

@@ -1572,6 +1611,9 @@ int b53_vlan_add(struct dsa_switch *ds, int port,
15721611
else
15731612
vl->untag &= ~BIT(port);
15741613

1614+
if (!dev->vlan_filtering)
1615+
return 0;
1616+
15751617
b53_set_vlan_entry(dev, vlan->vid, vl);
15761618
b53_fast_age_vlan(dev, vlan->vid);
15771619

@@ -1596,23 +1638,22 @@ int b53_vlan_del(struct dsa_switch *ds, int port,
15961638
if (vlan->vid == 0)
15971639
return 0;
15981640

1599-
if (!ds->vlan_filtering)
1600-
return 0;
1601-
1602-
b53_read16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port), &pvid);
1641+
pvid = dev->ports[port].pvid;
16031642

16041643
vl = &dev->vlans[vlan->vid];
16051644

1606-
b53_get_vlan_entry(dev, vlan->vid, vl);
1607-
16081645
vl->members &= ~BIT(port);
16091646

16101647
if (pvid == vlan->vid)
16111648
pvid = b53_default_pvid(dev);
1649+
dev->ports[port].pvid = pvid;
16121650

16131651
if (untagged && !b53_vlan_port_needs_forced_tagged(ds, port))
16141652
vl->untag &= ~(BIT(port));
16151653

1654+
if (!dev->vlan_filtering)
1655+
return 0;
1656+
16161657
b53_set_vlan_entry(dev, vlan->vid, vl);
16171658
b53_fast_age_vlan(dev, vlan->vid);
16181659

@@ -1959,7 +2000,7 @@ int b53_br_join(struct dsa_switch *ds, int port, struct dsa_bridge bridge,
19592000
pvid = b53_default_pvid(dev);
19602001
vl = &dev->vlans[pvid];
19612002

1962-
if (ds->vlan_filtering) {
2003+
if (dev->vlan_filtering) {
19632004
/* Make this port leave the all VLANs join since we will have
19642005
* proper VLAN entries from now on
19652006
*/
@@ -2039,7 +2080,7 @@ void b53_br_leave(struct dsa_switch *ds, int port, struct dsa_bridge bridge)
20392080
pvid = b53_default_pvid(dev);
20402081
vl = &dev->vlans[pvid];
20412082

2042-
if (ds->vlan_filtering) {
2083+
if (dev->vlan_filtering) {
20432084
/* Make this port join all VLANs without VLAN entries */
20442085
if (is58xx(dev)) {
20452086
b53_read16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, &reg);
@@ -2797,6 +2838,7 @@ struct b53_device *b53_switch_alloc(struct device *base,
27972838
ds->ops = &b53_switch_ops;
27982839
ds->phylink_mac_ops = &b53_phylink_mac_ops;
27992840
dev->vlan_enabled = true;
2841+
dev->vlan_filtering = false;
28002842
/* Let DSA handle the case were multiple bridges span the same switch
28012843
* device and different VLAN awareness settings are requested, which
28022844
* would be breaking filtering semantics for any of the other bridge

drivers/net/dsa/b53/b53_priv.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ struct b53_pcs {
9595

9696
struct b53_port {
9797
u16 vlan_ctl_mask;
98+
u16 pvid;
9899
struct ethtool_keee eee;
99100
};
100101

@@ -146,6 +147,7 @@ struct b53_device {
146147
unsigned int num_vlans;
147148
struct b53_vlan *vlans;
148149
bool vlan_enabled;
150+
bool vlan_filtering;
149151
unsigned int num_ports;
150152
struct b53_port *ports;
151153

0 commit comments

Comments
 (0)