kernel: bump 6.1 to 6.1.63
[openwrt/staging/stintel.git] / target / linux / ipq40xx / patches-6.1 / 701-net-dsa-add-out-of-band-tagging-protocol.patch
1 From a32e16b3c2fc1954ad6e09737439f60e5890278e Mon Sep 17 00:00:00 2001
2 From: Maxime Chevallier <maxime.chevallier@bootlin.com>
3 Date: Fri, 4 Nov 2022 18:41:49 +0100
4 Subject: [PATCH] net: dsa: add out-of-band tagging protocol
5
6 This tagging protocol is designed for the situation where the link
7 between the MAC and the Switch is designed such that the Destination
8 Port, which is usually embedded in some part of the Ethernet Header, is
9 sent out-of-band, and isn't present at all in the Ethernet frame.
10
11 This can happen when the MAC and Switch are tightly integrated on an
12 SoC, as is the case with the Qualcomm IPQ4019 for example, where the DSA
13 tag is inserted directly into the DMA descriptors. In that case,
14 the MAC driver is responsible for sending the tag to the switch using
15 the out-of-band medium. To do so, the MAC driver needs to have the
16 information of the destination port for that skb.
17
18 Add a new tagging protocol based on SKB extensions to convey the
19 information about the destination port to the MAC driver
20
21 Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
22 ---
23 Documentation/networking/dsa/dsa.rst | 13 +++++++-
24 MAINTAINERS | 1 +
25 include/linux/dsa/oob.h | 16 +++++++++
26 include/linux/skbuff.h | 3 ++
27 include/net/dsa.h | 2 ++
28 net/core/skbuff.c | 10 ++++++
29 net/dsa/Kconfig | 9 +++++
30 net/dsa/Makefile | 1 +
31 net/dsa/tag_oob.c | 49 ++++++++++++++++++++++++++++
32 9 files changed, 103 insertions(+), 1 deletion(-)
33 create mode 100644 include/linux/dsa/oob.h
34 create mode 100644 net/dsa/tag_oob.c
35
36 --- a/Documentation/networking/dsa/dsa.rst
37 +++ b/Documentation/networking/dsa/dsa.rst
38 @@ -66,7 +66,8 @@ Switch tagging protocols
39 ------------------------
40
41 DSA supports many vendor-specific tagging protocols, one software-defined
42 -tagging protocol, and a tag-less mode as well (``DSA_TAG_PROTO_NONE``).
43 +tagging protocol, a tag-less mode as well (``DSA_TAG_PROTO_NONE``) and an
44 +out-of-band tagging protocol (``DSA_TAG_PROTO_OOB``).
45
46 The exact format of the tag protocol is vendor specific, but in general, they
47 all contain something which:
48 @@ -217,6 +218,16 @@ receive all frames regardless of the val
49 setting the ``promisc_on_master`` property of the ``struct dsa_device_ops``.
50 Note that this assumes a DSA-unaware master driver, which is the norm.
51
52 +Some SoCs have a tight integration between the conduit network interface and the
53 +embedded switch, such that the DSA tag isn't transmitted in the packet data,
54 +but through another media, using so-called out-of-band tagging. In that case,
55 +the host MAC driver is in charge of transmitting the tag to the switch.
56 +An example is the IPQ4019 SoC, that transmits the tag between the ipqess
57 +ethernet controller and the qca8k switch using the DMA descriptor. In that
58 +configuration, tag-chaining is permitted, but the OOB tag will always be the
59 +top-most switch in the tree. The tagger (``DSA_TAG_PROTO_OOB``) uses skb
60 +extensions to transmit the tag to and from the MAC driver.
61 +
62 Master network devices
63 ----------------------
64
65 --- a/MAINTAINERS
66 +++ b/MAINTAINERS
67 @@ -17070,6 +17070,7 @@ L: netdev@vger.kernel.org
68 S: Maintained
69 F: Documentation/devicetree/bindings/net/qcom,ipq4019-ess-edma.yaml
70 F: drivers/net/ethernet/qualcomm/ipqess/
71 +F: net/dsa/tag_oob.c
72
73 QUALCOMM ETHQOS ETHERNET DRIVER
74 M: Vinod Koul <vkoul@kernel.org>
75 --- /dev/null
76 +++ b/include/linux/dsa/oob.h
77 @@ -0,0 +1,16 @@
78 +/* SPDX-License-Identifier: GPL-2.0-only
79 + * Copyright (C) 2022 Maxime Chevallier <maxime.chevallier@bootlin.com>
80 + */
81 +
82 +#ifndef _NET_DSA_OOB_H
83 +#define _NET_DSA_OOB_H
84 +
85 +#include <linux/skbuff.h>
86 +
87 +struct dsa_oob_tag_info {
88 + u16 port;
89 +};
90 +
91 +int dsa_oob_tag_push(struct sk_buff *skb, struct dsa_oob_tag_info *ti);
92 +int dsa_oob_tag_pop(struct sk_buff *skb, struct dsa_oob_tag_info *ti);
93 +#endif
94 --- a/include/linux/skbuff.h
95 +++ b/include/linux/skbuff.h
96 @@ -4588,6 +4588,9 @@ enum skb_ext_id {
97 #if IS_ENABLED(CONFIG_MCTP_FLOWS)
98 SKB_EXT_MCTP,
99 #endif
100 +#if IS_ENABLED(CONFIG_NET_DSA_TAG_OOB)
101 + SKB_EXT_DSA_OOB,
102 +#endif
103 SKB_EXT_NUM, /* must be last */
104 };
105
106 --- a/include/net/dsa.h
107 +++ b/include/net/dsa.h
108 @@ -55,6 +55,7 @@ struct phylink_link_state;
109 #define DSA_TAG_PROTO_RTL8_4T_VALUE 25
110 #define DSA_TAG_PROTO_RZN1_A5PSW_VALUE 26
111 #define DSA_TAG_PROTO_LAN937X_VALUE 27
112 +#define DSA_TAG_PROTO_OOB_VALUE 28
113
114 enum dsa_tag_protocol {
115 DSA_TAG_PROTO_NONE = DSA_TAG_PROTO_NONE_VALUE,
116 @@ -85,6 +86,7 @@ enum dsa_tag_protocol {
117 DSA_TAG_PROTO_RTL8_4T = DSA_TAG_PROTO_RTL8_4T_VALUE,
118 DSA_TAG_PROTO_RZN1_A5PSW = DSA_TAG_PROTO_RZN1_A5PSW_VALUE,
119 DSA_TAG_PROTO_LAN937X = DSA_TAG_PROTO_LAN937X_VALUE,
120 + DSA_TAG_PROTO_OOB = DSA_TAG_PROTO_OOB_VALUE,
121 };
122
123 struct dsa_switch;
124 --- a/net/core/skbuff.c
125 +++ b/net/core/skbuff.c
126 @@ -62,8 +62,12 @@
127 #include <linux/mpls.h>
128 #include <linux/kcov.h>
129 #include <linux/if.h>
130 +#ifdef CONFIG_NET_DSA_TAG_OOB
131 +#include <linux/dsa/oob.h>
132 +#endif
133
134 #include <net/protocol.h>
135 +#include <net/dsa.h>
136 #include <net/dst.h>
137 #include <net/sock.h>
138 #include <net/checksum.h>
139 @@ -4516,6 +4520,9 @@ static const u8 skb_ext_type_len[] = {
140 #if IS_ENABLED(CONFIG_MCTP_FLOWS)
141 [SKB_EXT_MCTP] = SKB_EXT_CHUNKSIZEOF(struct mctp_flow),
142 #endif
143 +#if IS_ENABLED(CONFIG_NET_DSA_TAG_OOB)
144 + [SKB_EXT_DSA_OOB] = SKB_EXT_CHUNKSIZEOF(struct dsa_oob_tag_info),
145 +#endif
146 };
147
148 static __always_inline unsigned int skb_ext_total_length(void)
149 @@ -4536,6 +4543,9 @@ static __always_inline unsigned int skb_
150 #if IS_ENABLED(CONFIG_MCTP_FLOWS)
151 skb_ext_type_len[SKB_EXT_MCTP] +
152 #endif
153 +#if IS_ENABLED(CONFIG_NET_DSA_TAG_OOB)
154 + skb_ext_type_len[SKB_EXT_DSA_OOB] +
155 +#endif
156 0;
157 }
158
159 --- a/net/dsa/Kconfig
160 +++ b/net/dsa/Kconfig
161 @@ -113,6 +113,15 @@ config NET_DSA_TAG_OCELOT_8021Q
162 this mode, less TCAM resources (VCAP IS1, IS2, ES0) are available for
163 use with tc-flower.
164
165 +config NET_DSA_TAG_OOB
166 + select SKB_EXTENSIONS
167 + tristate "Tag driver for Out-of-band tagging drivers"
168 + help
169 + Say Y or M if you want to enable support for pairs of embedded
170 + switches and host MAC drivers which perform demultiplexing and
171 + packet steering to ports using out of band metadata processed
172 + by the DSA master, rather than tags present in the packets.
173 +
174 config NET_DSA_TAG_QCA
175 tristate "Tag driver for Qualcomm Atheros QCA8K switches"
176 help
177 --- a/net/dsa/Makefile
178 +++ b/net/dsa/Makefile
179 @@ -22,6 +22,7 @@ obj-$(CONFIG_NET_DSA_TAG_LAN9303) += tag
180 obj-$(CONFIG_NET_DSA_TAG_MTK) += tag_mtk.o
181 obj-$(CONFIG_NET_DSA_TAG_OCELOT) += tag_ocelot.o
182 obj-$(CONFIG_NET_DSA_TAG_OCELOT_8021Q) += tag_ocelot_8021q.o
183 +obj-$(CONFIG_NET_DSA_TAG_OOB) += tag_oob.o
184 obj-$(CONFIG_NET_DSA_TAG_QCA) += tag_qca.o
185 obj-$(CONFIG_NET_DSA_TAG_RTL4_A) += tag_rtl4_a.o
186 obj-$(CONFIG_NET_DSA_TAG_RTL8_4) += tag_rtl8_4.o
187 --- /dev/null
188 +++ b/net/dsa/tag_oob.c
189 @@ -0,0 +1,49 @@
190 +// SPDX-License-Identifier: GPL-2.0-only
191 +
192 +/* Copyright (c) 2022, Maxime Chevallier <maxime.chevallier@bootlin.com> */
193 +
194 +#include <linux/bitfield.h>
195 +#include <linux/dsa/oob.h>
196 +#include <linux/skbuff.h>
197 +
198 +#include "dsa_priv.h"
199 +
200 +static struct sk_buff *oob_tag_xmit(struct sk_buff *skb,
201 + struct net_device *dev)
202 +{
203 + struct dsa_oob_tag_info *tag_info = skb_ext_add(skb, SKB_EXT_DSA_OOB);
204 + struct dsa_port *dp = dsa_slave_to_port(dev);
205 +
206 + tag_info->port = dp->index;
207 +
208 + return skb;
209 +}
210 +
211 +static struct sk_buff *oob_tag_rcv(struct sk_buff *skb,
212 + struct net_device *dev)
213 +{
214 + struct dsa_oob_tag_info *tag_info = skb_ext_find(skb, SKB_EXT_DSA_OOB);
215 +
216 + if (!tag_info)
217 + return NULL;
218 +
219 + skb->dev = dsa_master_find_slave(dev, 0, tag_info->port);
220 + if (!skb->dev)
221 + return NULL;
222 +
223 + return skb;
224 +}
225 +
226 +static const struct dsa_device_ops oob_tag_dsa_ops = {
227 + .name = "oob",
228 + .proto = DSA_TAG_PROTO_OOB,
229 + .xmit = oob_tag_xmit,
230 + .rcv = oob_tag_rcv,
231 +};
232 +
233 +MODULE_LICENSE("GPL");
234 +MODULE_DESCRIPTION("DSA tag driver for out-of-band tagging");
235 +MODULE_AUTHOR("Maxime Chevallier <maxime.chevallier@bootlin.com>");
236 +MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_OOB);
237 +
238 +module_dsa_tag_driver(oob_tag_dsa_ops);