xref: /openbmc/linux/net/dsa/tag_ksz.c (revision 94214f14)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * net/dsa/tag_ksz.c - Microchip KSZ Switch tag format handling
4  * Copyright (c) 2017 Microchip Technology
5  */
6 
7 #include <linux/etherdevice.h>
8 #include <linux/list.h>
9 #include <net/dsa.h>
10 
11 #include "tag.h"
12 
13 #define KSZ8795_NAME "ksz8795"
14 #define KSZ9477_NAME "ksz9477"
15 #define KSZ9893_NAME "ksz9893"
16 #define LAN937X_NAME "lan937x"
17 
18 /* Typically only one byte is used for tail tag. */
19 #define KSZ_EGRESS_TAG_LEN		1
20 #define KSZ_INGRESS_TAG_LEN		1
21 
22 static struct sk_buff *ksz_common_rcv(struct sk_buff *skb,
23 				      struct net_device *dev,
24 				      unsigned int port, unsigned int len)
25 {
26 	skb->dev = dsa_master_find_slave(dev, 0, port);
27 	if (!skb->dev)
28 		return NULL;
29 
30 	if (pskb_trim_rcsum(skb, skb->len - len))
31 		return NULL;
32 
33 	dsa_default_offload_fwd_mark(skb);
34 
35 	return skb;
36 }
37 
38 /*
39  * For Ingress (Host -> KSZ8795), 1 byte is added before FCS.
40  * ---------------------------------------------------------------------------
41  * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag(1byte)|FCS(4bytes)
42  * ---------------------------------------------------------------------------
43  * tag : each bit represents port (eg, 0x01=port1, 0x02=port2, 0x10=port5)
44  *
45  * For Egress (KSZ8795 -> Host), 1 byte is added before FCS.
46  * ---------------------------------------------------------------------------
47  * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag0(1byte)|FCS(4bytes)
48  * ---------------------------------------------------------------------------
49  * tag0 : zero-based value represents port
50  *	  (eg, 0x00=port1, 0x02=port3, 0x06=port7)
51  */
52 
53 #define KSZ8795_TAIL_TAG_OVERRIDE	BIT(6)
54 #define KSZ8795_TAIL_TAG_LOOKUP		BIT(7)
55 
56 static struct sk_buff *ksz8795_xmit(struct sk_buff *skb, struct net_device *dev)
57 {
58 	struct dsa_port *dp = dsa_slave_to_port(dev);
59 	u8 *tag;
60 	u8 *addr;
61 
62 	if (skb->ip_summed == CHECKSUM_PARTIAL && skb_checksum_help(skb))
63 		return NULL;
64 
65 	/* Tag encoding */
66 	tag = skb_put(skb, KSZ_INGRESS_TAG_LEN);
67 	addr = skb_mac_header(skb);
68 
69 	*tag = 1 << dp->index;
70 	if (is_link_local_ether_addr(addr))
71 		*tag |= KSZ8795_TAIL_TAG_OVERRIDE;
72 
73 	return skb;
74 }
75 
76 static struct sk_buff *ksz8795_rcv(struct sk_buff *skb, struct net_device *dev)
77 {
78 	u8 *tag = skb_tail_pointer(skb) - KSZ_EGRESS_TAG_LEN;
79 
80 	return ksz_common_rcv(skb, dev, tag[0] & 7, KSZ_EGRESS_TAG_LEN);
81 }
82 
83 static const struct dsa_device_ops ksz8795_netdev_ops = {
84 	.name	= KSZ8795_NAME,
85 	.proto	= DSA_TAG_PROTO_KSZ8795,
86 	.xmit	= ksz8795_xmit,
87 	.rcv	= ksz8795_rcv,
88 	.needed_tailroom = KSZ_INGRESS_TAG_LEN,
89 };
90 
91 DSA_TAG_DRIVER(ksz8795_netdev_ops);
92 MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_KSZ8795, KSZ8795_NAME);
93 
94 /*
95  * For Ingress (Host -> KSZ9477), 2 bytes are added before FCS.
96  * ---------------------------------------------------------------------------
97  * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag0(1byte)|tag1(1byte)|FCS(4bytes)
98  * ---------------------------------------------------------------------------
99  * tag0 : Prioritization (not used now)
100  * tag1 : each bit represents port (eg, 0x01=port1, 0x02=port2, 0x10=port5)
101  *
102  * For Egress (KSZ9477 -> Host), 1 byte is added before FCS.
103  * ---------------------------------------------------------------------------
104  * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag0(1byte)|FCS(4bytes)
105  * ---------------------------------------------------------------------------
106  * tag0 : zero-based value represents port
107  *	  (eg, 0x00=port1, 0x02=port3, 0x06=port7)
108  */
109 
110 #define KSZ9477_INGRESS_TAG_LEN		2
111 #define KSZ9477_PTP_TAG_LEN		4
112 #define KSZ9477_PTP_TAG_INDICATION	0x80
113 
114 #define KSZ9477_TAIL_TAG_OVERRIDE	BIT(9)
115 #define KSZ9477_TAIL_TAG_LOOKUP		BIT(10)
116 
117 static struct sk_buff *ksz9477_xmit(struct sk_buff *skb,
118 				    struct net_device *dev)
119 {
120 	struct dsa_port *dp = dsa_slave_to_port(dev);
121 	__be16 *tag;
122 	u8 *addr;
123 	u16 val;
124 
125 	if (skb->ip_summed == CHECKSUM_PARTIAL && skb_checksum_help(skb))
126 		return NULL;
127 
128 	/* Tag encoding */
129 	tag = skb_put(skb, KSZ9477_INGRESS_TAG_LEN);
130 	addr = skb_mac_header(skb);
131 
132 	val = BIT(dp->index);
133 
134 	if (is_link_local_ether_addr(addr))
135 		val |= KSZ9477_TAIL_TAG_OVERRIDE;
136 
137 	*tag = cpu_to_be16(val);
138 
139 	return skb;
140 }
141 
142 static struct sk_buff *ksz9477_rcv(struct sk_buff *skb, struct net_device *dev)
143 {
144 	/* Tag decoding */
145 	u8 *tag = skb_tail_pointer(skb) - KSZ_EGRESS_TAG_LEN;
146 	unsigned int port = tag[0] & 7;
147 	unsigned int len = KSZ_EGRESS_TAG_LEN;
148 
149 	/* Extra 4-bytes PTP timestamp */
150 	if (tag[0] & KSZ9477_PTP_TAG_INDICATION)
151 		len += KSZ9477_PTP_TAG_LEN;
152 
153 	return ksz_common_rcv(skb, dev, port, len);
154 }
155 
156 static const struct dsa_device_ops ksz9477_netdev_ops = {
157 	.name	= KSZ9477_NAME,
158 	.proto	= DSA_TAG_PROTO_KSZ9477,
159 	.xmit	= ksz9477_xmit,
160 	.rcv	= ksz9477_rcv,
161 	.needed_tailroom = KSZ9477_INGRESS_TAG_LEN,
162 };
163 
164 DSA_TAG_DRIVER(ksz9477_netdev_ops);
165 MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_KSZ9477, KSZ9477_NAME);
166 
167 #define KSZ9893_TAIL_TAG_OVERRIDE	BIT(5)
168 #define KSZ9893_TAIL_TAG_LOOKUP		BIT(6)
169 
170 static struct sk_buff *ksz9893_xmit(struct sk_buff *skb,
171 				    struct net_device *dev)
172 {
173 	struct dsa_port *dp = dsa_slave_to_port(dev);
174 	u8 *addr;
175 	u8 *tag;
176 
177 	if (skb->ip_summed == CHECKSUM_PARTIAL && skb_checksum_help(skb))
178 		return NULL;
179 
180 	/* Tag encoding */
181 	tag = skb_put(skb, KSZ_INGRESS_TAG_LEN);
182 	addr = skb_mac_header(skb);
183 
184 	*tag = BIT(dp->index);
185 
186 	if (is_link_local_ether_addr(addr))
187 		*tag |= KSZ9893_TAIL_TAG_OVERRIDE;
188 
189 	return skb;
190 }
191 
192 static const struct dsa_device_ops ksz9893_netdev_ops = {
193 	.name	= KSZ9893_NAME,
194 	.proto	= DSA_TAG_PROTO_KSZ9893,
195 	.xmit	= ksz9893_xmit,
196 	.rcv	= ksz9477_rcv,
197 	.needed_tailroom = KSZ_INGRESS_TAG_LEN,
198 };
199 
200 DSA_TAG_DRIVER(ksz9893_netdev_ops);
201 MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_KSZ9893, KSZ9893_NAME);
202 
203 /* For xmit, 2 bytes are added before FCS.
204  * ---------------------------------------------------------------------------
205  * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag0(1byte)|tag1(1byte)|FCS(4bytes)
206  * ---------------------------------------------------------------------------
207  * tag0 : represents tag override, lookup and valid
208  * tag1 : each bit represents port (eg, 0x01=port1, 0x02=port2, 0x80=port8)
209  *
210  * For rcv, 1 byte is added before FCS.
211  * ---------------------------------------------------------------------------
212  * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag0(1byte)|FCS(4bytes)
213  * ---------------------------------------------------------------------------
214  * tag0 : zero-based value represents port
215  *	  (eg, 0x00=port1, 0x02=port3, 0x07=port8)
216  */
217 #define LAN937X_EGRESS_TAG_LEN		2
218 
219 #define LAN937X_TAIL_TAG_BLOCKING_OVERRIDE	BIT(11)
220 #define LAN937X_TAIL_TAG_LOOKUP			BIT(12)
221 #define LAN937X_TAIL_TAG_VALID			BIT(13)
222 #define LAN937X_TAIL_TAG_PORT_MASK		7
223 
224 static struct sk_buff *lan937x_xmit(struct sk_buff *skb,
225 				    struct net_device *dev)
226 {
227 	struct dsa_port *dp = dsa_slave_to_port(dev);
228 	const struct ethhdr *hdr = eth_hdr(skb);
229 	__be16 *tag;
230 	u16 val;
231 
232 	if (skb->ip_summed == CHECKSUM_PARTIAL && skb_checksum_help(skb))
233 		return NULL;
234 
235 	tag = skb_put(skb, LAN937X_EGRESS_TAG_LEN);
236 
237 	val = BIT(dp->index);
238 
239 	if (is_link_local_ether_addr(hdr->h_dest))
240 		val |= LAN937X_TAIL_TAG_BLOCKING_OVERRIDE;
241 
242 	/* Tail tag valid bit - This bit should always be set by the CPU */
243 	val |= LAN937X_TAIL_TAG_VALID;
244 
245 	put_unaligned_be16(val, tag);
246 
247 	return skb;
248 }
249 
250 static const struct dsa_device_ops lan937x_netdev_ops = {
251 	.name	= LAN937X_NAME,
252 	.proto	= DSA_TAG_PROTO_LAN937X,
253 	.xmit	= lan937x_xmit,
254 	.rcv	= ksz9477_rcv,
255 	.needed_tailroom = LAN937X_EGRESS_TAG_LEN,
256 };
257 
258 DSA_TAG_DRIVER(lan937x_netdev_ops);
259 MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_LAN937X, LAN937X_NAME);
260 
261 static struct dsa_tag_driver *dsa_tag_driver_array[] = {
262 	&DSA_TAG_DRIVER_NAME(ksz8795_netdev_ops),
263 	&DSA_TAG_DRIVER_NAME(ksz9477_netdev_ops),
264 	&DSA_TAG_DRIVER_NAME(ksz9893_netdev_ops),
265 	&DSA_TAG_DRIVER_NAME(lan937x_netdev_ops),
266 };
267 
268 module_dsa_tag_drivers(dsa_tag_driver_array);
269 
270 MODULE_LICENSE("GPL");
271