public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 00/15] Introduce the dsa_xmit_port_mask() tagging protocol helper
@ 2025-11-27 12:08 Vladimir Oltean
  2025-11-27 12:08 ` [PATCH net-next 01/15] net: dsa: introduce " Vladimir Oltean
                   ` (15 more replies)
  0 siblings, 16 replies; 23+ messages in thread
From: Vladimir Oltean @ 2025-11-27 12:08 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Alvin Šipraga, Clément Léger,
	Daniel Golle, David Yang, DENG Qingfang, Florian Fainelli,
	George McCollister, Hauke Mehrtens, Jonas Gorski, Kurt Kanzenbach,
	Linus Walleij, linux-renesas-soc, Sean Wang, UNGLinuxDriver,
	Woojung Huh

What
----

Some DSA tags have just the port number in the TX header format, others
have a bit field where in theory, multiple bits can be set, even though
DSA only sets one.

The latter kind is now making use of a dsa_xmit_port_mask() helper,
which will decide when to set more than 1 bit in that mask.

Why
---

David Yang has pointed out in a recently posted patch that HSR packet
duplication on transmission can be offloaded even on HSR-unaware
switches. This should be made generally available to all DSA switches.

How to test
-----------

These patches just lay the groundwork, and there should be no functional
change - so for this set, regression testing is all that's necessary.

For testing the HSR packet duplication idea, I've put together a branch:
https://github.com/vladimiroltean/linux/commits/dsa-simple-hsr-offload/
where most drivers are patched to call dsa_port_simple_hsr_join() and
dsa_port_simple_hsr_leave().

Assuming there are volunteers to also test the latter, one can enable
CONFIG_HSR and create a HSR device using:
$ ip link add name hsr0 type hsr slave1 swp0 slave2 swp1 supervision 45 version 1

This needs to be connected using 2 cables to another system where the
same command was run. Then, one should be able to ping the other board
through the hsr0 interface.

Without the Github branch, a ping over HSR should increase the DSA
conduit interface's TX counters by 2 packets. With the Github branch,
the TX counters should increase by only 1 packet.

Why so many patches
-------------------

To avoid the situation where a patch has to be backported, conflicts
with the work done here, pulls this in as a dependency, and that pulls
in 13 other unrelated drivers. These don't have any dependencies between
each other and can be cherry-picked at will (except they all depend on
patch 1/15).

When will you post the rest of the patches from the Github branch
-----------------------------------------------------------------

Tomorrow. This will leave some time for some early feedback while still
having a chance to catch v6.19.

Thanks for reading!

Cc: "Alvin Šipraga" <alsi@bang-olufsen.dk>
Cc: Chester A. Unal" <chester.a.unal@arinc9.com>
Cc: "Clément Léger" <clement.leger@bootlin.com>
Cc: Daniel Golle <daniel@makrotopia.org>
Cc: David Yang <mmyangfl@gmail.com>
Cc: DENG Qingfang <dqfext@gmail.com>
Cc: Florian Fainelli <florian.fainelli@broadcom.com>
Cc: George McCollister <george.mccollister@gmail.com>
Cc: Hauke Mehrtens <hauke@hauke-m.de>
Cc: Jonas Gorski <jonas.gorski@gmail.com>
Cc: Kurt Kanzenbach <kurt@linutronix.de>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: linux-renesas-soc@vger.kernel.org
Cc: Sean Wang <sean.wang@mediatek.com>
Cc: UNGLinuxDriver@microchip.com
Cc: Woojung Huh <woojung.huh@microchip.com>

Vladimir Oltean (15):
  net: dsa: introduce the dsa_xmit_port_mask() tagging protocol helper
  net: dsa: tag_brcm: use the dsa_xmit_port_mask() helper
  net: dsa: tag_gswip: use the dsa_xmit_port_mask() helper
  net: dsa: tag_hellcreek: use the dsa_xmit_port_mask() helper
  net: dsa: tag_ksz: use the dsa_xmit_port_mask() helper
  net: dsa: tag_mtk: use the dsa_xmit_port_mask() helper
  net: dsa: tag_mxl_gsw1xx: use the dsa_xmit_port_mask() helper
  net: dsa: tag_ocelot: use the dsa_xmit_port_mask() helper
  net: dsa: tag_qca: use the dsa_xmit_port_mask() helper
  net: dsa: tag_rtl4_a: use the dsa_xmit_port_mask() helper
  net: dsa: tag_rtl8_4: use the dsa_xmit_port_mask() helper
  net: dsa: tag_rzn1_a5psw: use the dsa_xmit_port_mask() helper
  net: dsa: tag_trailer: use the dsa_xmit_port_mask() helper
  net: dsa: tag_xrs700x: use the dsa_xmit_port_mask() helper
  net: dsa: tag_yt921x: use the dsa_xmit_port_mask() helper

 net/dsa/tag.h            | 18 ++++++++++++++++++
 net/dsa/tag_brcm.c       |  8 ++++----
 net/dsa/tag_gswip.c      |  6 ++----
 net/dsa/tag_hellcreek.c  |  3 +--
 net/dsa/tag_ksz.c        | 20 ++++----------------
 net/dsa/tag_mtk.c        |  3 ++-
 net/dsa/tag_mxl-gsw1xx.c |  7 ++++---
 net/dsa/tag_ocelot.c     |  6 ++----
 net/dsa/tag_qca.c        |  3 +--
 net/dsa/tag_rtl4_a.c     |  2 +-
 net/dsa/tag_rtl8_4.c     |  3 +--
 net/dsa/tag_rzn1_a5psw.c |  3 +--
 net/dsa/tag_trailer.c    |  3 +--
 net/dsa/tag_xrs700x.c    |  8 +-------
 net/dsa/tag_yt921x.c     |  8 +++-----
 15 files changed, 46 insertions(+), 55 deletions(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH net-next 01/15] net: dsa: introduce the dsa_xmit_port_mask() tagging protocol helper
  2025-11-27 12:08 [PATCH net-next 00/15] Introduce the dsa_xmit_port_mask() tagging protocol helper Vladimir Oltean
@ 2025-11-27 12:08 ` Vladimir Oltean
  2025-11-27 12:08 ` [PATCH net-next 02/15] net: dsa: tag_brcm: use the dsa_xmit_port_mask() helper Vladimir Oltean
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 23+ messages in thread
From: Vladimir Oltean @ 2025-11-27 12:08 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Alvin Šipraga, Clément Léger,
	Daniel Golle, David Yang, DENG Qingfang, Florian Fainelli,
	George McCollister, Hauke Mehrtens, Jonas Gorski, Kurt Kanzenbach,
	Linus Walleij, linux-renesas-soc, Sean Wang, UNGLinuxDriver,
	Woojung Huh

Many tagging protocols deal with the transmit port mask being a bit
mask, and set it to BIT(dp->index). Not a big deal.

Also, some tagging protocols are written for switches which support HSR
offload (including packet duplication offload), there we see a walk
using dsa_hsr_foreach_port() to find the other port in the same switch
that's member of the HSR, and set that bit in the port mask too.

That isn't sufficiently interesting either, until you come to realize
that there isn't anything special in the second case that switches just
in the first one can't do too.

It just becomes a matter of "is it wise to do it? are sufficient people
using HSR/PRP with generic off-the-shelf switches to justify add an
extra test in the data path?" - the answer to which is probably "it
depends". It isn't _much_ worse to not have HSR offload at all, so as to
make it impractical, esp. with a rich OS like Linux. But the HSR users
are rather specialized in industrial networking.

Anyway, the change acts on the premise that we're going to have support
for this, it should be uniformly implemented for everyone, and that if
we find some sort of balance, we can keep everyone relatively happy.

So I've disabled that logic if CONFIG_HSR isn't enabled, and I've tilted
the branch predictor to say it's unlikely we're transmitting through a
port with this capability currently active. On branch miss, we're still
going to save the transmission of one packet, so there's some remaining
benefit there too. I don't _think_ we need to jump to static keys yet.

The helper returns a 32-bit zero-based unsigned number, that callers
have to transpose using FIELD_PREP(). It is not the first time we assume
DSA switches won't be larger than 32 ports - dsa_user_ports() has that
assumption baked into it too.

One last development note about why pass the "skb" argument when this
isn't used. Looking at the compiled code on arm64, which is identical
both with and without it, the answer is "why not?" - who knows what
other features dependent on the skb may be handled in the future.

Link: https://lore.kernel.org/netdev/20251126093240.2853294-4-mmyangfl@gmail.com/
Cc: "Alvin Šipraga" <alsi@bang-olufsen.dk>
Cc: Chester A. Unal" <chester.a.unal@arinc9.com>
Cc: "Clément Léger" <clement.leger@bootlin.com>
Cc: Daniel Golle <daniel@makrotopia.org>
Cc: David Yang <mmyangfl@gmail.com>
Cc: DENG Qingfang <dqfext@gmail.com>
Cc: Florian Fainelli <florian.fainelli@broadcom.com>
Cc: George McCollister <george.mccollister@gmail.com>
Cc: Hauke Mehrtens <hauke@hauke-m.de>
Cc: Jonas Gorski <jonas.gorski@gmail.com>
Cc: Kurt Kanzenbach <kurt@linutronix.de>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: linux-renesas-soc@vger.kernel.org
Cc: Sean Wang <sean.wang@mediatek.com>
Cc: UNGLinuxDriver@microchip.com
Cc: Woojung Huh <woojung.huh@microchip.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 net/dsa/tag.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/net/dsa/tag.h b/net/dsa/tag.h
index 5d80ddad4ff6..cf52283fe9df 100644
--- a/net/dsa/tag.h
+++ b/net/dsa/tag.h
@@ -319,6 +319,24 @@ static inline void *dsa_etype_header_pos_tx(struct sk_buff *skb)
 	return skb->data + 2 * ETH_ALEN;
 }
 
+static inline unsigned long dsa_xmit_port_mask(const struct sk_buff *skb,
+					       const struct net_device *dev)
+{
+	struct dsa_port *dp = dsa_user_to_port(dev);
+	unsigned long mask = BIT(dp->index);
+
+	if (IS_ENABLED(CONFIG_HSR) &&
+	    unlikely(dev->features & NETIF_F_HW_HSR_DUP)) {
+		struct net_device *hsr_dev = dp->hsr_dev;
+		struct dsa_port *other_dp;
+
+		dsa_hsr_foreach_port(other_dp, dp->ds, hsr_dev)
+			mask |= BIT(other_dp->index);
+	}
+
+	return mask;
+}
+
 /* Create 2 modaliases per tagging protocol, one to auto-load the module
  * given the ID reported by get_tag_protocol(), and the other by name.
  */
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH net-next 02/15] net: dsa: tag_brcm: use the dsa_xmit_port_mask() helper
  2025-11-27 12:08 [PATCH net-next 00/15] Introduce the dsa_xmit_port_mask() tagging protocol helper Vladimir Oltean
  2025-11-27 12:08 ` [PATCH net-next 01/15] net: dsa: introduce " Vladimir Oltean
@ 2025-11-27 12:08 ` Vladimir Oltean
  2025-11-27 13:29   ` Jonas Gorski
  2025-11-27 12:08 ` [PATCH net-next 03/15] net: dsa: tag_gswip: " Vladimir Oltean
                   ` (13 subsequent siblings)
  15 siblings, 1 reply; 23+ messages in thread
From: Vladimir Oltean @ 2025-11-27 12:08 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Florian Fainelli, Jonas Gorski

The "brcm" and "brcm-prepend" tagging protocols populate a bit mask for
the TX ports, so we can use dsa_xmit_port_mask() to centralize the
decision of how to set that field. The port mask is written u8 by u8,
first the high octet and then the low octet.

Cc: Florian Fainelli <florian.fainelli@broadcom.com>
Cc: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 net/dsa/tag_brcm.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c
index eadb358179ce..cf9420439054 100644
--- a/net/dsa/tag_brcm.c
+++ b/net/dsa/tag_brcm.c
@@ -92,6 +92,7 @@ static struct sk_buff *brcm_tag_xmit_ll(struct sk_buff *skb,
 {
 	struct dsa_port *dp = dsa_user_to_port(dev);
 	u16 queue = skb_get_queue_mapping(skb);
+	u16 port_mask;
 	u8 *brcm_tag;
 
 	/* The Ethernet switch we are interfaced with needs packets to be at
@@ -119,10 +120,9 @@ static struct sk_buff *brcm_tag_xmit_ll(struct sk_buff *skb,
 	brcm_tag[0] = (1 << BRCM_OPCODE_SHIFT) |
 		       ((queue & BRCM_IG_TC_MASK) << BRCM_IG_TC_SHIFT);
 	brcm_tag[1] = 0;
-	brcm_tag[2] = 0;
-	if (dp->index == 8)
-		brcm_tag[2] = BRCM_IG_DSTMAP2_MASK;
-	brcm_tag[3] = (1 << dp->index) & BRCM_IG_DSTMAP1_MASK;
+	port_mask = dsa_xmit_port_mask(skb, dev);
+	brcm_tag[2] = (port_mask >> 8) & BRCM_IG_DSTMAP2_MASK;
+	brcm_tag[3] = port_mask & BRCM_IG_DSTMAP1_MASK;
 
 	/* Now tell the conduit network device about the desired output queue
 	 * as well
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH net-next 03/15] net: dsa: tag_gswip: use the dsa_xmit_port_mask() helper
  2025-11-27 12:08 [PATCH net-next 00/15] Introduce the dsa_xmit_port_mask() tagging protocol helper Vladimir Oltean
  2025-11-27 12:08 ` [PATCH net-next 01/15] net: dsa: introduce " Vladimir Oltean
  2025-11-27 12:08 ` [PATCH net-next 02/15] net: dsa: tag_brcm: use the dsa_xmit_port_mask() helper Vladimir Oltean
@ 2025-11-27 12:08 ` Vladimir Oltean
  2025-11-27 12:08 ` [PATCH net-next 04/15] net: dsa: tag_hellcreek: " Vladimir Oltean
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 23+ messages in thread
From: Vladimir Oltean @ 2025-11-27 12:08 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Hauke Mehrtens, Daniel Golle

The "gswip" tagging protocol populates a bit mask for the TX ports, so
we can use dsa_xmit_port_mask() to centralize the decision of how to set
that field.

Cc: Hauke Mehrtens <hauke@hauke-m.de>
Cc: Daniel Golle <daniel@makrotopia.org>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 net/dsa/tag_gswip.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/net/dsa/tag_gswip.c b/net/dsa/tag_gswip.c
index 51a1f46a567f..5fa436121087 100644
--- a/net/dsa/tag_gswip.c
+++ b/net/dsa/tag_gswip.c
@@ -48,8 +48,7 @@
 
 /* Byte 3 */
 #define GSWIP_TX_DPID_EN		BIT(0)
-#define GSWIP_TX_PORT_MAP_SHIFT		1
-#define GSWIP_TX_PORT_MAP_MASK		GENMASK(6, 1)
+#define GSWIP_TX_PORT_MAP		GENMASK(6, 1)
 
 #define GSWIP_RX_HEADER_LEN	8
 
@@ -61,7 +60,6 @@
 static struct sk_buff *gswip_tag_xmit(struct sk_buff *skb,
 				      struct net_device *dev)
 {
-	struct dsa_port *dp = dsa_user_to_port(dev);
 	u8 *gswip_tag;
 
 	skb_push(skb, GSWIP_TX_HEADER_LEN);
@@ -70,7 +68,7 @@ static struct sk_buff *gswip_tag_xmit(struct sk_buff *skb,
 	gswip_tag[0] = GSWIP_TX_SLPID_CPU;
 	gswip_tag[1] = GSWIP_TX_DPID_ELAN;
 	gswip_tag[2] = GSWIP_TX_PORT_MAP_EN | GSWIP_TX_PORT_MAP_SEL;
-	gswip_tag[3] = BIT(dp->index + GSWIP_TX_PORT_MAP_SHIFT) & GSWIP_TX_PORT_MAP_MASK;
+	gswip_tag[3] = FIELD_PREP(GSWIP_TX_PORT_MAP, dsa_xmit_port_mask(skb, dev));
 	gswip_tag[3] |= GSWIP_TX_DPID_EN;
 
 	return skb;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH net-next 04/15] net: dsa: tag_hellcreek: use the dsa_xmit_port_mask() helper
  2025-11-27 12:08 [PATCH net-next 00/15] Introduce the dsa_xmit_port_mask() tagging protocol helper Vladimir Oltean
                   ` (2 preceding siblings ...)
  2025-11-27 12:08 ` [PATCH net-next 03/15] net: dsa: tag_gswip: " Vladimir Oltean
@ 2025-11-27 12:08 ` Vladimir Oltean
  2025-11-27 12:08 ` [PATCH net-next 05/15] net: dsa: tag_ksz: " Vladimir Oltean
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 23+ messages in thread
From: Vladimir Oltean @ 2025-11-27 12:08 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Kurt Kanzenbach

The "hellcreek" tagging protocol populates a bit mask for the TX ports,
so we can use dsa_xmit_port_mask() to centralize the decision of how to
set that field.

Cc: Kurt Kanzenbach <kurt@linutronix.de>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 net/dsa/tag_hellcreek.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/net/dsa/tag_hellcreek.c b/net/dsa/tag_hellcreek.c
index 663b25785d95..544ab15685a2 100644
--- a/net/dsa/tag_hellcreek.c
+++ b/net/dsa/tag_hellcreek.c
@@ -20,7 +20,6 @@
 static struct sk_buff *hellcreek_xmit(struct sk_buff *skb,
 				      struct net_device *dev)
 {
-	struct dsa_port *dp = dsa_user_to_port(dev);
 	u8 *tag;
 
 	/* Calculate checksums (if required) before adding the trailer tag to
@@ -33,7 +32,7 @@ static struct sk_buff *hellcreek_xmit(struct sk_buff *skb,
 
 	/* Tag encoding */
 	tag  = skb_put(skb, HELLCREEK_TAG_LEN);
-	*tag = BIT(dp->index);
+	*tag = dsa_xmit_port_mask(skb, dev);
 
 	return skb;
 }
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH net-next 05/15] net: dsa: tag_ksz: use the dsa_xmit_port_mask() helper
  2025-11-27 12:08 [PATCH net-next 00/15] Introduce the dsa_xmit_port_mask() tagging protocol helper Vladimir Oltean
                   ` (3 preceding siblings ...)
  2025-11-27 12:08 ` [PATCH net-next 04/15] net: dsa: tag_hellcreek: " Vladimir Oltean
@ 2025-11-27 12:08 ` Vladimir Oltean
  2025-11-27 12:08 ` [PATCH net-next 06/15] net: dsa: tag_mtk: " Vladimir Oltean
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 23+ messages in thread
From: Vladimir Oltean @ 2025-11-27 12:08 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Woojung Huh, UNGLinuxDriver

The "ksz8795", "ksz9893", "ksz9477" and "lan937x" tagging protocols
populate a bit mask for the TX ports.

Unlike the others, "ksz9477" also accelerates HSR packet duplication.

Make the HSR duplication logic available generically to all 4 taggers by
using the dsa_xmit_port_mask() function to set the TX port mask.

Cc: Woojung Huh <woojung.huh@microchip.com>
Cc: UNGLinuxDriver@microchip.com
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 net/dsa/tag_ksz.c | 20 ++++----------------
 1 file changed, 4 insertions(+), 16 deletions(-)

diff --git a/net/dsa/tag_ksz.c b/net/dsa/tag_ksz.c
index 0b7564b53790..9170a0148cc4 100644
--- a/net/dsa/tag_ksz.c
+++ b/net/dsa/tag_ksz.c
@@ -120,7 +120,6 @@ static struct sk_buff *ksz_common_rcv(struct sk_buff *skb,
 
 static struct sk_buff *ksz8795_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct dsa_port *dp = dsa_user_to_port(dev);
 	struct ethhdr *hdr;
 	u8 *tag;
 
@@ -131,7 +130,7 @@ static struct sk_buff *ksz8795_xmit(struct sk_buff *skb, struct net_device *dev)
 	tag = skb_put(skb, KSZ_INGRESS_TAG_LEN);
 	hdr = skb_eth_hdr(skb);
 
-	*tag = 1 << dp->index;
+	*tag = dsa_xmit_port_mask(skb, dev);
 	if (is_link_local_ether_addr(hdr->h_dest))
 		*tag |= KSZ8795_TAIL_TAG_OVERRIDE;
 
@@ -294,21 +293,12 @@ static struct sk_buff *ksz9477_xmit(struct sk_buff *skb,
 	tag = skb_put(skb, KSZ9477_INGRESS_TAG_LEN);
 	hdr = skb_eth_hdr(skb);
 
-	val = BIT(dp->index);
-
+	val = dsa_xmit_port_mask(skb, dev);
 	val |= FIELD_PREP(KSZ9477_TAIL_TAG_PRIO, prio);
 
 	if (is_link_local_ether_addr(hdr->h_dest))
 		val |= KSZ9477_TAIL_TAG_OVERRIDE;
 
-	if (dev->features & NETIF_F_HW_HSR_DUP) {
-		struct net_device *hsr_dev = dp->hsr_dev;
-		struct dsa_port *other_dp;
-
-		dsa_hsr_foreach_port(other_dp, dp->ds, hsr_dev)
-			val |= BIT(other_dp->index);
-	}
-
 	*tag = cpu_to_be16(val);
 
 	return ksz_defer_xmit(dp, skb);
@@ -371,8 +361,7 @@ static struct sk_buff *ksz9893_xmit(struct sk_buff *skb,
 	tag = skb_put(skb, KSZ_INGRESS_TAG_LEN);
 	hdr = skb_eth_hdr(skb);
 
-	*tag = BIT(dp->index);
-
+	*tag = dsa_xmit_port_mask(skb, dev);
 	*tag |= FIELD_PREP(KSZ9893_TAIL_TAG_PRIO, prio);
 
 	if (is_link_local_ether_addr(hdr->h_dest))
@@ -436,8 +425,7 @@ static struct sk_buff *lan937x_xmit(struct sk_buff *skb,
 
 	tag = skb_put(skb, LAN937X_EGRESS_TAG_LEN);
 
-	val = BIT(dp->index);
-
+	val = dsa_xmit_port_mask(skb, dev);
 	val |= FIELD_PREP(LAN937X_TAIL_TAG_PRIO, prio);
 
 	if (is_link_local_ether_addr(hdr->h_dest))
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH net-next 06/15] net: dsa: tag_mtk: use the dsa_xmit_port_mask() helper
  2025-11-27 12:08 [PATCH net-next 00/15] Introduce the dsa_xmit_port_mask() tagging protocol helper Vladimir Oltean
                   ` (4 preceding siblings ...)
  2025-11-27 12:08 ` [PATCH net-next 05/15] net: dsa: tag_ksz: " Vladimir Oltean
@ 2025-11-27 12:08 ` Vladimir Oltean
  2025-11-27 12:08 ` [PATCH net-next 07/15] net: dsa: tag_mxl_gsw1xx: " Vladimir Oltean
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 23+ messages in thread
From: Vladimir Oltean @ 2025-11-27 12:08 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Daniel Golle, DENG Qingfang, Sean Wang

The "mtk" tagging protocol populates a bit mask for the TX ports, so we
can use dsa_xmit_port_mask() to centralize the decision of how to set
that field.

Cc: Chester A. Unal" <chester.a.unal@arinc9.com>
Cc: Daniel Golle <daniel@makrotopia.org>
Cc: DENG Qingfang <dqfext@gmail.com>
Cc: Sean Wang <sean.wang@mediatek.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 net/dsa/tag_mtk.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/dsa/tag_mtk.c b/net/dsa/tag_mtk.c
index b670e3c53e91..dea3eecaf093 100644
--- a/net/dsa/tag_mtk.c
+++ b/net/dsa/tag_mtk.c
@@ -54,7 +54,8 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb,
 	 * whether that's a combined special tag with 802.1Q header.
 	 */
 	mtk_tag[0] = xmit_tpid;
-	mtk_tag[1] = (1 << dp->index) & MTK_HDR_XMIT_DP_BIT_MASK;
+	mtk_tag[1] = FIELD_PREP(MTK_HDR_XMIT_DP_BIT_MASK,
+				dsa_xmit_port_mask(skb, dev));
 
 	/* Tag control information is kept for 802.1Q */
 	if (xmit_tpid == MTK_HDR_XMIT_UNTAGGED) {
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH net-next 07/15] net: dsa: tag_mxl_gsw1xx: use the dsa_xmit_port_mask() helper
  2025-11-27 12:08 [PATCH net-next 00/15] Introduce the dsa_xmit_port_mask() tagging protocol helper Vladimir Oltean
                   ` (5 preceding siblings ...)
  2025-11-27 12:08 ` [PATCH net-next 06/15] net: dsa: tag_mtk: " Vladimir Oltean
@ 2025-11-27 12:08 ` Vladimir Oltean
  2025-11-27 12:08 ` [PATCH net-next 08/15] net: dsa: tag_ocelot: " Vladimir Oltean
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 23+ messages in thread
From: Vladimir Oltean @ 2025-11-27 12:08 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Hauke Mehrtens, Daniel Golle

The "gsw1xx" tagging protocol populates a bit mask for the TX ports, so
we can use dsa_xmit_port_mask() to centralize the decision of how to set
that field.

Cc: Hauke Mehrtens <hauke@hauke-m.de>
Cc: Daniel Golle <daniel@makrotopia.org>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 net/dsa/tag_mxl-gsw1xx.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/net/dsa/tag_mxl-gsw1xx.c b/net/dsa/tag_mxl-gsw1xx.c
index 701a079955f2..60f7c445e656 100644
--- a/net/dsa/tag_mxl-gsw1xx.c
+++ b/net/dsa/tag_mxl-gsw1xx.c
@@ -43,8 +43,8 @@
 static struct sk_buff *gsw1xx_tag_xmit(struct sk_buff *skb,
 				       struct net_device *dev)
 {
-	struct dsa_port *dp = dsa_user_to_port(dev);
 	__be16 *gsw1xx_tag;
+	u16 tag;
 
 	/* provide additional space 'GSW1XX_HEADER_LEN' bytes */
 	skb_push(skb, GSW1XX_HEADER_LEN);
@@ -55,9 +55,10 @@ static struct sk_buff *gsw1xx_tag_xmit(struct sk_buff *skb,
 	/* special tag ingress */
 	gsw1xx_tag = dsa_etype_header_pos_tx(skb);
 	gsw1xx_tag[0] = htons(ETH_P_MXLGSW);
-	gsw1xx_tag[1] = htons(GSW1XX_TX_PORT_MAP_EN | GSW1XX_TX_LRN_DIS |
-			FIELD_PREP(GSW1XX_TX_PORT_MAP, BIT(dp->index)));
 
+	tag = FIELD_PREP(GSW1XX_TX_PORT_MAP, dsa_xmit_port_mask(skb, dev)) |
+	      GSW1XX_TX_PORT_MAP_EN | GSW1XX_TX_LRN_DIS;
+	gsw1xx_tag[1] = htons(tag);
 	gsw1xx_tag[2] = 0;
 	gsw1xx_tag[3] = 0;
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH net-next 08/15] net: dsa: tag_ocelot: use the dsa_xmit_port_mask() helper
  2025-11-27 12:08 [PATCH net-next 00/15] Introduce the dsa_xmit_port_mask() tagging protocol helper Vladimir Oltean
                   ` (6 preceding siblings ...)
  2025-11-27 12:08 ` [PATCH net-next 07/15] net: dsa: tag_mxl_gsw1xx: " Vladimir Oltean
@ 2025-11-27 12:08 ` Vladimir Oltean
  2025-11-27 12:08 ` [PATCH net-next 09/15] net: dsa: tag_qca: " Vladimir Oltean
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 23+ messages in thread
From: Vladimir Oltean @ 2025-11-27 12:08 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni

The "ocelot" and "seville" tagging protocols populate a bit mask for the
TX ports, so we can use dsa_xmit_port_mask() to centralize the decision
of how to set that field.

This protocol used BIT_ULL() rather than simple BIT() to silence Smatch,
as explained in commit 1f778d500df3 ("net: mscc: ocelot: avoid type
promotion when calling ocelot_ifh_set_dest"). I would expect that this
tool no longer complains now, when the BIT(dp->index) is hidden inside
the dsa_xmit_port_mask() function, the return value of which is promoted
to u64.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 net/dsa/tag_ocelot.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/net/dsa/tag_ocelot.c b/net/dsa/tag_ocelot.c
index bf6608fc6be7..3405def79c2d 100644
--- a/net/dsa/tag_ocelot.c
+++ b/net/dsa/tag_ocelot.c
@@ -46,11 +46,10 @@ static void ocelot_xmit_common(struct sk_buff *skb, struct net_device *netdev,
 static struct sk_buff *ocelot_xmit(struct sk_buff *skb,
 				   struct net_device *netdev)
 {
-	struct dsa_port *dp = dsa_user_to_port(netdev);
 	void *injection;
 
 	ocelot_xmit_common(skb, netdev, cpu_to_be32(0x8880000a), &injection);
-	ocelot_ifh_set_dest(injection, BIT_ULL(dp->index));
+	ocelot_ifh_set_dest(injection, dsa_xmit_port_mask(skb, netdev));
 
 	return skb;
 }
@@ -58,11 +57,10 @@ static struct sk_buff *ocelot_xmit(struct sk_buff *skb,
 static struct sk_buff *seville_xmit(struct sk_buff *skb,
 				    struct net_device *netdev)
 {
-	struct dsa_port *dp = dsa_user_to_port(netdev);
 	void *injection;
 
 	ocelot_xmit_common(skb, netdev, cpu_to_be32(0x88800005), &injection);
-	seville_ifh_set_dest(injection, BIT_ULL(dp->index));
+	seville_ifh_set_dest(injection, dsa_xmit_port_mask(skb, netdev));
 
 	return skb;
 }
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH net-next 09/15] net: dsa: tag_qca: use the dsa_xmit_port_mask() helper
  2025-11-27 12:08 [PATCH net-next 00/15] Introduce the dsa_xmit_port_mask() tagging protocol helper Vladimir Oltean
                   ` (7 preceding siblings ...)
  2025-11-27 12:08 ` [PATCH net-next 08/15] net: dsa: tag_ocelot: " Vladimir Oltean
@ 2025-11-27 12:08 ` Vladimir Oltean
  2025-11-27 12:08 ` [PATCH net-next 10/15] net: dsa: tag_rtl4_a: " Vladimir Oltean
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 23+ messages in thread
From: Vladimir Oltean @ 2025-11-27 12:08 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni

The "qca" tagging protocol populates a bit mask for the TX ports, so we
can use dsa_xmit_port_mask() to centralize the decision of how to set
that field.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 net/dsa/tag_qca.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/net/dsa/tag_qca.c b/net/dsa/tag_qca.c
index 0cf61286b426..6d56a28c914c 100644
--- a/net/dsa/tag_qca.c
+++ b/net/dsa/tag_qca.c
@@ -14,7 +14,6 @@
 
 static struct sk_buff *qca_tag_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct dsa_port *dp = dsa_user_to_port(dev);
 	__be16 *phdr;
 	u16 hdr;
 
@@ -26,7 +25,7 @@ static struct sk_buff *qca_tag_xmit(struct sk_buff *skb, struct net_device *dev)
 	/* Set the version field, and set destination port information */
 	hdr = FIELD_PREP(QCA_HDR_XMIT_VERSION, QCA_HDR_VERSION);
 	hdr |= QCA_HDR_XMIT_FROM_CPU;
-	hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, BIT(dp->index));
+	hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, dsa_xmit_port_mask(skb, dev));
 
 	*phdr = htons(hdr);
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH net-next 10/15] net: dsa: tag_rtl4_a: use the dsa_xmit_port_mask() helper
  2025-11-27 12:08 [PATCH net-next 00/15] Introduce the dsa_xmit_port_mask() tagging protocol helper Vladimir Oltean
                   ` (8 preceding siblings ...)
  2025-11-27 12:08 ` [PATCH net-next 09/15] net: dsa: tag_qca: " Vladimir Oltean
@ 2025-11-27 12:08 ` Vladimir Oltean
  2025-12-31  3:17   ` Luiz Angelo Daros de Luca
  2025-12-31 21:05   ` Linus Walleij
  2025-11-27 12:08 ` [PATCH net-next 11/15] net: dsa: tag_rtl8_4: " Vladimir Oltean
                   ` (5 subsequent siblings)
  15 siblings, 2 replies; 23+ messages in thread
From: Vladimir Oltean @ 2025-11-27 12:08 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Linus Walleij, Alvin Šipraga

The "rtl4a" tagging protocol populates a bit mask for the TX ports,
so we can use dsa_xmit_port_mask() to centralize the decision of how to
set that field.

Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: "Alvin Šipraga" <alsi@bang-olufsen.dk>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 net/dsa/tag_rtl4_a.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/dsa/tag_rtl4_a.c b/net/dsa/tag_rtl4_a.c
index feaefa0e179b..3cc63eacfa03 100644
--- a/net/dsa/tag_rtl4_a.c
+++ b/net/dsa/tag_rtl4_a.c
@@ -57,7 +57,7 @@ static struct sk_buff *rtl4a_tag_xmit(struct sk_buff *skb,
 
 	out = (RTL4_A_PROTOCOL_RTL8366RB << RTL4_A_PROTOCOL_SHIFT);
 	/* The lower bits indicate the port number */
-	out |= BIT(dp->index);
+	out |= dsa_xmit_port_mask(skb, dev);
 
 	p = (__be16 *)(tag + 2);
 	*p = htons(out);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH net-next 11/15] net: dsa: tag_rtl8_4: use the dsa_xmit_port_mask() helper
  2025-11-27 12:08 [PATCH net-next 00/15] Introduce the dsa_xmit_port_mask() tagging protocol helper Vladimir Oltean
                   ` (9 preceding siblings ...)
  2025-11-27 12:08 ` [PATCH net-next 10/15] net: dsa: tag_rtl4_a: " Vladimir Oltean
@ 2025-11-27 12:08 ` Vladimir Oltean
  2025-12-31  3:20   ` Luiz Angelo Daros de Luca
  2025-12-31 21:05   ` Linus Walleij
  2025-11-27 12:08 ` [PATCH net-next 12/15] net: dsa: tag_rzn1_a5psw: " Vladimir Oltean
                   ` (4 subsequent siblings)
  15 siblings, 2 replies; 23+ messages in thread
From: Vladimir Oltean @ 2025-11-27 12:08 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Linus Walleij, Alvin Šipraga

The "rtl8_4" and "rtl8_4t" tagging protocols populate a bit mask for the
TX ports, so we can use dsa_xmit_port_mask() to centralize the decision
of how to set that field.

Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: "Alvin Šipraga" <alsi@bang-olufsen.dk>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 net/dsa/tag_rtl8_4.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/net/dsa/tag_rtl8_4.c b/net/dsa/tag_rtl8_4.c
index 15c2bae2b429..2464545da4d2 100644
--- a/net/dsa/tag_rtl8_4.c
+++ b/net/dsa/tag_rtl8_4.c
@@ -103,7 +103,6 @@
 static void rtl8_4_write_tag(struct sk_buff *skb, struct net_device *dev,
 			     void *tag)
 {
-	struct dsa_port *dp = dsa_user_to_port(dev);
 	__be16 tag16[RTL8_4_TAG_LEN / 2];
 
 	/* Set Realtek EtherType */
@@ -116,7 +115,7 @@ static void rtl8_4_write_tag(struct sk_buff *skb, struct net_device *dev,
 	tag16[2] = htons(FIELD_PREP(RTL8_4_LEARN_DIS, 1));
 
 	/* Zero ALLOW; set RX (CPU->switch) forwarding port mask */
-	tag16[3] = htons(FIELD_PREP(RTL8_4_RX, BIT(dp->index)));
+	tag16[3] = htons(FIELD_PREP(RTL8_4_RX, dsa_xmit_port_mask(skb, dev)));
 
 	memcpy(tag, tag16, RTL8_4_TAG_LEN);
 }
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH net-next 12/15] net: dsa: tag_rzn1_a5psw: use the dsa_xmit_port_mask() helper
  2025-11-27 12:08 [PATCH net-next 00/15] Introduce the dsa_xmit_port_mask() tagging protocol helper Vladimir Oltean
                   ` (10 preceding siblings ...)
  2025-11-27 12:08 ` [PATCH net-next 11/15] net: dsa: tag_rtl8_4: " Vladimir Oltean
@ 2025-11-27 12:08 ` Vladimir Oltean
  2025-11-27 12:09 ` [PATCH net-next 13/15] net: dsa: tag_trailer: " Vladimir Oltean
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 23+ messages in thread
From: Vladimir Oltean @ 2025-11-27 12:08 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Clément Léger, linux-renesas-soc

The "a5psw" tagging protocol populates a bit mask for the TX ports,
so we can use dsa_xmit_port_mask() to centralize the decision of how to
set that field.

Cc: "Clément Léger" <clement.leger@bootlin.com>
Cc: linux-renesas-soc@vger.kernel.org
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 net/dsa/tag_rzn1_a5psw.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/net/dsa/tag_rzn1_a5psw.c b/net/dsa/tag_rzn1_a5psw.c
index 69d51221b1e5..10994b3470f6 100644
--- a/net/dsa/tag_rzn1_a5psw.c
+++ b/net/dsa/tag_rzn1_a5psw.c
@@ -39,7 +39,6 @@ struct a5psw_tag {
 
 static struct sk_buff *a5psw_tag_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct dsa_port *dp = dsa_user_to_port(dev);
 	struct a5psw_tag *ptag;
 	u32 data2_val;
 
@@ -60,7 +59,7 @@ static struct sk_buff *a5psw_tag_xmit(struct sk_buff *skb, struct net_device *de
 
 	ptag = dsa_etype_header_pos_tx(skb);
 
-	data2_val = FIELD_PREP(A5PSW_CTRL_DATA_PORT, BIT(dp->index));
+	data2_val = FIELD_PREP(A5PSW_CTRL_DATA_PORT, dsa_xmit_port_mask(skb, dev));
 	ptag->ctrl_tag = htons(ETH_P_DSA_A5PSW);
 	ptag->ctrl_data = htons(A5PSW_CTRL_DATA_FORCE_FORWARD);
 	ptag->ctrl_data2_lo = htons(data2_val);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH net-next 13/15] net: dsa: tag_trailer: use the dsa_xmit_port_mask() helper
  2025-11-27 12:08 [PATCH net-next 00/15] Introduce the dsa_xmit_port_mask() tagging protocol helper Vladimir Oltean
                   ` (11 preceding siblings ...)
  2025-11-27 12:08 ` [PATCH net-next 12/15] net: dsa: tag_rzn1_a5psw: " Vladimir Oltean
@ 2025-11-27 12:09 ` Vladimir Oltean
  2025-11-27 12:09 ` [PATCH net-next 14/15] net: dsa: tag_xrs700x: " Vladimir Oltean
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 23+ messages in thread
From: Vladimir Oltean @ 2025-11-27 12:09 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni

The "trailer" tagging protocol populates a bit mask for the TX ports, so
we can use dsa_xmit_port_mask() to centralize the decision of how to set
that field.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 net/dsa/tag_trailer.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/net/dsa/tag_trailer.c b/net/dsa/tag_trailer.c
index 22742a53d6f4..4dce24cfe6a7 100644
--- a/net/dsa/tag_trailer.c
+++ b/net/dsa/tag_trailer.c
@@ -14,12 +14,11 @@
 
 static struct sk_buff *trailer_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct dsa_port *dp = dsa_user_to_port(dev);
 	u8 *trailer;
 
 	trailer = skb_put(skb, 4);
 	trailer[0] = 0x80;
-	trailer[1] = 1 << dp->index;
+	trailer[1] = dsa_xmit_port_mask(skb, dev);
 	trailer[2] = 0x10;
 	trailer[3] = 0x00;
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH net-next 14/15] net: dsa: tag_xrs700x: use the dsa_xmit_port_mask() helper
  2025-11-27 12:08 [PATCH net-next 00/15] Introduce the dsa_xmit_port_mask() tagging protocol helper Vladimir Oltean
                   ` (12 preceding siblings ...)
  2025-11-27 12:09 ` [PATCH net-next 13/15] net: dsa: tag_trailer: " Vladimir Oltean
@ 2025-11-27 12:09 ` Vladimir Oltean
  2025-11-27 12:09 ` [PATCH net-next 15/15] net: dsa: tag_yt921x: " Vladimir Oltean
  2025-11-29  4:10 ` [PATCH net-next 00/15] Introduce the dsa_xmit_port_mask() tagging protocol helper patchwork-bot+netdevbpf
  15 siblings, 0 replies; 23+ messages in thread
From: Vladimir Oltean @ 2025-11-27 12:09 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, George McCollister

The "xrs700x" is the original DSA tagging protocol with HSR TX
replication support, we now essentially move that logic to the
dsa_xmit_port_mask() helper. The end result is something akin to
hellcreek_xmit() (but reminds me I should also take care of
skb_checksum_help() for tail taggers in the core).

The implementation differences to dsa_xmit_port_mask() are immaterial.

Cc: George McCollister <george.mccollister@gmail.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 net/dsa/tag_xrs700x.c | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/net/dsa/tag_xrs700x.c b/net/dsa/tag_xrs700x.c
index 68d4633ddd5e..a05219f702c6 100644
--- a/net/dsa/tag_xrs700x.c
+++ b/net/dsa/tag_xrs700x.c
@@ -13,16 +13,10 @@
 
 static struct sk_buff *xrs700x_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct dsa_port *partner, *dp = dsa_user_to_port(dev);
 	u8 *trailer;
 
 	trailer = skb_put(skb, 1);
-	trailer[0] = BIT(dp->index);
-
-	if (dp->hsr_dev)
-		dsa_hsr_foreach_port(partner, dp->ds, dp->hsr_dev)
-			if (partner != dp)
-				trailer[0] |= BIT(partner->index);
+	trailer[0] = dsa_xmit_port_mask(skb, dev);
 
 	return skb;
 }
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH net-next 15/15] net: dsa: tag_yt921x: use the dsa_xmit_port_mask() helper
  2025-11-27 12:08 [PATCH net-next 00/15] Introduce the dsa_xmit_port_mask() tagging protocol helper Vladimir Oltean
                   ` (13 preceding siblings ...)
  2025-11-27 12:09 ` [PATCH net-next 14/15] net: dsa: tag_xrs700x: " Vladimir Oltean
@ 2025-11-27 12:09 ` Vladimir Oltean
  2025-11-29  4:10 ` [PATCH net-next 00/15] Introduce the dsa_xmit_port_mask() tagging protocol helper patchwork-bot+netdevbpf
  15 siblings, 0 replies; 23+ messages in thread
From: Vladimir Oltean @ 2025-11-27 12:09 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, David Yang

The "yt921x" tagging protocol populates a bit mask for the TX ports,
so we can use dsa_xmit_port_mask() to centralize the decision of how to
set that field.

Cc: David Yang <mmyangfl@gmail.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 net/dsa/tag_yt921x.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/net/dsa/tag_yt921x.c b/net/dsa/tag_yt921x.c
index 995da44f0a2a..6bbfd42dc5df 100644
--- a/net/dsa/tag_yt921x.c
+++ b/net/dsa/tag_yt921x.c
@@ -38,14 +38,11 @@
 #define  YT921X_TAG_RX_CMD_FORWARDED		0x80
 #define  YT921X_TAG_RX_CMD_UNK_UCAST		0xb2
 #define  YT921X_TAG_RX_CMD_UNK_MCAST		0xb4
-#define YT921X_TAG_TX_PORTS_M		GENMASK(10, 0)
-#define YT921X_TAG_TX_PORTn(port)	BIT(port)
+#define YT921X_TAG_TX_PORTS		GENMASK(10, 0)
 
 static struct sk_buff *
 yt921x_tag_xmit(struct sk_buff *skb, struct net_device *netdev)
 {
-	struct dsa_port *dp = dsa_user_to_port(netdev);
-	unsigned int port = dp->index;
 	__be16 *tag;
 	u16 tx;
 
@@ -58,7 +55,8 @@ yt921x_tag_xmit(struct sk_buff *skb, struct net_device *netdev)
 	/* VLAN tag unrelated when TX */
 	tag[1] = 0;
 	tag[2] = 0;
-	tx = YT921X_TAG_PORT_EN | YT921X_TAG_TX_PORTn(port);
+	tx = FIELD_PREP(YT921X_TAG_TX_PORTS, dsa_xmit_port_mask(skb, netdev)) |
+	     YT921X_TAG_PORT_EN;
 	tag[3] = htons(tx);
 
 	return skb;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCH net-next 02/15] net: dsa: tag_brcm: use the dsa_xmit_port_mask() helper
  2025-11-27 12:08 ` [PATCH net-next 02/15] net: dsa: tag_brcm: use the dsa_xmit_port_mask() helper Vladimir Oltean
@ 2025-11-27 13:29   ` Jonas Gorski
  2025-11-27 13:42     ` Vladimir Oltean
  0 siblings, 1 reply; 23+ messages in thread
From: Jonas Gorski @ 2025-11-27 13:29 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: netdev, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Florian Fainelli

On Thu, Nov 27, 2025 at 1:09 PM Vladimir Oltean <vladimir.oltean@nxp.com> wrote:
>
> The "brcm" and "brcm-prepend" tagging protocols populate a bit mask for
> the TX ports, so we can use dsa_xmit_port_mask() to centralize the
> decision of how to set that field. The port mask is written u8 by u8,
> first the high octet and then the low octet.
>
> Cc: Florian Fainelli <florian.fainelli@broadcom.com>
> Cc: Jonas Gorski <jonas.gorski@gmail.com>
> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
> ---
>  net/dsa/tag_brcm.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c
> index eadb358179ce..cf9420439054 100644
> --- a/net/dsa/tag_brcm.c
> +++ b/net/dsa/tag_brcm.c
> @@ -92,6 +92,7 @@ static struct sk_buff *brcm_tag_xmit_ll(struct sk_buff *skb,
>  {
>         struct dsa_port *dp = dsa_user_to_port(dev);
>         u16 queue = skb_get_queue_mapping(skb);
> +       u16 port_mask;
>         u8 *brcm_tag;
>
>         /* The Ethernet switch we are interfaced with needs packets to be at
> @@ -119,10 +120,9 @@ static struct sk_buff *brcm_tag_xmit_ll(struct sk_buff *skb,
>         brcm_tag[0] = (1 << BRCM_OPCODE_SHIFT) |
>                        ((queue & BRCM_IG_TC_MASK) << BRCM_IG_TC_SHIFT);
>         brcm_tag[1] = 0;
> -       brcm_tag[2] = 0;
> -       if (dp->index == 8)
> -               brcm_tag[2] = BRCM_IG_DSTMAP2_MASK;
> -       brcm_tag[3] = (1 << dp->index) & BRCM_IG_DSTMAP1_MASK;
> +       port_mask = dsa_xmit_port_mask(skb, dev);
> +       brcm_tag[2] = (port_mask >> 8) & BRCM_IG_DSTMAP2_MASK;
> +       brcm_tag[3] = port_mask & BRCM_IG_DSTMAP1_MASK;

Since this is a consecutive bitmask (actually [22:0]), I wonder if doing

put_unaligned_be16(port_mask, &brcm_tag[2]);

would be a bit more readable.

Or even more correct put_unaligned_be24(port_mask, &brcm_tag[1]), but
we don't support any switches with that many ports.

Best regards,
Jonas

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH net-next 02/15] net: dsa: tag_brcm: use the dsa_xmit_port_mask() helper
  2025-11-27 13:29   ` Jonas Gorski
@ 2025-11-27 13:42     ` Vladimir Oltean
  0 siblings, 0 replies; 23+ messages in thread
From: Vladimir Oltean @ 2025-11-27 13:42 UTC (permalink / raw)
  To: Jonas Gorski
  Cc: netdev, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Florian Fainelli

On Thu, Nov 27, 2025 at 02:29:27PM +0100, Jonas Gorski wrote:
> > @@ -119,10 +120,9 @@ static struct sk_buff *brcm_tag_xmit_ll(struct sk_buff *skb,
> >         brcm_tag[0] = (1 << BRCM_OPCODE_SHIFT) |
> >                        ((queue & BRCM_IG_TC_MASK) << BRCM_IG_TC_SHIFT);
> >         brcm_tag[1] = 0;
> > -       brcm_tag[2] = 0;
> > -       if (dp->index == 8)
> > -               brcm_tag[2] = BRCM_IG_DSTMAP2_MASK;
> > -       brcm_tag[3] = (1 << dp->index) & BRCM_IG_DSTMAP1_MASK;
> > +       port_mask = dsa_xmit_port_mask(skb, dev);
> > +       brcm_tag[2] = (port_mask >> 8) & BRCM_IG_DSTMAP2_MASK;
> > +       brcm_tag[3] = port_mask & BRCM_IG_DSTMAP1_MASK;
> 
> Since this is a consecutive bitmask (actually [22:0]), I wonder if doing
> 
> put_unaligned_be16(port_mask, &brcm_tag[2]);
> 
> would be a bit more readable.
> 
> Or even more correct put_unaligned_be24(port_mask, &brcm_tag[1]), but
> we don't support any switches with that many ports.

I don't think there's a technical requirement for unaligned access here.
We have to use unaligned access for tail tags, but this here is handling
EtherType and/or prepended headers, which are both aligned to a boundary
of 2 due to NET_IP_ALIGN AFAIK.

Anyway, with the replacement of u8 by u8 -> u16 by u16 access I do agree
it would be a good idea, as long as u16 is used throughout (not just in
order not to split the bit mask). Alternatively if there are more than
16 ports, there's pack() which tolerates bit fields crossing any
alignment boundary (but still performs u8 by u8 access).

But I don't feel like changing the access pattern of the tagger is in
the scope of this change set.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH net-next 00/15] Introduce the dsa_xmit_port_mask() tagging protocol helper
  2025-11-27 12:08 [PATCH net-next 00/15] Introduce the dsa_xmit_port_mask() tagging protocol helper Vladimir Oltean
                   ` (14 preceding siblings ...)
  2025-11-27 12:09 ` [PATCH net-next 15/15] net: dsa: tag_yt921x: " Vladimir Oltean
@ 2025-11-29  4:10 ` patchwork-bot+netdevbpf
  15 siblings, 0 replies; 23+ messages in thread
From: patchwork-bot+netdevbpf @ 2025-11-29  4:10 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: netdev, andrew, davem, edumazet, kuba, pabeni, alsi,
	clement.leger, daniel, mmyangfl, dqfext, florian.fainelli,
	george.mccollister, hauke, jonas.gorski, kurt, linus.walleij,
	linux-renesas-soc, sean.wang, UNGLinuxDriver, woojung.huh

Hello:

This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Thu, 27 Nov 2025 14:08:47 +0200 you wrote:
> What
> ----
> 
> Some DSA tags have just the port number in the TX header format, others
> have a bit field where in theory, multiple bits can be set, even though
> DSA only sets one.
> 
> [...]

Here is the summary with links:
  - [net-next,01/15] net: dsa: introduce the dsa_xmit_port_mask() tagging protocol helper
    https://git.kernel.org/netdev/net-next/c/6f2e1c75bc5e
  - [net-next,02/15] net: dsa: tag_brcm: use the dsa_xmit_port_mask() helper
    https://git.kernel.org/netdev/net-next/c/621d06a40e47
  - [net-next,03/15] net: dsa: tag_gswip: use the dsa_xmit_port_mask() helper
    https://git.kernel.org/netdev/net-next/c/e094428fb40c
  - [net-next,04/15] net: dsa: tag_hellcreek: use the dsa_xmit_port_mask() helper
    https://git.kernel.org/netdev/net-next/c/f59e44cc0d6c
  - [net-next,05/15] net: dsa: tag_ksz: use the dsa_xmit_port_mask() helper
    https://git.kernel.org/netdev/net-next/c/ea659a9292b1
  - [net-next,06/15] net: dsa: tag_mtk: use the dsa_xmit_port_mask() helper
    https://git.kernel.org/netdev/net-next/c/84a60bbec503
  - [net-next,07/15] net: dsa: tag_mxl_gsw1xx: use the dsa_xmit_port_mask() helper
    https://git.kernel.org/netdev/net-next/c/a4a00d9e365a
  - [net-next,08/15] net: dsa: tag_ocelot: use the dsa_xmit_port_mask() helper
    https://git.kernel.org/netdev/net-next/c/5733fe2a7ad1
  - [net-next,09/15] net: dsa: tag_qca: use the dsa_xmit_port_mask() helper
    https://git.kernel.org/netdev/net-next/c/48afabaf4aaa
  - [net-next,10/15] net: dsa: tag_rtl4_a: use the dsa_xmit_port_mask() helper
    https://git.kernel.org/netdev/net-next/c/4abf39c8aef5
  - [net-next,11/15] net: dsa: tag_rtl8_4: use the dsa_xmit_port_mask() helper
    https://git.kernel.org/netdev/net-next/c/5afe4ccc33f4
  - [net-next,12/15] net: dsa: tag_rzn1_a5psw: use the dsa_xmit_port_mask() helper
    https://git.kernel.org/netdev/net-next/c/b33aa90e68b4
  - [net-next,13/15] net: dsa: tag_trailer: use the dsa_xmit_port_mask() helper
    https://git.kernel.org/netdev/net-next/c/3c1975bbdf92
  - [net-next,14/15] net: dsa: tag_xrs700x: use the dsa_xmit_port_mask() helper
    https://git.kernel.org/netdev/net-next/c/24099389a63f
  - [net-next,15/15] net: dsa: tag_yt921x: use the dsa_xmit_port_mask() helper
    https://git.kernel.org/netdev/net-next/c/64b0d2edb61a

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH net-next 10/15] net: dsa: tag_rtl4_a: use the dsa_xmit_port_mask() helper
  2025-11-27 12:08 ` [PATCH net-next 10/15] net: dsa: tag_rtl4_a: " Vladimir Oltean
@ 2025-12-31  3:17   ` Luiz Angelo Daros de Luca
  2025-12-31 21:05   ` Linus Walleij
  1 sibling, 0 replies; 23+ messages in thread
From: Luiz Angelo Daros de Luca @ 2025-12-31  3:17 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: netdev, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Linus Walleij, Alvin Šipraga

>         out = (RTL4_A_PROTOCOL_RTL8366RB << RTL4_A_PROTOCOL_SHIFT);
>         /* The lower bits indicate the port number */
> -       out |= BIT(dp->index);
> +       out |= dsa_xmit_port_mask(skb, dev);
>
>         p = (__be16 *)(tag + 2);
>         *p = htons(out);
> --

It looks like overkill for this simple switch ASIC but it will work as before.

Reviewed-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH net-next 11/15] net: dsa: tag_rtl8_4: use the dsa_xmit_port_mask() helper
  2025-11-27 12:08 ` [PATCH net-next 11/15] net: dsa: tag_rtl8_4: " Vladimir Oltean
@ 2025-12-31  3:20   ` Luiz Angelo Daros de Luca
  2025-12-31 21:05   ` Linus Walleij
  1 sibling, 0 replies; 23+ messages in thread
From: Luiz Angelo Daros de Luca @ 2025-12-31  3:20 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: netdev, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Linus Walleij, Alvin Šipraga

> diff --git a/net/dsa/tag_rtl8_4.c b/net/dsa/tag_rtl8_4.c
> index 15c2bae2b429..2464545da4d2 100644
> --- a/net/dsa/tag_rtl8_4.c
> +++ b/net/dsa/tag_rtl8_4.c
> @@ -103,7 +103,6 @@
>  static void rtl8_4_write_tag(struct sk_buff *skb, struct net_device *dev,
>                              void *tag)
>  {
> -       struct dsa_port *dp = dsa_user_to_port(dev);
>         __be16 tag16[RTL8_4_TAG_LEN / 2];
>
>         /* Set Realtek EtherType */
> @@ -116,7 +115,7 @@ static void rtl8_4_write_tag(struct sk_buff *skb, struct net_device *dev,
>         tag16[2] = htons(FIELD_PREP(RTL8_4_LEARN_DIS, 1));
>
>         /* Zero ALLOW; set RX (CPU->switch) forwarding port mask */
> -       tag16[3] = htons(FIELD_PREP(RTL8_4_RX, BIT(dp->index)));
> +       tag16[3] = htons(FIELD_PREP(RTL8_4_RX, dsa_xmit_port_mask(skb, dev)));
>
>         memcpy(tag, tag16, RTL8_4_TAG_LEN);
>  }
> --

Reviewed-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH net-next 10/15] net: dsa: tag_rtl4_a: use the dsa_xmit_port_mask() helper
  2025-11-27 12:08 ` [PATCH net-next 10/15] net: dsa: tag_rtl4_a: " Vladimir Oltean
  2025-12-31  3:17   ` Luiz Angelo Daros de Luca
@ 2025-12-31 21:05   ` Linus Walleij
  1 sibling, 0 replies; 23+ messages in thread
From: Linus Walleij @ 2025-12-31 21:05 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: netdev, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Linus Walleij, Alvin Šipraga

On Thu, Nov 27, 2025 at 1:09 PM Vladimir Oltean <vladimir.oltean@nxp.com> wrote:

> The "rtl4a" tagging protocol populates a bit mask for the TX ports,
> so we can use dsa_xmit_port_mask() to centralize the decision of how to
> set that field.
>
> Cc: Linus Walleij <linus.walleij@linaro.org>
> Cc: "Alvin Šipraga" <alsi@bang-olufsen.dk>
> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>

Reviewed-by: Linus Walleij <linusw@kernel.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH net-next 11/15] net: dsa: tag_rtl8_4: use the dsa_xmit_port_mask() helper
  2025-11-27 12:08 ` [PATCH net-next 11/15] net: dsa: tag_rtl8_4: " Vladimir Oltean
  2025-12-31  3:20   ` Luiz Angelo Daros de Luca
@ 2025-12-31 21:05   ` Linus Walleij
  1 sibling, 0 replies; 23+ messages in thread
From: Linus Walleij @ 2025-12-31 21:05 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: netdev, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Linus Walleij, Alvin Šipraga

On Thu, Nov 27, 2025 at 1:09 PM Vladimir Oltean <vladimir.oltean@nxp.com> wrote:

> The "rtl8_4" and "rtl8_4t" tagging protocols populate a bit mask for the
> TX ports, so we can use dsa_xmit_port_mask() to centralize the decision
> of how to set that field.
>
> Cc: Linus Walleij <linus.walleij@linaro.org>
> Cc: "Alvin Šipraga" <alsi@bang-olufsen.dk>
> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>

Reviewed-by: Linus Walleij <linusw@kernel.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2025-12-31 21:05 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-27 12:08 [PATCH net-next 00/15] Introduce the dsa_xmit_port_mask() tagging protocol helper Vladimir Oltean
2025-11-27 12:08 ` [PATCH net-next 01/15] net: dsa: introduce " Vladimir Oltean
2025-11-27 12:08 ` [PATCH net-next 02/15] net: dsa: tag_brcm: use the dsa_xmit_port_mask() helper Vladimir Oltean
2025-11-27 13:29   ` Jonas Gorski
2025-11-27 13:42     ` Vladimir Oltean
2025-11-27 12:08 ` [PATCH net-next 03/15] net: dsa: tag_gswip: " Vladimir Oltean
2025-11-27 12:08 ` [PATCH net-next 04/15] net: dsa: tag_hellcreek: " Vladimir Oltean
2025-11-27 12:08 ` [PATCH net-next 05/15] net: dsa: tag_ksz: " Vladimir Oltean
2025-11-27 12:08 ` [PATCH net-next 06/15] net: dsa: tag_mtk: " Vladimir Oltean
2025-11-27 12:08 ` [PATCH net-next 07/15] net: dsa: tag_mxl_gsw1xx: " Vladimir Oltean
2025-11-27 12:08 ` [PATCH net-next 08/15] net: dsa: tag_ocelot: " Vladimir Oltean
2025-11-27 12:08 ` [PATCH net-next 09/15] net: dsa: tag_qca: " Vladimir Oltean
2025-11-27 12:08 ` [PATCH net-next 10/15] net: dsa: tag_rtl4_a: " Vladimir Oltean
2025-12-31  3:17   ` Luiz Angelo Daros de Luca
2025-12-31 21:05   ` Linus Walleij
2025-11-27 12:08 ` [PATCH net-next 11/15] net: dsa: tag_rtl8_4: " Vladimir Oltean
2025-12-31  3:20   ` Luiz Angelo Daros de Luca
2025-12-31 21:05   ` Linus Walleij
2025-11-27 12:08 ` [PATCH net-next 12/15] net: dsa: tag_rzn1_a5psw: " Vladimir Oltean
2025-11-27 12:09 ` [PATCH net-next 13/15] net: dsa: tag_trailer: " Vladimir Oltean
2025-11-27 12:09 ` [PATCH net-next 14/15] net: dsa: tag_xrs700x: " Vladimir Oltean
2025-11-27 12:09 ` [PATCH net-next 15/15] net: dsa: tag_yt921x: " Vladimir Oltean
2025-11-29  4:10 ` [PATCH net-next 00/15] Introduce the dsa_xmit_port_mask() tagging protocol helper patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox