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