74079d68a13d5ea7fc166a823bbd3f9210873986
[openwrt/openwrt.git] / target / linux / ipq40xx / patches-5.15 / 701-net-dsa-tag_ipq4019-add-shinfo-based-tagging-driver-.patch
1 From 29a0c2fae991cab142575c92276c0afdeb260ebe Mon Sep 17 00:00:00 2001
2 From: Gabor Juhos <j4g8y7@gmail.com>
3 Date: Thu, 28 Oct 2021 21:44:52 +0200
4 Subject: [PATCH] net: dsa: tag_ipq4019: add shinfo based tagging driver for
5 IPQ40xx
6
7 This change adds a tagging protocol driver for the built-in
8 ethernet switch of the Qualcomm Atheros IPQ4019 SoCs.
9
10 In comparison to the existing tagging protocols this hardware
11 requires a slightly different approach because the switch does
12 not use in-band tags.
13
14 On the receive path, the source port information is embedded
15 into the RX descriptors of the ethernet MAC hardware. Similarly,
16 the destination port mask must be sent via the TX descriptors
17 of the ethernet MAC when a packet is sent towards the switch.
18
19 In order to support this special requirements, this patch
20 adds a new tagging protocol driver.
21
22 The driver extracts the source port information directly
23 from the 'receive return descriptor' of the ethernet MAC.
24 It is possible because that descriptor is part of the skb
25 received from the ethernet driver.
26
27 Unfortunatley, it is not possible to put the destination
28 port information directly to the TX descriptors, because
29 those are handled internally by the driver of the ethernet
30 hardware.
31
32 To overcome this limitation, this tagging driver uses the
33 DSA specific fields in skb->shinfo to send the destination
34 port information to the ethernet driver.
35
36 A similar tagging driver is exist but that uses skb
37 extensions which causes unnecessary overhead.
38
39 Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
40 ---
41 include/linux/dsa/ipq4019.h | 11 ++++++
42 include/net/dsa.h | 2 +
43 net/dsa/Kconfig | 6 +++
44 net/dsa/Makefile | 1 +
45 net/dsa/tag_ipq4019.c | 79 +++++++++++++++++++++++++++++++++++++
46 5 files changed, 99 insertions(+)
47 create mode 100644 include/linux/dsa/ipq4019.h
48 create mode 100644 net/dsa/tag_ipq4019.c
49
50 --- /dev/null
51 +++ b/include/linux/dsa/ipq4019.h
52 @@ -0,0 +1,11 @@
53 +/* SPDX-License-Identifier: GPL-2.0-only */
54 +
55 +#ifndef DSA_IPQ40XX_H
56 +#define DSA_IPQ40XX_H
57 +
58 +struct ipq40xx_dsa_tag_data {
59 + u8 from_cpu;
60 + u8 dp;
61 +};
62 +
63 +#endif /* DSA_IPQ40XX_H */
64 --- a/include/net/dsa.h
65 +++ b/include/net/dsa.h
66 @@ -51,6 +51,7 @@ struct phylink_link_state;
67 #define DSA_TAG_PROTO_SEVILLE_VALUE 21
68 #define DSA_TAG_PROTO_BRCM_LEGACY_VALUE 22
69 #define DSA_TAG_PROTO_SJA1110_VALUE 23
70 +#define DSA_TAG_PROTO_IPQ4019_VALUE 24
71
72 enum dsa_tag_protocol {
73 DSA_TAG_PROTO_NONE = DSA_TAG_PROTO_NONE_VALUE,
74 @@ -77,6 +78,7 @@ enum dsa_tag_protocol {
75 DSA_TAG_PROTO_OCELOT_8021Q = DSA_TAG_PROTO_OCELOT_8021Q_VALUE,
76 DSA_TAG_PROTO_SEVILLE = DSA_TAG_PROTO_SEVILLE_VALUE,
77 DSA_TAG_PROTO_SJA1110 = DSA_TAG_PROTO_SJA1110_VALUE,
78 + DSA_TAG_PROTO_IPQ4019 = DSA_TAG_PROTO_IPQ4019_VALUE,
79 };
80
81 struct dsa_switch;
82 --- a/net/dsa/Kconfig
83 +++ b/net/dsa/Kconfig
84 @@ -57,6 +57,12 @@ config NET_DSA_TAG_HELLCREEK
85 Say Y or M if you want to enable support for tagging frames
86 for the Hirschmann Hellcreek TSN switches.
87
88 +config NET_DSA_TAG_IPQ4019
89 + tristate "Tag driver for Qualcomm Atheros IPQ4019 SoC built-in switch"
90 + help
91 + Say Y or M if you want to enable support for tagging frames for
92 + the built-in switch of the Qualcomm Atheros IPQ4019 SoC-s.
93 +
94 config NET_DSA_TAG_GSWIP
95 tristate "Tag driver for Lantiq / Intel GSWIP switches"
96 help
97 --- a/net/dsa/Makefile
98 +++ b/net/dsa/Makefile
99 @@ -8,6 +8,7 @@ obj-$(CONFIG_NET_DSA_TAG_AR9331) += tag_
100 obj-$(CONFIG_NET_DSA_TAG_BRCM_COMMON) += tag_brcm.o
101 obj-$(CONFIG_NET_DSA_TAG_DSA_COMMON) += tag_dsa.o
102 obj-$(CONFIG_NET_DSA_TAG_GSWIP) += tag_gswip.o
103 +obj-$(CONFIG_NET_DSA_TAG_IPQ4019) += tag_ipq4019.o
104 obj-$(CONFIG_NET_DSA_TAG_HELLCREEK) += tag_hellcreek.o
105 obj-$(CONFIG_NET_DSA_TAG_KSZ) += tag_ksz.o
106 obj-$(CONFIG_NET_DSA_TAG_RTL4_A) += tag_rtl4_a.o
107 --- /dev/null
108 +++ b/net/dsa/tag_ipq4019.c
109 @@ -0,0 +1,78 @@
110 +// SPDX-License-Identifier: GPL-2.0-only
111 +
112 +/* Copyright (c) 2021, Gabor Juhos <j4g8y7@gmail.com> */
113 +
114 +#include <linux/bitfield.h>
115 +#include <linux/dsa/ipq4019.h>
116 +
117 +#include "dsa_priv.h"
118 +
119 +/* Receive Return Descriptor */
120 +struct edma_rrd {
121 + u16 rrd0;
122 + u16 rrd1;
123 + u16 rrd2;
124 + u16 rrd3;
125 + u16 rrd4;
126 + u16 rrd5;
127 + u16 rrd6;
128 + u16 rrd7;
129 +} __packed;
130 +
131 +#define EDMA_RRD_SIZE sizeof(struct edma_rrd)
132 +
133 +#define EDMA_RRD1_PORT_ID_MASK GENMASK(14, 12)
134 +
135 +static struct sk_buff *ipq4019_sh_tag_xmit(struct sk_buff *skb,
136 + struct net_device *dev)
137 +{
138 + struct dsa_port *dp = dsa_slave_to_port(dev);
139 + struct ipq40xx_dsa_tag_data *tag_data;
140 +
141 + BUILD_BUG_ON(sizeof_field(struct skb_shared_info, dsa_tag_data) <
142 + sizeof(struct ipq40xx_dsa_tag_data));
143 +
144 + skb_shinfo(skb)->dsa_tag_proto = DSA_TAG_PROTO_IPQ4019;
145 + tag_data = (struct ipq40xx_dsa_tag_data *)skb_shinfo(skb)->dsa_tag_data;
146 +
147 + tag_data->from_cpu = 1;
148 + /* set the destination port information */
149 + tag_data->dp = BIT(dp->index);
150 +
151 + return skb;
152 +}
153 +
154 +static struct sk_buff *ipq4019_sh_tag_rcv(struct sk_buff *skb,
155 + struct net_device *dev)
156 +{
157 + struct edma_rrd *rrd;
158 + int offset;
159 + int port;
160 +
161 + offset = EDMA_RRD_SIZE + ETH_HLEN;
162 + if (unlikely(skb_headroom(skb) < offset))
163 + return NULL;
164 +
165 + rrd = (struct edma_rrd *)(skb->data - offset);
166 + port = FIELD_GET(EDMA_RRD1_PORT_ID_MASK, rrd->rrd1);
167 +
168 + skb->dev = dsa_master_find_slave(dev, 0, port);
169 + if (!skb->dev)
170 + return NULL;
171 +
172 + return skb;
173 +}
174 +
175 +const struct dsa_device_ops ipq4019_sh_tag_dsa_ops = {
176 + .name = "ipq4019-sh",
177 + .proto = DSA_TAG_PROTO_IPQ4019,
178 + .xmit = ipq4019_sh_tag_xmit,
179 + .rcv = ipq4019_sh_tag_rcv,
180 +};
181 +
182 +MODULE_LICENSE("GPL v2");
183 +MODULE_DESCRIPTION("DSA tag driver for the IPQ4019 SoC built-in ethernet switch");
184 +MODULE_AUTHOR("Gabor Juhos <j4g8y7@gmail.com>");
185 +MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_IPQ4019);
186 +
187 +module_dsa_tag_driver(ipq4019_sh_tag_dsa_ops);