1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(C) 2019 Marvell International Ltd.
5 #include <rte_common.h>
6 #include <rte_memzone.h>
8 #include "otx2_common.h"
9 #include "otx2_ethdev.h"
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)) *\
16 #define SA_TBL_SZ (RTE_MAX_ETHPORTS * sizeof(uint64_t))
17 #define LOOKUP_ARRAY_SZ (PTYPE_ARRAY_SZ + ERR_ARRAY_SZ +\
21 otx2_nix_supported_ptypes_get(struct rte_eth_dev *eth_dev)
23 RTE_SET_USED(eth_dev);
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 */
66 otx2_nix_ptypes_set(struct rte_eth_dev *eth_dev, uint32_t ptype_mask)
68 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
71 dev->rx_offload_flags |= NIX_RX_OFFLOAD_PTYPE_F;
72 dev->ptype_disable = 0;
74 dev->rx_offload_flags &= ~NIX_RX_OFFLOAD_PTYPE_F;
75 dev->ptype_disable = 1;
78 otx2_eth_set_rx_function(eth_dev);
84 * +------------------ +------------------ +
85 * | | IL4 | IL3| IL2 | TU | L4 | L3 | L2 |
86 * +-------------------+-------------------+
88 * +-------------------+------------------ +
89 * | | LH | LG | LF | LE | LD | LC | LB |
90 * +-------------------+-------------------+
92 * ptype [LE - LD - LC - LB] = TU - L4 - L3 - T2
93 * ptype_tunnel[LH - LG - LF] = IL4 - IL3 - IL2 - TU
97 nix_create_non_tunnel_ptype_array(uint16_t *ptype)
99 uint8_t lb, lc, ld, le;
103 for (idx = 0; idx < PTYPE_NON_TUNNEL_ARRAY_SZ; idx++) {
105 lc = (idx & 0xF0) >> 4;
106 ld = (idx & 0xF00) >> 8;
107 le = (idx & 0xF000) >> 12;
108 val = RTE_PTYPE_UNKNOWN;
111 case NPC_LT_LB_STAG_QINQ:
112 val |= RTE_PTYPE_L2_ETHER_QINQ;
115 val |= RTE_PTYPE_L2_ETHER_VLAN;
121 val |= RTE_PTYPE_L2_ETHER_ARP;
124 val |= RTE_PTYPE_L2_ETHER_NSH;
127 val |= RTE_PTYPE_L2_ETHER_FCOE;
130 val |= RTE_PTYPE_L2_ETHER_MPLS;
133 val |= RTE_PTYPE_L3_IPV4;
135 case NPC_LT_LC_IP_OPT:
136 val |= RTE_PTYPE_L3_IPV4_EXT;
139 val |= RTE_PTYPE_L3_IPV6;
141 case NPC_LT_LC_IP6_EXT:
142 val |= RTE_PTYPE_L3_IPV6_EXT;
145 val |= RTE_PTYPE_L2_ETHER_TIMESYNC;
151 val |= RTE_PTYPE_L4_TCP;
154 val |= RTE_PTYPE_L4_UDP;
157 val |= RTE_PTYPE_L4_SCTP;
160 case NPC_LT_LD_ICMP6:
161 val |= RTE_PTYPE_L4_ICMP;
164 val |= RTE_PTYPE_L4_IGMP;
167 val |= RTE_PTYPE_TUNNEL_GRE;
169 case NPC_LT_LD_NVGRE:
170 val |= RTE_PTYPE_TUNNEL_NVGRE;
173 val |= RTE_PTYPE_TUNNEL_ESP;
178 case NPC_LT_LE_VXLAN:
179 val |= RTE_PTYPE_TUNNEL_VXLAN;
181 case NPC_LT_LE_VXLANGPE:
182 val |= RTE_PTYPE_TUNNEL_VXLAN_GPE;
184 case NPC_LT_LE_GENEVE:
185 val |= RTE_PTYPE_TUNNEL_GENEVE;
188 val |= RTE_PTYPE_TUNNEL_GTPC;
191 val |= RTE_PTYPE_TUNNEL_GTPU;
193 case NPC_LT_LE_TU_MPLS_IN_GRE:
194 val |= RTE_PTYPE_TUNNEL_MPLS_IN_GRE;
196 case NPC_LT_LE_TU_MPLS_IN_UDP:
197 val |= RTE_PTYPE_TUNNEL_MPLS_IN_UDP;
204 #define TU_SHIFT(x) ((x) >> PTYPE_NON_TUNNEL_WIDTH)
206 nix_create_tunnel_ptype_array(uint16_t *ptype)
212 /* Skip non tunnel ptype array memory */
213 ptype = ptype + PTYPE_NON_TUNNEL_ARRAY_SZ;
215 for (idx = 0; idx < PTYPE_TUNNEL_ARRAY_SZ; idx++) {
217 lg = (idx & 0xF0) >> 4;
218 lh = (idx & 0xF00) >> 8;
219 val = RTE_PTYPE_UNKNOWN;
222 case NPC_LT_LF_TU_ETHER:
223 val |= TU_SHIFT(RTE_PTYPE_INNER_L2_ETHER);
227 case NPC_LT_LG_TU_IP:
228 val |= TU_SHIFT(RTE_PTYPE_INNER_L3_IPV4);
230 case NPC_LT_LG_TU_IP6:
231 val |= TU_SHIFT(RTE_PTYPE_INNER_L3_IPV6);
235 case NPC_LT_LH_TU_TCP:
236 val |= TU_SHIFT(RTE_PTYPE_INNER_L4_TCP);
238 case NPC_LT_LH_TU_UDP:
239 val |= TU_SHIFT(RTE_PTYPE_INNER_L4_UDP);
241 case NPC_LT_LH_TU_SCTP:
242 val |= TU_SHIFT(RTE_PTYPE_INNER_L4_SCTP);
244 case NPC_LT_LH_TU_ICMP:
245 case NPC_LT_LH_TU_ICMP6:
246 val |= TU_SHIFT(RTE_PTYPE_INNER_L4_ICMP);
255 nix_create_rx_ol_flags_array(void *mem)
257 uint16_t idx, errcode, errlev;
258 uint32_t val, *ol_flags;
260 /* Skip ptype array memory */
261 ol_flags = (uint32_t *)((uint8_t *)mem + PTYPE_ARRAY_SZ);
263 for (idx = 0; idx < BIT(ERRCODE_ERRLEN_WIDTH); idx++) {
265 errcode = (idx & 0xff0) >> 4;
267 val = PKT_RX_IP_CKSUM_UNKNOWN;
268 val |= PKT_RX_L4_CKSUM_UNKNOWN;
269 val |= PKT_RX_OUTER_L4_CKSUM_UNKNOWN;
273 /* Mark all errors as BAD checksum errors */
275 val |= PKT_RX_IP_CKSUM_BAD;
276 val |= PKT_RX_L4_CKSUM_BAD;
278 val |= PKT_RX_IP_CKSUM_GOOD;
279 val |= PKT_RX_L4_CKSUM_GOOD;
283 if (errcode == NPC_EC_OIP4_CSUM ||
284 errcode == NPC_EC_IP_FRAG_OFFSET_1) {
285 val |= PKT_RX_IP_CKSUM_BAD;
286 val |= PKT_RX_EIP_CKSUM_BAD;
288 val |= PKT_RX_IP_CKSUM_GOOD;
292 if (errcode == NPC_EC_IIP4_CSUM)
293 val |= PKT_RX_IP_CKSUM_BAD;
295 val |= PKT_RX_IP_CKSUM_GOOD;
298 val |= PKT_RX_IP_CKSUM_GOOD;
299 if (errcode == NIX_RX_PERRCODE_OL4_CHK) {
300 val |= PKT_RX_OUTER_L4_CKSUM_BAD;
301 val |= PKT_RX_L4_CKSUM_BAD;
302 } else if (errcode == NIX_RX_PERRCODE_IL4_CHK) {
303 val |= PKT_RX_L4_CKSUM_BAD;
305 val |= PKT_RX_L4_CKSUM_GOOD;
315 otx2_nix_fastpath_lookup_mem_get(void)
317 const char name[] = OTX2_NIX_FASTPATH_LOOKUP_MEM;
318 const struct rte_memzone *mz;
321 /* SA_TBL starts after PTYPE_ARRAY & ERR_ARRAY */
322 RTE_BUILD_BUG_ON(OTX2_NIX_SA_TBL_START != (PTYPE_ARRAY_SZ +
325 mz = rte_memzone_lookup(name);
329 /* Request for the first time */
330 mz = rte_memzone_reserve_aligned(name, LOOKUP_ARRAY_SZ,
331 SOCKET_ID_ANY, 0, OTX2_ALIGN);
334 /* Form the ptype array lookup memory */
335 nix_create_non_tunnel_ptype_array(mem);
336 nix_create_tunnel_ptype_array(mem);
337 /* Form the rx ol_flags based on errcode */
338 nix_create_rx_ol_flags_array(mem);