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;
next prev parent reply other threads:[~2026-08-06 7:31 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-06 7:31 [PATCH net 0/2] net: dsa: b53: fix " 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-12 7:24 ` Jonas Gorski
2026-08-12 9:21 ` Semih Baskan
2026-08-12 9:52 ` Jonas Gorski
2026-08-12 10:21 ` Semih Baskan
2026-08-12 18:12 ` Florian Fainelli
2026-08-12 7:14 ` Jonas Gorski
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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®