mbuf: add namespace to offload flags
[dpdk.git] / drivers / net / cnxk / cnxk_lookup.c
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 SA_BASE_TBL_SZ  (RTE_MAX_ETHPORTS * sizeof(uintptr_t))
11 #define LOOKUP_ARRAY_SZ (PTYPE_ARRAY_SZ + ERR_ARRAY_SZ + SA_BASE_TBL_SZ)
12 const uint32_t *
13 cnxk_nix_supported_ptypes_get(struct rte_eth_dev *eth_dev)
14 {
15         RTE_SET_USED(eth_dev);
16
17         static const uint32_t ptypes[] = {
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         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 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         for (idx = 0; idx < PTYPE_NON_TUNNEL_ARRAY_SZ; idx++) {
78                 lb = idx & 0xF;
79                 lc = (idx & 0xF0) >> 4;
80                 ld = (idx & 0xF00) >> 8;
81                 le = (idx & 0xF000) >> 12;
82                 val = RTE_PTYPE_UNKNOWN;
83
84                 switch (lb) {
85                 case NPC_LT_LB_STAG_QINQ:
86                         val |= RTE_PTYPE_L2_ETHER_QINQ;
87                         break;
88                 case NPC_LT_LB_CTAG:
89                         val |= RTE_PTYPE_L2_ETHER_VLAN;
90                         break;
91                 }
92
93                 switch (lc) {
94                 case NPC_LT_LC_ARP:
95                         val |= RTE_PTYPE_L2_ETHER_ARP;
96                         break;
97                 case NPC_LT_LC_NSH:
98                         val |= RTE_PTYPE_L2_ETHER_NSH;
99                         break;
100                 case NPC_LT_LC_FCOE:
101                         val |= RTE_PTYPE_L2_ETHER_FCOE;
102                         break;
103                 case NPC_LT_LC_MPLS:
104                         val |= RTE_PTYPE_L2_ETHER_MPLS;
105                         break;
106                 case NPC_LT_LC_IP:
107                         val |= RTE_PTYPE_L3_IPV4;
108                         break;
109                 case NPC_LT_LC_IP_OPT:
110                         val |= RTE_PTYPE_L3_IPV4_EXT;
111                         break;
112                 case NPC_LT_LC_IP6:
113                         val |= RTE_PTYPE_L3_IPV6;
114                         break;
115                 case NPC_LT_LC_IP6_EXT:
116                         val |= RTE_PTYPE_L3_IPV6_EXT;
117                         break;
118                 case NPC_LT_LC_PTP:
119                         val |= RTE_PTYPE_L2_ETHER_TIMESYNC;
120                         break;
121                 }
122
123                 switch (ld) {
124                 case NPC_LT_LD_TCP:
125                         val |= RTE_PTYPE_L4_TCP;
126                         break;
127                 case NPC_LT_LD_UDP:
128                         val |= RTE_PTYPE_L4_UDP;
129                         break;
130                 case NPC_LT_LD_SCTP:
131                         val |= RTE_PTYPE_L4_SCTP;
132                         break;
133                 case NPC_LT_LD_ICMP:
134                 case NPC_LT_LD_ICMP6:
135                         val |= RTE_PTYPE_L4_ICMP;
136                         break;
137                 case NPC_LT_LD_IGMP:
138                         val |= RTE_PTYPE_L4_IGMP;
139                         break;
140                 case NPC_LT_LD_GRE:
141                         val |= RTE_PTYPE_TUNNEL_GRE;
142                         break;
143                 case NPC_LT_LD_NVGRE:
144                         val |= RTE_PTYPE_TUNNEL_NVGRE;
145                         break;
146                 }
147
148                 switch (le) {
149                 case NPC_LT_LE_VXLAN:
150                         val |= RTE_PTYPE_TUNNEL_VXLAN;
151                         break;
152                 case NPC_LT_LE_ESP:
153                         val |= RTE_PTYPE_TUNNEL_ESP;
154                         break;
155                 case NPC_LT_LE_VXLANGPE:
156                         val |= RTE_PTYPE_TUNNEL_VXLAN_GPE;
157                         break;
158                 case NPC_LT_LE_GENEVE:
159                         val |= RTE_PTYPE_TUNNEL_GENEVE;
160                         break;
161                 case NPC_LT_LE_GTPC:
162                         val |= RTE_PTYPE_TUNNEL_GTPC;
163                         break;
164                 case NPC_LT_LE_GTPU:
165                         val |= RTE_PTYPE_TUNNEL_GTPU;
166                         break;
167                 case NPC_LT_LE_TU_MPLS_IN_GRE:
168                         val |= RTE_PTYPE_TUNNEL_MPLS_IN_GRE;
169                         break;
170                 case NPC_LT_LE_TU_MPLS_IN_UDP:
171                         val |= RTE_PTYPE_TUNNEL_MPLS_IN_UDP;
172                         break;
173                 }
174                 ptype[idx] = val;
175         }
176 }
177
178 #define TU_SHIFT(x) ((x) >> PTYPE_NON_TUNNEL_WIDTH)
179 static void
180 nix_create_tunnel_ptype_array(uint16_t *ptype)
181 {
182         uint8_t lf, lg, lh;
183         uint16_t val;
184         uint32_t idx;
185
186         /* Skip non tunnel ptype array memory */
187         ptype = ptype + PTYPE_NON_TUNNEL_ARRAY_SZ;
188
189         for (idx = 0; idx < PTYPE_TUNNEL_ARRAY_SZ; idx++) {
190                 lf = idx & 0xF;
191                 lg = (idx & 0xF0) >> 4;
192                 lh = (idx & 0xF00) >> 8;
193                 val = RTE_PTYPE_UNKNOWN;
194
195                 switch (lf) {
196                 case NPC_LT_LF_TU_ETHER:
197                         val |= TU_SHIFT(RTE_PTYPE_INNER_L2_ETHER);
198                         break;
199                 }
200                 switch (lg) {
201                 case NPC_LT_LG_TU_IP:
202                         val |= TU_SHIFT(RTE_PTYPE_INNER_L3_IPV4);
203                         break;
204                 case NPC_LT_LG_TU_IP6:
205                         val |= TU_SHIFT(RTE_PTYPE_INNER_L3_IPV6);
206                         break;
207                 }
208                 switch (lh) {
209                 case NPC_LT_LH_TU_TCP:
210                         val |= TU_SHIFT(RTE_PTYPE_INNER_L4_TCP);
211                         break;
212                 case NPC_LT_LH_TU_UDP:
213                         val |= TU_SHIFT(RTE_PTYPE_INNER_L4_UDP);
214                         break;
215                 case NPC_LT_LH_TU_SCTP:
216                         val |= TU_SHIFT(RTE_PTYPE_INNER_L4_SCTP);
217                         break;
218                 case NPC_LT_LH_TU_ICMP:
219                 case NPC_LT_LH_TU_ICMP6:
220                         val |= TU_SHIFT(RTE_PTYPE_INNER_L4_ICMP);
221                         break;
222                 }
223
224                 ptype[idx] = val;
225         }
226 }
227
228 static void
229 nix_create_rx_ol_flags_array(void *mem)
230 {
231         uint16_t idx, errcode, errlev;
232         uint32_t val, *ol_flags;
233
234         /* Skip ptype array memory */
235         ol_flags = (uint32_t *)((uint8_t *)mem + PTYPE_ARRAY_SZ);
236
237         for (idx = 0; idx < BIT(ERRCODE_ERRLEN_WIDTH); idx++) {
238                 errlev = idx & 0xf;
239                 errcode = (idx & 0xff0) >> 4;
240
241                 val = RTE_MBUF_F_RX_IP_CKSUM_UNKNOWN;
242                 val |= RTE_MBUF_F_RX_L4_CKSUM_UNKNOWN;
243                 val |= RTE_MBUF_F_RX_OUTER_L4_CKSUM_UNKNOWN;
244
245                 switch (errlev) {
246                 case NPC_ERRLEV_RE:
247                         /* Mark all errors as BAD checksum errors
248                          * including Outer L2 length mismatch error
249                          */
250                         if (errcode) {
251                                 val |= RTE_MBUF_F_RX_IP_CKSUM_BAD;
252                                 val |= RTE_MBUF_F_RX_L4_CKSUM_BAD;
253                         } else {
254                                 val |= RTE_MBUF_F_RX_IP_CKSUM_GOOD;
255                                 val |= RTE_MBUF_F_RX_L4_CKSUM_GOOD;
256                         }
257                         break;
258                 case NPC_ERRLEV_LC:
259                         if (errcode == NPC_EC_OIP4_CSUM ||
260                             errcode == NPC_EC_IP_FRAG_OFFSET_1) {
261                                 val |= RTE_MBUF_F_RX_IP_CKSUM_BAD;
262                                 val |= RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD;
263                         } else {
264                                 val |= RTE_MBUF_F_RX_IP_CKSUM_GOOD;
265                         }
266                         break;
267                 case NPC_ERRLEV_LG:
268                         if (errcode == NPC_EC_IIP4_CSUM)
269                                 val |= RTE_MBUF_F_RX_IP_CKSUM_BAD;
270                         else
271                                 val |= RTE_MBUF_F_RX_IP_CKSUM_GOOD;
272                         break;
273                 case NPC_ERRLEV_NIX:
274                         if (errcode == NIX_RX_PERRCODE_OL4_CHK ||
275                             errcode == NIX_RX_PERRCODE_OL4_LEN ||
276                             errcode == NIX_RX_PERRCODE_OL4_PORT) {
277                                 val |= RTE_MBUF_F_RX_IP_CKSUM_GOOD;
278                                 val |= RTE_MBUF_F_RX_L4_CKSUM_BAD;
279                                 val |= RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD;
280                         } else if (errcode == NIX_RX_PERRCODE_IL4_CHK ||
281                                    errcode == NIX_RX_PERRCODE_IL4_LEN ||
282                                    errcode == NIX_RX_PERRCODE_IL4_PORT) {
283                                 val |= RTE_MBUF_F_RX_IP_CKSUM_GOOD;
284                                 val |= RTE_MBUF_F_RX_L4_CKSUM_BAD;
285                         } else if (errcode == NIX_RX_PERRCODE_IL3_LEN ||
286                                    errcode == NIX_RX_PERRCODE_OL3_LEN) {
287                                 val |= RTE_MBUF_F_RX_IP_CKSUM_BAD;
288                         } else {
289                                 val |= RTE_MBUF_F_RX_IP_CKSUM_GOOD;
290                                 val |= RTE_MBUF_F_RX_L4_CKSUM_GOOD;
291                         }
292                         break;
293                 }
294                 ol_flags[idx] = val;
295         }
296 }
297
298 void *
299 cnxk_nix_fastpath_lookup_mem_get(void)
300 {
301         const char name[] = CNXK_NIX_FASTPATH_LOOKUP_MEM;
302         const struct rte_memzone *mz;
303         void *mem;
304
305         mz = rte_memzone_lookup(name);
306         if (mz != NULL)
307                 return mz->addr;
308
309         /* Request for the first time */
310         mz = rte_memzone_reserve_aligned(name, LOOKUP_ARRAY_SZ, SOCKET_ID_ANY,
311                                          0, ROC_ALIGN);
312         if (mz != NULL) {
313                 mem = mz->addr;
314                 /* Form the ptype array lookup memory */
315                 nix_create_non_tunnel_ptype_array(mem);
316                 nix_create_tunnel_ptype_array(mem);
317                 /* Form the rx ol_flags based on errcode */
318                 nix_create_rx_ol_flags_array(mem);
319                 return mem;
320         }
321         return NULL;
322 }
323
324 int
325 cnxk_nix_lookup_mem_sa_base_set(struct cnxk_eth_dev *dev)
326 {
327         void *lookup_mem = cnxk_nix_fastpath_lookup_mem_get();
328         uint16_t port = dev->eth_dev->data->port_id;
329         uintptr_t sa_base_tbl;
330         uintptr_t sa_base;
331         uint8_t sa_w;
332
333         if (!lookup_mem)
334                 return -EIO;
335
336         sa_base = roc_nix_inl_inb_sa_base_get(&dev->nix, dev->inb.inl_dev);
337         if (!sa_base)
338                 return -ENOTSUP;
339
340         sa_w = plt_log2_u32(dev->nix.ipsec_in_max_spi + 1);
341
342         /* Set SA Base in lookup mem */
343         sa_base_tbl = (uintptr_t)lookup_mem;
344         sa_base_tbl += PTYPE_ARRAY_SZ + ERR_ARRAY_SZ;
345         *((uintptr_t *)sa_base_tbl + port) = sa_base | sa_w;
346         return 0;
347 }
348
349 int
350 cnxk_nix_lookup_mem_sa_base_clear(struct cnxk_eth_dev *dev)
351 {
352         void *lookup_mem = cnxk_nix_fastpath_lookup_mem_get();
353         uint16_t port = dev->eth_dev->data->port_id;
354         uintptr_t sa_base_tbl;
355
356         if (!lookup_mem)
357                 return -EIO;
358
359         /* Set SA Base in lookup mem */
360         sa_base_tbl = (uintptr_t)lookup_mem;
361         sa_base_tbl += PTYPE_ARRAY_SZ + ERR_ARRAY_SZ;
362         *((uintptr_t *)sa_base_tbl + port) = 0;
363         return 0;
364 }