Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2021 Marvell.
3 : : */
4 : :
5 : : #include <rte_common.h>
6 : : #include <rte_memzone.h>
7 : :
8 : : #include "cnxk_ethdev.h"
9 : :
10 : : #define LOOKUP_ARRAY_SZ (PTYPE_ARRAY_SZ + ERR_ARRAY_SZ + SA_BASE_TBL_SZ + MEMPOOL_TBL_SZ)
11 : : const uint32_t *
12 : 0 : cnxk_nix_supported_ptypes_get(struct rte_eth_dev *eth_dev)
13 : : {
14 : : RTE_SET_USED(eth_dev);
15 : :
16 : : static const uint32_t ptypes[] = {
17 : : RTE_PTYPE_L2_ETHER, /* LA */
18 : : RTE_PTYPE_L2_ETHER_QINQ, /* LB */
19 : : RTE_PTYPE_L2_ETHER_VLAN, /* LB */
20 : : RTE_PTYPE_L2_ETHER_TIMESYNC, /* LB */
21 : : RTE_PTYPE_L2_ETHER_ARP, /* LC */
22 : : RTE_PTYPE_L2_ETHER_NSH, /* LC */
23 : : RTE_PTYPE_L2_ETHER_FCOE, /* LC */
24 : : RTE_PTYPE_L2_ETHER_MPLS, /* LC */
25 : : RTE_PTYPE_L3_IPV4, /* LC */
26 : : RTE_PTYPE_L3_IPV4_EXT, /* LC */
27 : : RTE_PTYPE_L3_IPV6, /* LC */
28 : : RTE_PTYPE_L3_IPV6_EXT, /* LC */
29 : : RTE_PTYPE_L4_TCP, /* LD */
30 : : RTE_PTYPE_L4_UDP, /* LD */
31 : : RTE_PTYPE_L4_SCTP, /* LD */
32 : : RTE_PTYPE_L4_ICMP, /* LD */
33 : : RTE_PTYPE_L4_IGMP, /* LD */
34 : : RTE_PTYPE_TUNNEL_GRE, /* LD */
35 : : RTE_PTYPE_TUNNEL_ESP, /* LD */
36 : : RTE_PTYPE_TUNNEL_NVGRE, /* LD */
37 : : RTE_PTYPE_TUNNEL_VXLAN, /* LE */
38 : : RTE_PTYPE_TUNNEL_GENEVE, /* LE */
39 : : RTE_PTYPE_TUNNEL_GTPC, /* LE */
40 : : RTE_PTYPE_TUNNEL_GTPU, /* LE */
41 : : RTE_PTYPE_TUNNEL_VXLAN_GPE, /* LE */
42 : : RTE_PTYPE_TUNNEL_MPLS_IN_GRE, /* LE */
43 : : RTE_PTYPE_TUNNEL_MPLS_IN_UDP, /* LE */
44 : : RTE_PTYPE_INNER_L2_ETHER, /* LF */
45 : : RTE_PTYPE_INNER_L3_IPV4, /* LG */
46 : : RTE_PTYPE_INNER_L3_IPV6, /* LG */
47 : : RTE_PTYPE_INNER_L4_TCP, /* LH */
48 : : RTE_PTYPE_INNER_L4_UDP, /* LH */
49 : : RTE_PTYPE_INNER_L4_SCTP, /* LH */
50 : : RTE_PTYPE_INNER_L4_ICMP, /* LH */
51 : : RTE_PTYPE_UNKNOWN,
52 : : };
53 : :
54 : 0 : return ptypes;
55 : : }
56 : :
57 : : /*
58 : : * +------------------ +------------------ +
59 : : * | | IL4 | IL3| IL2 | TU | L4 | L3 | L2 |
60 : : * +-------------------+-------------------+
61 : : *
62 : : * +-------------------+------------------ +
63 : : * | | LH | LG | LF | LE | LD | LC | LB |
64 : : * +-------------------+-------------------+
65 : : *
66 : : * ptype [LE - LD - LC - LB] = TU - L4 - L3 - T2
67 : : * ptype_tunnel[LH - LG - LF] = IL4 - IL3 - IL2 - TU
68 : : *
69 : : */
70 : : static void
71 : 0 : nix_create_non_tunnel_ptype_array(uint16_t *ptype)
72 : : {
73 : : uint8_t lb, lc, ld, le;
74 : : uint16_t val;
75 : : uint32_t idx;
76 : :
77 [ # # ]: 0 : for (idx = 0; idx < PTYPE_NON_TUNNEL_ARRAY_SZ; idx++) {
78 : 0 : lb = idx & 0xF;
79 : 0 : lc = (idx & 0xF0) >> 4;
80 : 0 : ld = (idx & 0xF00) >> 8;
81 : 0 : le = (idx & 0xF000) >> 12;
82 : : val = RTE_PTYPE_UNKNOWN;
83 : :
84 [ # # # ]: 0 : switch (lb) {
85 : : case NPC_LT_LB_STAG_QINQ:
86 : : val |= RTE_PTYPE_L2_ETHER_QINQ;
87 : : break;
88 : 0 : case NPC_LT_LB_CTAG:
89 : : val |= RTE_PTYPE_L2_ETHER_VLAN;
90 : 0 : break;
91 : 0 : default:
92 : : val |= RTE_PTYPE_L2_ETHER;
93 : : }
94 : :
95 [ # # # # : 0 : switch (lc) {
# # # # #
# ]
96 : 0 : case NPC_LT_LC_ARP:
97 : : val = (val & ~RTE_PTYPE_L2_MASK);
98 : : val |= RTE_PTYPE_L2_ETHER_ARP;
99 : 0 : break;
100 : 0 : case NPC_LT_LC_NSH:
101 : : val = (val & ~RTE_PTYPE_L2_MASK);
102 : : val |= RTE_PTYPE_L2_ETHER_NSH;
103 : 0 : break;
104 : 0 : case NPC_LT_LC_FCOE:
105 : : val = (val & ~RTE_PTYPE_L2_MASK);
106 : : val |= RTE_PTYPE_L2_ETHER_FCOE;
107 : 0 : break;
108 : 0 : case NPC_LT_LC_MPLS:
109 : : val = (val & ~RTE_PTYPE_L2_MASK);
110 : : val |= RTE_PTYPE_L2_ETHER_MPLS;
111 : 0 : break;
112 : 0 : case NPC_LT_LC_IP:
113 : 0 : val |= RTE_PTYPE_L3_IPV4;
114 : 0 : break;
115 : 0 : case NPC_LT_LC_IP_OPT:
116 : 0 : val |= RTE_PTYPE_L3_IPV4_EXT;
117 : 0 : break;
118 : 0 : case NPC_LT_LC_IP6:
119 : 0 : val |= RTE_PTYPE_L3_IPV6;
120 : 0 : break;
121 : 0 : case NPC_LT_LC_IP6_EXT:
122 : 0 : val |= RTE_PTYPE_L3_IPV6_EXT;
123 : 0 : break;
124 : 0 : case NPC_LT_LC_PTP:
125 : : val = (val & ~RTE_PTYPE_L2_MASK);
126 : : val |= RTE_PTYPE_L2_ETHER_TIMESYNC;
127 : 0 : break;
128 : : }
129 : :
130 [ # # # # : 0 : switch (ld) {
# # # # ]
131 : 0 : case NPC_LT_LD_TCP:
132 : 0 : val |= RTE_PTYPE_L4_TCP;
133 : 0 : break;
134 : 0 : case NPC_LT_LD_UDP:
135 : 0 : val |= RTE_PTYPE_L4_UDP;
136 : 0 : break;
137 : 0 : case NPC_LT_LD_SCTP:
138 : 0 : val |= RTE_PTYPE_L4_SCTP;
139 : 0 : break;
140 : 0 : case NPC_LT_LD_ICMP:
141 : : case NPC_LT_LD_ICMP6:
142 : 0 : val |= RTE_PTYPE_L4_ICMP;
143 : 0 : break;
144 : 0 : case NPC_LT_LD_IGMP:
145 : 0 : val |= RTE_PTYPE_L4_IGMP;
146 : 0 : break;
147 : 0 : case NPC_LT_LD_GRE:
148 : 0 : val |= RTE_PTYPE_TUNNEL_GRE;
149 : 0 : break;
150 : 0 : case NPC_LT_LD_NVGRE:
151 : 0 : val |= RTE_PTYPE_TUNNEL_NVGRE;
152 : 0 : break;
153 : : }
154 : :
155 [ # # # # : 0 : switch (le) {
# # # #
# ]
156 : 0 : case NPC_LT_LE_VXLAN:
157 : 0 : val |= RTE_PTYPE_TUNNEL_VXLAN;
158 : 0 : break;
159 : 0 : case NPC_LT_LE_ESP:
160 : 0 : val |= RTE_PTYPE_TUNNEL_ESP;
161 : 0 : break;
162 : 0 : case NPC_LT_LE_VXLANGPE:
163 : 0 : val |= RTE_PTYPE_TUNNEL_VXLAN_GPE;
164 : 0 : break;
165 : 0 : case NPC_LT_LE_GENEVE:
166 : 0 : val |= RTE_PTYPE_TUNNEL_GENEVE;
167 : 0 : break;
168 : 0 : case NPC_LT_LE_GTPC:
169 : 0 : val |= RTE_PTYPE_TUNNEL_GTPC;
170 : 0 : break;
171 : 0 : case NPC_LT_LE_GTPU:
172 : 0 : val |= RTE_PTYPE_TUNNEL_GTPU;
173 : 0 : break;
174 : 0 : case NPC_LT_LE_TU_MPLS_IN_GRE:
175 : 0 : val |= RTE_PTYPE_TUNNEL_MPLS_IN_GRE;
176 : 0 : break;
177 : 0 : case NPC_LT_LE_TU_MPLS_IN_UDP:
178 : 0 : val |= RTE_PTYPE_TUNNEL_MPLS_IN_UDP;
179 : 0 : break;
180 : : }
181 : 0 : ptype[idx] = val;
182 : : }
183 : 0 : }
184 : :
185 : : #define TU_SHIFT(x) ((x) >> PTYPE_NON_TUNNEL_WIDTH)
186 : : static void
187 : 0 : nix_create_tunnel_ptype_array(uint16_t *ptype)
188 : : {
189 : : uint8_t lf, lg, lh;
190 : : uint16_t val;
191 : : uint32_t idx;
192 : :
193 : : /* Skip non tunnel ptype array memory */
194 : : ptype = ptype + PTYPE_NON_TUNNEL_ARRAY_SZ;
195 : :
196 [ # # ]: 0 : for (idx = 0; idx < PTYPE_TUNNEL_ARRAY_SZ; idx++) {
197 : 0 : lf = idx & 0xF;
198 : 0 : lg = (idx & 0xF0) >> 4;
199 : 0 : lh = (idx & 0xF00) >> 8;
200 : : val = RTE_PTYPE_UNKNOWN;
201 : :
202 [ # # ]: 0 : switch (lf) {
203 : 0 : case NPC_LT_LF_TU_ETHER:
204 : : val |= TU_SHIFT(RTE_PTYPE_INNER_L2_ETHER);
205 : 0 : break;
206 : : }
207 [ # # # ]: 0 : switch (lg) {
208 : 0 : case NPC_LT_LG_TU_IP:
209 : 0 : val |= TU_SHIFT(RTE_PTYPE_INNER_L3_IPV4);
210 : 0 : break;
211 : 0 : case NPC_LT_LG_TU_IP6:
212 : 0 : val |= TU_SHIFT(RTE_PTYPE_INNER_L3_IPV6);
213 : 0 : break;
214 : : }
215 [ # # # # : 0 : switch (lh) {
# ]
216 : 0 : case NPC_LT_LH_TU_TCP:
217 : 0 : val |= TU_SHIFT(RTE_PTYPE_INNER_L4_TCP);
218 : 0 : break;
219 : 0 : case NPC_LT_LH_TU_UDP:
220 : 0 : val |= TU_SHIFT(RTE_PTYPE_INNER_L4_UDP);
221 : 0 : break;
222 : 0 : case NPC_LT_LH_TU_SCTP:
223 : 0 : val |= TU_SHIFT(RTE_PTYPE_INNER_L4_SCTP);
224 : 0 : break;
225 : 0 : case NPC_LT_LH_TU_ICMP:
226 : : case NPC_LT_LH_TU_ICMP6:
227 : 0 : val |= TU_SHIFT(RTE_PTYPE_INNER_L4_ICMP);
228 : 0 : break;
229 : : }
230 : :
231 : 0 : ptype[idx] = val;
232 : : }
233 : 0 : }
234 : :
235 : : static void
236 : 0 : nix_create_rx_ol_flags_array(void *mem)
237 : : {
238 : : uint16_t idx, errcode, errlev;
239 : : uint32_t val, *ol_flags;
240 : :
241 : : /* Skip ptype array memory */
242 : : ol_flags = (uint32_t *)((uint8_t *)mem + PTYPE_ARRAY_SZ);
243 : :
244 [ # # ]: 0 : for (idx = 0; idx < BIT(ERRCODE_ERRLEN_WIDTH); idx++) {
245 : 0 : errlev = idx & 0xf;
246 : 0 : errcode = (idx & 0xff0) >> 4;
247 : :
248 : : val = RTE_MBUF_F_RX_IP_CKSUM_UNKNOWN;
249 : : val |= RTE_MBUF_F_RX_L4_CKSUM_UNKNOWN;
250 : : val |= RTE_MBUF_F_RX_OUTER_L4_CKSUM_UNKNOWN;
251 : :
252 [ # # # # : 0 : switch (errlev) {
# ]
253 : 0 : case NPC_ERRLEV_RE:
254 : : /* Mark all errors as BAD checksum errors
255 : : * including Outer L2 length mismatch error
256 : : */
257 [ # # ]: 0 : if (errcode) {
258 : : val |= RTE_MBUF_F_RX_IP_CKSUM_BAD;
259 : : val |= RTE_MBUF_F_RX_L4_CKSUM_BAD;
260 : : } else {
261 : : val |= RTE_MBUF_F_RX_IP_CKSUM_GOOD;
262 : : val |= RTE_MBUF_F_RX_L4_CKSUM_GOOD;
263 : : }
264 : : break;
265 : 0 : case NPC_ERRLEV_LC:
266 : 0 : if (errcode == NPC_EC_OIP4_CSUM ||
267 [ # # ]: 0 : errcode == NPC_EC_IP_FRAG_OFFSET_1) {
268 : : val |= RTE_MBUF_F_RX_IP_CKSUM_BAD;
269 : : val |= RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD;
270 : : } else {
271 : : val |= RTE_MBUF_F_RX_IP_CKSUM_GOOD;
272 : : }
273 : : break;
274 : 0 : case NPC_ERRLEV_LG:
275 [ # # ]: 0 : if (errcode == NPC_EC_IIP4_CSUM)
276 : : val |= RTE_MBUF_F_RX_IP_CKSUM_BAD;
277 : : else
278 : : val |= RTE_MBUF_F_RX_IP_CKSUM_GOOD;
279 : : break;
280 : 0 : case NPC_ERRLEV_NIX:
281 : 0 : if (errcode == NIX_RX_PERRCODE_OL4_CHK ||
282 [ # # ]: 0 : errcode == NIX_RX_PERRCODE_OL4_LEN ||
283 : : errcode == NIX_RX_PERRCODE_OL4_PORT) {
284 : : val |= RTE_MBUF_F_RX_IP_CKSUM_GOOD;
285 : : val |= RTE_MBUF_F_RX_L4_CKSUM_BAD;
286 : : val |= RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD;
287 : : } else if (errcode == NIX_RX_PERRCODE_IL4_CHK ||
288 [ # # # ]: 0 : errcode == NIX_RX_PERRCODE_IL4_LEN ||
289 : : errcode == NIX_RX_PERRCODE_IL4_PORT) {
290 : : val |= RTE_MBUF_F_RX_IP_CKSUM_GOOD;
291 : : val |= RTE_MBUF_F_RX_L4_CKSUM_BAD;
292 : : } else if (errcode == NIX_RX_PERRCODE_IL3_LEN ||
293 : : errcode == NIX_RX_PERRCODE_OL3_LEN) {
294 : : val |= RTE_MBUF_F_RX_IP_CKSUM_BAD;
295 : : } else {
296 : : val |= RTE_MBUF_F_RX_IP_CKSUM_BAD;
297 : : val |= RTE_MBUF_F_RX_L4_CKSUM_BAD;
298 : : }
299 : : break;
300 : : }
301 : 0 : ol_flags[idx] = val;
302 : : }
303 : 0 : }
304 : :
305 : : void *
306 : 0 : cnxk_nix_fastpath_lookup_mem_get(void)
307 : : {
308 : 0 : const char name[] = CNXK_NIX_FASTPATH_LOOKUP_MEM;
309 : : const struct rte_memzone *mz;
310 : : void *mem;
311 : :
312 : 0 : mz = rte_memzone_lookup(name);
313 [ # # ]: 0 : if (mz != NULL)
314 : 0 : return mz->addr;
315 : :
316 : : /* Request for the first time */
317 : 0 : mz = rte_memzone_reserve_aligned(name, LOOKUP_ARRAY_SZ, SOCKET_ID_ANY,
318 : : 0, ROC_ALIGN);
319 [ # # ]: 0 : if (mz != NULL) {
320 : 0 : mem = mz->addr;
321 : : /* Form the ptype array lookup memory */
322 : 0 : nix_create_non_tunnel_ptype_array(mem);
323 : 0 : nix_create_tunnel_ptype_array(mem);
324 : : /* Form the rx ol_flags based on errcode */
325 : 0 : nix_create_rx_ol_flags_array(mem);
326 : 0 : return mem;
327 : : }
328 : : return NULL;
329 : : }
330 : :
331 : : int
332 : 0 : cnxk_nix_lookup_mem_sa_base_set(struct cnxk_eth_dev *dev)
333 : : {
334 : 0 : void *lookup_mem = cnxk_nix_fastpath_lookup_mem_get();
335 : 0 : uint16_t port = dev->eth_dev->data->port_id;
336 : : uintptr_t sa_base_tbl;
337 : : uintptr_t sa_base;
338 : : uint8_t sa_w;
339 : :
340 [ # # ]: 0 : if (!lookup_mem)
341 : : return -EIO;
342 : :
343 : 0 : sa_base = roc_nix_inl_inb_sa_base_get(&dev->nix, dev->inb.inl_dev);
344 [ # # ]: 0 : if (!sa_base)
345 : : return -ENOTSUP;
346 : :
347 : 0 : sa_w = plt_log2_u32(dev->nix.ipsec_in_max_spi + 1 -
348 [ # # ]: 0 : dev->nix.ipsec_in_min_spi);
349 : :
350 : : /* Set SA Base in lookup mem */
351 : 0 : sa_base_tbl = (uintptr_t)lookup_mem;
352 : 0 : sa_base_tbl += PTYPE_ARRAY_SZ + ERR_ARRAY_SZ;
353 : 0 : *((uintptr_t *)sa_base_tbl + port) = sa_base | sa_w;
354 : 0 : return 0;
355 : : }
356 : :
357 : : int
358 : 0 : cnxk_nix_lookup_mem_sa_base_clear(struct cnxk_eth_dev *dev)
359 : : {
360 : 0 : void *lookup_mem = cnxk_nix_fastpath_lookup_mem_get();
361 : 0 : uint16_t port = dev->eth_dev->data->port_id;
362 : : uintptr_t sa_base_tbl;
363 : :
364 [ # # ]: 0 : if (!lookup_mem)
365 : : return -EIO;
366 : :
367 : : /* Set SA Base in lookup mem */
368 : 0 : sa_base_tbl = (uintptr_t)lookup_mem;
369 : 0 : sa_base_tbl += PTYPE_ARRAY_SZ + ERR_ARRAY_SZ;
370 : 0 : *((uintptr_t *)sa_base_tbl + port) = 0;
371 : 0 : return 0;
372 : : }
373 : :
374 : : int
375 : 0 : cnxk_nix_lookup_mem_metapool_set(struct cnxk_eth_dev *dev)
376 : : {
377 : 0 : void *lookup_mem = cnxk_nix_fastpath_lookup_mem_get();
378 : 0 : uint16_t port = dev->eth_dev->data->port_id;
379 : : uintptr_t mp_tbl;
380 : :
381 [ # # ]: 0 : if (!lookup_mem)
382 : : return -EIO;
383 : :
384 : : /* Set Mempool in lookup mem */
385 : 0 : mp_tbl = (uintptr_t)lookup_mem;
386 : 0 : mp_tbl += PTYPE_ARRAY_SZ + ERR_ARRAY_SZ + SA_BASE_TBL_SZ;
387 : 0 : *((uintptr_t *)mp_tbl + port) = dev->nix.meta_mempool;
388 : 0 : return 0;
389 : : }
390 : :
391 : : int
392 : 0 : cnxk_nix_lookup_mem_metapool_clear(struct cnxk_eth_dev *dev)
393 : : {
394 : 0 : void *lookup_mem = cnxk_nix_fastpath_lookup_mem_get();
395 : 0 : uint16_t port = dev->eth_dev->data->port_id;
396 : : uintptr_t mp_tbl;
397 : :
398 [ # # ]: 0 : if (!lookup_mem)
399 : : return -EIO;
400 : :
401 : : /* Clear Mempool in lookup mem */
402 : 0 : mp_tbl = (uintptr_t)lookup_mem;
403 : 0 : mp_tbl += PTYPE_ARRAY_SZ + ERR_ARRAY_SZ + SA_BASE_TBL_SZ;
404 : 0 : *((uintptr_t *)mp_tbl + port) = dev->nix.meta_mempool;
405 : 0 : return 0;
406 : : }
|