All of lore.kernel.org
 help / color / mirror / Atom feed
From: Semih Baskan <strst.gs@gmail.com>
To: florian.fainelli@broadcom.com, jonas.gorski@gmail.com,
	andrew@lunn.ch, olteanv@gmail.com, davem@davemloft.net,
	edumazet@google.com, kuba@kernel.org, pabeni@redhat.com
Cc: vladimir.oltean@nxp.com, horms@kernel.org,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH net 1/2] net: dsa: let drivers offload 8021q uppers on standalone ports
Date: Thu,  6 Aug 2026 10:31:18 +0300	[thread overview]
Message-ID: <20260806073119.387-2-strst.gs@gmail.com> (raw)
In-Reply-To: <20260806073119.387-1-strst.gs@gmail.com>

Some switches cannot deliver a tagged frame to the CPU while its VID is
absent from the VLAN table, not even with VLAN filtering turned off.
b53 is one of them: its VID lookup is always active, and disabling it
moves the ARL to shared VLAN learning, where ARL operations force VID 0
and the hardware table drifts away from the bridge fdb. On such
hardware a standalone port can only receive the traffic of its 8021q
uppers if their VIDs are programmed into the table.

The existing opt-in for this class of problem,
ds->needs_standalone_vlan_filtering, delivers those VIDs but does more:
dsa_port_reset_vlan_filtering() also forces vlan_filtering=1 on a port
that leaves a VLAN-unaware bridge. hellcreek wants exactly that. b53
must not have it, because it sets vlan_filtering_is_global, so the
forced flip would turn the whole switch into a VLAN filtering device
the first time any port leaves a VLAN-unaware bridge and change
behaviour for every other port.

Add ds->needs_standalone_vlan_offload for the narrower need. It
advertises NETIF_F_HW_VLAN_CTAG_FILTER on user ports, so the 8021q
layer reports upper VIDs to .port_vlan_add, and it leaves the
vlan_filtering state alone.

Upper offload of such a switch never depends on vlan_filtering: every
VID was already delivered when the upper was created, since the
feature bit is always on. dsa_port_vlan_filtering() therefore skips
its ports entirely when a bridge toggles VLAN awareness. Restoring
them on the way up would add VIDs that were never cleared, and
clearing them on the way down would strip the driver's record of a
bridged port's uppers and the feature bit, leaving a port that later
leaves the bridge with uppers that cannot receive and no way to
re-offload them. The conduit change path keeps its explicit teardown
and restore of standalone VLANs, and now also runs it for a standalone
port of such a switch while VLAN filtering is off, because that port
has VLANs on the CPU port too.

The Fixes tag is for backport dependency tracking: the b53 fix in the
next patch needs this flag to exist.

Fixes: 06cfb2df7eb0 ("net: dsa: don't advertise 'rx-vlan-filter' when not needed")
Cc: stable@vger.kernel.org
Signed-off-by: Semih Baskan <strst.gs@gmail.com>
---
 include/net/dsa.h |  3 +++
 net/dsa/port.c    | 21 ++++++++++++++-------
 net/dsa/user.c    |  4 +++-
 3 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/include/net/dsa.h b/include/net/dsa.h
index 6f7f5c17b532..6f3a60c23d14 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -403,6 +403,9 @@ struct dsa_switch {
 	/* Keep VLAN filtering enabled on ports not offloading any upper */
 	u32			needs_standalone_vlan_filtering:1;
 
+	/* Offload 8021q uppers of standalone ports even when not filtering */
+	u32			needs_standalone_vlan_offload:1;
+
 	/* Pass .port_vlan_add and .port_vlan_del to drivers even for bridges
 	 * that have vlan_filtering=0. All drivers should ideally set this (and
 	 * then the option would get removed), but it is unknown whether this
diff --git a/net/dsa/port.c b/net/dsa/port.c
index 1f5536c0dffc..23d1c5ae6934 100644
--- a/net/dsa/port.c
+++ b/net/dsa/port.c
@@ -831,6 +831,9 @@ int dsa_port_vlan_filtering(struct dsa_port *dp, bool vlan_filtering,
 			if (!user)
 				continue;
 
+			if (ds->needs_standalone_vlan_offload)
+				continue;
+
 			err = dsa_user_manage_vlan_filtering(user,
 							     vlan_filtering);
 			if (err)
@@ -839,10 +842,12 @@ int dsa_port_vlan_filtering(struct dsa_port *dp, bool vlan_filtering,
 	} else {
 		dp->vlan_filtering = vlan_filtering;
 
-		err = dsa_user_manage_vlan_filtering(dp->user,
-						     vlan_filtering);
-		if (err)
-			goto restore;
+		if (!ds->needs_standalone_vlan_offload) {
+			err = dsa_user_manage_vlan_filtering(dp->user,
+							     vlan_filtering);
+			if (err)
+				goto restore;
+		}
 	}
 
 	return 0;
@@ -1445,10 +1450,12 @@ int dsa_port_change_conduit(struct dsa_port *dp, struct net_device *conduit,
 
 	/* The port might still be VLAN filtering even if it's no longer
 	 * under a bridge, either due to ds->vlan_filtering_is_global or
-	 * ds->needs_standalone_vlan_filtering. In turn this means VLANs
-	 * on the CPU port.
+	 * ds->needs_standalone_vlan_filtering, and standalone ports of a
+	 * ds->needs_standalone_vlan_offload switch keep their VLANs without
+	 * filtering. In turn this means VLANs on the CPU port.
 	 */
-	vlan_filtering = dsa_port_is_vlan_filtering(dp);
+	vlan_filtering = dsa_port_is_vlan_filtering(dp) ||
+			 (ds->needs_standalone_vlan_offload && !bridge_dev);
 	if (vlan_filtering) {
 		err = dsa_user_manage_vlan_filtering(dev, false);
 		if (err) {
diff --git a/net/dsa/user.c b/net/dsa/user.c
index 03c7af6abe18..2b1695b386ef 100644
--- a/net/dsa/user.c
+++ b/net/dsa/user.c
@@ -1946,6 +1946,7 @@ static int dsa_user_clear_vlan(struct net_device *vdev, int vid, void *arg)
  *
  * - If standalone (this includes software bridge, software LAG):
  *     - if ds->needs_standalone_vlan_filtering = true, OR if
+ *       ds->needs_standalone_vlan_offload = true, OR if
  *       (ds->vlan_filtering_is_global = true AND there are bridges spanning
  *       this switch chip which have vlan_filtering=1)
  *         - the 8021q upper VLANs
@@ -2718,7 +2719,8 @@ void dsa_user_setup_tagger(struct net_device *user)
 	user->hw_features |= NETIF_F_HW_TC;
 	if (user->needed_tailroom)
 		user->features &= ~(NETIF_F_SG | NETIF_F_FRAGLIST);
-	if (ds->needs_standalone_vlan_filtering)
+	if (ds->needs_standalone_vlan_filtering ||
+	    ds->needs_standalone_vlan_offload)
 		user->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
 
 	user->lltx = true;

  reply	other threads:[~2026-08-06  7:31 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-06  7:31 [PATCH net 0/2] net: dsa: b53: fix 8021q uppers on standalone ports Semih Baskan
2026-08-06  7:31 ` Semih Baskan [this message]
2026-08-06 11:15   ` [PATCH net 1/2] net: dsa: let drivers offload " Vladimir Oltean
2026-08-06 11:44     ` Semih Baskan
2026-08-06 12:43       ` Vladimir Oltean
2026-08-06 13:39         ` Semih Baskan
2026-08-10 12:08           ` Vladimir Oltean
2026-08-11  6:25             ` Semih Baskan
2026-08-11  7:44               ` Jonas Gorski
2026-08-11  9:58                 ` Vladimir Oltean
2026-08-11 13:19                   ` Semih Baskan
2026-08-06  7:31 ` [PATCH net 2/2] net: dsa: b53: " Semih Baskan
2026-08-06  8:39 ` [PATCH net 0/2] net: dsa: b53: fix " Jonas Gorski
2026-08-06 11:06   ` Semih Baskan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260806073119.387-2-strst.gs@gmail.com \
    --to=strst.gs@gmail.com \
    --cc=andrew@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=florian.fainelli@broadcom.com \
    --cc=horms@kernel.org \
    --cc=jonas.gorski@gmail.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=olteanv@gmail.com \
    --cc=pabeni@redhat.com \
    --cc=vladimir.oltean@nxp.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.