4764608c2d41707cdbd46fba56338519e31ac217
[dpdk.git] / drivers / net / octeontx2 / otx2_lookup.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2019 Marvell International Ltd.
3  */
4
5 #include <rte_common.h>
6 #include <rte_memzone.h>
7
8 #include "otx2_common.h"
9 #include "otx2_ethdev.h"
10
11 /* NIX_RX_PARSE_S's ERRCODE + ERRLEV (12 bits) */
12 #define ERRCODE_ERRLEN_WIDTH            12
13 #define ERR_ARRAY_SZ                    ((BIT(ERRCODE_ERRLEN_WIDTH)) *\
14                                         sizeof(uint32_t))
15
16 #define SA_TBL_SZ                       (RTE_MAX_ETHPORTS * sizeof(uint64_t))
17 #define LOOKUP_ARRAY_SZ                 (PTYPE_ARRAY_SZ + ERR_ARRAY_SZ +\
18                                         SA_TBL_SZ)
19
20 const uint32_t *
21 otx2_nix_supported_ptypes_get(struct rte_eth_dev *eth_dev)
22 {
23         RTE_SET_USED(eth_dev);
24
25         static const uint32_t ptypes[] = {
26                 RTE_PTYPE_L2_ETHER_QINQ, /* LB */
27                 RTE_PTYPE_L2_ETHER_VLAN, /* LB */
28                 RTE_PTYPE_L2_ETHER_TIMESYNC, /* LB */
29                 RTE_PTYPE_L2_ETHER_ARP,  /* LC */
30                 RTE_PTYPE_L2_ETHER_NSH,  /* LC */
31                 RTE_PTYPE_L2_ETHER_FCOE, /* LC */
32                 RTE_PTYPE_L2_ETHER_MPLS, /* LC */
33                 RTE_PTYPE_L3_IPV4,       /* LC */
34                 RTE_PTYPE_L3_IPV4_EXT,   /* LC */
35                 RTE_PTYPE_L3_IPV6,       /* LC */
36                 RTE_PTYPE_L3_IPV6_EXT,   /* LC */
37                 RTE_PTYPE_L4_TCP,        /* LD */
38                 RTE_PTYPE_L4_UDP,        /* LD */
39                 RTE_PTYPE_L4_SCTP,       /* LD */
40                 RTE_PTYPE_L4_ICMP,       /* LD */
41                 RTE_PTYPE_L4_IGMP,       /* LD */
42                 RTE_PTYPE_TUNNEL_GRE,    /* LD */
43                 RTE_PTYPE_TUNNEL_ESP,    /* LD */
44                 RTE_PTYPE_TUNNEL_NVGRE,  /* LD */
45                 RTE_PTYPE_TUNNEL_VXLAN,  /* LE */
46                 RTE_PTYPE_TUNNEL_GENEVE, /* LE */
47                 RTE_PTYPE_TUNNEL_GTPC,   /* LE */
48                 RTE_PTYPE_TUNNEL_GTPU,   /* LE */
49                 RTE_PTYPE_TUNNEL_VXLAN_GPE,   /* LE */
50                 RTE_PTYPE_TUNNEL_MPLS_IN_GRE, /* LE */
51                 RTE_PTYPE_TUNNEL_MPLS_IN_UDP, /* LE */
52                 RTE_PTYPE_INNER_L2_ETHER,/* LF */
53                 RTE_PTYPE_INNER_L3_IPV4, /* LG */
54                 RTE_PTYPE_INNER_L3_IPV6, /* LG */
55                 RTE_PTYPE_INNER_L4_TCP,  /* LH */
56                 RTE_PTYPE_INNER_L4_UDP,  /* LH */
57                 RTE_PTYPE_INNER_L4_SCTP, /* LH */
58                 RTE_PTYPE_INNER_L4_ICMP, /* LH */
59                 RTE_PTYPE_UNKNOWN,
60         };
61
62         return ptypes;
63 }
64
65 int
66 otx2_nix_ptypes_set(struct rte_eth_dev *eth_dev, uint32_t ptype_mask)
67 {
68         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
69
70         if (ptype_mask) {
71                 dev->rx_offload_flags |= NIX_RX_OFFLOAD_PTYPE_F;
72                 dev->ptype_disable = 0;
73         } else {
74                 dev->rx_offload_flags &= ~NIX_RX_OFFLOAD_PTYPE_F;
75                 dev->ptype_disable = 1;
76         }
77
78         otx2_eth_set_rx_function(eth_dev);
79
80         return 0;
81 }
82
83 /*
84  * +------------------ +------------------ +
85  * |  | IL4 | IL3| IL2 | TU | L4 | L3 | L2 |
86  * +-------------------+-------------------+
87  *
88  * +-------------------+------------------ +
89  * |  | LH | LG  | LF  | LE | LD | LC | LB |
90  * +-------------------+-------------------+
91  *
92  * ptype       [LE - LD - LC - LB]  = TU  - L4 -  L3  - T2
93  * ptype_tunnel[LH - LG - LF]  = IL4 - IL3 - IL2 - TU
94  *
95  */
96 static void
97 nix_create_non_tunnel_ptype_array(uint16_t *ptype)
98 {
99         uint8_t lb, lc, ld, le;
100         uint16_t val;
101         uint32_t idx;
102
103         for (idx = 0; idx < PTYPE_NON_TUNNEL_ARRAY_SZ; idx++) {
104                 lb = idx & 0xF;
105                 lc = (idx & 0xF0) >> 4;
106                 ld = (idx & 0xF00) >> 8;
107                 le = (idx & 0xF000) >> 12;
108                 val = RTE_PTYPE_UNKNOWN;
109
110                 switch (lb) {
111                 case NPC_LT_LB_STAG_QINQ:
112                         val |= RTE_PTYPE_L2_ETHER_QINQ;
113                         break;
114                 case NPC_LT_LB_CTAG:
115                         val |= RTE_PTYPE_L2_ETHER_VLAN;
116                         break;
117                 }
118
119                 switch (lc) {
120                 case NPC_LT_LC_ARP:
121                         val |= RTE_PTYPE_L2_ETHER_ARP;
122                         break;
123                 case NPC_LT_LC_NSH:
124                         val |= RTE_PTYPE_L2_ETHER_NSH;
125                         break;
126                 case NPC_LT_LC_FCOE:
127                         val |= RTE_PTYPE_L2_ETHER_FCOE;
128                         break;
129                 case NPC_LT_LC_MPLS:
130                         val |= RTE_PTYPE_L2_ETHER_MPLS;
131                         break;
132                 case NPC_LT_LC_IP:
133                         val |= RTE_PTYPE_L3_IPV4;
134                         break;
135                 case NPC_LT_LC_IP_OPT:
136                         val |= RTE_PTYPE_L3_IPV4_EXT;
137                         break;
138                 case NPC_LT_LC_IP6:
139                         val |= RTE_PTYPE_L3_IPV6;
140                         break;
141                 case NPC_LT_LC_IP6_EXT:
142                         val |= RTE_PTYPE_L3_IPV6_EXT;
143                         break;
144                 case NPC_LT_LC_PTP:
145                         val |= RTE_PTYPE_L2_ETHER_TIMESYNC;
146                         break;
147                 }
148
149                 switch (ld) {
150                 case NPC_LT_LD_TCP:
151                         val |= RTE_PTYPE_L4_TCP;
152                         break;
153                 case NPC_LT_LD_UDP:
154                         val |= RTE_PTYPE_L4_UDP;
155                         break;
156                 case NPC_LT_LD_SCTP:
157                         val |= RTE_PTYPE_L4_SCTP;
158                         break;
159                 case NPC_LT_LD_ICMP:
160                 case NPC_LT_LD_ICMP6:
161                         val |= RTE_PTYPE_L4_ICMP;
162                         break;
163                 case NPC_LT_LD_IGMP:
164                         val |= RTE_PTYPE_L4_IGMP;
165                         break;
166                 case NPC_LT_LD_GRE:
167                         val |= RTE_PTYPE_TUNNEL_GRE;
168                         break;
169                 case NPC_LT_LD_NVGRE:
170                         val |= RTE_PTYPE_TUNNEL_NVGRE;
171                         break;
172                 }
173
174                 switch (le) {
175                 case NPC_LT_LE_VXLAN:
176                         val |= RTE_PTYPE_TUNNEL_VXLAN;
177                         break;
178                 case NPC_LT_LE_ESP:
179                         val |= RTE_PTYPE_TUNNEL_ESP;
180                         break;
181                 case NPC_LT_LE_VXLANGPE:
182                         val |= RTE_PTYPE_TUNNEL_VXLAN_GPE;
183                         break;
184                 case NPC_LT_LE_GENEVE:
185                         val |= RTE_PTYPE_TUNNEL_GENEVE;
186                         break;
187                 case NPC_LT_LE_GTPC:
188                         val |= RTE_PTYPE_TUNNEL_GTPC;
189                         break;
190                 case NPC_LT_LE_GTPU:
191                         val |= RTE_PTYPE_TUNNEL_GTPU;
192                         break;
193                 case NPC_LT_LE_TU_MPLS_IN_GRE:
194                         val |= RTE_PTYPE_TUNNEL_MPLS_IN_GRE;
195                         break;
196                 case NPC_LT_LE_TU_MPLS_IN_UDP:
197                         val |= RTE_PTYPE_TUNNEL_MPLS_IN_UDP;
198                         break;
199                 }
200                 ptype[idx] = val;
201         }
202 }
203
204 #define TU_SHIFT(x) ((x) >> PTYPE_NON_TUNNEL_WIDTH)
205 static void
206 nix_create_tunnel_ptype_array(uint16_t *ptype)
207 {
208         uint8_t lf, lg, lh;
209         uint16_t val;
210         uint32_t idx;
211
212         /* Skip non tunnel ptype array memory */
213         ptype = ptype + PTYPE_NON_TUNNEL_ARRAY_SZ;
214
215         for (idx = 0; idx < PTYPE_TUNNEL_ARRAY_SZ; idx++) {
216                 lf = idx & 0xF;
217                 lg = (idx & 0xF0) >> 4;
218                 lh = (idx & 0xF00) >> 8;
219                 val = RTE_PTYPE_UNKNOWN;
220
221                 switch (lf) {
222                 case NPC_LT_LF_TU_ETHER:
223                         val |= TU_SHIFT(RTE_PTYPE_INNER_L2_ETHER);
224                         break;
225                 }
226                 switch (lg) {
227                 case NPC_LT_LG_TU_IP:
228                         val |= TU_SHIFT(RTE_PTYPE_INNER_L3_IPV4);
229                         break;
230                 case NPC_LT_LG_TU_IP6:
231                         val |= TU_SHIFT(RTE_PTYPE_INNER_L3_IPV6);
232                         break;
233                 }
234                 switch (lh) {
235                 case NPC_LT_LH_TU_TCP:
236                         val |= TU_SHIFT(RTE_PTYPE_INNER_L4_TCP);
237                         break;
238                 case NPC_LT_LH_TU_UDP:
239                         val |= TU_SHIFT(RTE_PTYPE_INNER_L4_UDP);
240                         break;
241                 case NPC_LT_LH_TU_SCTP:
242                         val |= TU_SHIFT(RTE_PTYPE_INNER_L4_SCTP);
243                         break;
244                 case NPC_LT_LH_TU_ICMP:
245                 case NPC_LT_LH_TU_ICMP6:
246                         val |= TU_SHIFT(RTE_PTYPE_INNER_L4_ICMP);
247                         break;
248                 }
249
250                 ptype[idx] = val;
251         }
252 }
253
254 static void
255 nix_create_rx_ol_flags_array(void *mem)
256 {
257         uint16_t idx, errcode, errlev;
258         uint32_t val, *ol_flags;
259
260         /* Skip ptype array memory */
261         ol_flags = (uint32_t *)((uint8_t *)mem + PTYPE_ARRAY_SZ);
262
263         for (idx = 0; idx < BIT(ERRCODE_ERRLEN_WIDTH); idx++) {
264                 errlev = idx & 0xf;
265                 errcode = (idx & 0xff0) >> 4;
266
267                 val = PKT_RX_IP_CKSUM_UNKNOWN;
268                 val |= PKT_RX_L4_CKSUM_UNKNOWN;
269                 val |= PKT_RX_OUTER_L4_CKSUM_UNKNOWN;
270
271                 switch (errlev) {
272                 case NPC_ERRLEV_RE:
273                         /* Mark all errors as BAD checksum errors
274                          * including Outer L2 length mismatch error
275                          */
276                         if (errcode) {
277                                 val |= PKT_RX_IP_CKSUM_BAD;
278                                 val |= PKT_RX_L4_CKSUM_BAD;
279                         } else {
280                                 val |= PKT_RX_IP_CKSUM_GOOD;
281                                 val |= PKT_RX_L4_CKSUM_GOOD;
282                         }
283                         break;
284                 case NPC_ERRLEV_LC:
285                         if (errcode == NPC_EC_OIP4_CSUM ||
286                             errcode == NPC_EC_IP_FRAG_OFFSET_1) {
287                                 val |= PKT_RX_IP_CKSUM_BAD;
288                                 val |= PKT_RX_OUTER_IP_CKSUM_BAD;
289                         } else {
290                                 val |= PKT_RX_IP_CKSUM_GOOD;
291                         }
292                         break;
293                 case NPC_ERRLEV_LG:
294                         if (errcode == NPC_EC_IIP4_CSUM)
295                                 val |= PKT_RX_IP_CKSUM_BAD;
296                         else
297                                 val |= PKT_RX_IP_CKSUM_GOOD;
298                         break;
299                 case NPC_ERRLEV_NIX:
300                         if (errcode == NIX_RX_PERRCODE_OL4_CHK ||
301                             errcode == NIX_RX_PERRCODE_OL4_LEN ||
302                             errcode == NIX_RX_PERRCODE_OL4_PORT) {
303                                 val |= PKT_RX_IP_CKSUM_GOOD;
304                                 val |= PKT_RX_L4_CKSUM_BAD;
305                                 val |= PKT_RX_OUTER_L4_CKSUM_BAD;
306                         } else if (errcode == NIX_RX_PERRCODE_IL4_CHK ||
307                                    errcode == NIX_RX_PERRCODE_IL4_LEN ||
308                                    errcode == NIX_RX_PERRCODE_IL4_PORT) {
309                                 val |= PKT_RX_IP_CKSUM_GOOD;
310                                 val |= PKT_RX_L4_CKSUM_BAD;
311                         } else if (errcode == NIX_RX_PERRCODE_IL3_LEN ||
312                                    errcode == NIX_RX_PERRCODE_OL3_LEN) {
313                                 val |= PKT_RX_IP_CKSUM_BAD;
314                         } else {
315                                 val |= PKT_RX_IP_CKSUM_GOOD;
316                                 val |= PKT_RX_L4_CKSUM_GOOD;
317                         }
318                         break;
319                 }
320                 ol_flags[idx] = val;
321         }
322 }
323
324 void *
325 otx2_nix_fastpath_lookup_mem_get(void)
326 {
327         const char name[] = OTX2_NIX_FASTPATH_LOOKUP_MEM;
328         const struct rte_memzone *mz;
329         void *mem;
330
331         /* SA_TBL starts after PTYPE_ARRAY & ERR_ARRAY */
332         RTE_BUILD_BUG_ON(OTX2_NIX_SA_TBL_START != (PTYPE_ARRAY_SZ +
333                                                    ERR_ARRAY_SZ));
334
335         mz = rte_memzone_lookup(name);
336         if (mz != NULL)
337                 return mz->addr;
338
339         /* Request for the first time */
340         mz = rte_memzone_reserve_aligned(name, LOOKUP_ARRAY_SZ,
341                                          SOCKET_ID_ANY, 0, OTX2_ALIGN);
342         if (mz != NULL) {
343                 mem = mz->addr;
344                 /* Form the ptype array lookup memory */
345                 nix_create_non_tunnel_ptype_array(mem);
346                 nix_create_tunnel_ptype_array(mem);
347                 /* Form the rx ol_flags based on errcode */
348                 nix_create_rx_ol_flags_array(mem);
349                 return mem;
350         }
351         return NULL;
352 }