Skip to content

Commit 0babc09

Browse files
KanjiMonstersmb49
authored andcommitted
net: dsa: b53: fix toggling vlan_filtering
BugLink: https://bugs.launchpad.net/bugs/2130277 [ 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> Signed-off-by: Manuel Diewald <manuel.diewald@canonical.com> Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
1 parent a299a7c commit 0babc09

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
@@ -750,6 +750,22 @@ static bool b53_vlan_port_needs_forced_tagged(struct dsa_switch *ds, int port)
750750
return dev->tag_protocol == DSA_TAG_PROTO_NONE && dsa_is_cpu_port(ds, port);
751751
}
752752

753+
static bool b53_vlan_port_may_join_untagged(struct dsa_switch *ds, int port)
754+
{
755+
struct b53_device *dev = ds->priv;
756+
struct dsa_port *dp;
757+
758+
if (!dev->vlan_filtering)
759+
return true;
760+
761+
dp = dsa_to_port(ds, port);
762+
763+
if (dsa_port_is_cpu(dp))
764+
return true;
765+
766+
return dp->bridge == NULL;
767+
}
768+
753769
int b53_configure_vlan(struct dsa_switch *ds)
754770
{
755771
struct b53_device *dev = ds->priv;
@@ -768,34 +784,47 @@ int b53_configure_vlan(struct dsa_switch *ds)
768784
b53_do_vlan_op(dev, VTA_CMD_CLEAR);
769785
}
770786

771-
b53_enable_vlan(dev, -1, dev->vlan_enabled, ds->vlan_filtering);
787+
b53_enable_vlan(dev, -1, dev->vlan_enabled, dev->vlan_filtering);
772788

773789
/* Create an untagged VLAN entry for the default PVID in case
774790
* CONFIG_VLAN_8021Q is disabled and there are no calls to
775791
* dsa_user_vlan_rx_add_vid() to create the default VLAN
776792
* entry. Do this only when the tagging protocol is not
777793
* DSA_TAG_PROTO_NONE
778794
*/
795+
v = &dev->vlans[def_vid];
779796
b53_for_each_port(dev, i) {
780-
v = &dev->vlans[def_vid];
781-
v->members |= BIT(i);
797+
if (!b53_vlan_port_may_join_untagged(ds, i))
798+
continue;
799+
800+
vl.members |= BIT(i);
782801
if (!b53_vlan_port_needs_forced_tagged(ds, i))
783-
v->untag = v->members;
784-
b53_write16(dev, B53_VLAN_PAGE,
785-
B53_VLAN_PORT_DEF_TAG(i), def_vid);
802+
vl.untag = vl.members;
803+
b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(i),
804+
def_vid);
786805
}
806+
b53_set_vlan_entry(dev, def_vid, &vl);
787807

788-
/* Upon initial call we have not set-up any VLANs, but upon
789-
* system resume, we need to restore all VLAN entries.
790-
*/
791-
for (vid = def_vid; vid < dev->num_vlans; vid++) {
792-
v = &dev->vlans[vid];
808+
if (dev->vlan_filtering) {
809+
/* Upon initial call we have not set-up any VLANs, but upon
810+
* system resume, we need to restore all VLAN entries.
811+
*/
812+
for (vid = def_vid + 1; vid < dev->num_vlans; vid++) {
813+
v = &dev->vlans[vid];
793814

794-
if (!v->members)
795-
continue;
815+
if (!v->members)
816+
continue;
817+
818+
b53_set_vlan_entry(dev, vid, v);
819+
b53_fast_age_vlan(dev, vid);
820+
}
796821

797-
b53_set_vlan_entry(dev, vid, v);
798-
b53_fast_age_vlan(dev, vid);
822+
b53_for_each_port(dev, i) {
823+
if (!dsa_is_cpu_port(ds, i))
824+
b53_write16(dev, B53_VLAN_PAGE,
825+
B53_VLAN_PORT_DEF_TAG(i),
826+
dev->ports[i].pvid);
827+
}
799828
}
800829

801830
return 0;
@@ -1115,7 +1144,9 @@ EXPORT_SYMBOL(b53_setup_devlink_resources);
11151144
static int b53_setup(struct dsa_switch *ds)
11161145
{
11171146
struct b53_device *dev = ds->priv;
1147+
struct b53_vlan *vl;
11181148
unsigned int port;
1149+
u16 pvid;
11191150
int ret;
11201151

11211152
/* Request bridge PVID untagged when DSA_TAG_PROTO_NONE is set
@@ -1129,6 +1160,15 @@ static int b53_setup(struct dsa_switch *ds)
11291160
return ret;
11301161
}
11311162

1163+
/* setup default vlan for filtering mode */
1164+
pvid = b53_default_pvid(dev);
1165+
vl = &dev->vlans[pvid];
1166+
b53_for_each_port(dev, port) {
1167+
vl->members |= BIT(port);
1168+
if (!b53_vlan_port_needs_forced_tagged(ds, port))
1169+
vl->untag |= BIT(port);
1170+
}
1171+
11321172
b53_reset_mib(dev);
11331173

11341174
ret = b53_apply_config(dev);
@@ -1483,7 +1523,10 @@ int b53_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
14831523
{
14841524
struct b53_device *dev = ds->priv;
14851525

1486-
b53_enable_vlan(dev, port, dev->vlan_enabled, vlan_filtering);
1526+
if (dev->vlan_filtering != vlan_filtering) {
1527+
dev->vlan_filtering = vlan_filtering;
1528+
b53_apply_config(dev);
1529+
}
14871530

14881531
return 0;
14891532
}
@@ -1508,7 +1551,7 @@ static int b53_vlan_prepare(struct dsa_switch *ds, int port,
15081551
if (vlan->vid >= dev->num_vlans)
15091552
return -ERANGE;
15101553

1511-
b53_enable_vlan(dev, port, true, ds->vlan_filtering);
1554+
b53_enable_vlan(dev, port, true, dev->vlan_filtering);
15121555

15131556
return 0;
15141557
}
@@ -1531,21 +1574,17 @@ int b53_vlan_add(struct dsa_switch *ds, int port,
15311574
if (vlan->vid == 0)
15321575
return 0;
15331576

1534-
if (!ds->vlan_filtering)
1535-
return 0;
1536-
1537-
b53_read16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port), &old_pvid);
1577+
old_pvid = dev->ports[port].pvid;
15381578
if (pvid)
15391579
new_pvid = vlan->vid;
15401580
else if (!pvid && vlan->vid == old_pvid)
15411581
new_pvid = b53_default_pvid(dev);
15421582
else
15431583
new_pvid = old_pvid;
1584+
dev->ports[port].pvid = new_pvid;
15441585

15451586
vl = &dev->vlans[vlan->vid];
15461587

1547-
b53_get_vlan_entry(dev, vlan->vid, vl);
1548-
15491588
if (dsa_is_cpu_port(ds, port))
15501589
untagged = false;
15511590

@@ -1555,6 +1594,9 @@ int b53_vlan_add(struct dsa_switch *ds, int port,
15551594
else
15561595
vl->untag &= ~BIT(port);
15571596

1597+
if (!dev->vlan_filtering)
1598+
return 0;
1599+
15581600
b53_set_vlan_entry(dev, vlan->vid, vl);
15591601
b53_fast_age_vlan(dev, vlan->vid);
15601602

@@ -1579,23 +1621,22 @@ int b53_vlan_del(struct dsa_switch *ds, int port,
15791621
if (vlan->vid == 0)
15801622
return 0;
15811623

1582-
if (!ds->vlan_filtering)
1583-
return 0;
1584-
1585-
b53_read16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port), &pvid);
1624+
pvid = dev->ports[port].pvid;
15861625

15871626
vl = &dev->vlans[vlan->vid];
15881627

1589-
b53_get_vlan_entry(dev, vlan->vid, vl);
1590-
15911628
vl->members &= ~BIT(port);
15921629

15931630
if (pvid == vlan->vid)
15941631
pvid = b53_default_pvid(dev);
1632+
dev->ports[port].pvid = pvid;
15951633

15961634
if (untagged && !b53_vlan_port_needs_forced_tagged(ds, port))
15971635
vl->untag &= ~(BIT(port));
15981636

1637+
if (!dev->vlan_filtering)
1638+
return 0;
1639+
15991640
b53_set_vlan_entry(dev, vlan->vid, vl);
16001641
b53_fast_age_vlan(dev, vlan->vid);
16011642

@@ -1942,7 +1983,7 @@ int b53_br_join(struct dsa_switch *ds, int port, struct dsa_bridge bridge,
19421983
pvid = b53_default_pvid(dev);
19431984
vl = &dev->vlans[pvid];
19441985

1945-
if (ds->vlan_filtering) {
1986+
if (dev->vlan_filtering) {
19461987
/* Make this port leave the all VLANs join since we will have
19471988
* proper VLAN entries from now on
19481989
*/
@@ -2022,7 +2063,7 @@ void b53_br_leave(struct dsa_switch *ds, int port, struct dsa_bridge bridge)
20222063
pvid = b53_default_pvid(dev);
20232064
vl = &dev->vlans[pvid];
20242065

2025-
if (ds->vlan_filtering) {
2066+
if (dev->vlan_filtering) {
20262067
/* Make this port join all VLANs without VLAN entries */
20272068
if (is58xx(dev)) {
20282069
b53_read16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, &reg);
@@ -2798,6 +2839,7 @@ struct b53_device *b53_switch_alloc(struct device *base,
27982839
dev->ops = ops;
27992840
ds->ops = &b53_switch_ops;
28002841
dev->vlan_enabled = true;
2842+
dev->vlan_filtering = false;
28012843
/* Let DSA handle the case were multiple bridges span the same switch
28022844
* device and different VLAN awareness settings are requested, which
28032845
* 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_eee 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)