GNU Linux-libre 5.15.54-gnu
[releases.git] / include / linux / dsa / ocelot.h
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/kthread.h>
9 #include <linux/packing.h>
10 #include <linux/skbuff.h>
11
12 struct ocelot_skb_cb {
13         struct sk_buff *clone;
14         unsigned int ptp_class; /* valid only for clones */
15         u32 tstamp_lo;
16         u8 ptp_cmd;
17         u8 ts_id;
18 };
19
20 #define OCELOT_SKB_CB(skb) \
21         ((struct ocelot_skb_cb *)((skb)->cb))
22
23 #define IFH_TAG_TYPE_C                  0
24 #define IFH_TAG_TYPE_S                  1
25
26 #define IFH_REW_OP_NOOP                 0x0
27 #define IFH_REW_OP_DSCP                 0x1
28 #define IFH_REW_OP_ONE_STEP_PTP         0x2
29 #define IFH_REW_OP_TWO_STEP_PTP         0x3
30 #define IFH_REW_OP_ORIGIN_PTP           0x5
31
32 #define OCELOT_TAG_LEN                  16
33 #define OCELOT_SHORT_PREFIX_LEN         4
34 #define OCELOT_LONG_PREFIX_LEN          16
35 #define OCELOT_TOTAL_TAG_LEN    (OCELOT_SHORT_PREFIX_LEN + OCELOT_TAG_LEN)
36
37 /* The CPU injection header and the CPU extraction header can have 3 types of
38  * prefixes: long, short and no prefix. The format of the header itself is the
39  * same in all 3 cases.
40  *
41  * Extraction with long prefix:
42  *
43  * +-------------------+-------------------+------+------+------------+-------+
44  * | ff:ff:ff:ff:ff:ff | fe:ff:ff:ff:ff:ff | 8880 | 000a | extraction | frame |
45  * |                   |                   |      |      |   header   |       |
46  * +-------------------+-------------------+------+------+------------+-------+
47  *        48 bits             48 bits      16 bits 16 bits  128 bits
48  *
49  * Extraction with short prefix:
50  *
51  *                                         +------+------+------------+-------+
52  *                                         | 8880 | 000a | extraction | frame |
53  *                                         |      |      |   header   |       |
54  *                                         +------+------+------------+-------+
55  *                                         16 bits 16 bits  128 bits
56  *
57  * Extraction with no prefix:
58  *
59  *                                                       +------------+-------+
60  *                                                       | extraction | frame |
61  *                                                       |   header   |       |
62  *                                                       +------------+-------+
63  *                                                          128 bits
64  *
65  *
66  * Injection with long prefix:
67  *
68  * +-------------------+-------------------+------+------+------------+-------+
69  * |      any dmac     |      any smac     | 8880 | 000a | injection  | frame |
70  * |                   |                   |      |      |   header   |       |
71  * +-------------------+-------------------+------+------+------------+-------+
72  *        48 bits             48 bits      16 bits 16 bits  128 bits
73  *
74  * Injection with short prefix:
75  *
76  *                                         +------+------+------------+-------+
77  *                                         | 8880 | 000a | injection  | frame |
78  *                                         |      |      |   header   |       |
79  *                                         +------+------+------------+-------+
80  *                                         16 bits 16 bits  128 bits
81  *
82  * Injection with no prefix:
83  *
84  *                                                       +------------+-------+
85  *                                                       | injection  | frame |
86  *                                                       |   header   |       |
87  *                                                       +------------+-------+
88  *                                                          128 bits
89  *
90  * The injection header looks like this (network byte order, bit 127
91  * is part of lowest address byte in memory, bit 0 is part of highest
92  * address byte):
93  *
94  *         +------+------+------+------+------+------+------+------+
95  * 127:120 |BYPASS| MASQ |          MASQ_PORT        |REW_OP|REW_OP|
96  *         +------+------+------+------+------+------+------+------+
97  * 119:112 |                         REW_OP                        |
98  *         +------+------+------+------+------+------+------+------+
99  * 111:104 |                         REW_VAL                       |
100  *         +------+------+------+------+------+------+------+------+
101  * 103: 96 |                         REW_VAL                       |
102  *         +------+------+------+------+------+------+------+------+
103  *  95: 88 |                         REW_VAL                       |
104  *         +------+------+------+------+------+------+------+------+
105  *  87: 80 |                         REW_VAL                       |
106  *         +------+------+------+------+------+------+------+------+
107  *  79: 72 |                          RSV                          |
108  *         +------+------+------+------+------+------+------+------+
109  *  71: 64 |            RSV            |           DEST            |
110  *         +------+------+------+------+------+------+------+------+
111  *  63: 56 |                         DEST                          |
112  *         +------+------+------+------+------+------+------+------+
113  *  55: 48 |                          RSV                          |
114  *         +------+------+------+------+------+------+------+------+
115  *  47: 40 |  RSV |         SRC_PORT          |     RSV     |TFRM_TIMER|
116  *         +------+------+------+------+------+------+------+------+
117  *  39: 32 |     TFRM_TIMER     |               RSV                |
118  *         +------+------+------+------+------+------+------+------+
119  *  31: 24 |  RSV |  DP  |   POP_CNT   |           CPUQ            |
120  *         +------+------+------+------+------+------+------+------+
121  *  23: 16 |           CPUQ            |      QOS_CLASS     |TAG_TYPE|
122  *         +------+------+------+------+------+------+------+------+
123  *  15:  8 |         PCP        |  DEI |            VID            |
124  *         +------+------+------+------+------+------+------+------+
125  *   7:  0 |                          VID                          |
126  *         +------+------+------+------+------+------+------+------+
127  *
128  * And the extraction header looks like this:
129  *
130  *         +------+------+------+------+------+------+------+------+
131  * 127:120 |  RSV |                  REW_OP                        |
132  *         +------+------+------+------+------+------+------+------+
133  * 119:112 |       REW_OP       |              REW_VAL             |
134  *         +------+------+------+------+------+------+------+------+
135  * 111:104 |                         REW_VAL                       |
136  *         +------+------+------+------+------+------+------+------+
137  * 103: 96 |                         REW_VAL                       |
138  *         +------+------+------+------+------+------+------+------+
139  *  95: 88 |                         REW_VAL                       |
140  *         +------+------+------+------+------+------+------+------+
141  *  87: 80 |       REW_VAL      |               LLEN               |
142  *         +------+------+------+------+------+------+------+------+
143  *  79: 72 | LLEN |                      WLEN                      |
144  *         +------+------+------+------+------+------+------+------+
145  *  71: 64 | WLEN |                      RSV                       |
146  *         +------+------+------+------+------+------+------+------+
147  *  63: 56 |                          RSV                          |
148  *         +------+------+------+------+------+------+------+------+
149  *  55: 48 |                          RSV                          |
150  *         +------+------+------+------+------+------+------+------+
151  *  47: 40 | RSV  |          SRC_PORT         |       ACL_ID       |
152  *         +------+------+------+------+------+------+------+------+
153  *  39: 32 |       ACL_ID       |  RSV |         SFLOW_ID          |
154  *         +------+------+------+------+------+------+------+------+
155  *  31: 24 |ACL_HIT| DP  |  LRN_FLAGS  |           CPUQ            |
156  *         +------+------+------+------+------+------+------+------+
157  *  23: 16 |           CPUQ            |      QOS_CLASS     |TAG_TYPE|
158  *         +------+------+------+------+------+------+------+------+
159  *  15:  8 |         PCP        |  DEI |            VID            |
160  *         +------+------+------+------+------+------+------+------+
161  *   7:  0 |                          VID                          |
162  *         +------+------+------+------+------+------+------+------+
163  */
164
165 struct felix_deferred_xmit_work {
166         struct dsa_port *dp;
167         struct sk_buff *skb;
168         struct kthread_work work;
169 };
170
171 struct felix_port {
172         void (*xmit_work_fn)(struct kthread_work *work);
173         struct kthread_worker *xmit_worker;
174 };
175
176 static inline void ocelot_xfh_get_rew_val(void *extraction, u64 *rew_val)
177 {
178         packing(extraction, rew_val, 116, 85, OCELOT_TAG_LEN, UNPACK, 0);
179 }
180
181 static inline void ocelot_xfh_get_len(void *extraction, u64 *len)
182 {
183         u64 llen, wlen;
184
185         packing(extraction, &llen, 84, 79, OCELOT_TAG_LEN, UNPACK, 0);
186         packing(extraction, &wlen, 78, 71, OCELOT_TAG_LEN, UNPACK, 0);
187
188         *len = 60 * wlen + llen - 80;
189 }
190
191 static inline void ocelot_xfh_get_src_port(void *extraction, u64 *src_port)
192 {
193         packing(extraction, src_port, 46, 43, OCELOT_TAG_LEN, UNPACK, 0);
194 }
195
196 static inline void ocelot_xfh_get_qos_class(void *extraction, u64 *qos_class)
197 {
198         packing(extraction, qos_class, 19, 17, OCELOT_TAG_LEN, UNPACK, 0);
199 }
200
201 static inline void ocelot_xfh_get_tag_type(void *extraction, u64 *tag_type)
202 {
203         packing(extraction, tag_type, 16, 16, OCELOT_TAG_LEN, UNPACK, 0);
204 }
205
206 static inline void ocelot_xfh_get_vlan_tci(void *extraction, u64 *vlan_tci)
207 {
208         packing(extraction, vlan_tci, 15, 0, OCELOT_TAG_LEN, UNPACK, 0);
209 }
210
211 static inline void ocelot_ifh_set_bypass(void *injection, u64 bypass)
212 {
213         packing(injection, &bypass, 127, 127, OCELOT_TAG_LEN, PACK, 0);
214 }
215
216 static inline void ocelot_ifh_set_rew_op(void *injection, u64 rew_op)
217 {
218         packing(injection, &rew_op, 125, 117, OCELOT_TAG_LEN, PACK, 0);
219 }
220
221 static inline void ocelot_ifh_set_dest(void *injection, u64 dest)
222 {
223         packing(injection, &dest, 67, 56, OCELOT_TAG_LEN, PACK, 0);
224 }
225
226 static inline void ocelot_ifh_set_qos_class(void *injection, u64 qos_class)
227 {
228         packing(injection, &qos_class, 19, 17, OCELOT_TAG_LEN, PACK, 0);
229 }
230
231 static inline void seville_ifh_set_dest(void *injection, u64 dest)
232 {
233         packing(injection, &dest, 67, 57, OCELOT_TAG_LEN, PACK, 0);
234 }
235
236 static inline void ocelot_ifh_set_src(void *injection, u64 src)
237 {
238         packing(injection, &src, 46, 43, OCELOT_TAG_LEN, PACK, 0);
239 }
240
241 static inline void ocelot_ifh_set_tag_type(void *injection, u64 tag_type)
242 {
243         packing(injection, &tag_type, 16, 16, OCELOT_TAG_LEN, PACK, 0);
244 }
245
246 static inline void ocelot_ifh_set_vid(void *injection, u64 vid)
247 {
248         packing(injection, &vid, 11, 0, OCELOT_TAG_LEN, PACK, 0);
249 }
250
251 /* Determine the PTP REW_OP to use for injecting the given skb */
252 static inline u32 ocelot_ptp_rew_op(struct sk_buff *skb)
253 {
254         struct sk_buff *clone = OCELOT_SKB_CB(skb)->clone;
255         u8 ptp_cmd = OCELOT_SKB_CB(skb)->ptp_cmd;
256         u32 rew_op = 0;
257
258         if (ptp_cmd == IFH_REW_OP_TWO_STEP_PTP && clone) {
259                 rew_op = ptp_cmd;
260                 rew_op |= OCELOT_SKB_CB(clone)->ts_id << 3;
261         } else if (ptp_cmd == IFH_REW_OP_ORIGIN_PTP) {
262                 rew_op = ptp_cmd;
263         }
264
265         return rew_op;
266 }
267
268 #endif