1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2021-2023 Broadcom 3 * All rights reserved. 4 */ 5 6 #include <glob.h> 7 #include <libgen.h> 8 #include <stdio.h> 9 #include <net/if.h> 10 #include <sys/ioctl.h> 11 #include <sys/socket.h> 12 #include <unistd.h> 13 14 #include "bnxt.h" 15 #include "bnxt_vnic.h" 16 #include "bnxt_hwrm.h" 17 #include "bnxt_tf_common.h" 18 #include "bnxt_tf_pmd_shim.h" 19 #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG 20 #include "ulp_template_debug_proto.h" 21 #endif 22 23 24 int 25 bnxt_tunnel_dst_port_free(struct bnxt *bp, 26 uint16_t port, 27 uint8_t type) 28 { 29 return bnxt_hwrm_tunnel_dst_port_free(bp, 30 port, 31 type); 32 } 33 34 int 35 bnxt_tunnel_dst_port_alloc(struct bnxt *bp, 36 uint16_t port, 37 uint8_t type) 38 { 39 int rc = 0; 40 rc = bnxt_hwrm_tunnel_dst_port_alloc(bp, 41 port, 42 type); 43 if (rc) { 44 PMD_DRV_LOG_LINE(ERR, "Tunnel type:%d alloc failed for port:%d error:%s", 45 type, port, 46 (rc == 47 HWRM_TUNNEL_DST_PORT_ALLOC_OUTPUT_ERROR_INFO_ERR_ALLOCATED) ? 48 "already allocated" : "no resource"); 49 } 50 return rc; 51 } 52 53 int 54 bnxt_tunnel_upar_id_get(struct bnxt *bp, 55 uint8_t type, 56 uint8_t *upar_id) 57 { 58 return bnxt_hwrm_tunnel_upar_id_get(bp, 59 upar_id, 60 type); 61 } 62 63 int32_t bnxt_rss_config_action_apply(struct bnxt_ulp_mapper_parms *parms) 64 { 65 struct bnxt_vnic_info *vnic = NULL; 66 struct bnxt *bp = NULL; 67 uint64_t rss_types; 68 uint16_t hwrm_type; 69 uint32_t rss_level, key_len; 70 uint8_t *rss_key; 71 struct ulp_rte_act_prop *ap = parms->act_prop; 72 int32_t rc = -EINVAL; 73 uint8_t rss_func; 74 75 bp = bnxt_pmd_get_bp(parms->port_id); 76 if (bp == NULL) { 77 BNXT_DRV_DBG(ERR, "Invalid bp for port_id %u\n", 78 parms->port_id); 79 return rc; 80 } 81 vnic = bnxt_get_default_vnic(bp); 82 if (vnic == NULL) { 83 BNXT_DRV_DBG(ERR, "default vnic not available for %u\n", 84 parms->port_id); 85 return rc; 86 } 87 88 /* get the details */ 89 memcpy(&rss_func, &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_FUNC], 90 BNXT_ULP_ACT_PROP_SZ_RSS_FUNC); 91 memcpy(&rss_types, &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_TYPES], 92 BNXT_ULP_ACT_PROP_SZ_RSS_TYPES); 93 memcpy(&rss_level, &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_LEVEL], 94 BNXT_ULP_ACT_PROP_SZ_RSS_LEVEL); 95 memcpy(&key_len, &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_KEY_LEN], 96 BNXT_ULP_ACT_PROP_SZ_RSS_KEY_LEN); 97 rss_key = &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_KEY]; 98 99 rc = bnxt_rte_flow_to_hwrm_ring_select_mode((enum rte_eth_hash_function)rss_func, 100 rss_types, bp, vnic); 101 if (rc != 0) { 102 BNXT_DRV_DBG(ERR, "Error unsupported rss hash func\n"); 103 return rc; 104 } 105 106 hwrm_type = bnxt_rte_to_hwrm_hash_types(rss_types); 107 if (!hwrm_type) { 108 BNXT_DRV_DBG(ERR, "Error unsupported rss config type\n"); 109 return rc; 110 } 111 /* Configure RSS only if the queue count is > 1 */ 112 if (vnic->rx_queue_cnt > 1) { 113 vnic->hash_type = hwrm_type; 114 vnic->hash_mode = 115 bnxt_rte_to_hwrm_hash_level(bp, rss_types, rss_level); 116 memcpy(vnic->rss_hash_key, rss_key, 117 BNXT_ULP_ACT_PROP_SZ_RSS_KEY); 118 rc = bnxt_hwrm_vnic_rss_cfg(bp, vnic); 119 if (rc) { 120 BNXT_DRV_DBG(ERR, "Error configuring vnic RSS config\n"); 121 return rc; 122 } 123 BNXT_DRV_DBG(INFO, "Rss config successfully applied\n"); 124 } 125 return 0; 126 } 127 128 #define PARENT_PHY_INTF_PATH "/sys/bus/pci/devices/%s/physfn/net/*" 129 #define ULP_PRT_MAC_PATH "/sys/bus/pci/devices/%s/physfn/net/%s/address" 130 131 #define ULP_FILE_PATH_SIZE 256 132 133 static int32_t glob_error_fn(const char *epath, int32_t eerrno) 134 { 135 BNXT_DRV_DBG(ERR, "path %s error %d\n", epath, eerrno); 136 return 0; 137 } 138 139 static int32_t ulp_pmd_get_mac_by_pci(const char *pci_name, uint8_t *mac) 140 { 141 char path[ULP_FILE_PATH_SIZE], dev_str[ULP_FILE_PATH_SIZE]; 142 char *intf_name; 143 glob_t gres; 144 FILE *fp; 145 int32_t rc = -EINVAL; 146 147 memset(path, 0, sizeof(path)); 148 sprintf(path, PARENT_PHY_INTF_PATH, pci_name); 149 150 /* There can be only one, no more, no less */ 151 if (glob(path, 0, glob_error_fn, &gres) == 0) { 152 if (gres.gl_pathc != 1) 153 return rc; 154 155 /* Replace the PCI address with interface name and get index */ 156 intf_name = basename(gres.gl_pathv[0]); 157 sprintf(path, ULP_PRT_MAC_PATH, pci_name, intf_name); 158 159 fp = fopen(path, "r"); 160 if (!fp) { 161 BNXT_DRV_DBG(ERR, "Error in getting bond mac address\n"); 162 return rc; 163 } 164 165 memset(dev_str, 0, sizeof(dev_str)); 166 if (fgets(dev_str, sizeof(dev_str), fp) == NULL) { 167 BNXT_DRV_DBG(ERR, "Error in reading %s\n", path); 168 fclose(fp); 169 return rc; 170 } 171 172 if (sscanf(dev_str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx\n", 173 &mac[0], &mac[1], &mac[2], 174 &mac[3], &mac[4], &mac[5]) == 6) 175 rc = 0; 176 fclose(fp); 177 } 178 return rc; 179 } 180 181 int32_t bnxt_pmd_get_parent_mac_addr(struct bnxt_ulp_mapper_parms *parms, 182 uint8_t *mac) 183 { 184 struct bnxt *bp = NULL; 185 int32_t rc = -EINVAL; 186 187 bp = bnxt_pmd_get_bp(parms->port_id); 188 if (bp == NULL) { 189 BNXT_DRV_DBG(ERR, "Invalid bp for port_id %u\n", 190 parms->port_id); 191 return rc; 192 } 193 return ulp_pmd_get_mac_by_pci(bp->pdev->name, &mac[2]); 194 } 195 196 uint16_t 197 bnxt_pmd_get_svif(uint16_t port_id, bool func_svif, 198 enum bnxt_ulp_intf_type type) 199 { 200 struct rte_eth_dev *eth_dev; 201 struct bnxt *bp; 202 203 eth_dev = &rte_eth_devices[port_id]; 204 if (rte_eth_dev_is_repr(eth_dev)) { 205 struct bnxt_representor *vfr = eth_dev->data->dev_private; 206 if (!vfr) 207 return 0; 208 209 if (type == BNXT_ULP_INTF_TYPE_VF_REP) 210 return vfr->svif; 211 212 eth_dev = vfr->parent_dev; 213 } 214 215 bp = eth_dev->data->dev_private; 216 217 return func_svif ? bp->func_svif : bp->port_svif; 218 } 219 220 void 221 bnxt_pmd_get_iface_mac(uint16_t port, enum bnxt_ulp_intf_type type, 222 uint8_t *mac, uint8_t *parent_mac) 223 { 224 struct rte_eth_dev *eth_dev; 225 struct bnxt *bp; 226 227 if (type != BNXT_ULP_INTF_TYPE_TRUSTED_VF && 228 type != BNXT_ULP_INTF_TYPE_PF) 229 return; 230 231 eth_dev = &rte_eth_devices[port]; 232 bp = eth_dev->data->dev_private; 233 memcpy(mac, bp->mac_addr, RTE_ETHER_ADDR_LEN); 234 235 if (type == BNXT_ULP_INTF_TYPE_TRUSTED_VF) 236 memcpy(parent_mac, bp->parent->mac_addr, RTE_ETHER_ADDR_LEN); 237 } 238 239 uint16_t 240 bnxt_pmd_get_parent_vnic_id(uint16_t port, enum bnxt_ulp_intf_type type) 241 { 242 struct rte_eth_dev *eth_dev; 243 struct bnxt *bp; 244 245 if (type != BNXT_ULP_INTF_TYPE_TRUSTED_VF) 246 return 0; 247 248 eth_dev = &rte_eth_devices[port]; 249 bp = eth_dev->data->dev_private; 250 251 return bp->parent->vnic; 252 } 253 254 uint16_t 255 bnxt_pmd_get_vnic_id(uint16_t port, enum bnxt_ulp_intf_type type) 256 { 257 struct rte_eth_dev *eth_dev; 258 struct bnxt_vnic_info *vnic; 259 struct bnxt *bp; 260 261 eth_dev = &rte_eth_devices[port]; 262 if (rte_eth_dev_is_repr(eth_dev)) { 263 struct bnxt_representor *vfr = eth_dev->data->dev_private; 264 if (!vfr) 265 return 0; 266 267 if (type == BNXT_ULP_INTF_TYPE_VF_REP) 268 return vfr->dflt_vnic_id; 269 270 eth_dev = vfr->parent_dev; 271 } 272 273 bp = eth_dev->data->dev_private; 274 275 vnic = bnxt_get_default_vnic(bp); 276 277 return vnic->fw_vnic_id; 278 } 279 280 uint16_t 281 bnxt_pmd_get_fw_func_id(uint16_t port, enum bnxt_ulp_intf_type type) 282 { 283 struct rte_eth_dev *eth_dev; 284 struct bnxt *bp; 285 286 eth_dev = &rte_eth_devices[port]; 287 if (rte_eth_dev_is_repr(eth_dev)) { 288 struct bnxt_representor *vfr = eth_dev->data->dev_private; 289 if (!vfr) 290 return 0; 291 292 if (type == BNXT_ULP_INTF_TYPE_VF_REP) 293 return vfr->fw_fid; 294 295 eth_dev = vfr->parent_dev; 296 } 297 298 bp = eth_dev->data->dev_private; 299 300 return bp->fw_fid; 301 } 302 303 enum bnxt_ulp_intf_type 304 bnxt_pmd_get_interface_type(uint16_t port) 305 { 306 struct rte_eth_dev *eth_dev; 307 struct bnxt *bp; 308 309 eth_dev = &rte_eth_devices[port]; 310 if (rte_eth_dev_is_repr(eth_dev)) 311 return BNXT_ULP_INTF_TYPE_VF_REP; 312 313 bp = eth_dev->data->dev_private; 314 if (BNXT_PF(bp)) 315 return BNXT_ULP_INTF_TYPE_PF; 316 else if (BNXT_VF_IS_TRUSTED(bp)) 317 return BNXT_ULP_INTF_TYPE_TRUSTED_VF; 318 else if (BNXT_VF(bp)) 319 return BNXT_ULP_INTF_TYPE_VF; 320 321 return BNXT_ULP_INTF_TYPE_INVALID; 322 } 323 324 uint16_t 325 bnxt_pmd_get_phy_port_id(uint16_t port_id) 326 { 327 struct bnxt_representor *vfr; 328 struct rte_eth_dev *eth_dev; 329 struct bnxt *bp; 330 331 eth_dev = &rte_eth_devices[port_id]; 332 if (rte_eth_dev_is_repr(eth_dev)) { 333 vfr = eth_dev->data->dev_private; 334 if (!vfr) 335 return 0; 336 337 eth_dev = vfr->parent_dev; 338 } 339 340 bp = eth_dev->data->dev_private; 341 342 return BNXT_PF(bp) ? bp->pf->port_id : bp->parent->port_id; 343 } 344 345 uint16_t 346 bnxt_pmd_get_parif(uint16_t port_id, enum bnxt_ulp_intf_type type) 347 { 348 struct rte_eth_dev *eth_dev; 349 struct bnxt *bp; 350 351 eth_dev = &rte_eth_devices[port_id]; 352 if (rte_eth_dev_is_repr(eth_dev)) { 353 struct bnxt_representor *vfr = eth_dev->data->dev_private; 354 if (!vfr) 355 return 0; 356 357 if (type == BNXT_ULP_INTF_TYPE_VF_REP) 358 return vfr->fw_fid - 1; 359 360 eth_dev = vfr->parent_dev; 361 } 362 363 bp = eth_dev->data->dev_private; 364 365 return BNXT_PF(bp) ? bp->fw_fid - 1 : bp->parent->fid - 1; 366 } 367 368 uint16_t 369 bnxt_pmd_get_vport(uint16_t port_id) 370 { 371 return (1 << bnxt_pmd_get_phy_port_id(port_id)); 372 } 373 374 int32_t 375 bnxt_pmd_set_unicast_rxmask(struct rte_eth_dev *eth_dev) 376 { 377 struct bnxt *bp = eth_dev->data->dev_private; 378 struct bnxt_vnic_info *vnic; 379 uint32_t old_flags; 380 int32_t rc; 381 382 rc = is_bnxt_in_error(bp); 383 if (rc) 384 return rc; 385 386 /* Filter settings will get applied when port is started */ 387 if (!eth_dev->data->dev_started) 388 return 0; 389 390 if (bp->vnic_info == NULL) 391 return 0; 392 393 vnic = bnxt_get_default_vnic(bp); 394 395 old_flags = vnic->flags; 396 vnic->flags |= BNXT_VNIC_INFO_UCAST; 397 vnic->flags &= ~BNXT_VNIC_INFO_PROMISC; 398 vnic->flags &= ~BNXT_VNIC_INFO_ALLMULTI; 399 vnic->flags &= ~BNXT_VNIC_INFO_BCAST; 400 rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL); 401 if (rc != 0) 402 vnic->flags = old_flags; 403 404 return rc; 405 } 406 407 int32_t bnxt_pmd_queue_action_create(struct bnxt_ulp_mapper_parms *parms, 408 uint16_t *vnic_idx, uint16_t *vnic_id) 409 { 410 struct bnxt *bp = NULL; 411 uint16_t q_index; 412 struct ulp_rte_act_prop *ap = parms->act_prop; 413 414 bp = bnxt_pmd_get_bp(parms->port_id); 415 if (bp == NULL) { 416 BNXT_DRV_DBG(ERR, "Invalid bp for port_id %u\n", 417 parms->port_id); 418 return -EINVAL; 419 } 420 421 memcpy(&q_index, &ap->act_details[BNXT_ULP_ACT_PROP_IDX_QUEUE_INDEX], 422 BNXT_ULP_ACT_PROP_SZ_QUEUE_INDEX); 423 424 return bnxt_vnic_queue_action_alloc(bp, q_index, vnic_idx, vnic_id); 425 } 426 427 int32_t bnxt_pmd_queue_action_delete(struct bnxt *bp, uint16_t vnic_idx) 428 { 429 return bnxt_vnic_queue_action_free(bp, vnic_idx); 430 } 431 432 int32_t bnxt_pmd_rss_action_create(struct bnxt_ulp_mapper_parms *parms, 433 uint16_t *vnic_idx, uint16_t *vnic_id) 434 { 435 struct bnxt *bp = NULL; 436 struct bnxt_vnic_rss_info rss_info = {0}; 437 struct ulp_rte_act_prop *ap = parms->act_prop; 438 439 bp = bnxt_pmd_get_bp(parms->port_id); 440 if (bp == NULL) { 441 BNXT_DRV_DBG(ERR, "Invalid bp for port_id %u\n", 442 parms->port_id); 443 return -EINVAL; 444 } 445 446 /* get the details */ 447 memset(&rss_info, 0, sizeof(rss_info)); 448 memcpy(&rss_info.rss_func, 449 &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_FUNC], 450 BNXT_ULP_ACT_PROP_SZ_RSS_FUNC); 451 memcpy(&rss_info.rss_types, 452 &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_TYPES], 453 BNXT_ULP_ACT_PROP_SZ_RSS_TYPES); 454 memcpy(&rss_info.rss_level, 455 &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_LEVEL], 456 BNXT_ULP_ACT_PROP_SZ_RSS_LEVEL); 457 memcpy(&rss_info.key_len, 458 &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_KEY_LEN], 459 BNXT_ULP_ACT_PROP_SZ_RSS_KEY_LEN); 460 if (rss_info.key_len) 461 rss_info.key = &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_KEY]; 462 memcpy(&rss_info.queue_num, 463 &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_QUEUE_NUM], 464 BNXT_ULP_ACT_PROP_SZ_RSS_QUEUE_NUM); 465 466 /* Validate the size of the queue list */ 467 if (sizeof(rss_info.queue_list) < BNXT_ULP_ACT_PROP_SZ_RSS_QUEUE) { 468 BNXT_DRV_DBG(ERR, "Mismatch of RSS queue size in template\n"); 469 return -EINVAL; 470 } 471 memcpy(rss_info.queue_list, 472 &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_QUEUE], 473 BNXT_ULP_ACT_PROP_SZ_RSS_QUEUE); 474 475 return bnxt_vnic_rss_action_alloc(bp, &rss_info, vnic_idx, vnic_id); 476 } 477 478 int32_t bnxt_pmd_rss_action_delete(struct bnxt *bp, uint16_t vnic_idx) 479 { 480 return bnxt_vnic_rss_action_free(bp, vnic_idx); 481 } 482 483 #define ULP_GLOBAL_TUNNEL_UDP_PORT_SHIFT 32 484 #define ULP_GLOBAL_TUNNEL_UDP_PORT_MASK ((uint16_t)0xffff) 485 #define ULP_GLOBAL_TUNNEL_PORT_ID_SHIFT 16 486 #define ULP_GLOBAL_TUNNEL_PORT_ID_MASK ((uint16_t)0xffff) 487 #define ULP_GLOBAL_TUNNEL_UPARID_SHIFT 8 488 #define ULP_GLOBAL_TUNNEL_UPARID_MASK ((uint16_t)0xff) 489 #define ULP_GLOBAL_TUNNEL_TYPE_SHIFT 0 490 #define ULP_GLOBAL_TUNNEL_TYPE_MASK ((uint16_t)0xff) 491 492 /* Extracts the dpdk port id and tunnel type from the handle */ 493 static void 494 bnxt_pmd_global_reg_hndl_to_data(uint64_t handle, uint16_t *port, 495 uint8_t *upar_id, uint8_t *type, 496 uint16_t *udp_port) 497 { 498 *type = (handle >> ULP_GLOBAL_TUNNEL_TYPE_SHIFT) & 499 ULP_GLOBAL_TUNNEL_TYPE_MASK; 500 *upar_id = (handle >> ULP_GLOBAL_TUNNEL_UPARID_SHIFT) & 501 ULP_GLOBAL_TUNNEL_UPARID_MASK; 502 *port = (handle >> ULP_GLOBAL_TUNNEL_PORT_ID_SHIFT) & 503 ULP_GLOBAL_TUNNEL_PORT_ID_MASK; 504 *udp_port = (handle >> ULP_GLOBAL_TUNNEL_UDP_PORT_SHIFT) & 505 ULP_GLOBAL_TUNNEL_UDP_PORT_MASK; 506 } 507 508 /* Packs the dpdk port id and tunnel type in the handle */ 509 static void 510 bnxt_pmd_global_reg_data_to_hndl(uint16_t port_id, uint8_t upar_id, 511 uint8_t type, uint16_t udp_port, 512 uint64_t *handle) 513 { 514 *handle = 0; 515 *handle |= (udp_port & ULP_GLOBAL_TUNNEL_UDP_PORT_MASK); 516 *handle <<= ULP_GLOBAL_TUNNEL_UDP_PORT_SHIFT; 517 *handle |= (port_id & ULP_GLOBAL_TUNNEL_PORT_ID_MASK) << 518 ULP_GLOBAL_TUNNEL_PORT_ID_SHIFT; 519 *handle |= (upar_id & ULP_GLOBAL_TUNNEL_UPARID_MASK) << 520 ULP_GLOBAL_TUNNEL_UPARID_SHIFT; 521 *handle |= (type & ULP_GLOBAL_TUNNEL_TYPE_MASK); 522 } 523 524 /* Sets or resets the tunnel ports. 525 * If dport == 0, then the port_id and type are retrieved from the handle. 526 * otherwise, the incoming port_id, type, and dport are used. 527 * The type is enum ulp_mapper_ulp_global_tunnel_type 528 */ 529 int32_t 530 bnxt_pmd_global_tunnel_set(struct bnxt_ulp_context *ulp_ctx, 531 uint16_t port_id, uint8_t type, 532 uint16_t udp_port, uint64_t *handle) 533 { 534 uint8_t hwtype = 0, ltype, lupar_id = 0; 535 struct rte_eth_dev *eth_dev; 536 struct rte_eth_udp_tunnel udp_tunnel = { 0 }; 537 uint32_t *ulp_flags; 538 struct bnxt *bp; 539 int32_t rc = 0; 540 uint16_t ludp_port = udp_port; 541 542 if (!udp_port) { 543 /* Free based on the handle */ 544 if (!handle) { 545 BNXT_DRV_DBG(ERR, "Free with invalid handle\n"); 546 return -EINVAL; 547 } 548 bnxt_pmd_global_reg_hndl_to_data(*handle, &port_id, 549 &lupar_id, <ype, &ludp_port); 550 } 551 552 /* convert to HWRM type */ 553 switch (type) { 554 case BNXT_ULP_RESOURCE_SUB_TYPE_GLOBAL_REGISTER_CUST_VXLAN: 555 udp_tunnel.prot_type = RTE_ETH_TUNNEL_TYPE_VXLAN; 556 break; 557 case BNXT_ULP_RESOURCE_SUB_TYPE_GLOBAL_REGISTER_CUST_ECPRI: 558 udp_tunnel.prot_type = RTE_ETH_TUNNEL_TYPE_ECPRI; 559 break; 560 case BNXT_ULP_RESOURCE_SUB_TYPE_GLOBAL_REGISTER_CUST_VXLAN_GPE: 561 udp_tunnel.prot_type = RTE_ETH_TUNNEL_TYPE_VXLAN_GPE; 562 break; 563 case BNXT_ULP_RESOURCE_SUB_TYPE_GLOBAL_REGISTER_CUST_GENEVE: 564 udp_tunnel.prot_type = RTE_ETH_TUNNEL_TYPE_GENEVE; 565 break; 566 case BNXT_ULP_RESOURCE_SUB_TYPE_GLOBAL_REGISTER_CUST_VXLAN_GPE_V6: 567 hwtype = HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN_GPE_V6; 568 break; 569 case BNXT_ULP_RESOURCE_SUB_TYPE_GLOBAL_REGISTER_CUST_VXLAN_IP: 570 hwtype = HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN_V4; 571 break; 572 default: 573 BNXT_DRV_DBG(ERR, "Tunnel Type (%d) invalid\n", type); 574 return -EINVAL; 575 } 576 577 if (udp_tunnel.prot_type) { 578 udp_tunnel.udp_port = ludp_port; 579 if (!rte_eth_dev_is_valid_port(port_id)) { 580 PMD_DRV_LOG_LINE(ERR, "Invalid port %d", port_id); 581 return -EINVAL; 582 } 583 584 eth_dev = &rte_eth_devices[port_id]; 585 if (!is_bnxt_supported(eth_dev)) { 586 PMD_DRV_LOG_LINE(ERR, "Device %d not supported", port_id); 587 return -EINVAL; 588 } 589 590 if (udp_port) { 591 rc = bnxt_udp_tunnel_port_add_op(eth_dev, &udp_tunnel); 592 } else { 593 /* TODO: Make the counters shareable so the resource 594 * free can be synced up between core dpdk path and 595 * the tf path. 596 */ 597 if (eth_dev->data->dev_started != 0) 598 rc = bnxt_udp_tunnel_port_del_op(eth_dev, &udp_tunnel); 599 } 600 } else { 601 bp = bnxt_pmd_get_bp(port_id); 602 if (!bp) { 603 BNXT_DRV_DBG(ERR, "Unable to get dev by port %d\n", 604 port_id); 605 return -EINVAL; 606 } 607 if (udp_port) 608 rc = bnxt_hwrm_tunnel_dst_port_alloc(bp, udp_port, 609 hwtype); 610 else 611 rc = bnxt_hwrm_tunnel_dst_port_free(bp, ludp_port, 612 hwtype); 613 } 614 615 if (rc) { 616 PMD_DRV_LOG_LINE(ERR, "Tunnel set failed for port:%d error:%d", 617 port_id, rc); 618 return rc; 619 } 620 #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG 621 ulp_mapper_global_register_tbl_dump(type, udp_port); 622 #endif 623 if (udp_port) 624 bnxt_pmd_global_reg_data_to_hndl(port_id, lupar_id, 625 type, udp_port, handle); 626 627 if (type == BNXT_ULP_RESOURCE_SUB_TYPE_GLOBAL_REGISTER_CUST_VXLAN || 628 type == BNXT_ULP_RESOURCE_SUB_TYPE_GLOBAL_REGISTER_CUST_VXLAN_IP) { 629 ulp_flags = &ulp_ctx->cfg_data->ulp_flags; 630 if (udp_port) 631 *ulp_flags |= BNXT_ULP_DYNAMIC_VXLAN_PORT; 632 else 633 *ulp_flags &= ~BNXT_ULP_DYNAMIC_VXLAN_PORT; 634 } 635 if (type == BNXT_ULP_RESOURCE_SUB_TYPE_GLOBAL_REGISTER_CUST_GENEVE) { 636 ulp_flags = &ulp_ctx->cfg_data->ulp_flags; 637 if (udp_port) 638 *ulp_flags |= BNXT_ULP_DYNAMIC_GENEVE_PORT; 639 else 640 *ulp_flags &= ~BNXT_ULP_DYNAMIC_GENEVE_PORT; 641 } 642 643 return rc; 644 } 645 646 #define BNXT_ULP_HOT_UP_DYNAMIC_ENV_VAR "BNXT_ULP_T_HA_SUPPORT" 647 /* This function queries the linux shell variable to determine 648 * whether Hot upgrade should be disabled or not. 649 * If BNXT_ULP_T_HA_SUPPORT is set to zero explicitly then 650 * hotupgrade is disabled. 651 */ 652 static bool bnxt_pmd_get_hot_upgrade_env(void) 653 { 654 char *env; 655 bool hot_up = 1; 656 657 env = getenv(BNXT_ULP_HOT_UP_DYNAMIC_ENV_VAR); 658 if (env && strcmp(env, "0") == 0) 659 hot_up = 0; 660 return hot_up; 661 } 662 663 int32_t bnxt_pmd_bd_act_set(uint16_t port_id, uint32_t act) 664 { 665 struct rte_eth_dev *eth_dev; 666 int32_t rc = -EINVAL; 667 668 eth_dev = &rte_eth_devices[port_id]; 669 if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) { 670 struct bnxt_representor *vfr = eth_dev->data->dev_private; 671 if (!vfr) 672 return rc; 673 vfr->vfr_tx_cfa_action = act; 674 } else { 675 struct bnxt *bp = eth_dev->data->dev_private; 676 bp->tx_cfa_action = act; 677 } 678 679 return 0; 680 } 681 682 static bool hot_up_api; 683 static bool hot_up_configured_by_api; 684 /* There are two ways to configure hot upgrade. 685 * By either calling this bnxt_pmd_configure_hot_upgrade API or 686 * setting the BNXT_ULP_T_HA_SUPPORT environment variable. 687 * bnxt_pmd_configure_hot_upgrade takes precedence over the 688 * environment variable way. Once the setting is done through 689 * bnxt_pmd_configure_hot_upgrade, can't switch back to env 690 * variable. 691 * 692 * bnxt_pmd_configure_hot_upgrade must be called before 693 * dev_start eth_dev_ops is called for the configuration to 694 * take effect. 695 */ 696 void bnxt_pmd_configure_hot_upgrade(bool enable) 697 { 698 hot_up_configured_by_api = true; 699 hot_up_api = enable; 700 } 701 702 bool bnxt_pmd_get_hot_up_config(void) 703 { 704 if (hot_up_configured_by_api) 705 return hot_up_api; 706 707 return bnxt_pmd_get_hot_upgrade_env(); 708 } 709