]> Git Repo - linux.git/blob - net/dsa/tag_ksz.c
net: ipa: add IPA v4.7 support
[linux.git] / net / dsa / tag_ksz.c
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");
This page took 0.044824 seconds and 4 git commands to generate.