Skip to content

Commit 2dc2bd5

Browse files
KanjiMonsterkuba-moo
authored andcommitted
net: dsa: b53: fix toggling vlan_filtering
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>
1 parent f089652 commit 2dc2bd5

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;
@@ -1127,7 +1156,9 @@ EXPORT_SYMBOL(b53_setup_devlink_resources);
11271156
static int b53_setup(struct dsa_switch *ds)
11281157
{
11291158
struct b53_device *dev = ds->priv;
1159+
struct b53_vlan *vl;
11301160
unsigned int port;
1161+
u16 pvid;
11311162
int ret;
11321163

11331164
/* Request bridge PVID untagged when DSA_TAG_PROTO_NONE is set
@@ -1146,6 +1177,15 @@ static int b53_setup(struct dsa_switch *ds)
11461177
return ret;
11471178
}
11481179

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

11511191
ret = b53_apply_config(dev);
@@ -1499,7 +1539,10 @@ int b53_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
14991539
{
15001540
struct b53_device *dev = ds->priv;
15011541

1502-
b53_enable_vlan(dev, port, dev->vlan_enabled, vlan_filtering);
1542+
if (dev->vlan_filtering != vlan_filtering) {
1543+
dev->vlan_filtering = vlan_filtering;
1544+
b53_apply_config(dev);
1545+
}
15031546

15041547
return 0;
15051548
}
@@ -1524,7 +1567,7 @@ static int b53_vlan_prepare(struct dsa_switch *ds, int port,
15241567
if (vlan->vid >= dev->num_vlans)
15251568
return -ERANGE;
15261569

1527-
b53_enable_vlan(dev, port, true, ds->vlan_filtering);
1570+
b53_enable_vlan(dev, port, true, dev->vlan_filtering);
15281571

15291572
return 0;
15301573
}
@@ -1547,21 +1590,17 @@ int b53_vlan_add(struct dsa_switch *ds, int port,
15471590
if (vlan->vid == 0)
15481591
return 0;
15491592

1550-
if (!ds->vlan_filtering)
1551-
return 0;
1552-
1553-
b53_read16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port), &old_pvid);
1593+
old_pvid = dev->ports[port].pvid;
15541594
if (pvid)
15551595
new_pvid = vlan->vid;
15561596
else if (!pvid && vlan->vid == old_pvid)
15571597
new_pvid = b53_default_pvid(dev);
15581598
else
15591599
new_pvid = old_pvid;
1600+
dev->ports[port].pvid = new_pvid;
15601601

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

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

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

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

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

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

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

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

16091646
if (pvid == vlan->vid)
16101647
pvid = b53_default_pvid(dev);
1648+
dev->ports[port].pvid = pvid;
16111649

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

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

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

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

2041-
if (ds->vlan_filtering) {
2082+
if (dev->vlan_filtering) {
20422083
/* Make this port join all VLANs without VLAN entries */
20432084
if (is58xx(dev)) {
20442085
b53_read16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, &reg);
@@ -2803,6 +2844,7 @@ struct b53_device *b53_switch_alloc(struct device *base,
28032844
ds->ops = &b53_switch_ops;
28042845
ds->phylink_mac_ops = &b53_phylink_mac_ops;
28052846
dev->vlan_enabled = true;
2847+
dev->vlan_filtering = false;
28062848
/* Let DSA handle the case were multiple bridges span the same switch
28072849
* device and different VLAN awareness settings are requested, which
28082850
* 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
@@ -96,6 +96,7 @@ struct b53_pcs {
9696

9797
struct b53_port {
9898
u16 vlan_ctl_mask;
99+
u16 pvid;
99100
struct ethtool_keee eee;
100101
};
101102

@@ -147,6 +148,7 @@ struct b53_device {
147148
unsigned int num_vlans;
148149
struct b53_vlan *vlans;
149150
bool vlan_enabled;
151+
bool vlan_filtering;
150152
unsigned int num_ports;
151153
struct b53_port *ports;
152154

0 commit comments

Comments
 (0)