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