1 /* SPDX-License-Identifier: GPL-2.0
2  * Copyright 2019-2021 NXP Semiconductors
3  */
4 
5 #ifndef _NET_DSA_TAG_OCELOT_H
6 #define _NET_DSA_TAG_OCELOT_H
7 
8 #include <linux/packing.h>
9 
10 #define OCELOT_TAG_LEN			16
11 #define OCELOT_SHORT_PREFIX_LEN		4
12 #define OCELOT_LONG_PREFIX_LEN		16
13 #define OCELOT_TOTAL_TAG_LEN	(OCELOT_SHORT_PREFIX_LEN + OCELOT_TAG_LEN)
14 
15 /* The CPU injection header and the CPU extraction header can have 3 types of
16  * prefixes: long, short and no prefix. The format of the header itself is the
17  * same in all 3 cases.
18  *
19  * Extraction with long prefix:
20  *
21  * +-------------------+-------------------+------+------+------------+-------+
22  * | ff:ff:ff:ff:ff:ff | fe:ff:ff:ff:ff:ff | 8880 | 000a | extraction | frame |
23  * |                   |                   |      |      |   header   |       |
24  * +-------------------+-------------------+------+------+------------+-------+
25  *        48 bits             48 bits      16 bits 16 bits  128 bits
26  *
27  * Extraction with short prefix:
28  *
29  *                                         +------+------+------------+-------+
30  *                                         | 8880 | 000a | extraction | frame |
31  *                                         |      |      |   header   |       |
32  *                                         +------+------+------------+-------+
33  *                                         16 bits 16 bits  128 bits
34  *
35  * Extraction with no prefix:
36  *
37  *                                                       +------------+-------+
38  *                                                       | extraction | frame |
39  *                                                       |   header   |       |
40  *                                                       +------------+-------+
41  *                                                          128 bits
42  *
43  *
44  * Injection with long prefix:
45  *
46  * +-------------------+-------------------+------+------+------------+-------+
47  * |      any dmac     |      any smac     | 8880 | 000a | injection  | frame |
48  * |                   |                   |      |      |   header   |       |
49  * +-------------------+-------------------+------+------+------------+-------+
50  *        48 bits             48 bits      16 bits 16 bits  128 bits
51  *
52  * Injection with short prefix:
53  *
54  *                                         +------+------+------------+-------+
55  *                                         | 8880 | 000a | injection  | frame |
56  *                                         |      |      |   header   |       |
57  *                                         +------+------+------------+-------+
58  *                                         16 bits 16 bits  128 bits
59  *
60  * Injection with no prefix:
61  *
62  *                                                       +------------+-------+
63  *                                                       | injection  | frame |
64  *                                                       |   header   |       |
65  *                                                       +------------+-------+
66  *                                                          128 bits
67  *
68  * The injection header looks like this (network byte order, bit 127
69  * is part of lowest address byte in memory, bit 0 is part of highest
70  * address byte):
71  *
72  *         +------+------+------+------+------+------+------+------+
73  * 127:120 |BYPASS| MASQ |          MASQ_PORT        |REW_OP|REW_OP|
74  *         +------+------+------+------+------+------+------+------+
75  * 119:112 |                         REW_OP                        |
76  *         +------+------+------+------+------+------+------+------+
77  * 111:104 |                         REW_VAL                       |
78  *         +------+------+------+------+------+------+------+------+
79  * 103: 96 |                         REW_VAL                       |
80  *         +------+------+------+------+------+------+------+------+
81  *  95: 88 |                         REW_VAL                       |
82  *         +------+------+------+------+------+------+------+------+
83  *  87: 80 |                         REW_VAL                       |
84  *         +------+------+------+------+------+------+------+------+
85  *  79: 72 |                          RSV                          |
86  *         +------+------+------+------+------+------+------+------+
87  *  71: 64 |            RSV            |           DEST            |
88  *         +------+------+------+------+------+------+------+------+
89  *  63: 56 |                         DEST                          |
90  *         +------+------+------+------+------+------+------+------+
91  *  55: 48 |                          RSV                          |
92  *         +------+------+------+------+------+------+------+------+
93  *  47: 40 |  RSV |         SRC_PORT          |     RSV     |TFRM_TIMER|
94  *         +------+------+------+------+------+------+------+------+
95  *  39: 32 |     TFRM_TIMER     |               RSV                |
96  *         +------+------+------+------+------+------+------+------+
97  *  31: 24 |  RSV |  DP  |   POP_CNT   |           CPUQ            |
98  *         +------+------+------+------+------+------+------+------+
99  *  23: 16 |           CPUQ            |      QOS_CLASS     |TAG_TYPE|
100  *         +------+------+------+------+------+------+------+------+
101  *  15:  8 |         PCP        |  DEI |            VID            |
102  *         +------+------+------+------+------+------+------+------+
103  *   7:  0 |                          VID                          |
104  *         +------+------+------+------+------+------+------+------+
105  *
106  * And the extraction header looks like this:
107  *
108  *         +------+------+------+------+------+------+------+------+
109  * 127:120 |  RSV |                  REW_OP                        |
110  *         +------+------+------+------+------+------+------+------+
111  * 119:112 |       REW_OP       |              REW_VAL             |
112  *         +------+------+------+------+------+------+------+------+
113  * 111:104 |                         REW_VAL                       |
114  *         +------+------+------+------+------+------+------+------+
115  * 103: 96 |                         REW_VAL                       |
116  *         +------+------+------+------+------+------+------+------+
117  *  95: 88 |                         REW_VAL                       |
118  *         +------+------+------+------+------+------+------+------+
119  *  87: 80 |       REW_VAL      |               LLEN               |
120  *         +------+------+------+------+------+------+------+------+
121  *  79: 72 | LLEN |                      WLEN                      |
122  *         +------+------+------+------+------+------+------+------+
123  *  71: 64 | WLEN |                      RSV                       |
124  *         +------+------+------+------+------+------+------+------+
125  *  63: 56 |                          RSV                          |
126  *         +------+------+------+------+------+------+------+------+
127  *  55: 48 |                          RSV                          |
128  *         +------+------+------+------+------+------+------+------+
129  *  47: 40 | RSV  |          SRC_PORT         |       ACL_ID       |
130  *         +------+------+------+------+------+------+------+------+
131  *  39: 32 |       ACL_ID       |  RSV |         SFLOW_ID          |
132  *         +------+------+------+------+------+------+------+------+
133  *  31: 24 |ACL_HIT| DP  |  LRN_FLAGS  |           CPUQ            |
134  *         +------+------+------+------+------+------+------+------+
135  *  23: 16 |           CPUQ            |      QOS_CLASS     |TAG_TYPE|
136  *         +------+------+------+------+------+------+------+------+
137  *  15:  8 |         PCP        |  DEI |            VID            |
138  *         +------+------+------+------+------+------+------+------+
139  *   7:  0 |                          VID                          |
140  *         +------+------+------+------+------+------+------+------+
141  */
142 
ocelot_xfh_get_rew_val(void * extraction,u64 * rew_val)143 static inline void ocelot_xfh_get_rew_val(void *extraction, u64 *rew_val)
144 {
145 	packing(extraction, rew_val, 116, 85, OCELOT_TAG_LEN, UNPACK, 0);
146 }
147 
ocelot_xfh_get_len(void * extraction,u64 * len)148 static inline void ocelot_xfh_get_len(void *extraction, u64 *len)
149 {
150 	u64 llen, wlen;
151 
152 	packing(extraction, &llen, 84, 79, OCELOT_TAG_LEN, UNPACK, 0);
153 	packing(extraction, &wlen, 78, 71, OCELOT_TAG_LEN, UNPACK, 0);
154 
155 	*len = 60 * wlen + llen - 80;
156 }
157 
ocelot_xfh_get_src_port(void * extraction,u64 * src_port)158 static inline void ocelot_xfh_get_src_port(void *extraction, u64 *src_port)
159 {
160 	packing(extraction, src_port, 46, 43, OCELOT_TAG_LEN, UNPACK, 0);
161 }
162 
ocelot_xfh_get_qos_class(void * extraction,u64 * qos_class)163 static inline void ocelot_xfh_get_qos_class(void *extraction, u64 *qos_class)
164 {
165 	packing(extraction, qos_class, 19, 17, OCELOT_TAG_LEN, UNPACK, 0);
166 }
167 
ocelot_xfh_get_tag_type(void * extraction,u64 * tag_type)168 static inline void ocelot_xfh_get_tag_type(void *extraction, u64 *tag_type)
169 {
170 	packing(extraction, tag_type, 16, 16, OCELOT_TAG_LEN, UNPACK, 0);
171 }
172 
ocelot_xfh_get_vlan_tci(void * extraction,u64 * vlan_tci)173 static inline void ocelot_xfh_get_vlan_tci(void *extraction, u64 *vlan_tci)
174 {
175 	packing(extraction, vlan_tci, 15, 0, OCELOT_TAG_LEN, UNPACK, 0);
176 }
177 
ocelot_ifh_set_bypass(void * injection,u64 bypass)178 static inline void ocelot_ifh_set_bypass(void *injection, u64 bypass)
179 {
180 	packing(injection, &bypass, 127, 127, OCELOT_TAG_LEN, PACK, 0);
181 }
182 
ocelot_ifh_set_rew_op(void * injection,u64 rew_op)183 static inline void ocelot_ifh_set_rew_op(void *injection, u64 rew_op)
184 {
185 	packing(injection, &rew_op, 125, 117, OCELOT_TAG_LEN, PACK, 0);
186 }
187 
ocelot_ifh_set_dest(void * injection,u64 dest)188 static inline void ocelot_ifh_set_dest(void *injection, u64 dest)
189 {
190 	packing(injection, &dest, 67, 56, OCELOT_TAG_LEN, PACK, 0);
191 }
192 
ocelot_ifh_set_qos_class(void * injection,u64 qos_class)193 static inline void ocelot_ifh_set_qos_class(void *injection, u64 qos_class)
194 {
195 	packing(injection, &qos_class, 19, 17, OCELOT_TAG_LEN, PACK, 0);
196 }
197 
seville_ifh_set_dest(void * injection,u64 dest)198 static inline void seville_ifh_set_dest(void *injection, u64 dest)
199 {
200 	packing(injection, &dest, 67, 57, OCELOT_TAG_LEN, PACK, 0);
201 }
202 
ocelot_ifh_set_src(void * injection,u64 src)203 static inline void ocelot_ifh_set_src(void *injection, u64 src)
204 {
205 	packing(injection, &src, 46, 43, OCELOT_TAG_LEN, PACK, 0);
206 }
207 
ocelot_ifh_set_tag_type(void * injection,u64 tag_type)208 static inline void ocelot_ifh_set_tag_type(void *injection, u64 tag_type)
209 {
210 	packing(injection, &tag_type, 16, 16, OCELOT_TAG_LEN, PACK, 0);
211 }
212 
ocelot_ifh_set_vid(void * injection,u64 vid)213 static inline void ocelot_ifh_set_vid(void *injection, u64 vid)
214 {
215 	packing(injection, &vid, 11, 0, OCELOT_TAG_LEN, PACK, 0);
216 }
217 
218 #endif
219