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 dev->nix.ipsec_in_min_spi); 342 343 /* Set SA Base in lookup mem */ 344 sa_base_tbl = (uintptr_t)lookup_mem; 345 sa_base_tbl += PTYPE_ARRAY_SZ + ERR_ARRAY_SZ; 346 *((uintptr_t *)sa_base_tbl + port) = sa_base | sa_w; 347 return 0; 348 } 349 350 int 351 cnxk_nix_lookup_mem_sa_base_clear(struct cnxk_eth_dev *dev) 352 { 353 void *lookup_mem = cnxk_nix_fastpath_lookup_mem_get(); 354 uint16_t port = dev->eth_dev->data->port_id; 355 uintptr_t sa_base_tbl; 356 357 if (!lookup_mem) 358 return -EIO; 359 360 /* Set SA Base in lookup mem */ 361 sa_base_tbl = (uintptr_t)lookup_mem; 362 sa_base_tbl += PTYPE_ARRAY_SZ + ERR_ARRAY_SZ; 363 *((uintptr_t *)sa_base_tbl + port) = 0; 364 return 0; 365 } 366