Commit f089652b authored by Jonas Gorski's avatar Jonas Gorski Committed by Jakub Kicinski
Browse files

net: dsa: b53: do not program vlans when vlan filtering is off



Documentation/networking/switchdev.rst says:

- with VLAN filtering turned off: the bridge is strictly VLAN unaware and its
  data path will process all Ethernet frames as if they are VLAN-untagged.
  The bridge VLAN database can still be modified, but the modifications should
  have no effect while VLAN filtering is turned off.

This breaks if we immediately apply the VLAN configuration, so skip
writing it when vlan_filtering is off.

Fixes: 0ee2af4e ("net: dsa: set configure_vlan_while_not_filtering to true by default")
Signed-off-by: default avatarJonas Gorski <jonas.gorski@gmail.com>
Tested-by: default avatarFlorian Fainelli <florian.fainelli@broadcom.com>
Reviewed-by: default avatarFlorian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20250429201710.330937-9-jonas.gorski@gmail.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 45e9d59d
Loading
Loading
Loading
Loading
+28 −20
Original line number Diff line number Diff line
@@ -1547,6 +1547,9 @@ int b53_vlan_add(struct dsa_switch *ds, int port,
	if (vlan->vid == 0)
		return 0;

	if (!ds->vlan_filtering)
		return 0;

	b53_read16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port), &old_pvid);
	if (pvid)
		new_pvid = vlan->vid;
@@ -1592,6 +1595,9 @@ int b53_vlan_del(struct dsa_switch *ds, int port,
	if (vlan->vid == 0)
		return 0;

	if (!ds->vlan_filtering)
		return 0;

	b53_read16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port), &pvid);

	vl = &dev->vlans[vlan->vid];
@@ -1952,18 +1958,20 @@ int b53_br_join(struct dsa_switch *ds, int port, struct dsa_bridge bridge,
	pvid = b53_default_pvid(dev);
	vl = &dev->vlans[pvid];

	/* Make this port leave the all VLANs join since we will have proper
	 * VLAN entries from now on
	if (ds->vlan_filtering) {
		/* Make this port leave the all VLANs join since we will have
		 * proper VLAN entries from now on
		 */
		if (is58xx(dev)) {
		b53_read16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, &reg);
			b53_read16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN,
				   &reg);
			reg &= ~BIT(port);
			if ((reg & BIT(cpu_port)) == BIT(cpu_port))
				reg &= ~BIT(cpu_port);
		b53_write16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, reg);
			b53_write16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN,
				    reg);
		}

	if (ds->vlan_filtering) {
		b53_get_vlan_entry(dev, pvid, vl);
		vl->members &= ~BIT(port);
		if (vl->members == BIT(cpu_port))
@@ -2030,6 +2038,7 @@ void b53_br_leave(struct dsa_switch *ds, int port, struct dsa_bridge bridge)
	pvid = b53_default_pvid(dev);
	vl = &dev->vlans[pvid];

	if (ds->vlan_filtering) {
		/* Make this port join all VLANs without VLAN entries */
		if (is58xx(dev)) {
			b53_read16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, &reg);
@@ -2039,7 +2048,6 @@ void b53_br_leave(struct dsa_switch *ds, int port, struct dsa_bridge bridge)
			b53_write16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, reg);
		}

	if (ds->vlan_filtering) {
		b53_get_vlan_entry(dev, pvid, vl);
		vl->members |= BIT(port) | BIT(cpu_port);
		vl->untag |= BIT(port) | BIT(cpu_port);