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