bmips: backport upstream dsa b53 is63xx patch
[openwrt/staging/noltari.git] / target / linux / bmips / patches-5.10 / 502-net-dsa-b53-support-tags-for-legacy-switches.patch
1 From 3bc3d79efdff6e29b80bf35f7a56baaa36e4d8fe Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
3 Date: Fri, 12 Mar 2021 12:35:39 +0100
4 Subject: [PATCH] net: dsa: b53: support tags for legacy switches
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
10 ---
11 drivers/net/dsa/b53/Kconfig | 1 +
12 drivers/net/dsa/b53/b53_common.c | 6 +++
13 include/net/dsa.h | 2 +
14 net/dsa/Kconfig | 7 +++
15 net/dsa/tag_brcm.c | 93 ++++++++++++++++++++++++++++++++
16 5 files changed, 109 insertions(+)
17
18 --- a/drivers/net/dsa/b53/Kconfig
19 +++ b/drivers/net/dsa/b53/Kconfig
20 @@ -3,6 +3,7 @@ menuconfig B53
21 tristate "Broadcom BCM53xx managed switch support"
22 depends on NET_DSA
23 select NET_DSA_TAG_BRCM
24 + select NET_DSA_TAG_BRCM_LEGACY
25 select NET_DSA_TAG_BRCM_PREPEND
26 help
27 This driver adds support for Broadcom managed switch chips. It supports
28 --- a/drivers/net/dsa/b53/b53_common.c
29 +++ b/drivers/net/dsa/b53/b53_common.c
30 @@ -1992,6 +1992,7 @@ static bool b53_can_enable_brcm_tags(str
31
32 switch (tag_protocol) {
33 case DSA_TAG_PROTO_BRCM:
34 + case DSA_TAG_PROTO_BRCM_LEGACY:
35 case DSA_TAG_PROTO_BRCM_PREPEND:
36 dev_warn(ds->dev,
37 "Port %d is stacked to Broadcom tag switch\n", port);
38 @@ -2013,12 +2014,16 @@ enum dsa_tag_protocol b53_get_tag_protoc
39 /* Older models (5325, 5365) support a different tag format that we do
40 * not support in net/dsa/tag_brcm.c yet.
41 */
42 - if (is5325(dev) || is5365(dev) ||
43 - !b53_can_enable_brcm_tags(ds, port, mprot)) {
44 + if (!b53_can_enable_brcm_tags(ds, port, mprot)) {
45 dev->tag_protocol = DSA_TAG_PROTO_NONE;
46 goto out;
47 }
48
49 + if (is5325(dev) || is5365(dev) || is63xx(dev)) {
50 + dev->tag_protocol = DSA_TAG_PROTO_BRCM_LEGACY;
51 + goto out;
52 + }
53 +
54 /* Broadcom BCM58xx chips have a flow accelerator on Port 8
55 * which requires us to use the prepended Broadcom tag type
56 */
57 --- a/include/net/dsa.h
58 +++ b/include/net/dsa.h
59 @@ -45,10 +45,12 @@ struct phylink_link_state;
60 #define DSA_TAG_PROTO_OCELOT_VALUE 15
61 #define DSA_TAG_PROTO_AR9331_VALUE 16
62 #define DSA_TAG_PROTO_RTL4_A_VALUE 17
63 +#define DSA_TAG_PROTO_BRCM_LEGACY_VALUE 22
64
65 enum dsa_tag_protocol {
66 DSA_TAG_PROTO_NONE = DSA_TAG_PROTO_NONE_VALUE,
67 DSA_TAG_PROTO_BRCM = DSA_TAG_PROTO_BRCM_VALUE,
68 + DSA_TAG_PROTO_BRCM_LEGACY = DSA_TAG_PROTO_BRCM_LEGACY_VALUE,
69 DSA_TAG_PROTO_BRCM_PREPEND = DSA_TAG_PROTO_BRCM_PREPEND_VALUE,
70 DSA_TAG_PROTO_DSA = DSA_TAG_PROTO_DSA_VALUE,
71 DSA_TAG_PROTO_EDSA = DSA_TAG_PROTO_EDSA_VALUE,
72 --- a/net/dsa/Kconfig
73 +++ b/net/dsa/Kconfig
74 @@ -47,6 +47,13 @@ config NET_DSA_TAG_BRCM
75 Say Y if you want to enable support for tagging frames for the
76 Broadcom switches which place the tag after the MAC source address.
77
78 +config NET_DSA_TAG_BRCM_LEGACY
79 + tristate "Tag driver for Broadcom legacy switches using in-frame headers"
80 + select NET_DSA_TAG_BRCM_COMMON
81 + help
82 + Say Y if you want to enable support for tagging frames for the
83 + Broadcom legacy switches which place the tag after the MAC source
84 + address.
85
86 config NET_DSA_TAG_BRCM_PREPEND
87 tristate "Tag driver for Broadcom switches using prepended headers"
88 --- a/net/dsa/tag_brcm.c
89 +++ b/net/dsa/tag_brcm.c
90 @@ -8,9 +8,23 @@
91 #include <linux/etherdevice.h>
92 #include <linux/list.h>
93 #include <linux/slab.h>
94 +#include <linux/types.h>
95
96 #include "dsa_priv.h"
97
98 +struct bcm_legacy_tag {
99 + uint16_t type;
100 +#define BRCM_LEG_TYPE 0x8874
101 +
102 + uint32_t tag;
103 +#define BRCM_LEG_TAG_PORT_ID (0xf)
104 +#define BRCM_LEG_TAG_MULTICAST (1 << 29)
105 +#define BRCM_LEG_TAG_EGRESS (2 << 29)
106 +#define BRCM_LEG_TAG_INGRESS (3 << 29)
107 +} __attribute__((packed));
108 +
109 +#define BRCM_LEG_TAG_LEN sizeof(struct bcm_legacy_tag)
110 +
111 /* This tag length is 4 bytes, older ones were 6 bytes, we do not
112 * handle them
113 */
114 @@ -197,6 +211,85 @@ DSA_TAG_DRIVER(brcm_netdev_ops);
115 MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM);
116 #endif
117
118 +#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY)
119 +static struct sk_buff *brcm_leg_tag_xmit(struct sk_buff *skb,
120 + struct net_device *dev)
121 +{
122 + struct dsa_port *dp = dsa_slave_to_port(dev);
123 + struct bcm_legacy_tag *brcm_tag;
124 +
125 + if (skb_cow_head(skb, BRCM_LEG_TAG_LEN) < 0)
126 + return NULL;
127 +
128 + /* The Ethernet switch we are interfaced with needs packets to be at
129 + * least 64 bytes (including FCS) otherwise they will be discarded when
130 + * they enter the switch port logic. When Broadcom tags are enabled, we
131 + * need to make sure that packets are at least 70 bytes
132 + * (including FCS and tag) because the length verification is done after
133 + * the Broadcom tag is stripped off the ingress packet.
134 + *
135 + * Let dsa_slave_xmit() free the SKB
136 + */
137 + if (__skb_put_padto(skb, ETH_ZLEN + BRCM_LEG_TAG_LEN, false))
138 + return NULL;
139 +
140 + skb_push(skb, BRCM_LEG_TAG_LEN);
141 +
142 + memmove(skb->data, skb->data + BRCM_LEG_TAG_LEN, 2 * ETH_ALEN);
143 +
144 + brcm_tag = (struct bcm_legacy_tag *) (skb->data + 2 * ETH_ALEN);
145 +
146 + brcm_tag->type = BRCM_LEG_TYPE;
147 + brcm_tag->tag = BRCM_LEG_TAG_EGRESS;
148 + brcm_tag->tag |= dp->index & BRCM_LEG_TAG_PORT_ID;
149 +
150 + return skb;
151 +}
152 +
153 +
154 +static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb,
155 + struct net_device *dev,
156 + struct packet_type *pt)
157 +{
158 + int source_port;
159 + struct bcm_legacy_tag *brcm_tag;
160 +
161 + if (unlikely(!pskb_may_pull(skb, BRCM_LEG_TAG_LEN)))
162 + return NULL;
163 +
164 + brcm_tag = (struct bcm_legacy_tag *) (skb->data - 2);
165 +
166 + source_port = brcm_tag->tag & BRCM_LEG_TAG_PORT_ID;
167 +
168 + skb->dev = dsa_master_find_slave(dev, 0, source_port);
169 + if (!skb->dev)
170 + return NULL;
171 +
172 + /* Remove Broadcom tag and update checksum */
173 + skb_pull_rcsum(skb, BRCM_LEG_TAG_LEN);
174 +
175 + skb->offload_fwd_mark = 1;
176 +
177 + /* Move the Ethernet DA and SA */
178 + memmove(skb->data - ETH_HLEN,
179 + skb->data - ETH_HLEN - BRCM_LEG_TAG_LEN,
180 + 2 * ETH_ALEN);
181 +
182 + return skb;
183 +}
184 +
185 +static const struct dsa_device_ops brcm_legacy_netdev_ops = {
186 + .name = "brcm-legacy",
187 + .proto = DSA_TAG_PROTO_BRCM_LEGACY,
188 + .xmit = brcm_leg_tag_xmit,
189 + .rcv = brcm_leg_tag_rcv,
190 + .overhead = BRCM_LEG_TAG_LEN,
191 +};
192 +
193 +DSA_TAG_DRIVER(brcm_legacy_netdev_ops);
194 +MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM_LEGACY);
195 +#endif /* CONFIG_NET_DSA_TAG_BRCM_LEGACY */
196 +
197 #if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_PREPEND)
198 static struct sk_buff *brcm_tag_xmit_prepend(struct sk_buff *skb,
199 struct net_device *dev)
200 @@ -229,6 +322,9 @@ static struct dsa_tag_driver *dsa_tag_dr
201 #if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM)
202 &DSA_TAG_DRIVER_NAME(brcm_netdev_ops),
203 #endif
204 +#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY)
205 + &DSA_TAG_DRIVER_NAME(brcm_legacy_netdev_ops),
206 +#endif
207 #if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_PREPEND)
208 &DSA_TAG_DRIVER_NAME(brcm_prepend_netdev_ops),
209 #endif