xref: /dpdk/drivers/net/cnxk/cnxk_lookup.c (revision ba6a168a06581b5b3d523f984722a3e5f65bbb82)
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 *
cnxk_nix_supported_ptypes_get(struct rte_eth_dev * eth_dev,size_t * no_of_elements)12 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 	*no_of_elements = RTE_DIM(ptypes);
55 	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
nix_create_non_tunnel_ptype_array(uint16_t * ptype)72 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 	for (idx = 0; idx < PTYPE_NON_TUNNEL_ARRAY_SZ; idx++) {
79 		lb = idx & 0xF;
80 		lc = (idx & 0xF0) >> 4;
81 		ld = (idx & 0xF00) >> 8;
82 		le = (idx & 0xF000) >> 12;
83 		val = RTE_PTYPE_UNKNOWN;
84 
85 		switch (lb) {
86 		case NPC_LT_LB_STAG_QINQ:
87 			val |= RTE_PTYPE_L2_ETHER_QINQ;
88 			break;
89 		case NPC_LT_LB_CTAG:
90 			val |= RTE_PTYPE_L2_ETHER_VLAN;
91 			break;
92 		default:
93 			val |= RTE_PTYPE_L2_ETHER;
94 		}
95 
96 		switch (lc) {
97 		case NPC_LT_LC_ARP:
98 			val = (val & ~RTE_PTYPE_L2_MASK);
99 			val |= RTE_PTYPE_L2_ETHER_ARP;
100 			break;
101 		case NPC_LT_LC_NSH:
102 			val = (val & ~RTE_PTYPE_L2_MASK);
103 			val |= RTE_PTYPE_L2_ETHER_NSH;
104 			break;
105 		case NPC_LT_LC_FCOE:
106 			val = (val & ~RTE_PTYPE_L2_MASK);
107 			val |= RTE_PTYPE_L2_ETHER_FCOE;
108 			break;
109 		case NPC_LT_LC_MPLS:
110 			val = (val & ~RTE_PTYPE_L2_MASK);
111 			val |= RTE_PTYPE_L2_ETHER_MPLS;
112 			break;
113 		case NPC_LT_LC_IP:
114 			val |= RTE_PTYPE_L3_IPV4;
115 			break;
116 		case NPC_LT_LC_IP_OPT:
117 			val |= RTE_PTYPE_L3_IPV4_EXT;
118 			break;
119 		case NPC_LT_LC_IP6:
120 			val |= RTE_PTYPE_L3_IPV6;
121 			break;
122 		case NPC_LT_LC_IP6_EXT:
123 			val |= RTE_PTYPE_L3_IPV6_EXT;
124 			break;
125 		case NPC_LT_LC_PTP:
126 			val = (val & ~RTE_PTYPE_L2_MASK);
127 			val |= RTE_PTYPE_L2_ETHER_TIMESYNC;
128 			break;
129 		}
130 
131 		switch (ld) {
132 		case NPC_LT_LD_TCP:
133 			val |= RTE_PTYPE_L4_TCP;
134 			break;
135 		case NPC_LT_LD_UDP:
136 			val |= RTE_PTYPE_L4_UDP;
137 			break;
138 		case NPC_LT_LD_SCTP:
139 			val |= RTE_PTYPE_L4_SCTP;
140 			break;
141 		case NPC_LT_LD_ICMP:
142 		case NPC_LT_LD_ICMP6:
143 			val |= RTE_PTYPE_L4_ICMP;
144 			break;
145 		case NPC_LT_LD_IGMP:
146 			val |= RTE_PTYPE_L4_IGMP;
147 			break;
148 		case NPC_LT_LD_GRE:
149 			val |= RTE_PTYPE_TUNNEL_GRE;
150 			break;
151 		case NPC_LT_LD_NVGRE:
152 			val |= RTE_PTYPE_TUNNEL_NVGRE;
153 			break;
154 		}
155 
156 		switch (le) {
157 		case NPC_LT_LE_VXLAN:
158 			val |= RTE_PTYPE_TUNNEL_VXLAN;
159 			break;
160 		case NPC_LT_LE_ESP:
161 			val |= RTE_PTYPE_TUNNEL_ESP;
162 			break;
163 		case NPC_LT_LE_VXLANGPE:
164 			val |= RTE_PTYPE_TUNNEL_VXLAN_GPE;
165 			break;
166 		case NPC_LT_LE_GENEVE:
167 			val |= RTE_PTYPE_TUNNEL_GENEVE;
168 			break;
169 		case NPC_LT_LE_GTPC:
170 			val |= RTE_PTYPE_TUNNEL_GTPC;
171 			break;
172 		case NPC_LT_LE_GTPU:
173 			val |= RTE_PTYPE_TUNNEL_GTPU;
174 			break;
175 		case NPC_LT_LE_TU_MPLS_IN_GRE:
176 			val |= RTE_PTYPE_TUNNEL_MPLS_IN_GRE;
177 			break;
178 		case NPC_LT_LE_TU_MPLS_IN_UDP:
179 			val |= RTE_PTYPE_TUNNEL_MPLS_IN_UDP;
180 			break;
181 		}
182 		ptype[idx] = val;
183 	}
184 }
185 
186 #define TU_SHIFT(x) ((x) >> PTYPE_NON_TUNNEL_WIDTH)
187 static void
nix_create_tunnel_ptype_array(uint16_t * ptype)188 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 	for (idx = 0; idx < PTYPE_TUNNEL_ARRAY_SZ; idx++) {
198 		lf = idx & 0xF;
199 		lg = (idx & 0xF0) >> 4;
200 		lh = (idx & 0xF00) >> 8;
201 		val = RTE_PTYPE_UNKNOWN;
202 
203 		switch (lf) {
204 		case NPC_LT_LF_TU_ETHER:
205 			val |= TU_SHIFT(RTE_PTYPE_INNER_L2_ETHER);
206 			break;
207 		}
208 		switch (lg) {
209 		case NPC_LT_LG_TU_IP:
210 			val |= TU_SHIFT(RTE_PTYPE_INNER_L3_IPV4);
211 			break;
212 		case NPC_LT_LG_TU_IP6:
213 			val |= TU_SHIFT(RTE_PTYPE_INNER_L3_IPV6);
214 			break;
215 		}
216 		switch (lh) {
217 		case NPC_LT_LH_TU_TCP:
218 			val |= TU_SHIFT(RTE_PTYPE_INNER_L4_TCP);
219 			break;
220 		case NPC_LT_LH_TU_UDP:
221 			val |= TU_SHIFT(RTE_PTYPE_INNER_L4_UDP);
222 			break;
223 		case NPC_LT_LH_TU_SCTP:
224 			val |= TU_SHIFT(RTE_PTYPE_INNER_L4_SCTP);
225 			break;
226 		case NPC_LT_LH_TU_ICMP:
227 		case NPC_LT_LH_TU_ICMP6:
228 			val |= TU_SHIFT(RTE_PTYPE_INNER_L4_ICMP);
229 			break;
230 		}
231 
232 		ptype[idx] = val;
233 	}
234 }
235 
236 static void
nix_create_rx_ol_flags_array(void * mem)237 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 	for (idx = 0; idx < BIT(ERRCODE_ERRLEN_WIDTH); idx++) {
246 		errlev = idx & 0xf;
247 		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 		switch (errlev) {
254 		case NPC_ERRLEV_RE:
255 			/* Mark all errors as BAD checksum errors
256 			 * including Outer L2 length mismatch error
257 			 */
258 			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 		case NPC_ERRLEV_LC:
267 			if (errcode == NPC_EC_OIP4_CSUM ||
268 			    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 		case NPC_ERRLEV_LG:
276 			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 		case NPC_ERRLEV_NIX:
282 			if (errcode == NIX_RX_PERRCODE_OL4_CHK ||
283 			    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 				   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 		ol_flags[idx] = val;
303 	}
304 }
305 
306 void *
cnxk_nix_fastpath_lookup_mem_get(void)307 cnxk_nix_fastpath_lookup_mem_get(void)
308 {
309 	const char name[] = CNXK_NIX_FASTPATH_LOOKUP_MEM;
310 	const struct rte_memzone *mz;
311 	void *mem;
312 
313 	mz = rte_memzone_lookup(name);
314 	if (mz != NULL)
315 		return mz->addr;
316 
317 	/* Request for the first time */
318 	mz = rte_memzone_reserve_aligned(name, LOOKUP_ARRAY_SZ, SOCKET_ID_ANY,
319 					 0, ROC_ALIGN);
320 	if (mz != NULL) {
321 		mem = mz->addr;
322 		/* Form the ptype array lookup memory */
323 		nix_create_non_tunnel_ptype_array(mem);
324 		nix_create_tunnel_ptype_array(mem);
325 		/* Form the rx ol_flags based on errcode */
326 		nix_create_rx_ol_flags_array(mem);
327 		return mem;
328 	}
329 	return NULL;
330 }
331 
332 int
cnxk_nix_lookup_mem_sa_base_set(struct cnxk_eth_dev * dev)333 cnxk_nix_lookup_mem_sa_base_set(struct cnxk_eth_dev *dev)
334 {
335 	void *lookup_mem = cnxk_nix_fastpath_lookup_mem_get();
336 	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 	if (!lookup_mem)
342 		return -EIO;
343 
344 	sa_base = roc_nix_inl_inb_sa_base_get(&dev->nix, dev->inb.inl_dev);
345 	if (!sa_base)
346 		return -ENOTSUP;
347 
348 	sa_w = plt_log2_u32(dev->nix.ipsec_in_max_spi + 1 -
349 			    dev->nix.ipsec_in_min_spi);
350 
351 	/* Set SA Base in lookup mem */
352 	sa_base_tbl = (uintptr_t)lookup_mem;
353 	sa_base_tbl += PTYPE_ARRAY_SZ + ERR_ARRAY_SZ;
354 	*((uintptr_t *)sa_base_tbl + port) = sa_base | sa_w;
355 	return 0;
356 }
357 
358 int
cnxk_nix_lookup_mem_sa_base_clear(struct cnxk_eth_dev * dev)359 cnxk_nix_lookup_mem_sa_base_clear(struct cnxk_eth_dev *dev)
360 {
361 	void *lookup_mem = cnxk_nix_fastpath_lookup_mem_get();
362 	uint16_t port = dev->eth_dev->data->port_id;
363 	uintptr_t sa_base_tbl;
364 
365 	if (!lookup_mem)
366 		return -EIO;
367 
368 	/* Set SA Base in lookup mem */
369 	sa_base_tbl = (uintptr_t)lookup_mem;
370 	sa_base_tbl += PTYPE_ARRAY_SZ + ERR_ARRAY_SZ;
371 	*((uintptr_t *)sa_base_tbl + port) = 0;
372 	return 0;
373 }
374 
375 int
cnxk_nix_lookup_mem_metapool_set(struct cnxk_eth_dev * dev)376 cnxk_nix_lookup_mem_metapool_set(struct cnxk_eth_dev *dev)
377 {
378 	void *lookup_mem = cnxk_nix_fastpath_lookup_mem_get();
379 	uint16_t port = dev->eth_dev->data->port_id;
380 	uintptr_t mp_tbl;
381 
382 	if (!lookup_mem)
383 		return -EIO;
384 
385 	/* Set Mempool in lookup mem */
386 	mp_tbl = (uintptr_t)lookup_mem;
387 	mp_tbl += PTYPE_ARRAY_SZ + ERR_ARRAY_SZ + SA_BASE_TBL_SZ;
388 	*((uintptr_t *)mp_tbl + port) = dev->nix.meta_mempool;
389 	return 0;
390 }
391 
392 int
cnxk_nix_lookup_mem_metapool_clear(struct cnxk_eth_dev * dev)393 cnxk_nix_lookup_mem_metapool_clear(struct cnxk_eth_dev *dev)
394 {
395 	void *lookup_mem = cnxk_nix_fastpath_lookup_mem_get();
396 	uint16_t port = dev->eth_dev->data->port_id;
397 	uintptr_t mp_tbl;
398 
399 	if (!lookup_mem)
400 		return -EIO;
401 
402 	/* Clear Mempool in lookup mem */
403 	mp_tbl = (uintptr_t)lookup_mem;
404 	mp_tbl += PTYPE_ARRAY_SZ + ERR_ARRAY_SZ + SA_BASE_TBL_SZ;
405 	*((uintptr_t *)mp_tbl + port) = dev->nix.meta_mempool;
406 	return 0;
407 }
408