1 /* SPDX-License-Identifier: GPL-2.0
2 * Copyright 2019-2021 NXP
3 */
4
5 #ifndef _NET_DSA_TAG_OCELOT_H
6 #define _NET_DSA_TAG_OCELOT_H
7
8 #include <linux/if_bridge.h>
9 #include <linux/if_vlan.h>
10 #include <linux/kthread.h>
11 #include <linux/packing.h>
12 #include <linux/skbuff.h>
13 #include <net/dsa.h>
14
15 struct ocelot_skb_cb {
16 struct sk_buff *clone;
17 unsigned int ptp_class; /* valid only for clones */
18 u32 tstamp_lo;
19 u8 ptp_cmd;
20 u8 ts_id;
21 };
22
23 #define OCELOT_SKB_CB(skb) \
24 ((struct ocelot_skb_cb *)((skb)->cb))
25
26 #define IFH_TAG_TYPE_C 0
27 #define IFH_TAG_TYPE_S 1
28
29 #define IFH_REW_OP_NOOP 0x0
30 #define IFH_REW_OP_DSCP 0x1
31 #define IFH_REW_OP_ONE_STEP_PTP 0x2
32 #define IFH_REW_OP_TWO_STEP_PTP 0x3
33 #define IFH_REW_OP_ORIGIN_PTP 0x5
34
35 #define OCELOT_TAG_LEN 16
36 #define OCELOT_SHORT_PREFIX_LEN 4
37 #define OCELOT_LONG_PREFIX_LEN 16
38 #define OCELOT_TOTAL_TAG_LEN (OCELOT_SHORT_PREFIX_LEN + OCELOT_TAG_LEN)
39
40 /* The CPU injection header and the CPU extraction header can have 3 types of
41 * prefixes: long, short and no prefix. The format of the header itself is the
42 * same in all 3 cases.
43 *
44 * Extraction with long prefix:
45 *
46 * +-------------------+-------------------+------+------+------------+-------+
47 * | ff:ff:ff:ff:ff:ff | fe:ff:ff:ff:ff:ff | 8880 | 000a | extraction | frame |
48 * | | | | | header | |
49 * +-------------------+-------------------+------+------+------------+-------+
50 * 48 bits 48 bits 16 bits 16 bits 128 bits
51 *
52 * Extraction with short prefix:
53 *
54 * +------+------+------------+-------+
55 * | 8880 | 000a | extraction | frame |
56 * | | | header | |
57 * +------+------+------------+-------+
58 * 16 bits 16 bits 128 bits
59 *
60 * Extraction with no prefix:
61 *
62 * +------------+-------+
63 * | extraction | frame |
64 * | header | |
65 * +------------+-------+
66 * 128 bits
67 *
68 *
69 * Injection with long prefix:
70 *
71 * +-------------------+-------------------+------+------+------------+-------+
72 * | any dmac | any smac | 8880 | 000a | injection | frame |
73 * | | | | | header | |
74 * +-------------------+-------------------+------+------+------------+-------+
75 * 48 bits 48 bits 16 bits 16 bits 128 bits
76 *
77 * Injection with short prefix:
78 *
79 * +------+------+------------+-------+
80 * | 8880 | 000a | injection | frame |
81 * | | | header | |
82 * +------+------+------------+-------+
83 * 16 bits 16 bits 128 bits
84 *
85 * Injection with no prefix:
86 *
87 * +------------+-------+
88 * | injection | frame |
89 * | header | |
90 * +------------+-------+
91 * 128 bits
92 *
93 * The injection header looks like this (network byte order, bit 127
94 * is part of lowest address byte in memory, bit 0 is part of highest
95 * address byte):
96 *
97 * +------+------+------+------+------+------+------+------+
98 * 127:120 |BYPASS| MASQ | MASQ_PORT |REW_OP|REW_OP|
99 * +------+------+------+------+------+------+------+------+
100 * 119:112 | REW_OP |
101 * +------+------+------+------+------+------+------+------+
102 * 111:104 | REW_VAL |
103 * +------+------+------+------+------+------+------+------+
104 * 103: 96 | REW_VAL |
105 * +------+------+------+------+------+------+------+------+
106 * 95: 88 | REW_VAL |
107 * +------+------+------+------+------+------+------+------+
108 * 87: 80 | REW_VAL |
109 * +------+------+------+------+------+------+------+------+
110 * 79: 72 | RSV |
111 * +------+------+------+------+------+------+------+------+
112 * 71: 64 | RSV | DEST |
113 * +------+------+------+------+------+------+------+------+
114 * 63: 56 | DEST |
115 * +------+------+------+------+------+------+------+------+
116 * 55: 48 | RSV |
117 * +------+------+------+------+------+------+------+------+
118 * 47: 40 | RSV | SRC_PORT | RSV |TFRM_TIMER|
119 * +------+------+------+------+------+------+------+------+
120 * 39: 32 | TFRM_TIMER | RSV |
121 * +------+------+------+------+------+------+------+------+
122 * 31: 24 | RSV | DP | POP_CNT | CPUQ |
123 * +------+------+------+------+------+------+------+------+
124 * 23: 16 | CPUQ | QOS_CLASS |TAG_TYPE|
125 * +------+------+------+------+------+------+------+------+
126 * 15: 8 | PCP | DEI | VID |
127 * +------+------+------+------+------+------+------+------+
128 * 7: 0 | VID |
129 * +------+------+------+------+------+------+------+------+
130 *
131 * And the extraction header looks like this:
132 *
133 * +------+------+------+------+------+------+------+------+
134 * 127:120 | RSV | REW_OP |
135 * +------+------+------+------+------+------+------+------+
136 * 119:112 | REW_OP | REW_VAL |
137 * +------+------+------+------+------+------+------+------+
138 * 111:104 | REW_VAL |
139 * +------+------+------+------+------+------+------+------+
140 * 103: 96 | REW_VAL |
141 * +------+------+------+------+------+------+------+------+
142 * 95: 88 | REW_VAL |
143 * +------+------+------+------+------+------+------+------+
144 * 87: 80 | REW_VAL | LLEN |
145 * +------+------+------+------+------+------+------+------+
146 * 79: 72 | LLEN | WLEN |
147 * +------+------+------+------+------+------+------+------+
148 * 71: 64 | WLEN | RSV |
149 * +------+------+------+------+------+------+------+------+
150 * 63: 56 | RSV |
151 * +------+------+------+------+------+------+------+------+
152 * 55: 48 | RSV |
153 * +------+------+------+------+------+------+------+------+
154 * 47: 40 | RSV | SRC_PORT | ACL_ID |
155 * +------+------+------+------+------+------+------+------+
156 * 39: 32 | ACL_ID | RSV | SFLOW_ID |
157 * +------+------+------+------+------+------+------+------+
158 * 31: 24 |ACL_HIT| DP | LRN_FLAGS | CPUQ |
159 * +------+------+------+------+------+------+------+------+
160 * 23: 16 | CPUQ | QOS_CLASS |TAG_TYPE|
161 * +------+------+------+------+------+------+------+------+
162 * 15: 8 | PCP | DEI | VID |
163 * +------+------+------+------+------+------+------+------+
164 * 7: 0 | VID |
165 * +------+------+------+------+------+------+------+------+
166 */
167
168 struct felix_deferred_xmit_work {
169 struct dsa_port *dp;
170 struct sk_buff *skb;
171 struct kthread_work work;
172 };
173
174 struct ocelot_8021q_tagger_data {
175 void (*xmit_work_fn)(struct kthread_work *work);
176 };
177
178 static inline struct ocelot_8021q_tagger_data *
ocelot_8021q_tagger_data(struct dsa_switch * ds)179 ocelot_8021q_tagger_data(struct dsa_switch *ds)
180 {
181 BUG_ON(ds->dst->tag_ops->proto != DSA_TAG_PROTO_OCELOT_8021Q);
182
183 return ds->tagger_data;
184 }
185
ocelot_xfh_get_rew_val(void * extraction,u64 * rew_val)186 static inline void ocelot_xfh_get_rew_val(void *extraction, u64 *rew_val)
187 {
188 packing(extraction, rew_val, 116, 85, OCELOT_TAG_LEN, UNPACK, 0);
189 }
190
ocelot_xfh_get_len(void * extraction,u64 * len)191 static inline void ocelot_xfh_get_len(void *extraction, u64 *len)
192 {
193 u64 llen, wlen;
194
195 packing(extraction, &llen, 84, 79, OCELOT_TAG_LEN, UNPACK, 0);
196 packing(extraction, &wlen, 78, 71, OCELOT_TAG_LEN, UNPACK, 0);
197
198 *len = 60 * wlen + llen - 80;
199 }
200
ocelot_xfh_get_src_port(void * extraction,u64 * src_port)201 static inline void ocelot_xfh_get_src_port(void *extraction, u64 *src_port)
202 {
203 packing(extraction, src_port, 46, 43, OCELOT_TAG_LEN, UNPACK, 0);
204 }
205
ocelot_xfh_get_qos_class(void * extraction,u64 * qos_class)206 static inline void ocelot_xfh_get_qos_class(void *extraction, u64 *qos_class)
207 {
208 packing(extraction, qos_class, 19, 17, OCELOT_TAG_LEN, UNPACK, 0);
209 }
210
ocelot_xfh_get_tag_type(void * extraction,u64 * tag_type)211 static inline void ocelot_xfh_get_tag_type(void *extraction, u64 *tag_type)
212 {
213 packing(extraction, tag_type, 16, 16, OCELOT_TAG_LEN, UNPACK, 0);
214 }
215
ocelot_xfh_get_vlan_tci(void * extraction,u64 * vlan_tci)216 static inline void ocelot_xfh_get_vlan_tci(void *extraction, u64 *vlan_tci)
217 {
218 packing(extraction, vlan_tci, 15, 0, OCELOT_TAG_LEN, UNPACK, 0);
219 }
220
ocelot_ifh_set_bypass(void * injection,u64 bypass)221 static inline void ocelot_ifh_set_bypass(void *injection, u64 bypass)
222 {
223 packing(injection, &bypass, 127, 127, OCELOT_TAG_LEN, PACK, 0);
224 }
225
ocelot_ifh_set_rew_op(void * injection,u64 rew_op)226 static inline void ocelot_ifh_set_rew_op(void *injection, u64 rew_op)
227 {
228 packing(injection, &rew_op, 125, 117, OCELOT_TAG_LEN, PACK, 0);
229 }
230
ocelot_ifh_set_dest(void * injection,u64 dest)231 static inline void ocelot_ifh_set_dest(void *injection, u64 dest)
232 {
233 packing(injection, &dest, 67, 56, OCELOT_TAG_LEN, PACK, 0);
234 }
235
ocelot_ifh_set_qos_class(void * injection,u64 qos_class)236 static inline void ocelot_ifh_set_qos_class(void *injection, u64 qos_class)
237 {
238 packing(injection, &qos_class, 19, 17, OCELOT_TAG_LEN, PACK, 0);
239 }
240
seville_ifh_set_dest(void * injection,u64 dest)241 static inline void seville_ifh_set_dest(void *injection, u64 dest)
242 {
243 packing(injection, &dest, 67, 57, OCELOT_TAG_LEN, PACK, 0);
244 }
245
ocelot_ifh_set_src(void * injection,u64 src)246 static inline void ocelot_ifh_set_src(void *injection, u64 src)
247 {
248 packing(injection, &src, 46, 43, OCELOT_TAG_LEN, PACK, 0);
249 }
250
ocelot_ifh_set_tag_type(void * injection,u64 tag_type)251 static inline void ocelot_ifh_set_tag_type(void *injection, u64 tag_type)
252 {
253 packing(injection, &tag_type, 16, 16, OCELOT_TAG_LEN, PACK, 0);
254 }
255
ocelot_ifh_set_vlan_tci(void * injection,u64 vlan_tci)256 static inline void ocelot_ifh_set_vlan_tci(void *injection, u64 vlan_tci)
257 {
258 packing(injection, &vlan_tci, 15, 0, OCELOT_TAG_LEN, PACK, 0);
259 }
260
261 /* Determine the PTP REW_OP to use for injecting the given skb */
ocelot_ptp_rew_op(struct sk_buff * skb)262 static inline u32 ocelot_ptp_rew_op(struct sk_buff *skb)
263 {
264 struct sk_buff *clone = OCELOT_SKB_CB(skb)->clone;
265 u8 ptp_cmd = OCELOT_SKB_CB(skb)->ptp_cmd;
266 u32 rew_op = 0;
267
268 if (ptp_cmd == IFH_REW_OP_TWO_STEP_PTP && clone) {
269 rew_op = ptp_cmd;
270 rew_op |= OCELOT_SKB_CB(clone)->ts_id << 3;
271 } else if (ptp_cmd == IFH_REW_OP_ORIGIN_PTP) {
272 rew_op = ptp_cmd;
273 }
274
275 return rew_op;
276 }
277
278 /**
279 * ocelot_xmit_get_vlan_info: Determine VLAN_TCI and TAG_TYPE for injected frame
280 * @skb: Pointer to socket buffer
281 * @br: Pointer to bridge device that the port is under, if any
282 * @vlan_tci:
283 * @tag_type:
284 *
285 * If the port is under a VLAN-aware bridge, remove the VLAN header from the
286 * payload and move it into the DSA tag, which will make the switch classify
287 * the packet to the bridge VLAN. Otherwise, leave the classified VLAN at zero,
288 * which is the pvid of standalone ports (OCELOT_STANDALONE_PVID), although not
289 * of VLAN-unaware bridge ports (that would be ocelot_vlan_unaware_pvid()).
290 * Anyway, VID 0 is fine because it is stripped on egress for these port modes,
291 * and source address learning is not performed for packets injected from the
292 * CPU anyway, so it doesn't matter that the VID is "wrong".
293 */
ocelot_xmit_get_vlan_info(struct sk_buff * skb,struct net_device * br,u64 * vlan_tci,u64 * tag_type)294 static inline void ocelot_xmit_get_vlan_info(struct sk_buff *skb,
295 struct net_device *br,
296 u64 *vlan_tci, u64 *tag_type)
297 {
298 struct vlan_ethhdr *hdr;
299 u16 proto, tci;
300
301 if (!br || !br_vlan_enabled(br)) {
302 *vlan_tci = 0;
303 *tag_type = IFH_TAG_TYPE_C;
304 return;
305 }
306
307 hdr = (struct vlan_ethhdr *)skb_mac_header(skb);
308 br_vlan_get_proto(br, &proto);
309
310 if (ntohs(hdr->h_vlan_proto) == proto) {
311 vlan_remove_tag(skb, &tci);
312 *vlan_tci = tci;
313 } else {
314 rcu_read_lock();
315 br_vlan_get_pvid_rcu(br, &tci);
316 rcu_read_unlock();
317 *vlan_tci = tci;
318 }
319
320 *tag_type = (proto != ETH_P_8021Q) ? IFH_TAG_TYPE_S : IFH_TAG_TYPE_C;
321 }
322
323 #endif
324