1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2014-2018 Broadcom 3 * All rights reserved. 4 */ 5 6 #include <sys/queue.h> 7 8 #include <rte_log.h> 9 #include <rte_malloc.h> 10 #include <rte_flow.h> 11 #include <rte_flow_driver.h> 12 #include <rte_tailq.h> 13 14 #include "bnxt.h" 15 #include "bnxt_filter.h" 16 #include "bnxt_hwrm.h" 17 #include "bnxt_ring.h" 18 #include "bnxt_rxq.h" 19 #include "bnxt_vnic.h" 20 #include "bnxt_util.h" 21 #include "hsi_struct_def_dpdk.h" 22 23 static int 24 bnxt_flow_args_validate(const struct rte_flow_attr *attr, 25 const struct rte_flow_item pattern[], 26 const struct rte_flow_action actions[], 27 struct rte_flow_error *error) 28 { 29 if (!pattern) { 30 rte_flow_error_set(error, 31 EINVAL, 32 RTE_FLOW_ERROR_TYPE_ITEM_NUM, 33 NULL, 34 "NULL pattern."); 35 return -rte_errno; 36 } 37 38 if (!actions) { 39 rte_flow_error_set(error, 40 EINVAL, 41 RTE_FLOW_ERROR_TYPE_ACTION_NUM, 42 NULL, 43 "NULL action."); 44 return -rte_errno; 45 } 46 47 if (!attr) { 48 rte_flow_error_set(error, 49 EINVAL, 50 RTE_FLOW_ERROR_TYPE_ATTR, 51 NULL, 52 "NULL attribute."); 53 return -rte_errno; 54 } 55 56 return 0; 57 } 58 59 static const struct rte_flow_item * 60 bnxt_flow_non_void_item(const struct rte_flow_item *cur) 61 { 62 while (1) { 63 if (cur->type != RTE_FLOW_ITEM_TYPE_VOID) 64 return cur; 65 cur++; 66 } 67 } 68 69 static const struct rte_flow_action * 70 bnxt_flow_non_void_action(const struct rte_flow_action *cur) 71 { 72 while (1) { 73 if (cur->type != RTE_FLOW_ACTION_TYPE_VOID) 74 return cur; 75 cur++; 76 } 77 } 78 79 static int 80 bnxt_filter_type_check(const struct rte_flow_item pattern[], 81 struct rte_flow_error *error __rte_unused) 82 { 83 const struct rte_flow_item *item = 84 bnxt_flow_non_void_item(pattern); 85 int use_ntuple = 1; 86 bool has_vlan = 0; 87 88 while (item->type != RTE_FLOW_ITEM_TYPE_END) { 89 switch (item->type) { 90 case RTE_FLOW_ITEM_TYPE_ANY: 91 case RTE_FLOW_ITEM_TYPE_ETH: 92 use_ntuple = 0; 93 break; 94 case RTE_FLOW_ITEM_TYPE_VLAN: 95 use_ntuple = 0; 96 has_vlan = 1; 97 break; 98 case RTE_FLOW_ITEM_TYPE_IPV4: 99 case RTE_FLOW_ITEM_TYPE_IPV6: 100 case RTE_FLOW_ITEM_TYPE_TCP: 101 case RTE_FLOW_ITEM_TYPE_UDP: 102 /* FALLTHROUGH */ 103 /* need ntuple match, reset exact match */ 104 use_ntuple |= 1; 105 break; 106 default: 107 PMD_DRV_LOG(DEBUG, "Unknown Flow type\n"); 108 use_ntuple |= 0; 109 } 110 item++; 111 } 112 113 if (has_vlan && use_ntuple) { 114 PMD_DRV_LOG(ERR, 115 "VLAN flow cannot use NTUPLE filter\n"); 116 rte_flow_error_set(error, EINVAL, 117 RTE_FLOW_ERROR_TYPE_ITEM, 118 item, 119 "Cannot use VLAN with NTUPLE"); 120 return -rte_errno; 121 } 122 123 return use_ntuple; 124 } 125 126 static int 127 bnxt_validate_and_parse_flow_type(struct bnxt *bp, 128 const struct rte_flow_attr *attr, 129 const struct rte_flow_item pattern[], 130 struct rte_flow_error *error, 131 struct bnxt_filter_info *filter) 132 { 133 const struct rte_flow_item *item = bnxt_flow_non_void_item(pattern); 134 const struct rte_flow_item_vlan *vlan_spec, *vlan_mask; 135 const struct rte_flow_item_ipv4 *ipv4_spec, *ipv4_mask; 136 const struct rte_flow_item_ipv6 *ipv6_spec, *ipv6_mask; 137 const struct rte_flow_item_tcp *tcp_spec, *tcp_mask; 138 const struct rte_flow_item_udp *udp_spec, *udp_mask; 139 const struct rte_flow_item_eth *eth_spec, *eth_mask; 140 const struct rte_flow_item_nvgre *nvgre_spec; 141 const struct rte_flow_item_nvgre *nvgre_mask; 142 const struct rte_flow_item_gre *gre_spec; 143 const struct rte_flow_item_gre *gre_mask; 144 const struct rte_flow_item_vxlan *vxlan_spec; 145 const struct rte_flow_item_vxlan *vxlan_mask; 146 uint8_t vni_mask[] = {0xFF, 0xFF, 0xFF}; 147 uint8_t tni_mask[] = {0xFF, 0xFF, 0xFF}; 148 const struct rte_flow_item_vf *vf_spec; 149 uint32_t tenant_id_be = 0, valid_flags = 0; 150 bool vni_masked = 0; 151 bool tni_masked = 0; 152 uint32_t en_ethertype; 153 uint8_t inner = 0; 154 uint32_t vf = 0; 155 uint32_t en = 0; 156 int use_ntuple; 157 int dflt_vnic; 158 159 use_ntuple = bnxt_filter_type_check(pattern, error); 160 if (use_ntuple < 0) 161 return use_ntuple; 162 PMD_DRV_LOG(DEBUG, "Use NTUPLE %d\n", use_ntuple); 163 164 filter->filter_type = use_ntuple ? 165 HWRM_CFA_NTUPLE_FILTER : HWRM_CFA_EM_FILTER; 166 en_ethertype = use_ntuple ? 167 NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE : 168 EM_FLOW_ALLOC_INPUT_EN_ETHERTYPE; 169 170 while (item->type != RTE_FLOW_ITEM_TYPE_END) { 171 if (item->last) { 172 /* last or range is NOT supported as match criteria */ 173 rte_flow_error_set(error, EINVAL, 174 RTE_FLOW_ERROR_TYPE_ITEM, 175 item, 176 "No support for range"); 177 return -rte_errno; 178 } 179 180 if (!item->spec || !item->mask) { 181 rte_flow_error_set(error, EINVAL, 182 RTE_FLOW_ERROR_TYPE_ITEM, 183 item, 184 "spec/mask is NULL"); 185 return -rte_errno; 186 } 187 188 switch (item->type) { 189 case RTE_FLOW_ITEM_TYPE_ANY: 190 inner = 191 ((const struct rte_flow_item_any *)item->spec)->num > 3; 192 if (inner) 193 PMD_DRV_LOG(DEBUG, "Parse inner header\n"); 194 break; 195 case RTE_FLOW_ITEM_TYPE_ETH: 196 if (!item->spec || !item->mask) 197 break; 198 199 eth_spec = item->spec; 200 eth_mask = item->mask; 201 202 /* Source MAC address mask cannot be partially set. 203 * Should be All 0's or all 1's. 204 * Destination MAC address mask must not be partially 205 * set. Should be all 1's or all 0's. 206 */ 207 if ((!rte_is_zero_ether_addr(ð_mask->src) && 208 !rte_is_broadcast_ether_addr(ð_mask->src)) || 209 (!rte_is_zero_ether_addr(ð_mask->dst) && 210 !rte_is_broadcast_ether_addr(ð_mask->dst))) { 211 rte_flow_error_set(error, 212 EINVAL, 213 RTE_FLOW_ERROR_TYPE_ITEM, 214 item, 215 "MAC_addr mask not valid"); 216 return -rte_errno; 217 } 218 219 /* Mask is not allowed. Only exact matches are */ 220 if (eth_mask->type && 221 eth_mask->type != RTE_BE16(0xffff)) { 222 rte_flow_error_set(error, EINVAL, 223 RTE_FLOW_ERROR_TYPE_ITEM, 224 item, 225 "ethertype mask not valid"); 226 return -rte_errno; 227 } 228 229 if (rte_is_broadcast_ether_addr(ð_mask->dst)) { 230 if (!rte_is_unicast_ether_addr(ð_spec->dst)) { 231 rte_flow_error_set(error, 232 EINVAL, 233 RTE_FLOW_ERROR_TYPE_ITEM, 234 item, 235 "DMAC is invalid"); 236 return -rte_errno; 237 } 238 rte_memcpy(filter->dst_macaddr, 239 ð_spec->dst, RTE_ETHER_ADDR_LEN); 240 en |= use_ntuple ? 241 NTUPLE_FLTR_ALLOC_INPUT_EN_DST_MACADDR : 242 EM_FLOW_ALLOC_INPUT_EN_DST_MACADDR; 243 valid_flags |= inner ? 244 BNXT_FLOW_L2_INNER_DST_VALID_FLAG : 245 BNXT_FLOW_L2_DST_VALID_FLAG; 246 filter->priority = attr->priority; 247 PMD_DRV_LOG(DEBUG, 248 "Creating a priority flow\n"); 249 } 250 251 if (rte_is_broadcast_ether_addr(ð_mask->src)) { 252 if (!rte_is_unicast_ether_addr(ð_spec->src)) { 253 rte_flow_error_set(error, 254 EINVAL, 255 RTE_FLOW_ERROR_TYPE_ITEM, 256 item, 257 "SMAC is invalid"); 258 return -rte_errno; 259 } 260 rte_memcpy(filter->src_macaddr, 261 ð_spec->src, RTE_ETHER_ADDR_LEN); 262 en |= use_ntuple ? 263 NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_MACADDR : 264 EM_FLOW_ALLOC_INPUT_EN_SRC_MACADDR; 265 valid_flags |= inner ? 266 BNXT_FLOW_L2_INNER_SRC_VALID_FLAG : 267 BNXT_FLOW_L2_SRC_VALID_FLAG; 268 } /* 269 * else { 270 * PMD_DRV_LOG(ERR, "Handle this condition\n"); 271 * } 272 */ 273 if (eth_mask->type) { 274 filter->ethertype = 275 rte_be_to_cpu_16(eth_spec->type); 276 en |= en_ethertype; 277 } 278 if (inner) 279 valid_flags |= BNXT_FLOW_PARSE_INNER_FLAG; 280 281 break; 282 case RTE_FLOW_ITEM_TYPE_VLAN: 283 vlan_spec = item->spec; 284 vlan_mask = item->mask; 285 if (en & en_ethertype) { 286 rte_flow_error_set(error, EINVAL, 287 RTE_FLOW_ERROR_TYPE_ITEM, 288 item, 289 "VLAN TPID matching is not" 290 " supported"); 291 return -rte_errno; 292 } 293 if (vlan_mask->tci && 294 vlan_mask->tci == RTE_BE16(0x0fff)) { 295 /* Only the VLAN ID can be matched. */ 296 filter->l2_ovlan = 297 rte_be_to_cpu_16(vlan_spec->tci & 298 RTE_BE16(0x0fff)); 299 en |= EM_FLOW_ALLOC_INPUT_EN_OVLAN_VID; 300 } else { 301 rte_flow_error_set(error, 302 EINVAL, 303 RTE_FLOW_ERROR_TYPE_ITEM, 304 item, 305 "VLAN mask is invalid"); 306 return -rte_errno; 307 } 308 if (vlan_mask->inner_type && 309 vlan_mask->inner_type != RTE_BE16(0xffff)) { 310 rte_flow_error_set(error, EINVAL, 311 RTE_FLOW_ERROR_TYPE_ITEM, 312 item, 313 "inner ethertype mask not" 314 " valid"); 315 return -rte_errno; 316 } 317 if (vlan_mask->inner_type) { 318 filter->ethertype = 319 rte_be_to_cpu_16(vlan_spec->inner_type); 320 en |= en_ethertype; 321 } 322 323 break; 324 case RTE_FLOW_ITEM_TYPE_IPV4: 325 /* If mask is not involved, we could use EM filters. */ 326 ipv4_spec = item->spec; 327 ipv4_mask = item->mask; 328 329 if (!item->spec || !item->mask) 330 break; 331 332 /* Only IP DST and SRC fields are maskable. */ 333 if (ipv4_mask->hdr.version_ihl || 334 ipv4_mask->hdr.type_of_service || 335 ipv4_mask->hdr.total_length || 336 ipv4_mask->hdr.packet_id || 337 ipv4_mask->hdr.fragment_offset || 338 ipv4_mask->hdr.time_to_live || 339 ipv4_mask->hdr.next_proto_id || 340 ipv4_mask->hdr.hdr_checksum) { 341 rte_flow_error_set(error, 342 EINVAL, 343 RTE_FLOW_ERROR_TYPE_ITEM, 344 item, 345 "Invalid IPv4 mask."); 346 return -rte_errno; 347 } 348 349 filter->dst_ipaddr[0] = ipv4_spec->hdr.dst_addr; 350 filter->src_ipaddr[0] = ipv4_spec->hdr.src_addr; 351 352 if (use_ntuple) 353 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR | 354 NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR; 355 else 356 en |= EM_FLOW_ALLOC_INPUT_EN_SRC_IPADDR | 357 EM_FLOW_ALLOC_INPUT_EN_DST_IPADDR; 358 359 if (ipv4_mask->hdr.src_addr) { 360 filter->src_ipaddr_mask[0] = 361 ipv4_mask->hdr.src_addr; 362 en |= !use_ntuple ? 0 : 363 NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK; 364 } 365 366 if (ipv4_mask->hdr.dst_addr) { 367 filter->dst_ipaddr_mask[0] = 368 ipv4_mask->hdr.dst_addr; 369 en |= !use_ntuple ? 0 : 370 NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK; 371 } 372 373 filter->ip_addr_type = use_ntuple ? 374 HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_IP_ADDR_TYPE_IPV4 : 375 HWRM_CFA_EM_FLOW_ALLOC_INPUT_IP_ADDR_TYPE_IPV4; 376 377 if (ipv4_spec->hdr.next_proto_id) { 378 filter->ip_protocol = 379 ipv4_spec->hdr.next_proto_id; 380 if (use_ntuple) 381 en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO; 382 else 383 en |= EM_FLOW_ALLOC_INPUT_EN_IP_PROTO; 384 } 385 break; 386 case RTE_FLOW_ITEM_TYPE_IPV6: 387 ipv6_spec = item->spec; 388 ipv6_mask = item->mask; 389 390 if (!item->spec || !item->mask) 391 break; 392 393 /* Only IP DST and SRC fields are maskable. */ 394 if (ipv6_mask->hdr.vtc_flow || 395 ipv6_mask->hdr.payload_len || 396 ipv6_mask->hdr.proto || 397 ipv6_mask->hdr.hop_limits) { 398 rte_flow_error_set(error, 399 EINVAL, 400 RTE_FLOW_ERROR_TYPE_ITEM, 401 item, 402 "Invalid IPv6 mask."); 403 return -rte_errno; 404 } 405 406 if (use_ntuple) 407 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR | 408 NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR; 409 else 410 en |= EM_FLOW_ALLOC_INPUT_EN_SRC_IPADDR | 411 EM_FLOW_ALLOC_INPUT_EN_DST_IPADDR; 412 413 rte_memcpy(filter->src_ipaddr, 414 ipv6_spec->hdr.src_addr, 16); 415 rte_memcpy(filter->dst_ipaddr, 416 ipv6_spec->hdr.dst_addr, 16); 417 418 if (!bnxt_check_zero_bytes(ipv6_mask->hdr.src_addr, 419 16)) { 420 rte_memcpy(filter->src_ipaddr_mask, 421 ipv6_mask->hdr.src_addr, 16); 422 en |= !use_ntuple ? 0 : 423 NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK; 424 } 425 426 if (!bnxt_check_zero_bytes(ipv6_mask->hdr.dst_addr, 427 16)) { 428 rte_memcpy(filter->dst_ipaddr_mask, 429 ipv6_mask->hdr.dst_addr, 16); 430 en |= !use_ntuple ? 0 : 431 NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK; 432 } 433 434 filter->ip_addr_type = use_ntuple ? 435 NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV6 : 436 EM_FLOW_ALLOC_INPUT_IP_ADDR_TYPE_IPV6; 437 break; 438 case RTE_FLOW_ITEM_TYPE_TCP: 439 tcp_spec = item->spec; 440 tcp_mask = item->mask; 441 442 if (!item->spec || !item->mask) 443 break; 444 445 /* Check TCP mask. Only DST & SRC ports are maskable */ 446 if (tcp_mask->hdr.sent_seq || 447 tcp_mask->hdr.recv_ack || 448 tcp_mask->hdr.data_off || 449 tcp_mask->hdr.tcp_flags || 450 tcp_mask->hdr.rx_win || 451 tcp_mask->hdr.cksum || 452 tcp_mask->hdr.tcp_urp) { 453 rte_flow_error_set(error, 454 EINVAL, 455 RTE_FLOW_ERROR_TYPE_ITEM, 456 item, 457 "Invalid TCP mask"); 458 return -rte_errno; 459 } 460 461 filter->src_port = tcp_spec->hdr.src_port; 462 filter->dst_port = tcp_spec->hdr.dst_port; 463 464 if (use_ntuple) 465 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT | 466 NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT; 467 else 468 en |= EM_FLOW_ALLOC_INPUT_EN_SRC_PORT | 469 EM_FLOW_ALLOC_INPUT_EN_DST_PORT; 470 471 if (tcp_mask->hdr.dst_port) { 472 filter->dst_port_mask = tcp_mask->hdr.dst_port; 473 en |= !use_ntuple ? 0 : 474 NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT_MASK; 475 } 476 477 if (tcp_mask->hdr.src_port) { 478 filter->src_port_mask = tcp_mask->hdr.src_port; 479 en |= !use_ntuple ? 0 : 480 NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT_MASK; 481 } 482 break; 483 case RTE_FLOW_ITEM_TYPE_UDP: 484 udp_spec = item->spec; 485 udp_mask = item->mask; 486 487 if (!item->spec || !item->mask) 488 break; 489 490 if (udp_mask->hdr.dgram_len || 491 udp_mask->hdr.dgram_cksum) { 492 rte_flow_error_set(error, 493 EINVAL, 494 RTE_FLOW_ERROR_TYPE_ITEM, 495 item, 496 "Invalid UDP mask"); 497 return -rte_errno; 498 } 499 500 filter->src_port = udp_spec->hdr.src_port; 501 filter->dst_port = udp_spec->hdr.dst_port; 502 503 if (use_ntuple) 504 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT | 505 NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT; 506 else 507 en |= EM_FLOW_ALLOC_INPUT_EN_SRC_PORT | 508 EM_FLOW_ALLOC_INPUT_EN_DST_PORT; 509 510 if (udp_mask->hdr.dst_port) { 511 filter->dst_port_mask = udp_mask->hdr.dst_port; 512 en |= !use_ntuple ? 0 : 513 NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT_MASK; 514 } 515 516 if (udp_mask->hdr.src_port) { 517 filter->src_port_mask = udp_mask->hdr.src_port; 518 en |= !use_ntuple ? 0 : 519 NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT_MASK; 520 } 521 break; 522 case RTE_FLOW_ITEM_TYPE_VXLAN: 523 vxlan_spec = item->spec; 524 vxlan_mask = item->mask; 525 /* Check if VXLAN item is used to describe protocol. 526 * If yes, both spec and mask should be NULL. 527 * If no, both spec and mask shouldn't be NULL. 528 */ 529 if ((!vxlan_spec && vxlan_mask) || 530 (vxlan_spec && !vxlan_mask)) { 531 rte_flow_error_set(error, 532 EINVAL, 533 RTE_FLOW_ERROR_TYPE_ITEM, 534 item, 535 "Invalid VXLAN item"); 536 return -rte_errno; 537 } 538 539 if (!vxlan_spec && !vxlan_mask) { 540 filter->tunnel_type = 541 CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN; 542 break; 543 } 544 545 if (vxlan_spec->rsvd1 || vxlan_spec->rsvd0[0] || 546 vxlan_spec->rsvd0[1] || vxlan_spec->rsvd0[2] || 547 vxlan_spec->flags != 0x8) { 548 rte_flow_error_set(error, 549 EINVAL, 550 RTE_FLOW_ERROR_TYPE_ITEM, 551 item, 552 "Invalid VXLAN item"); 553 return -rte_errno; 554 } 555 556 /* Check if VNI is masked. */ 557 if (vxlan_spec && vxlan_mask) { 558 vni_masked = 559 !!memcmp(vxlan_mask->vni, vni_mask, 560 RTE_DIM(vni_mask)); 561 if (vni_masked) { 562 rte_flow_error_set 563 (error, 564 EINVAL, 565 RTE_FLOW_ERROR_TYPE_ITEM, 566 item, 567 "Invalid VNI mask"); 568 return -rte_errno; 569 } 570 571 rte_memcpy(((uint8_t *)&tenant_id_be + 1), 572 vxlan_spec->vni, 3); 573 filter->vni = 574 rte_be_to_cpu_32(tenant_id_be); 575 filter->tunnel_type = 576 CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN; 577 } 578 break; 579 case RTE_FLOW_ITEM_TYPE_NVGRE: 580 nvgre_spec = item->spec; 581 nvgre_mask = item->mask; 582 /* Check if NVGRE item is used to describe protocol. 583 * If yes, both spec and mask should be NULL. 584 * If no, both spec and mask shouldn't be NULL. 585 */ 586 if ((!nvgre_spec && nvgre_mask) || 587 (nvgre_spec && !nvgre_mask)) { 588 rte_flow_error_set(error, 589 EINVAL, 590 RTE_FLOW_ERROR_TYPE_ITEM, 591 item, 592 "Invalid NVGRE item"); 593 return -rte_errno; 594 } 595 596 if (!nvgre_spec && !nvgre_mask) { 597 filter->tunnel_type = 598 CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_NVGRE; 599 break; 600 } 601 602 if (nvgre_spec->c_k_s_rsvd0_ver != 0x2000 || 603 nvgre_spec->protocol != 0x6558) { 604 rte_flow_error_set(error, 605 EINVAL, 606 RTE_FLOW_ERROR_TYPE_ITEM, 607 item, 608 "Invalid NVGRE item"); 609 return -rte_errno; 610 } 611 612 if (nvgre_spec && nvgre_mask) { 613 tni_masked = 614 !!memcmp(nvgre_mask->tni, tni_mask, 615 RTE_DIM(tni_mask)); 616 if (tni_masked) { 617 rte_flow_error_set 618 (error, 619 EINVAL, 620 RTE_FLOW_ERROR_TYPE_ITEM, 621 item, 622 "Invalid TNI mask"); 623 return -rte_errno; 624 } 625 rte_memcpy(((uint8_t *)&tenant_id_be + 1), 626 nvgre_spec->tni, 3); 627 filter->vni = 628 rte_be_to_cpu_32(tenant_id_be); 629 filter->tunnel_type = 630 CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_NVGRE; 631 } 632 break; 633 634 case RTE_FLOW_ITEM_TYPE_GRE: 635 gre_spec = (const struct rte_flow_item_gre *)item->spec; 636 gre_mask = (const struct rte_flow_item_gre *)item->mask; 637 638 /* 639 *Check if GRE item is used to describe protocol. 640 * If yes, both spec and mask should be NULL. 641 * If no, both spec and mask shouldn't be NULL. 642 */ 643 if (!!gre_spec ^ !!gre_mask) { 644 rte_flow_error_set(error, EINVAL, 645 RTE_FLOW_ERROR_TYPE_ITEM, 646 item, 647 "Invalid GRE item"); 648 return -rte_errno; 649 } 650 651 if (!gre_spec && !gre_mask) { 652 filter->tunnel_type = 653 CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_IPGRE; 654 break; 655 } 656 break; 657 658 case RTE_FLOW_ITEM_TYPE_VF: 659 vf_spec = item->spec; 660 vf = vf_spec->id; 661 if (!BNXT_PF(bp)) { 662 rte_flow_error_set(error, 663 EINVAL, 664 RTE_FLOW_ERROR_TYPE_ITEM, 665 item, 666 "Configuring on a VF!"); 667 return -rte_errno; 668 } 669 670 if (vf >= bp->pdev->max_vfs) { 671 rte_flow_error_set(error, 672 EINVAL, 673 RTE_FLOW_ERROR_TYPE_ITEM, 674 item, 675 "Incorrect VF id!"); 676 return -rte_errno; 677 } 678 679 if (!attr->transfer) { 680 rte_flow_error_set(error, 681 ENOTSUP, 682 RTE_FLOW_ERROR_TYPE_ITEM, 683 item, 684 "Matching VF traffic without" 685 " affecting it (transfer attribute)" 686 " is unsupported"); 687 return -rte_errno; 688 } 689 690 filter->mirror_vnic_id = 691 dflt_vnic = bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(bp, vf); 692 if (dflt_vnic < 0) { 693 /* This simply indicates there's no driver 694 * loaded. This is not an error. 695 */ 696 rte_flow_error_set 697 (error, 698 EINVAL, 699 RTE_FLOW_ERROR_TYPE_ITEM, 700 item, 701 "Unable to get default VNIC for VF"); 702 return -rte_errno; 703 } 704 705 filter->mirror_vnic_id = dflt_vnic; 706 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_MIRROR_VNIC_ID; 707 break; 708 default: 709 break; 710 } 711 item++; 712 } 713 filter->enables = en; 714 filter->valid_flags = valid_flags; 715 716 return 0; 717 } 718 719 /* Parse attributes */ 720 static int 721 bnxt_flow_parse_attr(const struct rte_flow_attr *attr, 722 struct rte_flow_error *error) 723 { 724 /* Must be input direction */ 725 if (!attr->ingress) { 726 rte_flow_error_set(error, 727 EINVAL, 728 RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, 729 attr, 730 "Only support ingress."); 731 return -rte_errno; 732 } 733 734 /* Not supported */ 735 if (attr->egress) { 736 rte_flow_error_set(error, 737 EINVAL, 738 RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, 739 attr, 740 "No support for egress."); 741 return -rte_errno; 742 } 743 744 return 0; 745 } 746 747 static struct bnxt_filter_info * 748 bnxt_find_matching_l2_filter(struct bnxt *bp, struct bnxt_filter_info *nf) 749 { 750 struct bnxt_filter_info *mf, *f0; 751 struct bnxt_vnic_info *vnic0; 752 struct rte_flow *flow; 753 int i; 754 755 vnic0 = &bp->vnic_info[0]; 756 f0 = STAILQ_FIRST(&vnic0->filter); 757 758 /* This flow has same DST MAC as the port/l2 filter. */ 759 if (memcmp(f0->l2_addr, nf->dst_macaddr, RTE_ETHER_ADDR_LEN) == 0) 760 return f0; 761 762 for (i = bp->max_vnics - 1; i >= 0; i--) { 763 struct bnxt_vnic_info *vnic = &bp->vnic_info[i]; 764 765 if (vnic->fw_vnic_id == INVALID_VNIC_ID) 766 continue; 767 768 STAILQ_FOREACH(flow, &vnic->flow_list, next) { 769 mf = flow->filter; 770 771 if (mf->matching_l2_fltr_ptr) 772 continue; 773 774 if (mf->ethertype == nf->ethertype && 775 mf->l2_ovlan == nf->l2_ovlan && 776 mf->l2_ovlan_mask == nf->l2_ovlan_mask && 777 mf->l2_ivlan == nf->l2_ivlan && 778 mf->l2_ivlan_mask == nf->l2_ivlan_mask && 779 !memcmp(mf->src_macaddr, nf->src_macaddr, 780 RTE_ETHER_ADDR_LEN) && 781 !memcmp(mf->dst_macaddr, nf->dst_macaddr, 782 RTE_ETHER_ADDR_LEN)) 783 return mf; 784 } 785 } 786 return NULL; 787 } 788 789 static struct bnxt_filter_info * 790 bnxt_create_l2_filter(struct bnxt *bp, struct bnxt_filter_info *nf, 791 struct bnxt_vnic_info *vnic) 792 { 793 struct bnxt_filter_info *filter1; 794 int rc; 795 796 /* Alloc new L2 filter. 797 * This flow needs MAC filter which does not match any existing 798 * L2 filters. 799 */ 800 filter1 = bnxt_get_unused_filter(bp); 801 if (filter1 == NULL) 802 return NULL; 803 804 filter1->flags = HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_XDP_DISABLE; 805 filter1->flags |= HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX; 806 if (nf->valid_flags & BNXT_FLOW_L2_SRC_VALID_FLAG || 807 nf->valid_flags & BNXT_FLOW_L2_DST_VALID_FLAG) { 808 filter1->flags |= 809 HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_OUTERMOST; 810 PMD_DRV_LOG(DEBUG, "Create Outer filter\n"); 811 } 812 813 if (nf->filter_type == HWRM_CFA_L2_FILTER && 814 (nf->valid_flags & BNXT_FLOW_L2_SRC_VALID_FLAG || 815 nf->valid_flags & BNXT_FLOW_L2_INNER_SRC_VALID_FLAG)) { 816 PMD_DRV_LOG(DEBUG, "Create L2 filter for SRC MAC\n"); 817 filter1->flags |= 818 HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_SOURCE_VALID; 819 memcpy(filter1->l2_addr, nf->src_macaddr, RTE_ETHER_ADDR_LEN); 820 } else { 821 PMD_DRV_LOG(DEBUG, "Create L2 filter for DST MAC\n"); 822 memcpy(filter1->l2_addr, nf->dst_macaddr, RTE_ETHER_ADDR_LEN); 823 } 824 825 if (nf->priority && 826 (nf->valid_flags & BNXT_FLOW_L2_DST_VALID_FLAG || 827 nf->valid_flags & BNXT_FLOW_L2_INNER_DST_VALID_FLAG)) { 828 /* Tell the FW where to place the filter in the table. */ 829 if (nf->priority > 65535) { 830 filter1->pri_hint = 831 HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_BELOW_FILTER; 832 /* This will place the filter in TCAM */ 833 filter1->l2_filter_id_hint = (uint64_t)-1; 834 } 835 } 836 837 if (nf->valid_flags & (BNXT_FLOW_L2_DST_VALID_FLAG | 838 BNXT_FLOW_L2_SRC_VALID_FLAG | 839 BNXT_FLOW_L2_INNER_SRC_VALID_FLAG | 840 BNXT_FLOW_L2_INNER_DST_VALID_FLAG)) { 841 filter1->enables = 842 HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR | 843 L2_FILTER_ALLOC_INPUT_EN_L2_ADDR_MASK; 844 memset(filter1->l2_addr_mask, 0xff, RTE_ETHER_ADDR_LEN); 845 } 846 847 if (nf->valid_flags & BNXT_FLOW_L2_DROP_FLAG) { 848 filter1->flags |= 849 HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_DROP; 850 if (nf->ethertype == RTE_ETHER_TYPE_IPV4) { 851 /* Num VLANs for drop filter will/should be 0. 852 * If the req is memset to 0, then the count will 853 * be automatically set to 0. 854 */ 855 if (nf->valid_flags & BNXT_FLOW_PARSE_INNER_FLAG) { 856 filter1->enables |= 857 L2_FILTER_ALLOC_INPUT_EN_T_NUM_VLANS; 858 } else { 859 filter1->enables |= 860 L2_FILTER_ALLOC_INPUT_EN_NUM_VLANS; 861 filter1->flags |= 862 HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_OUTERMOST; 863 } 864 } 865 } 866 867 rc = bnxt_hwrm_set_l2_filter(bp, vnic->fw_vnic_id, 868 filter1); 869 if (rc) { 870 bnxt_free_filter(bp, filter1); 871 return NULL; 872 } 873 filter1->l2_ref_cnt++; 874 return filter1; 875 } 876 877 struct bnxt_filter_info * 878 bnxt_get_l2_filter(struct bnxt *bp, struct bnxt_filter_info *nf, 879 struct bnxt_vnic_info *vnic) 880 { 881 struct bnxt_filter_info *l2_filter = NULL; 882 883 l2_filter = bnxt_find_matching_l2_filter(bp, nf); 884 if (l2_filter) { 885 l2_filter->l2_ref_cnt++; 886 nf->matching_l2_fltr_ptr = l2_filter; 887 } else { 888 l2_filter = bnxt_create_l2_filter(bp, nf, vnic); 889 nf->matching_l2_fltr_ptr = NULL; 890 } 891 892 return l2_filter; 893 } 894 895 static int bnxt_vnic_prep(struct bnxt *bp, struct bnxt_vnic_info *vnic) 896 { 897 struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf; 898 uint64_t rx_offloads = dev_conf->rxmode.offloads; 899 int rc; 900 901 rc = bnxt_vnic_grp_alloc(bp, vnic); 902 if (rc) 903 goto ret; 904 905 rc = bnxt_hwrm_vnic_alloc(bp, vnic); 906 if (rc) { 907 PMD_DRV_LOG(ERR, "HWRM vnic alloc failure rc: %x\n", rc); 908 goto ret; 909 } 910 bp->nr_vnics++; 911 912 /* RSS context is required only when there is more than one RSS ring */ 913 if (vnic->rx_queue_cnt > 1) { 914 rc = bnxt_hwrm_vnic_ctx_alloc(bp, vnic, 0 /* ctx_idx 0 */); 915 if (rc) { 916 PMD_DRV_LOG(ERR, 917 "HWRM vnic ctx alloc failure: %x\n", rc); 918 goto ret; 919 } 920 } else { 921 PMD_DRV_LOG(DEBUG, "No RSS context required\n"); 922 } 923 924 if (rx_offloads & DEV_RX_OFFLOAD_VLAN_STRIP) 925 vnic->vlan_strip = true; 926 else 927 vnic->vlan_strip = false; 928 929 rc = bnxt_hwrm_vnic_cfg(bp, vnic); 930 if (rc) 931 goto ret; 932 933 bnxt_hwrm_vnic_plcmode_cfg(bp, vnic); 934 935 ret: 936 return rc; 937 } 938 939 static int match_vnic_rss_cfg(struct bnxt *bp, 940 struct bnxt_vnic_info *vnic, 941 const struct rte_flow_action_rss *rss) 942 { 943 unsigned int match = 0, i; 944 945 if (vnic->rx_queue_cnt != rss->queue_num) 946 return -EINVAL; 947 948 for (i = 0; i < rss->queue_num; i++) { 949 if (!bp->rx_queues[rss->queue[i]]->vnic->rx_queue_cnt && 950 !bp->rx_queues[rss->queue[i]]->rx_started) 951 return -EINVAL; 952 } 953 954 for (i = 0; i < vnic->rx_queue_cnt; i++) { 955 int j; 956 957 for (j = 0; j < vnic->rx_queue_cnt; j++) { 958 if (bp->grp_info[rss->queue[i]].fw_grp_id == 959 vnic->fw_grp_ids[j]) 960 match++; 961 } 962 } 963 964 if (match != vnic->rx_queue_cnt) { 965 PMD_DRV_LOG(ERR, 966 "VNIC queue count %d vs queues matched %d\n", 967 match, vnic->rx_queue_cnt); 968 return -EINVAL; 969 } 970 971 return 0; 972 } 973 974 static void 975 bnxt_update_filter_flags_en(struct bnxt_filter_info *filter, 976 struct bnxt_filter_info *filter1, 977 int use_ntuple) 978 { 979 if (!use_ntuple && 980 !(filter->valid_flags & 981 ~(BNXT_FLOW_L2_DST_VALID_FLAG | 982 BNXT_FLOW_L2_SRC_VALID_FLAG | 983 BNXT_FLOW_L2_INNER_SRC_VALID_FLAG | 984 BNXT_FLOW_L2_INNER_DST_VALID_FLAG | 985 BNXT_FLOW_L2_DROP_FLAG | 986 BNXT_FLOW_PARSE_INNER_FLAG))) { 987 filter->flags = filter1->flags; 988 filter->enables = filter1->enables; 989 filter->filter_type = HWRM_CFA_L2_FILTER; 990 memcpy(filter->l2_addr, filter1->l2_addr, RTE_ETHER_ADDR_LEN); 991 memset(filter->l2_addr_mask, 0xff, RTE_ETHER_ADDR_LEN); 992 filter->pri_hint = filter1->pri_hint; 993 filter->l2_filter_id_hint = filter1->l2_filter_id_hint; 994 } 995 filter->fw_l2_filter_id = filter1->fw_l2_filter_id; 996 filter->l2_ref_cnt = filter1->l2_ref_cnt; 997 PMD_DRV_LOG(DEBUG, 998 "l2_filter: %p fw_l2_filter_id %" PRIx64 " l2_ref_cnt %u\n", 999 filter1, filter->fw_l2_filter_id, filter->l2_ref_cnt); 1000 } 1001 1002 static int 1003 bnxt_validate_and_parse_flow(struct rte_eth_dev *dev, 1004 const struct rte_flow_item pattern[], 1005 const struct rte_flow_action actions[], 1006 const struct rte_flow_attr *attr, 1007 struct rte_flow_error *error, 1008 struct bnxt_filter_info *filter) 1009 { 1010 const struct rte_flow_action *act = 1011 bnxt_flow_non_void_action(actions); 1012 struct bnxt *bp = dev->data->dev_private; 1013 struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf; 1014 struct bnxt_vnic_info *vnic = NULL, *vnic0 = NULL; 1015 const struct rte_flow_action_queue *act_q; 1016 const struct rte_flow_action_vf *act_vf; 1017 struct bnxt_filter_info *filter1 = NULL; 1018 const struct rte_flow_action_rss *rss; 1019 struct bnxt_rx_queue *rxq = NULL; 1020 int dflt_vnic, vnic_id; 1021 unsigned int rss_idx; 1022 uint32_t vf = 0, i; 1023 int rc, use_ntuple; 1024 1025 rc = 1026 bnxt_validate_and_parse_flow_type(bp, attr, pattern, error, filter); 1027 if (rc != 0) 1028 goto ret; 1029 1030 rc = bnxt_flow_parse_attr(attr, error); 1031 if (rc != 0) 1032 goto ret; 1033 1034 /* Since we support ingress attribute only - right now. */ 1035 if (filter->filter_type == HWRM_CFA_EM_FILTER) 1036 filter->flags = HWRM_CFA_EM_FLOW_ALLOC_INPUT_FLAGS_PATH_RX; 1037 1038 use_ntuple = bnxt_filter_type_check(pattern, error); 1039 switch (act->type) { 1040 case RTE_FLOW_ACTION_TYPE_QUEUE: 1041 /* Allow this flow. Redirect to a VNIC. */ 1042 act_q = (const struct rte_flow_action_queue *)act->conf; 1043 if (!act_q->index || act_q->index >= bp->rx_nr_rings) { 1044 rte_flow_error_set(error, 1045 EINVAL, 1046 RTE_FLOW_ERROR_TYPE_ACTION, 1047 act, 1048 "Invalid queue ID."); 1049 rc = -rte_errno; 1050 goto ret; 1051 } 1052 PMD_DRV_LOG(DEBUG, "Queue index %d\n", act_q->index); 1053 1054 vnic_id = attr->group; 1055 if (!vnic_id) { 1056 PMD_DRV_LOG(DEBUG, "Group id is 0\n"); 1057 vnic_id = act_q->index; 1058 } 1059 1060 vnic = &bp->vnic_info[vnic_id]; 1061 if (vnic == NULL) { 1062 rte_flow_error_set(error, 1063 EINVAL, 1064 RTE_FLOW_ERROR_TYPE_ACTION, 1065 act, 1066 "No matching VNIC found."); 1067 rc = -rte_errno; 1068 goto ret; 1069 } 1070 if (vnic->rx_queue_cnt) { 1071 if (vnic->start_grp_id != act_q->index) { 1072 PMD_DRV_LOG(ERR, 1073 "VNIC already in use\n"); 1074 rte_flow_error_set(error, 1075 EINVAL, 1076 RTE_FLOW_ERROR_TYPE_ACTION, 1077 act, 1078 "VNIC already in use"); 1079 rc = -rte_errno; 1080 goto ret; 1081 } 1082 goto use_vnic; 1083 } 1084 1085 rxq = bp->rx_queues[act_q->index]; 1086 1087 if (!(dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS) && rxq && 1088 vnic->fw_vnic_id != INVALID_HW_RING_ID) 1089 goto use_vnic; 1090 1091 //if (!rxq || 1092 //bp->vnic_info[0].fw_grp_ids[act_q->index] != 1093 //INVALID_HW_RING_ID || 1094 //!rxq->rx_deferred_start) { 1095 if (!rxq || 1096 bp->vnic_info[0].fw_grp_ids[act_q->index] != 1097 INVALID_HW_RING_ID) { 1098 PMD_DRV_LOG(ERR, 1099 "Queue invalid or used with other VNIC\n"); 1100 rte_flow_error_set(error, 1101 EINVAL, 1102 RTE_FLOW_ERROR_TYPE_ACTION, 1103 act, 1104 "Queue invalid queue or in use"); 1105 rc = -rte_errno; 1106 goto ret; 1107 } 1108 1109 rxq->vnic = vnic; 1110 rxq->rx_started = 1; 1111 vnic->rx_queue_cnt++; 1112 vnic->start_grp_id = act_q->index; 1113 vnic->end_grp_id = act_q->index; 1114 vnic->func_default = 0; //This is not a default VNIC. 1115 1116 PMD_DRV_LOG(DEBUG, "VNIC found\n"); 1117 1118 rc = bnxt_vnic_prep(bp, vnic); 1119 if (rc) { 1120 rte_flow_error_set(error, 1121 EINVAL, 1122 RTE_FLOW_ERROR_TYPE_ACTION, 1123 act, 1124 "VNIC prep fail"); 1125 rc = -rte_errno; 1126 goto ret; 1127 } 1128 1129 PMD_DRV_LOG(DEBUG, 1130 "vnic[%d] = %p vnic->fw_grp_ids = %p\n", 1131 act_q->index, vnic, vnic->fw_grp_ids); 1132 1133 use_vnic: 1134 vnic->ff_pool_idx = vnic_id; 1135 PMD_DRV_LOG(DEBUG, 1136 "Setting vnic ff_idx %d\n", vnic->ff_pool_idx); 1137 filter->dst_id = vnic->fw_vnic_id; 1138 filter1 = bnxt_get_l2_filter(bp, filter, vnic); 1139 if (filter1 == NULL) { 1140 rte_flow_error_set(error, 1141 ENOSPC, 1142 RTE_FLOW_ERROR_TYPE_ACTION, 1143 act, 1144 "Filter not available"); 1145 rc = -rte_errno; 1146 goto ret; 1147 } 1148 1149 PMD_DRV_LOG(DEBUG, "new fltr: %p l2fltr: %p l2_ref_cnt: %d\n", 1150 filter, filter1, filter1->l2_ref_cnt); 1151 bnxt_update_filter_flags_en(filter, filter1, use_ntuple); 1152 break; 1153 case RTE_FLOW_ACTION_TYPE_DROP: 1154 vnic0 = &bp->vnic_info[0]; 1155 filter->dst_id = vnic0->fw_vnic_id; 1156 filter->valid_flags |= BNXT_FLOW_L2_DROP_FLAG; 1157 filter1 = bnxt_get_l2_filter(bp, filter, vnic0); 1158 if (filter1 == NULL) { 1159 rte_flow_error_set(error, 1160 ENOSPC, 1161 RTE_FLOW_ERROR_TYPE_ACTION, 1162 act, 1163 "Filter not available"); 1164 rc = -rte_errno; 1165 goto ret; 1166 } 1167 1168 if (filter->filter_type == HWRM_CFA_EM_FILTER) 1169 filter->flags = 1170 HWRM_CFA_EM_FLOW_ALLOC_INPUT_FLAGS_DROP; 1171 else if (filter->filter_type == HWRM_CFA_NTUPLE_FILTER) 1172 filter->flags = 1173 HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_FLAGS_DROP; 1174 1175 bnxt_update_filter_flags_en(filter, filter1, use_ntuple); 1176 break; 1177 case RTE_FLOW_ACTION_TYPE_COUNT: 1178 vnic0 = &bp->vnic_info[0]; 1179 filter1 = bnxt_get_l2_filter(bp, filter, vnic0); 1180 if (filter1 == NULL) { 1181 rte_flow_error_set(error, 1182 ENOSPC, 1183 RTE_FLOW_ERROR_TYPE_ACTION, 1184 act, 1185 "New filter not available"); 1186 rc = -rte_errno; 1187 goto ret; 1188 } 1189 1190 filter->fw_l2_filter_id = filter1->fw_l2_filter_id; 1191 filter->flags = HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_FLAGS_METER; 1192 break; 1193 case RTE_FLOW_ACTION_TYPE_VF: 1194 act_vf = (const struct rte_flow_action_vf *)act->conf; 1195 vf = act_vf->id; 1196 1197 if (filter->tunnel_type == 1198 CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN || 1199 filter->tunnel_type == 1200 CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_IPGRE) { 1201 /* If issued on a VF, ensure id is 0 and is trusted */ 1202 if (BNXT_VF(bp)) { 1203 if (!BNXT_VF_IS_TRUSTED(bp) || vf) { 1204 rte_flow_error_set(error, EINVAL, 1205 RTE_FLOW_ERROR_TYPE_ACTION, 1206 act, 1207 "Incorrect VF"); 1208 rc = -rte_errno; 1209 goto ret; 1210 } 1211 } 1212 1213 filter->enables |= filter->tunnel_type; 1214 filter->filter_type = HWRM_CFA_TUNNEL_REDIRECT_FILTER; 1215 goto done; 1216 } 1217 1218 if (vf >= bp->pdev->max_vfs) { 1219 rte_flow_error_set(error, 1220 EINVAL, 1221 RTE_FLOW_ERROR_TYPE_ACTION, 1222 act, 1223 "Incorrect VF id!"); 1224 rc = -rte_errno; 1225 goto ret; 1226 } 1227 1228 filter->mirror_vnic_id = 1229 dflt_vnic = bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(bp, vf); 1230 if (dflt_vnic < 0) { 1231 /* This simply indicates there's no driver loaded. 1232 * This is not an error. 1233 */ 1234 rte_flow_error_set(error, 1235 EINVAL, 1236 RTE_FLOW_ERROR_TYPE_ACTION, 1237 act, 1238 "Unable to get default VNIC for VF"); 1239 rc = -rte_errno; 1240 goto ret; 1241 } 1242 1243 filter->mirror_vnic_id = dflt_vnic; 1244 filter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_MIRROR_VNIC_ID; 1245 1246 vnic0 = &bp->vnic_info[0]; 1247 filter1 = bnxt_get_l2_filter(bp, filter, vnic0); 1248 if (filter1 == NULL) { 1249 rte_flow_error_set(error, 1250 ENOSPC, 1251 RTE_FLOW_ERROR_TYPE_ACTION, 1252 act, 1253 "New filter not available"); 1254 rc = -rte_errno; 1255 goto ret; 1256 } 1257 1258 filter->fw_l2_filter_id = filter1->fw_l2_filter_id; 1259 break; 1260 case RTE_FLOW_ACTION_TYPE_RSS: 1261 rss = (const struct rte_flow_action_rss *)act->conf; 1262 1263 vnic_id = attr->group; 1264 if (!vnic_id) { 1265 PMD_DRV_LOG(ERR, "Group id cannot be 0\n"); 1266 rte_flow_error_set(error, 1267 EINVAL, 1268 RTE_FLOW_ERROR_TYPE_ATTR, 1269 NULL, 1270 "Group id cannot be 0"); 1271 rc = -rte_errno; 1272 goto ret; 1273 } 1274 1275 vnic = &bp->vnic_info[vnic_id]; 1276 if (vnic == NULL) { 1277 rte_flow_error_set(error, 1278 EINVAL, 1279 RTE_FLOW_ERROR_TYPE_ACTION, 1280 act, 1281 "No matching VNIC for RSS group."); 1282 rc = -rte_errno; 1283 goto ret; 1284 } 1285 PMD_DRV_LOG(DEBUG, "VNIC found\n"); 1286 1287 /* Check if requested RSS config matches RSS config of VNIC 1288 * only if it is not a fresh VNIC configuration. 1289 * Otherwise the existing VNIC configuration can be used. 1290 */ 1291 if (vnic->rx_queue_cnt) { 1292 rc = match_vnic_rss_cfg(bp, vnic, rss); 1293 if (rc) { 1294 PMD_DRV_LOG(ERR, 1295 "VNIC and RSS config mismatch\n"); 1296 rte_flow_error_set(error, 1297 EINVAL, 1298 RTE_FLOW_ERROR_TYPE_ACTION, 1299 act, 1300 "VNIC and RSS cfg mismatch"); 1301 rc = -rte_errno; 1302 goto ret; 1303 } 1304 goto vnic_found; 1305 } 1306 1307 for (i = 0; i < rss->queue_num; i++) { 1308 PMD_DRV_LOG(DEBUG, "RSS action Queue %d\n", 1309 rss->queue[i]); 1310 1311 if (!rss->queue[i] || 1312 rss->queue[i] >= bp->rx_nr_rings || 1313 !bp->rx_queues[rss->queue[i]]) { 1314 rte_flow_error_set(error, 1315 EINVAL, 1316 RTE_FLOW_ERROR_TYPE_ACTION, 1317 act, 1318 "Invalid queue ID for RSS"); 1319 rc = -rte_errno; 1320 goto ret; 1321 } 1322 rxq = bp->rx_queues[rss->queue[i]]; 1323 1324 //if (bp->vnic_info[0].fw_grp_ids[rss->queue[i]] != 1325 //INVALID_HW_RING_ID || 1326 //!rxq->rx_deferred_start) { 1327 if (bp->vnic_info[0].fw_grp_ids[rss->queue[i]] != 1328 INVALID_HW_RING_ID) { 1329 PMD_DRV_LOG(ERR, 1330 "queue active with other VNIC\n"); 1331 rte_flow_error_set(error, 1332 EINVAL, 1333 RTE_FLOW_ERROR_TYPE_ACTION, 1334 act, 1335 "Invalid queue ID for RSS"); 1336 rc = -rte_errno; 1337 goto ret; 1338 } 1339 1340 rxq->vnic = vnic; 1341 rxq->rx_started = 1; 1342 vnic->rx_queue_cnt++; 1343 } 1344 1345 vnic->start_grp_id = rss->queue[0]; 1346 vnic->end_grp_id = rss->queue[rss->queue_num - 1]; 1347 vnic->func_default = 0; //This is not a default VNIC. 1348 1349 rc = bnxt_vnic_prep(bp, vnic); 1350 if (rc) { 1351 rte_flow_error_set(error, 1352 EINVAL, 1353 RTE_FLOW_ERROR_TYPE_ACTION, 1354 act, 1355 "VNIC prep fail"); 1356 rc = -rte_errno; 1357 goto ret; 1358 } 1359 1360 PMD_DRV_LOG(DEBUG, 1361 "vnic[%d] = %p vnic->fw_grp_ids = %p\n", 1362 vnic_id, vnic, vnic->fw_grp_ids); 1363 1364 vnic->ff_pool_idx = vnic_id; 1365 PMD_DRV_LOG(DEBUG, 1366 "Setting vnic ff_pool_idx %d\n", vnic->ff_pool_idx); 1367 1368 /* This can be done only after vnic_grp_alloc is done. */ 1369 for (i = 0; i < vnic->rx_queue_cnt; i++) { 1370 vnic->fw_grp_ids[i] = 1371 bp->grp_info[rss->queue[i]].fw_grp_id; 1372 /* Make sure vnic0 does not use these rings. */ 1373 bp->vnic_info[0].fw_grp_ids[rss->queue[i]] = 1374 INVALID_HW_RING_ID; 1375 } 1376 1377 for (rss_idx = 0; rss_idx < HW_HASH_INDEX_SIZE; ) { 1378 for (i = 0; i < vnic->rx_queue_cnt; i++) 1379 vnic->rss_table[rss_idx++] = 1380 vnic->fw_grp_ids[i]; 1381 } 1382 1383 /* Configure RSS only if the queue count is > 1 */ 1384 if (vnic->rx_queue_cnt > 1) { 1385 vnic->hash_type = 1386 bnxt_rte_to_hwrm_hash_types(rss->types); 1387 1388 if (!rss->key_len) { 1389 /* If hash key has not been specified, 1390 * use random hash key. 1391 */ 1392 prandom_bytes(vnic->rss_hash_key, 1393 HW_HASH_KEY_SIZE); 1394 } else { 1395 if (rss->key_len > HW_HASH_KEY_SIZE) 1396 memcpy(vnic->rss_hash_key, 1397 rss->key, 1398 HW_HASH_KEY_SIZE); 1399 else 1400 memcpy(vnic->rss_hash_key, 1401 rss->key, 1402 rss->key_len); 1403 } 1404 bnxt_hwrm_vnic_rss_cfg(bp, vnic); 1405 } else { 1406 PMD_DRV_LOG(DEBUG, "No RSS config required\n"); 1407 } 1408 1409 vnic_found: 1410 filter->dst_id = vnic->fw_vnic_id; 1411 filter1 = bnxt_get_l2_filter(bp, filter, vnic); 1412 if (filter1 == NULL) { 1413 rte_flow_error_set(error, 1414 ENOSPC, 1415 RTE_FLOW_ERROR_TYPE_ACTION, 1416 act, 1417 "New filter not available"); 1418 rc = -rte_errno; 1419 goto ret; 1420 } 1421 1422 PMD_DRV_LOG(DEBUG, "L2 filter created\n"); 1423 bnxt_update_filter_flags_en(filter, filter1, use_ntuple); 1424 break; 1425 default: 1426 rte_flow_error_set(error, 1427 EINVAL, 1428 RTE_FLOW_ERROR_TYPE_ACTION, 1429 act, 1430 "Invalid action."); 1431 rc = -rte_errno; 1432 goto ret; 1433 } 1434 1435 if (filter1 && !filter->matching_l2_fltr_ptr) { 1436 bnxt_free_filter(bp, filter1); 1437 filter1->fw_l2_filter_id = -1; 1438 } 1439 1440 done: 1441 act = bnxt_flow_non_void_action(++act); 1442 if (act->type != RTE_FLOW_ACTION_TYPE_END) { 1443 rte_flow_error_set(error, 1444 EINVAL, 1445 RTE_FLOW_ERROR_TYPE_ACTION, 1446 act, 1447 "Invalid action."); 1448 rc = -rte_errno; 1449 goto ret; 1450 } 1451 1452 return rc; 1453 ret: 1454 1455 //TODO: Cleanup according to ACTION TYPE. 1456 if (rte_errno) { 1457 if (vnic && STAILQ_EMPTY(&vnic->filter)) 1458 vnic->rx_queue_cnt = 0; 1459 1460 if (rxq && !vnic->rx_queue_cnt) 1461 rxq->vnic = &bp->vnic_info[0]; 1462 } 1463 return rc; 1464 } 1465 1466 static 1467 struct bnxt_vnic_info *find_matching_vnic(struct bnxt *bp, 1468 struct bnxt_filter_info *filter) 1469 { 1470 struct bnxt_vnic_info *vnic = NULL; 1471 unsigned int i; 1472 1473 for (i = 0; i < bp->max_vnics; i++) { 1474 vnic = &bp->vnic_info[i]; 1475 if (vnic->fw_vnic_id != INVALID_VNIC_ID && 1476 filter->dst_id == vnic->fw_vnic_id) { 1477 PMD_DRV_LOG(DEBUG, "Found matching VNIC Id %d\n", 1478 vnic->ff_pool_idx); 1479 return vnic; 1480 } 1481 } 1482 return NULL; 1483 } 1484 1485 static int 1486 bnxt_flow_validate(struct rte_eth_dev *dev, 1487 const struct rte_flow_attr *attr, 1488 const struct rte_flow_item pattern[], 1489 const struct rte_flow_action actions[], 1490 struct rte_flow_error *error) 1491 { 1492 struct bnxt *bp = dev->data->dev_private; 1493 struct bnxt_vnic_info *vnic = NULL; 1494 struct bnxt_filter_info *filter; 1495 int ret = 0; 1496 1497 bnxt_acquire_flow_lock(bp); 1498 ret = bnxt_flow_args_validate(attr, pattern, actions, error); 1499 if (ret != 0) { 1500 bnxt_release_flow_lock(bp); 1501 return ret; 1502 } 1503 1504 filter = bnxt_get_unused_filter(bp); 1505 if (filter == NULL) { 1506 PMD_DRV_LOG(ERR, "Not enough resources for a new flow.\n"); 1507 bnxt_release_flow_lock(bp); 1508 return -ENOMEM; 1509 } 1510 1511 ret = bnxt_validate_and_parse_flow(dev, pattern, actions, attr, 1512 error, filter); 1513 if (ret) 1514 goto exit; 1515 1516 vnic = find_matching_vnic(bp, filter); 1517 if (vnic) { 1518 if (STAILQ_EMPTY(&vnic->filter)) { 1519 rte_free(vnic->fw_grp_ids); 1520 bnxt_hwrm_vnic_ctx_free(bp, vnic); 1521 bnxt_hwrm_vnic_free(bp, vnic); 1522 vnic->rx_queue_cnt = 0; 1523 PMD_DRV_LOG(DEBUG, "Free VNIC\n"); 1524 } 1525 } 1526 1527 if (filter->filter_type == HWRM_CFA_EM_FILTER) 1528 bnxt_hwrm_clear_em_filter(bp, filter); 1529 else if (filter->filter_type == HWRM_CFA_NTUPLE_FILTER) 1530 bnxt_hwrm_clear_ntuple_filter(bp, filter); 1531 else 1532 bnxt_hwrm_clear_l2_filter(bp, filter); 1533 1534 exit: 1535 /* No need to hold on to this filter if we are just validating flow */ 1536 filter->fw_l2_filter_id = UINT64_MAX; 1537 bnxt_free_filter(bp, filter); 1538 bnxt_release_flow_lock(bp); 1539 1540 return ret; 1541 } 1542 1543 static void 1544 bnxt_update_filter(struct bnxt *bp, struct bnxt_filter_info *old_filter, 1545 struct bnxt_filter_info *new_filter) 1546 { 1547 /* Clear the new L2 filter that was created in the previous step in 1548 * bnxt_validate_and_parse_flow. For L2 filters, we will use the new 1549 * filter which points to the new destination queue and so we clear 1550 * the previous L2 filter. For ntuple filters, we are going to reuse 1551 * the old L2 filter and create new NTUPLE filter with this new 1552 * destination queue subsequently during bnxt_flow_create. 1553 */ 1554 if (new_filter->filter_type == HWRM_CFA_L2_FILTER) { 1555 bnxt_hwrm_clear_l2_filter(bp, old_filter); 1556 bnxt_hwrm_set_l2_filter(bp, new_filter->dst_id, new_filter); 1557 } else { 1558 if (new_filter->filter_type == HWRM_CFA_EM_FILTER) 1559 bnxt_hwrm_clear_em_filter(bp, old_filter); 1560 if (new_filter->filter_type == HWRM_CFA_NTUPLE_FILTER) 1561 bnxt_hwrm_clear_ntuple_filter(bp, old_filter); 1562 } 1563 } 1564 1565 static int 1566 bnxt_match_filter(struct bnxt *bp, struct bnxt_filter_info *nf) 1567 { 1568 struct bnxt_filter_info *mf; 1569 struct rte_flow *flow; 1570 int i; 1571 1572 for (i = bp->max_vnics - 1; i >= 0; i--) { 1573 struct bnxt_vnic_info *vnic = &bp->vnic_info[i]; 1574 1575 if (vnic->fw_vnic_id == INVALID_VNIC_ID) 1576 continue; 1577 1578 STAILQ_FOREACH(flow, &vnic->flow_list, next) { 1579 mf = flow->filter; 1580 1581 if (mf->filter_type == nf->filter_type && 1582 mf->flags == nf->flags && 1583 mf->src_port == nf->src_port && 1584 mf->src_port_mask == nf->src_port_mask && 1585 mf->dst_port == nf->dst_port && 1586 mf->dst_port_mask == nf->dst_port_mask && 1587 mf->ip_protocol == nf->ip_protocol && 1588 mf->ip_addr_type == nf->ip_addr_type && 1589 mf->ethertype == nf->ethertype && 1590 mf->vni == nf->vni && 1591 mf->tunnel_type == nf->tunnel_type && 1592 mf->l2_ovlan == nf->l2_ovlan && 1593 mf->l2_ovlan_mask == nf->l2_ovlan_mask && 1594 mf->l2_ivlan == nf->l2_ivlan && 1595 mf->l2_ivlan_mask == nf->l2_ivlan_mask && 1596 !memcmp(mf->l2_addr, nf->l2_addr, 1597 RTE_ETHER_ADDR_LEN) && 1598 !memcmp(mf->l2_addr_mask, nf->l2_addr_mask, 1599 RTE_ETHER_ADDR_LEN) && 1600 !memcmp(mf->src_macaddr, nf->src_macaddr, 1601 RTE_ETHER_ADDR_LEN) && 1602 !memcmp(mf->dst_macaddr, nf->dst_macaddr, 1603 RTE_ETHER_ADDR_LEN) && 1604 !memcmp(mf->src_ipaddr, nf->src_ipaddr, 1605 sizeof(nf->src_ipaddr)) && 1606 !memcmp(mf->src_ipaddr_mask, nf->src_ipaddr_mask, 1607 sizeof(nf->src_ipaddr_mask)) && 1608 !memcmp(mf->dst_ipaddr, nf->dst_ipaddr, 1609 sizeof(nf->dst_ipaddr)) && 1610 !memcmp(mf->dst_ipaddr_mask, nf->dst_ipaddr_mask, 1611 sizeof(nf->dst_ipaddr_mask))) { 1612 if (mf->dst_id == nf->dst_id) 1613 return -EEXIST; 1614 /* Free the old filter, update flow 1615 * with new filter 1616 */ 1617 bnxt_update_filter(bp, mf, nf); 1618 STAILQ_REMOVE(&vnic->filter, mf, 1619 bnxt_filter_info, next); 1620 STAILQ_INSERT_TAIL(&vnic->filter, nf, next); 1621 bnxt_free_filter(bp, mf); 1622 flow->filter = nf; 1623 return -EXDEV; 1624 } 1625 } 1626 } 1627 return 0; 1628 } 1629 1630 static struct rte_flow * 1631 bnxt_flow_create(struct rte_eth_dev *dev, 1632 const struct rte_flow_attr *attr, 1633 const struct rte_flow_item pattern[], 1634 const struct rte_flow_action actions[], 1635 struct rte_flow_error *error) 1636 { 1637 struct bnxt *bp = dev->data->dev_private; 1638 struct bnxt_vnic_info *vnic = NULL; 1639 struct bnxt_filter_info *filter; 1640 bool update_flow = false; 1641 struct rte_flow *flow; 1642 int ret = 0; 1643 uint32_t tun_type; 1644 1645 if (BNXT_VF(bp) && !BNXT_VF_IS_TRUSTED(bp)) { 1646 rte_flow_error_set(error, EINVAL, 1647 RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 1648 "Failed to create flow, Not a Trusted VF!"); 1649 return NULL; 1650 } 1651 1652 if (!dev->data->dev_started) { 1653 rte_flow_error_set(error, 1654 EINVAL, 1655 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, 1656 NULL, 1657 "Device must be started"); 1658 return NULL; 1659 } 1660 1661 flow = rte_zmalloc("bnxt_flow", sizeof(struct rte_flow), 0); 1662 if (!flow) { 1663 rte_flow_error_set(error, ENOMEM, 1664 RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 1665 "Failed to allocate memory"); 1666 return flow; 1667 } 1668 1669 bnxt_acquire_flow_lock(bp); 1670 ret = bnxt_flow_args_validate(attr, pattern, actions, error); 1671 if (ret != 0) { 1672 PMD_DRV_LOG(ERR, "Not a validate flow.\n"); 1673 goto free_flow; 1674 } 1675 1676 filter = bnxt_get_unused_filter(bp); 1677 if (filter == NULL) { 1678 PMD_DRV_LOG(ERR, "Not enough resources for a new flow.\n"); 1679 goto free_flow; 1680 } 1681 1682 ret = bnxt_validate_and_parse_flow(dev, pattern, actions, attr, 1683 error, filter); 1684 if (ret != 0) 1685 goto free_filter; 1686 1687 ret = bnxt_match_filter(bp, filter); 1688 if (ret == -EEXIST) { 1689 PMD_DRV_LOG(DEBUG, "Flow already exists.\n"); 1690 /* Clear the filter that was created as part of 1691 * validate_and_parse_flow() above 1692 */ 1693 bnxt_hwrm_clear_l2_filter(bp, filter); 1694 goto free_filter; 1695 } else if (ret == -EXDEV) { 1696 PMD_DRV_LOG(DEBUG, "Flow with same pattern exists\n"); 1697 PMD_DRV_LOG(DEBUG, "Updating with different destination\n"); 1698 update_flow = true; 1699 } 1700 1701 /* If tunnel redirection to a VF/PF is specified then only tunnel_type 1702 * is set and enable is set to the tunnel type. Issue hwrm cmd directly 1703 * in such a case. 1704 */ 1705 if (filter->filter_type == HWRM_CFA_TUNNEL_REDIRECT_FILTER && 1706 filter->enables == filter->tunnel_type) { 1707 ret = bnxt_hwrm_tunnel_redirect_query(bp, &tun_type); 1708 if (ret) { 1709 rte_flow_error_set(error, -ret, 1710 RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 1711 "Unable to query tunnel to VF"); 1712 goto free_filter; 1713 } 1714 if (tun_type == (1U << filter->tunnel_type)) { 1715 ret = 1716 bnxt_hwrm_tunnel_redirect_free(bp, 1717 filter->tunnel_type); 1718 if (ret) { 1719 PMD_DRV_LOG(ERR, 1720 "Unable to free existing tunnel\n"); 1721 rte_flow_error_set(error, -ret, 1722 RTE_FLOW_ERROR_TYPE_HANDLE, 1723 NULL, 1724 "Unable to free preexisting " 1725 "tunnel on VF"); 1726 goto free_filter; 1727 } 1728 } 1729 ret = bnxt_hwrm_tunnel_redirect(bp, filter->tunnel_type); 1730 if (ret) { 1731 rte_flow_error_set(error, -ret, 1732 RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 1733 "Unable to redirect tunnel to VF"); 1734 goto free_filter; 1735 } 1736 vnic = &bp->vnic_info[0]; 1737 goto done; 1738 } 1739 1740 if (filter->filter_type == HWRM_CFA_EM_FILTER) { 1741 filter->enables |= 1742 HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_L2_FILTER_ID; 1743 ret = bnxt_hwrm_set_em_filter(bp, filter->dst_id, filter); 1744 } 1745 1746 if (filter->filter_type == HWRM_CFA_NTUPLE_FILTER) { 1747 filter->enables |= 1748 HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_L2_FILTER_ID; 1749 ret = bnxt_hwrm_set_ntuple_filter(bp, filter->dst_id, filter); 1750 } 1751 1752 vnic = find_matching_vnic(bp, filter); 1753 done: 1754 if (!ret || update_flow) { 1755 flow->filter = filter; 1756 flow->vnic = vnic; 1757 if (update_flow) { 1758 ret = -EXDEV; 1759 goto free_flow; 1760 } 1761 1762 STAILQ_INSERT_TAIL(&vnic->filter, filter, next); 1763 PMD_DRV_LOG(ERR, "Successfully created flow.\n"); 1764 STAILQ_INSERT_TAIL(&vnic->flow_list, flow, next); 1765 bnxt_release_flow_lock(bp); 1766 return flow; 1767 } 1768 1769 free_filter: 1770 bnxt_free_filter(bp, filter); 1771 free_flow: 1772 if (ret == -EEXIST) 1773 rte_flow_error_set(error, ret, 1774 RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 1775 "Matching Flow exists."); 1776 else if (ret == -EXDEV) 1777 rte_flow_error_set(error, 0, 1778 RTE_FLOW_ERROR_TYPE_NONE, NULL, 1779 "Flow with pattern exists, updating destination queue"); 1780 else 1781 rte_flow_error_set(error, -ret, 1782 RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 1783 "Failed to create flow."); 1784 rte_free(flow); 1785 flow = NULL; 1786 bnxt_release_flow_lock(bp); 1787 return flow; 1788 } 1789 1790 static int bnxt_handle_tunnel_redirect_destroy(struct bnxt *bp, 1791 struct bnxt_filter_info *filter, 1792 struct rte_flow_error *error) 1793 { 1794 uint16_t tun_dst_fid; 1795 uint32_t tun_type; 1796 int ret = 0; 1797 1798 ret = bnxt_hwrm_tunnel_redirect_query(bp, &tun_type); 1799 if (ret) { 1800 rte_flow_error_set(error, -ret, 1801 RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 1802 "Unable to query tunnel to VF"); 1803 return ret; 1804 } 1805 if (tun_type == (1U << filter->tunnel_type)) { 1806 ret = bnxt_hwrm_tunnel_redirect_info(bp, filter->tunnel_type, 1807 &tun_dst_fid); 1808 if (ret) { 1809 rte_flow_error_set(error, -ret, 1810 RTE_FLOW_ERROR_TYPE_HANDLE, 1811 NULL, 1812 "tunnel_redirect info cmd fail"); 1813 return ret; 1814 } 1815 PMD_DRV_LOG(INFO, "Pre-existing tunnel fid = %x vf->fid = %x\n", 1816 tun_dst_fid + bp->first_vf_id, bp->fw_fid); 1817 1818 /* Tunnel doesn't belong to this VF, so don't send HWRM 1819 * cmd, just delete the flow from driver 1820 */ 1821 if (bp->fw_fid != (tun_dst_fid + bp->first_vf_id)) 1822 PMD_DRV_LOG(ERR, 1823 "Tunnel does not belong to this VF, skip hwrm_tunnel_redirect_free\n"); 1824 else 1825 ret = bnxt_hwrm_tunnel_redirect_free(bp, 1826 filter->tunnel_type); 1827 } 1828 return ret; 1829 } 1830 1831 static int 1832 bnxt_flow_destroy(struct rte_eth_dev *dev, 1833 struct rte_flow *flow, 1834 struct rte_flow_error *error) 1835 { 1836 struct bnxt *bp = dev->data->dev_private; 1837 struct bnxt_filter_info *filter; 1838 struct bnxt_vnic_info *vnic; 1839 int ret = 0; 1840 1841 bnxt_acquire_flow_lock(bp); 1842 if (!flow) { 1843 rte_flow_error_set(error, EINVAL, 1844 RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 1845 "Invalid flow: failed to destroy flow."); 1846 bnxt_release_flow_lock(bp); 1847 return -EINVAL; 1848 } 1849 1850 filter = flow->filter; 1851 vnic = flow->vnic; 1852 1853 if (!filter) { 1854 rte_flow_error_set(error, EINVAL, 1855 RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 1856 "Invalid flow: failed to destroy flow."); 1857 bnxt_release_flow_lock(bp); 1858 return -EINVAL; 1859 } 1860 1861 if (filter->filter_type == HWRM_CFA_TUNNEL_REDIRECT_FILTER && 1862 filter->enables == filter->tunnel_type) { 1863 ret = bnxt_handle_tunnel_redirect_destroy(bp, 1864 filter, 1865 error); 1866 if (!ret) { 1867 goto done; 1868 } else { 1869 bnxt_release_flow_lock(bp); 1870 return ret; 1871 } 1872 } 1873 1874 ret = bnxt_match_filter(bp, filter); 1875 if (ret == 0) 1876 PMD_DRV_LOG(ERR, "Could not find matching flow\n"); 1877 1878 if (filter->filter_type == HWRM_CFA_EM_FILTER) 1879 ret = bnxt_hwrm_clear_em_filter(bp, filter); 1880 if (filter->filter_type == HWRM_CFA_NTUPLE_FILTER) 1881 ret = bnxt_hwrm_clear_ntuple_filter(bp, filter); 1882 ret = bnxt_hwrm_clear_l2_filter(bp, filter); 1883 1884 done: 1885 if (!ret) { 1886 /* If it is a L2 drop filter, when the filter is created, 1887 * the FW updates the BC/MC records. 1888 * Once this filter is removed, issue the set_rx_mask command 1889 * to reset the BC/MC records in the HW to the settings 1890 * before the drop counter is created. 1891 */ 1892 if (filter->valid_flags & BNXT_FLOW_L2_DROP_FLAG) 1893 bnxt_set_rx_mask_no_vlan(bp, &bp->vnic_info[0]); 1894 1895 STAILQ_REMOVE(&vnic->filter, filter, bnxt_filter_info, next); 1896 bnxt_free_filter(bp, filter); 1897 STAILQ_REMOVE(&vnic->flow_list, flow, rte_flow, next); 1898 rte_free(flow); 1899 1900 /* If this was the last flow associated with this vnic, 1901 * switch the queue back to RSS pool. 1902 */ 1903 if (vnic && !vnic->func_default && 1904 STAILQ_EMPTY(&vnic->flow_list)) { 1905 rte_free(vnic->fw_grp_ids); 1906 if (vnic->rx_queue_cnt > 1) 1907 bnxt_hwrm_vnic_ctx_free(bp, vnic); 1908 1909 bnxt_hwrm_vnic_free(bp, vnic); 1910 vnic->rx_queue_cnt = 0; 1911 } 1912 } else { 1913 rte_flow_error_set(error, -ret, 1914 RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 1915 "Failed to destroy flow."); 1916 } 1917 1918 bnxt_release_flow_lock(bp); 1919 return ret; 1920 } 1921 1922 static int 1923 bnxt_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error) 1924 { 1925 struct bnxt *bp = dev->data->dev_private; 1926 struct bnxt_filter_info *filter = NULL; 1927 struct bnxt_vnic_info *vnic; 1928 struct rte_flow *flow; 1929 unsigned int i; 1930 int ret = 0; 1931 1932 bnxt_acquire_flow_lock(bp); 1933 for (i = 0; i < bp->max_vnics; i++) { 1934 vnic = &bp->vnic_info[i]; 1935 if (vnic && vnic->fw_vnic_id == INVALID_VNIC_ID) 1936 continue; 1937 1938 while (!STAILQ_EMPTY(&vnic->flow_list)) { 1939 flow = STAILQ_FIRST(&vnic->flow_list); 1940 filter = flow->filter; 1941 1942 if (filter->filter_type == 1943 HWRM_CFA_TUNNEL_REDIRECT_FILTER && 1944 filter->enables == filter->tunnel_type) { 1945 ret = 1946 bnxt_handle_tunnel_redirect_destroy(bp, 1947 filter, 1948 error); 1949 if (!ret) { 1950 goto done; 1951 } else { 1952 bnxt_release_flow_lock(bp); 1953 return ret; 1954 } 1955 } 1956 1957 if (filter->filter_type == HWRM_CFA_EM_FILTER) 1958 ret = bnxt_hwrm_clear_em_filter(bp, filter); 1959 if (filter->filter_type == HWRM_CFA_NTUPLE_FILTER) 1960 ret = bnxt_hwrm_clear_ntuple_filter(bp, filter); 1961 else if (i) 1962 ret = bnxt_hwrm_clear_l2_filter(bp, filter); 1963 1964 if (ret) { 1965 rte_flow_error_set 1966 (error, 1967 -ret, 1968 RTE_FLOW_ERROR_TYPE_HANDLE, 1969 NULL, 1970 "Failed to flush flow in HW."); 1971 bnxt_release_flow_lock(bp); 1972 return -rte_errno; 1973 } 1974 done: 1975 STAILQ_REMOVE(&vnic->flow_list, flow, 1976 rte_flow, next); 1977 1978 STAILQ_REMOVE(&vnic->filter, 1979 filter, 1980 bnxt_filter_info, 1981 next); 1982 bnxt_free_filter(bp, filter); 1983 1984 rte_free(flow); 1985 1986 /* If this was the last flow associated with this vnic, 1987 * switch the queue back to RSS pool. 1988 */ 1989 if (STAILQ_EMPTY(&vnic->flow_list)) { 1990 rte_free(vnic->fw_grp_ids); 1991 if (vnic->rx_queue_cnt > 1) 1992 bnxt_hwrm_vnic_ctx_free(bp, vnic); 1993 bnxt_hwrm_vnic_free(bp, vnic); 1994 vnic->rx_queue_cnt = 0; 1995 } 1996 } 1997 } 1998 1999 bnxt_release_flow_lock(bp); 2000 return ret; 2001 } 2002 2003 const struct rte_flow_ops bnxt_flow_ops = { 2004 .validate = bnxt_flow_validate, 2005 .create = bnxt_flow_create, 2006 .destroy = bnxt_flow_destroy, 2007 .flush = bnxt_flow_flush, 2008 }; 2009