Skip to content

Commit bdc6470

Browse files
committed
Merge branch 'net-dsa-b53-accumulated-fixes'
Jonas Gorski says: ==================== net: dsa: b53: accumulated fixes This patchset aims at fixing most issues observed while running the vlan_unaware_bridge, vlan_aware_bridge and local_termination selftests. Most tests succeed with these patches on BCM53115, connected to a BCM6368. It took me a while to figure out that a lot of tests will fail if all ports have the same MAC address, as the switches drop any frames with DA == SA. Luckily BCM63XX boards often have enough MACs allocated for all ports, so I just needed to assign them. The still failing tests are: FDB learning, both vlan aware aware and unaware: This is expected, as b53 currently does not implement changing the ageing time, and both the bridge code and DSA ignore that, so the learned entries don't age out as expected. ping and ping6 in vlan unaware: These fail because of the now fixed learning, the switch trying to forward packet ingressing on one of the standalone ports to the learned port of the mac address when the packets ingressed on the bridged port. The port VLAN masks only prevent forwarding to other ports, but the ARL lookup will still happen, and the packet gets dropped because the port isn't allowed to forward there. I have a fix/workaround for that, but as it is a bit more controversial and makes use of an unrelated feature, I decided to hold off from that and post it later. This wasn't noticed so far, because learning was never working in VLAN unaware mode, so the traffic was always broadcast (which sidesteps the issue). Finally some of the multicast tests from local_termination fail, where the reception worked except it shouldn't. This doesn't seem to me as a super serious issue, so I didn't attempt to debug/fix these yet. I'm not super confident I didn't break sf2 along the way, but I did compile test and tried to find ways it cause issues (I failed to find any). I hope Florian will tell me. ==================== Link: https://patch.msgid.link/20250429201710.330937-1-jonas.gorski@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents ea78f20 + 2e7179c commit bdc6470

File tree

3 files changed

+154
-57
lines changed

3 files changed

+154
-57
lines changed

drivers/net/dsa/b53/b53_common.c

Lines changed: 150 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -373,15 +373,17 @@ static void b53_enable_vlan(struct b53_device *dev, int port, bool enable,
373373
b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5, &vc5);
374374
}
375375

376+
vc1 &= ~VC1_RX_MCST_FWD_EN;
377+
376378
if (enable) {
377379
vc0 |= VC0_VLAN_EN | VC0_VID_CHK_EN | VC0_VID_HASH_VID;
378-
vc1 |= VC1_RX_MCST_UNTAG_EN | VC1_RX_MCST_FWD_EN;
380+
vc1 |= VC1_RX_MCST_UNTAG_EN;
379381
vc4 &= ~VC4_ING_VID_CHECK_MASK;
380382
if (enable_filtering) {
381383
vc4 |= VC4_ING_VID_VIO_DROP << VC4_ING_VID_CHECK_S;
382384
vc5 |= VC5_DROP_VTABLE_MISS;
383385
} else {
384-
vc4 |= VC4_ING_VID_VIO_FWD << VC4_ING_VID_CHECK_S;
386+
vc4 |= VC4_NO_ING_VID_CHK << VC4_ING_VID_CHECK_S;
385387
vc5 &= ~VC5_DROP_VTABLE_MISS;
386388
}
387389

@@ -393,7 +395,7 @@ static void b53_enable_vlan(struct b53_device *dev, int port, bool enable,
393395

394396
} else {
395397
vc0 &= ~(VC0_VLAN_EN | VC0_VID_CHK_EN | VC0_VID_HASH_VID);
396-
vc1 &= ~(VC1_RX_MCST_UNTAG_EN | VC1_RX_MCST_FWD_EN);
398+
vc1 &= ~VC1_RX_MCST_UNTAG_EN;
397399
vc4 &= ~VC4_ING_VID_CHECK_MASK;
398400
vc5 &= ~VC5_DROP_VTABLE_MISS;
399401

@@ -576,6 +578,18 @@ static void b53_eee_enable_set(struct dsa_switch *ds, int port, bool enable)
576578
b53_write16(dev, B53_EEE_PAGE, B53_EEE_EN_CTRL, reg);
577579
}
578580

581+
int b53_setup_port(struct dsa_switch *ds, int port)
582+
{
583+
struct b53_device *dev = ds->priv;
584+
585+
b53_port_set_ucast_flood(dev, port, true);
586+
b53_port_set_mcast_flood(dev, port, true);
587+
b53_port_set_learning(dev, port, false);
588+
589+
return 0;
590+
}
591+
EXPORT_SYMBOL(b53_setup_port);
592+
579593
int b53_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy)
580594
{
581595
struct b53_device *dev = ds->priv;
@@ -588,10 +602,6 @@ int b53_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy)
588602

589603
cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
590604

591-
b53_port_set_ucast_flood(dev, port, true);
592-
b53_port_set_mcast_flood(dev, port, true);
593-
b53_port_set_learning(dev, port, false);
594-
595605
if (dev->ops->irq_enable)
596606
ret = dev->ops->irq_enable(dev, port);
597607
if (ret)
@@ -722,10 +732,6 @@ static void b53_enable_cpu_port(struct b53_device *dev, int port)
722732
b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), port_ctrl);
723733

724734
b53_brcm_hdr_setup(dev->ds, port);
725-
726-
b53_port_set_ucast_flood(dev, port, true);
727-
b53_port_set_mcast_flood(dev, port, true);
728-
b53_port_set_learning(dev, port, false);
729735
}
730736

731737
static void b53_enable_mib(struct b53_device *dev)
@@ -761,6 +767,22 @@ static bool b53_vlan_port_needs_forced_tagged(struct dsa_switch *ds, int port)
761767
return dev->tag_protocol == DSA_TAG_PROTO_NONE && dsa_is_cpu_port(ds, port);
762768
}
763769

770+
static bool b53_vlan_port_may_join_untagged(struct dsa_switch *ds, int port)
771+
{
772+
struct b53_device *dev = ds->priv;
773+
struct dsa_port *dp;
774+
775+
if (!dev->vlan_filtering)
776+
return true;
777+
778+
dp = dsa_to_port(ds, port);
779+
780+
if (dsa_port_is_cpu(dp))
781+
return true;
782+
783+
return dp->bridge == NULL;
784+
}
785+
764786
int b53_configure_vlan(struct dsa_switch *ds)
765787
{
766788
struct b53_device *dev = ds->priv;
@@ -779,34 +801,47 @@ int b53_configure_vlan(struct dsa_switch *ds)
779801
b53_do_vlan_op(dev, VTA_CMD_CLEAR);
780802
}
781803

782-
b53_enable_vlan(dev, -1, dev->vlan_enabled, ds->vlan_filtering);
804+
b53_enable_vlan(dev, -1, dev->vlan_enabled, dev->vlan_filtering);
783805

784806
/* Create an untagged VLAN entry for the default PVID in case
785807
* CONFIG_VLAN_8021Q is disabled and there are no calls to
786808
* dsa_user_vlan_rx_add_vid() to create the default VLAN
787809
* entry. Do this only when the tagging protocol is not
788810
* DSA_TAG_PROTO_NONE
789811
*/
812+
v = &dev->vlans[def_vid];
790813
b53_for_each_port(dev, i) {
791-
v = &dev->vlans[def_vid];
792-
v->members |= BIT(i);
814+
if (!b53_vlan_port_may_join_untagged(ds, i))
815+
continue;
816+
817+
vl.members |= BIT(i);
793818
if (!b53_vlan_port_needs_forced_tagged(ds, i))
794-
v->untag = v->members;
795-
b53_write16(dev, B53_VLAN_PAGE,
796-
B53_VLAN_PORT_DEF_TAG(i), def_vid);
819+
vl.untag = vl.members;
820+
b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(i),
821+
def_vid);
797822
}
823+
b53_set_vlan_entry(dev, def_vid, &vl);
798824

799-
/* Upon initial call we have not set-up any VLANs, but upon
800-
* system resume, we need to restore all VLAN entries.
801-
*/
802-
for (vid = def_vid; vid < dev->num_vlans; vid++) {
803-
v = &dev->vlans[vid];
825+
if (dev->vlan_filtering) {
826+
/* Upon initial call we have not set-up any VLANs, but upon
827+
* system resume, we need to restore all VLAN entries.
828+
*/
829+
for (vid = def_vid + 1; vid < dev->num_vlans; vid++) {
830+
v = &dev->vlans[vid];
804831

805-
if (!v->members)
806-
continue;
832+
if (!v->members)
833+
continue;
834+
835+
b53_set_vlan_entry(dev, vid, v);
836+
b53_fast_age_vlan(dev, vid);
837+
}
807838

808-
b53_set_vlan_entry(dev, vid, v);
809-
b53_fast_age_vlan(dev, vid);
839+
b53_for_each_port(dev, i) {
840+
if (!dsa_is_cpu_port(ds, i))
841+
b53_write16(dev, B53_VLAN_PAGE,
842+
B53_VLAN_PORT_DEF_TAG(i),
843+
dev->ports[i].pvid);
844+
}
810845
}
811846

812847
return 0;
@@ -1125,20 +1160,36 @@ EXPORT_SYMBOL(b53_setup_devlink_resources);
11251160
static int b53_setup(struct dsa_switch *ds)
11261161
{
11271162
struct b53_device *dev = ds->priv;
1163+
struct b53_vlan *vl;
11281164
unsigned int port;
1165+
u16 pvid;
11291166
int ret;
11301167

11311168
/* Request bridge PVID untagged when DSA_TAG_PROTO_NONE is set
11321169
* which forces the CPU port to be tagged in all VLANs.
11331170
*/
11341171
ds->untag_bridge_pvid = dev->tag_protocol == DSA_TAG_PROTO_NONE;
11351172

1173+
/* The switch does not tell us the original VLAN for untagged
1174+
* packets, so keep the CPU port always tagged.
1175+
*/
1176+
ds->untag_vlan_aware_bridge_pvid = true;
1177+
11361178
ret = b53_reset_switch(dev);
11371179
if (ret) {
11381180
dev_err(ds->dev, "failed to reset switch\n");
11391181
return ret;
11401182
}
11411183

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

11441195
ret = b53_apply_config(dev);
@@ -1492,7 +1543,10 @@ int b53_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
14921543
{
14931544
struct b53_device *dev = ds->priv;
14941545

1495-
b53_enable_vlan(dev, port, dev->vlan_enabled, vlan_filtering);
1546+
if (dev->vlan_filtering != vlan_filtering) {
1547+
dev->vlan_filtering = vlan_filtering;
1548+
b53_apply_config(dev);
1549+
}
14961550

14971551
return 0;
14981552
}
@@ -1517,7 +1571,7 @@ static int b53_vlan_prepare(struct dsa_switch *ds, int port,
15171571
if (vlan->vid >= dev->num_vlans)
15181572
return -ERANGE;
15191573

1520-
b53_enable_vlan(dev, port, true, ds->vlan_filtering);
1574+
b53_enable_vlan(dev, port, true, dev->vlan_filtering);
15211575

15221576
return 0;
15231577
}
@@ -1530,32 +1584,46 @@ int b53_vlan_add(struct dsa_switch *ds, int port,
15301584
bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
15311585
bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
15321586
struct b53_vlan *vl;
1587+
u16 old_pvid, new_pvid;
15331588
int err;
15341589

15351590
err = b53_vlan_prepare(ds, port, vlan);
15361591
if (err)
15371592
return err;
15381593

1539-
vl = &dev->vlans[vlan->vid];
1594+
if (vlan->vid == 0)
1595+
return 0;
15401596

1541-
b53_get_vlan_entry(dev, vlan->vid, vl);
1597+
old_pvid = dev->ports[port].pvid;
1598+
if (pvid)
1599+
new_pvid = vlan->vid;
1600+
else if (!pvid && vlan->vid == old_pvid)
1601+
new_pvid = b53_default_pvid(dev);
1602+
else
1603+
new_pvid = old_pvid;
1604+
dev->ports[port].pvid = new_pvid;
1605+
1606+
vl = &dev->vlans[vlan->vid];
15421607

1543-
if (vlan->vid == 0 && vlan->vid == b53_default_pvid(dev))
1544-
untagged = true;
1608+
if (dsa_is_cpu_port(ds, port))
1609+
untagged = false;
15451610

15461611
vl->members |= BIT(port);
15471612
if (untagged && !b53_vlan_port_needs_forced_tagged(ds, port))
15481613
vl->untag |= BIT(port);
15491614
else
15501615
vl->untag &= ~BIT(port);
15511616

1617+
if (!dev->vlan_filtering)
1618+
return 0;
1619+
15521620
b53_set_vlan_entry(dev, vlan->vid, vl);
15531621
b53_fast_age_vlan(dev, vlan->vid);
15541622

1555-
if (pvid && !dsa_is_cpu_port(ds, port)) {
1623+
if (!dsa_is_cpu_port(ds, port) && new_pvid != old_pvid) {
15561624
b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port),
1557-
vlan->vid);
1558-
b53_fast_age_vlan(dev, vlan->vid);
1625+
new_pvid);
1626+
b53_fast_age_vlan(dev, old_pvid);
15591627
}
15601628

15611629
return 0;
@@ -1570,20 +1638,25 @@ int b53_vlan_del(struct dsa_switch *ds, int port,
15701638
struct b53_vlan *vl;
15711639
u16 pvid;
15721640

1573-
b53_read16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port), &pvid);
1641+
if (vlan->vid == 0)
1642+
return 0;
15741643

1575-
vl = &dev->vlans[vlan->vid];
1644+
pvid = dev->ports[port].pvid;
15761645

1577-
b53_get_vlan_entry(dev, vlan->vid, vl);
1646+
vl = &dev->vlans[vlan->vid];
15781647

15791648
vl->members &= ~BIT(port);
15801649

15811650
if (pvid == vlan->vid)
15821651
pvid = b53_default_pvid(dev);
1652+
dev->ports[port].pvid = pvid;
15831653

15841654
if (untagged && !b53_vlan_port_needs_forced_tagged(ds, port))
15851655
vl->untag &= ~(BIT(port));
15861656

1657+
if (!dev->vlan_filtering)
1658+
return 0;
1659+
15871660
b53_set_vlan_entry(dev, vlan->vid, vl);
15881661
b53_fast_age_vlan(dev, vlan->vid);
15891662

@@ -1916,8 +1989,9 @@ int b53_br_join(struct dsa_switch *ds, int port, struct dsa_bridge bridge,
19161989
bool *tx_fwd_offload, struct netlink_ext_ack *extack)
19171990
{
19181991
struct b53_device *dev = ds->priv;
1992+
struct b53_vlan *vl;
19191993
s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
1920-
u16 pvlan, reg;
1994+
u16 pvlan, reg, pvid;
19211995
unsigned int i;
19221996

19231997
/* On 7278, port 7 which connects to the ASP should only receive
@@ -1926,15 +2000,29 @@ int b53_br_join(struct dsa_switch *ds, int port, struct dsa_bridge bridge,
19262000
if (dev->chip_id == BCM7278_DEVICE_ID && port == 7)
19272001
return -EINVAL;
19282002

1929-
/* Make this port leave the all VLANs join since we will have proper
1930-
* VLAN entries from now on
1931-
*/
1932-
if (is58xx(dev)) {
1933-
b53_read16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, &reg);
1934-
reg &= ~BIT(port);
1935-
if ((reg & BIT(cpu_port)) == BIT(cpu_port))
1936-
reg &= ~BIT(cpu_port);
1937-
b53_write16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, reg);
2003+
pvid = b53_default_pvid(dev);
2004+
vl = &dev->vlans[pvid];
2005+
2006+
if (dev->vlan_filtering) {
2007+
/* Make this port leave the all VLANs join since we will have
2008+
* proper VLAN entries from now on
2009+
*/
2010+
if (is58xx(dev)) {
2011+
b53_read16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN,
2012+
&reg);
2013+
reg &= ~BIT(port);
2014+
if ((reg & BIT(cpu_port)) == BIT(cpu_port))
2015+
reg &= ~BIT(cpu_port);
2016+
b53_write16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN,
2017+
reg);
2018+
}
2019+
2020+
b53_get_vlan_entry(dev, pvid, vl);
2021+
vl->members &= ~BIT(port);
2022+
if (vl->members == BIT(cpu_port))
2023+
vl->members &= ~BIT(cpu_port);
2024+
vl->untag = vl->members;
2025+
b53_set_vlan_entry(dev, pvid, vl);
19382026
}
19392027

19402028
b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), &pvlan);
@@ -1967,7 +2055,7 @@ EXPORT_SYMBOL(b53_br_join);
19672055
void b53_br_leave(struct dsa_switch *ds, int port, struct dsa_bridge bridge)
19682056
{
19692057
struct b53_device *dev = ds->priv;
1970-
struct b53_vlan *vl = &dev->vlans[0];
2058+
struct b53_vlan *vl;
19712059
s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
19722060
unsigned int i;
19732061
u16 pvlan, reg, pvid;
@@ -1993,15 +2081,18 @@ void b53_br_leave(struct dsa_switch *ds, int port, struct dsa_bridge bridge)
19932081
dev->ports[port].vlan_ctl_mask = pvlan;
19942082

19952083
pvid = b53_default_pvid(dev);
2084+
vl = &dev->vlans[pvid];
2085+
2086+
if (dev->vlan_filtering) {
2087+
/* Make this port join all VLANs without VLAN entries */
2088+
if (is58xx(dev)) {
2089+
b53_read16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, &reg);
2090+
reg |= BIT(port);
2091+
if (!(reg & BIT(cpu_port)))
2092+
reg |= BIT(cpu_port);
2093+
b53_write16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, reg);
2094+
}
19962095

1997-
/* Make this port join all VLANs without VLAN entries */
1998-
if (is58xx(dev)) {
1999-
b53_read16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, &reg);
2000-
reg |= BIT(port);
2001-
if (!(reg & BIT(cpu_port)))
2002-
reg |= BIT(cpu_port);
2003-
b53_write16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, reg);
2004-
} else {
20052096
b53_get_vlan_entry(dev, pvid, vl);
20062097
vl->members |= BIT(port) | BIT(cpu_port);
20072098
vl->untag |= BIT(port) | BIT(cpu_port);
@@ -2300,6 +2391,7 @@ static const struct dsa_switch_ops b53_switch_ops = {
23002391
.phy_read = b53_phy_read16,
23012392
.phy_write = b53_phy_write16,
23022393
.phylink_get_caps = b53_phylink_get_caps,
2394+
.port_setup = b53_setup_port,
23032395
.port_enable = b53_enable_port,
23042396
.port_disable = b53_disable_port,
23052397
.support_eee = b53_support_eee,
@@ -2757,6 +2849,7 @@ struct b53_device *b53_switch_alloc(struct device *base,
27572849
ds->ops = &b53_switch_ops;
27582850
ds->phylink_mac_ops = &b53_phylink_mac_ops;
27592851
dev->vlan_enabled = true;
2852+
dev->vlan_filtering = false;
27602853
/* Let DSA handle the case were multiple bridges span the same switch
27612854
* device and different VLAN awareness settings are requested, which
27622855
* would be breaking filtering semantics for any of the other bridge

0 commit comments

Comments
 (0)