]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
qualcommax: add DSA out-of-band tagging protocol
authorJohn Crispin <john@phrozen.org>
Wed, 18 Feb 2026 16:35:05 +0000 (17:35 +0100)
committerRobert Marko <robimarko@gmail.com>
Sat, 11 Jul 2026 20:26:43 +0000 (22:26 +0200)
Add kernel patch for the DSA out-of-band tagging protocol used by the
PPE switch driver, and enable CONFIG_NET_DSA_TAG_OOB.

Signed-off-by: John Crispin <john@phrozen.org>
Link: https://github.com/openwrt/openwrt/pull/22381
Signed-off-by: Robert Marko <robimarko@gmail.com>
target/linux/qualcommax/patches-6.12/0950-net-dsa-add-out-of-band-tagging-protocol.patch [new file with mode: 0644]

diff --git a/target/linux/qualcommax/patches-6.12/0950-net-dsa-add-out-of-band-tagging-protocol.patch b/target/linux/qualcommax/patches-6.12/0950-net-dsa-add-out-of-band-tagging-protocol.patch
new file mode 100644 (file)
index 0000000..142c8bb
--- /dev/null
@@ -0,0 +1,220 @@
+From a32e16b3c2fc1954ad6e09737439f60e5890278e Mon Sep 17 00:00:00 2001
+From: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Date: Fri, 4 Nov 2022 18:41:49 +0100
+Subject: [PATCH] net: dsa: add out-of-band tagging protocol
+
+This tagging protocol is designed for the situation where the link
+between the MAC and the Switch is designed such that the Destination
+Port, which is usually embedded in some part of the Ethernet Header, is
+sent out-of-band, and isn't present at all in the Ethernet frame.
+
+This can happen when the MAC and Switch are tightly integrated on an
+SoC, as is the case with the Qualcomm IPQ4019 for example, where the DSA
+tag is inserted directly into the DMA descriptors. In that case,
+the MAC driver is responsible for sending the tag to the switch using
+the out-of-band medium. To do so, the MAC driver needs to have the
+information of the destination port for that skb.
+
+Add a new tagging protocol based on SKB extensions to convey the
+information about the destination port to the MAC driver
+
+Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+---
+ Documentation/networking/dsa/dsa.rst | 13 +++++++-
+ MAINTAINERS                          |  1 +
+ include/linux/dsa/oob.h              | 16 +++++++++
+ include/linux/skbuff.h               |  3 ++
+ include/net/dsa.h                    |  2 ++
+ net/core/skbuff.c                    | 10 ++++++
+ net/dsa/Kconfig                      |  9 +++++
+ net/dsa/Makefile                     |  1 +
+ net/dsa/tag_oob.c                    | 49 ++++++++++++++++++++++++++++
+ 9 files changed, 103 insertions(+), 1 deletion(-)
+ create mode 100644 include/linux/dsa/oob.h
+ create mode 100644 net/dsa/tag_oob.c
+
+--- a/Documentation/networking/dsa/dsa.rst
++++ b/Documentation/networking/dsa/dsa.rst
+@@ -70,7 +70,8 @@ Switch tagging protocols
+ ------------------------
+ DSA supports many vendor-specific tagging protocols, one software-defined
+-tagging protocol, and a tag-less mode as well (``DSA_TAG_PROTO_NONE``).
++tagging protocol, a tag-less mode as well (``DSA_TAG_PROTO_NONE``) and an
++out-of-band tagging protocol (``DSA_TAG_PROTO_OOB``).
+ The exact format of the tag protocol is vendor specific, but in general, they
+ all contain something which:
+@@ -221,6 +222,16 @@ receive all frames regardless of the val
+ setting the ``promisc_on_conduit`` property of the ``struct dsa_device_ops``.
+ Note that this assumes a DSA-unaware conduit driver, which is the norm.
++Some SoCs have a tight integration between the conduit network interface and the
++embedded switch, such that the DSA tag isn't transmitted in the packet data,
++but through another media, using so-called out-of-band tagging. In that case,
++the host MAC driver is in charge of transmitting the tag to the switch.
++An example is the IPQ4019 SoC, that transmits the tag between the ipqess
++ethernet controller and the qca8k switch using the DMA descriptor. In that
++configuration, tag-chaining is permitted, but the OOB tag will always be the
++top-most switch in the tree. The tagger (``DSA_TAG_PROTO_OOB``) uses skb
++extensions to transmit the tag to and from the MAC driver.
++
+ Conduit network devices
+ -----------------------
+--- /dev/null
++++ b/include/linux/dsa/oob.h
+@@ -0,0 +1,16 @@
++/* SPDX-License-Identifier: GPL-2.0-only
++ * Copyright (C) 2022 Maxime Chevallier <maxime.chevallier@bootlin.com>
++ */
++
++#ifndef _NET_DSA_OOB_H
++#define _NET_DSA_OOB_H
++
++#include <linux/skbuff.h>
++
++struct dsa_oob_tag_info {
++      u16 port;
++};
++
++int dsa_oob_tag_push(struct sk_buff *skb, struct dsa_oob_tag_info *ti);
++int dsa_oob_tag_pop(struct sk_buff *skb, struct dsa_oob_tag_info *ti);
++#endif
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -4852,6 +4852,9 @@ enum skb_ext_id {
+ #if IS_ENABLED(CONFIG_MCTP_FLOWS)
+       SKB_EXT_MCTP,
+ #endif
++#if IS_ENABLED(CONFIG_NET_DSA_TAG_OOB)
++      SKB_EXT_DSA_OOB,
++#endif
+       SKB_EXT_NUM, /* must be last */
+ };
+--- a/include/net/dsa.h
++++ b/include/net/dsa.h
+@@ -57,6 +57,7 @@ struct tc_action;
+ #define DSA_TAG_PROTO_BRCM_LEGACY_FCS_VALUE   29
+ #define DSA_TAG_PROTO_MXL862_VALUE            30
+ #define DSA_TAG_PROTO_MXL862_8021Q_VALUE      31
++#define DSA_TAG_PROTO_OOB_VALUE                       32
+ enum dsa_tag_protocol {
+       DSA_TAG_PROTO_NONE              = DSA_TAG_PROTO_NONE_VALUE,
+@@ -91,6 +92,7 @@ enum dsa_tag_protocol {
+       DSA_TAG_PROTO_VSC73XX_8021Q     = DSA_TAG_PROTO_VSC73XX_8021Q_VALUE,
+       DSA_TAG_PROTO_MXL862            = DSA_TAG_PROTO_MXL862_VALUE,
+       DSA_TAG_PROTO_MXL862_8021Q      = DSA_TAG_PROTO_MXL862_8021Q_VALUE,
++      DSA_TAG_PROTO_OOB               = DSA_TAG_PROTO_OOB_VALUE,
+ };
+ struct dsa_switch;
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -65,8 +65,12 @@
+ #include <linux/kcov.h>
+ #include <linux/iov_iter.h>
+ #include <linux/if.h>
++#ifdef CONFIG_NET_DSA_TAG_OOB
++#include <linux/dsa/oob.h>
++#endif
+ #include <net/protocol.h>
++#include <net/dsa.h>
+ #include <net/dst.h>
+ #include <net/sock.h>
+ #include <net/checksum.h>
+@@ -5097,6 +5101,9 @@ static const u8 skb_ext_type_len[] = {
+ #if IS_ENABLED(CONFIG_MCTP_FLOWS)
+       [SKB_EXT_MCTP] = SKB_EXT_CHUNKSIZEOF(struct mctp_flow),
+ #endif
++#if IS_ENABLED(CONFIG_NET_DSA_TAG_OOB)
++      [SKB_EXT_DSA_OOB] = SKB_EXT_CHUNKSIZEOF(struct dsa_oob_tag_info),
++#endif
+ };
+ static __always_inline unsigned int skb_ext_total_length(void)
+--- a/net/dsa/Kconfig
++++ b/net/dsa/Kconfig
+@@ -145,6 +145,15 @@ config NET_DSA_TAG_OCELOT_8021Q
+         this mode, less TCAM resources (VCAP IS1, IS2, ES0) are available for
+         use with tc-flower.
++config NET_DSA_TAG_OOB
++      select SKB_EXTENSIONS
++      tristate "Tag driver for Out-of-band tagging drivers"
++      help
++        Say Y or M if you want to enable support for pairs of embedded
++        switches and host MAC drivers which perform demultiplexing and
++        packet steering to ports using out of band metadata processed
++        by the DSA master, rather than tags present in the packets.
++
+ config NET_DSA_TAG_QCA
+       tristate "Tag driver for Qualcomm Atheros QCA8K switches"
+       help
+--- a/net/dsa/Makefile
++++ b/net/dsa/Makefile
+@@ -33,6 +33,7 @@ obj-$(CONFIG_NET_DSA_TAG_MXL_862XX_8021Q
+ obj-$(CONFIG_NET_DSA_TAG_NONE) += tag_none.o
+ obj-$(CONFIG_NET_DSA_TAG_OCELOT) += tag_ocelot.o
+ obj-$(CONFIG_NET_DSA_TAG_OCELOT_8021Q) += tag_ocelot_8021q.o
++obj-$(CONFIG_NET_DSA_TAG_OOB) += tag_oob.o
+ obj-$(CONFIG_NET_DSA_TAG_QCA) += tag_qca.o
+ obj-$(CONFIG_NET_DSA_TAG_RTL4_A) += tag_rtl4_a.o
+ obj-$(CONFIG_NET_DSA_TAG_RTL8_4) += tag_rtl8_4.o
+--- /dev/null
++++ b/net/dsa/tag_oob.c
+@@ -0,0 +1,51 @@
++// SPDX-License-Identifier: GPL-2.0-only
++
++/* Copyright (c) 2022, Maxime Chevallier <maxime.chevallier@bootlin.com> */
++
++#include <linux/bitfield.h>
++#include <linux/dsa/oob.h>
++#include <linux/skbuff.h>
++
++#include "tag.h"
++
++#define OOB_NAME "oob"
++
++static struct sk_buff *oob_tag_xmit(struct sk_buff *skb,
++                                  struct net_device *dev)
++{
++      struct dsa_oob_tag_info *tag_info = skb_ext_add(skb, SKB_EXT_DSA_OOB);
++      struct dsa_port *dp = dsa_user_to_port(dev);
++
++      tag_info->port = dp->index;
++
++      return skb;
++}
++
++static struct sk_buff *oob_tag_rcv(struct sk_buff *skb,
++                                 struct net_device *dev)
++{
++      struct dsa_oob_tag_info *tag_info = skb_ext_find(skb, SKB_EXT_DSA_OOB);
++
++      if (!tag_info)
++              return NULL;
++
++      skb->dev = dsa_conduit_find_user(dev, 0, tag_info->port);
++      if (!skb->dev)
++              return NULL;
++
++      return skb;
++}
++
++static const struct dsa_device_ops oob_tag_dsa_ops = {
++      .name   = OOB_NAME,
++      .proto  = DSA_TAG_PROTO_OOB,
++      .xmit   = oob_tag_xmit,
++      .rcv    = oob_tag_rcv,
++};
++
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("DSA tag driver for out-of-band tagging");
++MODULE_AUTHOR("Maxime Chevallier <maxime.chevallier@bootlin.com>");
++MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_OOB, OOB_NAME);
++
++module_dsa_tag_driver(oob_tag_dsa_ops);