1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2014-2018 Broadcom 3 * All rights reserved. 4 */ 5 6 #include <inttypes.h> 7 #include <stdbool.h> 8 9 #include <rte_dev.h> 10 #include <rte_ethdev_driver.h> 11 #include <rte_ethdev_pci.h> 12 #include <rte_malloc.h> 13 #include <rte_cycles.h> 14 #include <rte_alarm.h> 15 #include <rte_kvargs.h> 16 #include <rte_vect.h> 17 18 #include "bnxt.h" 19 #include "bnxt_filter.h" 20 #include "bnxt_hwrm.h" 21 #include "bnxt_irq.h" 22 #include "bnxt_reps.h" 23 #include "bnxt_ring.h" 24 #include "bnxt_rxq.h" 25 #include "bnxt_rxr.h" 26 #include "bnxt_stats.h" 27 #include "bnxt_txq.h" 28 #include "bnxt_txr.h" 29 #include "bnxt_vnic.h" 30 #include "hsi_struct_def_dpdk.h" 31 #include "bnxt_nvm_defs.h" 32 #include "bnxt_tf_common.h" 33 #include "ulp_flow_db.h" 34 #include "rte_pmd_bnxt.h" 35 36 #define DRV_MODULE_NAME "bnxt" 37 static const char bnxt_version[] = 38 "Broadcom NetXtreme driver " DRV_MODULE_NAME; 39 40 /* 41 * The set of PCI devices this driver supports 42 */ 43 static const struct rte_pci_id bnxt_pci_id_map[] = { 44 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 45 BROADCOM_DEV_ID_STRATUS_NIC_VF1) }, 46 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 47 BROADCOM_DEV_ID_STRATUS_NIC_VF2) }, 48 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_STRATUS_NIC) }, 49 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57414_VF) }, 50 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57304_VF) }, 51 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_NS2) }, 52 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_VF) }, 53 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57407_MF) }, 54 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_5741X_VF) }, 55 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_5731X_VF) }, 56 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57417_MF) }, 57 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57412) }, 58 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57414) }, 59 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57416_RJ45) }, 60 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57417_RJ45) }, 61 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57412_MF) }, 62 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57317_RJ45) }, 63 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57417_SFP) }, 64 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57416_SFP) }, 65 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57317_SFP) }, 66 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57414_MF) }, 67 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57416_MF) }, 68 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_58802) }, 69 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_58804) }, 70 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_58808) }, 71 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_58802_VF) }, 72 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57508) }, 73 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57504) }, 74 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57502) }, 75 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57500_VF1) }, 76 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57500_VF2) }, 77 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57508_MF1) }, 78 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57504_MF1) }, 79 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57502_MF1) }, 80 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57508_MF2) }, 81 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57504_MF2) }, 82 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57502_MF2) }, 83 { .vendor_id = 0, /* sentinel */ }, 84 }; 85 86 #define BNXT_DEVARG_TRUFLOW "host-based-truflow" 87 #define BNXT_DEVARG_FLOW_XSTAT "flow-xstat" 88 #define BNXT_DEVARG_MAX_NUM_KFLOWS "max-num-kflows" 89 #define BNXT_DEVARG_REPRESENTOR "representor" 90 #define BNXT_DEVARG_REP_BASED_PF "rep-based-pf" 91 #define BNXT_DEVARG_REP_IS_PF "rep-is-pf" 92 #define BNXT_DEVARG_REP_Q_R2F "rep-q-r2f" 93 #define BNXT_DEVARG_REP_Q_F2R "rep-q-f2r" 94 #define BNXT_DEVARG_REP_FC_R2F "rep-fc-r2f" 95 #define BNXT_DEVARG_REP_FC_F2R "rep-fc-f2r" 96 97 static const char *const bnxt_dev_args[] = { 98 BNXT_DEVARG_REPRESENTOR, 99 BNXT_DEVARG_TRUFLOW, 100 BNXT_DEVARG_FLOW_XSTAT, 101 BNXT_DEVARG_MAX_NUM_KFLOWS, 102 BNXT_DEVARG_REP_BASED_PF, 103 BNXT_DEVARG_REP_IS_PF, 104 BNXT_DEVARG_REP_Q_R2F, 105 BNXT_DEVARG_REP_Q_F2R, 106 BNXT_DEVARG_REP_FC_R2F, 107 BNXT_DEVARG_REP_FC_F2R, 108 NULL 109 }; 110 111 /* 112 * truflow == false to disable the feature 113 * truflow == true to enable the feature 114 */ 115 #define BNXT_DEVARG_TRUFLOW_INVALID(truflow) ((truflow) > 1) 116 117 /* 118 * flow_xstat == false to disable the feature 119 * flow_xstat == true to enable the feature 120 */ 121 #define BNXT_DEVARG_FLOW_XSTAT_INVALID(flow_xstat) ((flow_xstat) > 1) 122 123 /* 124 * rep_is_pf == false to indicate VF representor 125 * rep_is_pf == true to indicate PF representor 126 */ 127 #define BNXT_DEVARG_REP_IS_PF_INVALID(rep_is_pf) ((rep_is_pf) > 1) 128 129 /* 130 * rep_based_pf == Physical index of the PF 131 */ 132 #define BNXT_DEVARG_REP_BASED_PF_INVALID(rep_based_pf) ((rep_based_pf) > 15) 133 /* 134 * rep_q_r2f == Logical COS Queue index for the rep to endpoint direction 135 */ 136 #define BNXT_DEVARG_REP_Q_R2F_INVALID(rep_q_r2f) ((rep_q_r2f) > 3) 137 138 /* 139 * rep_q_f2r == Logical COS Queue index for the endpoint to rep direction 140 */ 141 #define BNXT_DEVARG_REP_Q_F2R_INVALID(rep_q_f2r) ((rep_q_f2r) > 3) 142 143 /* 144 * rep_fc_r2f == Flow control for the representor to endpoint direction 145 */ 146 #define BNXT_DEVARG_REP_FC_R2F_INVALID(rep_fc_r2f) ((rep_fc_r2f) > 1) 147 148 /* 149 * rep_fc_f2r == Flow control for the endpoint to representor direction 150 */ 151 #define BNXT_DEVARG_REP_FC_F2R_INVALID(rep_fc_f2r) ((rep_fc_f2r) > 1) 152 153 int bnxt_cfa_code_dynfield_offset = -1; 154 155 /* 156 * max_num_kflows must be >= 32 157 * and must be a power-of-2 supported value 158 * return: 1 -> invalid 159 * 0 -> valid 160 */ 161 static int bnxt_devarg_max_num_kflow_invalid(uint16_t max_num_kflows) 162 { 163 if (max_num_kflows < 32 || !rte_is_power_of_2(max_num_kflows)) 164 return 1; 165 return 0; 166 } 167 168 static int bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask); 169 static int bnxt_dev_uninit(struct rte_eth_dev *eth_dev); 170 static int bnxt_init_resources(struct bnxt *bp, bool reconfig_dev); 171 static int bnxt_uninit_resources(struct bnxt *bp, bool reconfig_dev); 172 static void bnxt_cancel_fw_health_check(struct bnxt *bp); 173 static int bnxt_restore_vlan_filters(struct bnxt *bp); 174 static void bnxt_dev_recover(void *arg); 175 static void bnxt_free_error_recovery_info(struct bnxt *bp); 176 static void bnxt_free_rep_info(struct bnxt *bp); 177 178 int is_bnxt_in_error(struct bnxt *bp) 179 { 180 if (bp->flags & BNXT_FLAG_FATAL_ERROR) 181 return -EIO; 182 if (bp->flags & BNXT_FLAG_FW_RESET) 183 return -EBUSY; 184 185 return 0; 186 } 187 188 /***********************/ 189 190 /* 191 * High level utility functions 192 */ 193 194 static uint16_t bnxt_rss_ctxts(const struct bnxt *bp) 195 { 196 unsigned int num_rss_rings = RTE_MIN(bp->rx_nr_rings, 197 BNXT_RSS_TBL_SIZE_P5); 198 199 if (!BNXT_CHIP_P5(bp)) 200 return 1; 201 202 return RTE_ALIGN_MUL_CEIL(num_rss_rings, 203 BNXT_RSS_ENTRIES_PER_CTX_P5) / 204 BNXT_RSS_ENTRIES_PER_CTX_P5; 205 } 206 207 uint16_t bnxt_rss_hash_tbl_size(const struct bnxt *bp) 208 { 209 if (!BNXT_CHIP_P5(bp)) 210 return HW_HASH_INDEX_SIZE; 211 212 return bnxt_rss_ctxts(bp) * BNXT_RSS_ENTRIES_PER_CTX_P5; 213 } 214 215 static void bnxt_free_parent_info(struct bnxt *bp) 216 { 217 rte_free(bp->parent); 218 } 219 220 static void bnxt_free_pf_info(struct bnxt *bp) 221 { 222 rte_free(bp->pf); 223 } 224 225 static void bnxt_free_link_info(struct bnxt *bp) 226 { 227 rte_free(bp->link_info); 228 } 229 230 static void bnxt_free_leds_info(struct bnxt *bp) 231 { 232 if (BNXT_VF(bp)) 233 return; 234 235 rte_free(bp->leds); 236 bp->leds = NULL; 237 } 238 239 static void bnxt_free_flow_stats_info(struct bnxt *bp) 240 { 241 rte_free(bp->flow_stat); 242 bp->flow_stat = NULL; 243 } 244 245 static void bnxt_free_cos_queues(struct bnxt *bp) 246 { 247 rte_free(bp->rx_cos_queue); 248 rte_free(bp->tx_cos_queue); 249 } 250 251 static void bnxt_free_mem(struct bnxt *bp, bool reconfig) 252 { 253 bnxt_free_filter_mem(bp); 254 bnxt_free_vnic_attributes(bp); 255 bnxt_free_vnic_mem(bp); 256 257 /* tx/rx rings are configured as part of *_queue_setup callbacks. 258 * If the number of rings change across fw update, 259 * we don't have much choice except to warn the user. 260 */ 261 if (!reconfig) { 262 bnxt_free_stats(bp); 263 bnxt_free_tx_rings(bp); 264 bnxt_free_rx_rings(bp); 265 } 266 bnxt_free_async_cp_ring(bp); 267 bnxt_free_rxtx_nq_ring(bp); 268 269 rte_free(bp->grp_info); 270 bp->grp_info = NULL; 271 } 272 273 static int bnxt_alloc_parent_info(struct bnxt *bp) 274 { 275 bp->parent = rte_zmalloc("bnxt_parent_info", 276 sizeof(struct bnxt_parent_info), 0); 277 if (bp->parent == NULL) 278 return -ENOMEM; 279 280 return 0; 281 } 282 283 static int bnxt_alloc_pf_info(struct bnxt *bp) 284 { 285 bp->pf = rte_zmalloc("bnxt_pf_info", sizeof(struct bnxt_pf_info), 0); 286 if (bp->pf == NULL) 287 return -ENOMEM; 288 289 return 0; 290 } 291 292 static int bnxt_alloc_link_info(struct bnxt *bp) 293 { 294 bp->link_info = 295 rte_zmalloc("bnxt_link_info", sizeof(struct bnxt_link_info), 0); 296 if (bp->link_info == NULL) 297 return -ENOMEM; 298 299 return 0; 300 } 301 302 static int bnxt_alloc_leds_info(struct bnxt *bp) 303 { 304 if (BNXT_VF(bp)) 305 return 0; 306 307 bp->leds = rte_zmalloc("bnxt_leds", 308 BNXT_MAX_LED * sizeof(struct bnxt_led_info), 309 0); 310 if (bp->leds == NULL) 311 return -ENOMEM; 312 313 return 0; 314 } 315 316 static int bnxt_alloc_cos_queues(struct bnxt *bp) 317 { 318 bp->rx_cos_queue = 319 rte_zmalloc("bnxt_rx_cosq", 320 BNXT_COS_QUEUE_COUNT * 321 sizeof(struct bnxt_cos_queue_info), 322 0); 323 if (bp->rx_cos_queue == NULL) 324 return -ENOMEM; 325 326 bp->tx_cos_queue = 327 rte_zmalloc("bnxt_tx_cosq", 328 BNXT_COS_QUEUE_COUNT * 329 sizeof(struct bnxt_cos_queue_info), 330 0); 331 if (bp->tx_cos_queue == NULL) 332 return -ENOMEM; 333 334 return 0; 335 } 336 337 static int bnxt_alloc_flow_stats_info(struct bnxt *bp) 338 { 339 bp->flow_stat = rte_zmalloc("bnxt_flow_xstat", 340 sizeof(struct bnxt_flow_stat_info), 0); 341 if (bp->flow_stat == NULL) 342 return -ENOMEM; 343 344 return 0; 345 } 346 347 static int bnxt_alloc_mem(struct bnxt *bp, bool reconfig) 348 { 349 int rc; 350 351 rc = bnxt_alloc_ring_grps(bp); 352 if (rc) 353 goto alloc_mem_err; 354 355 rc = bnxt_alloc_async_ring_struct(bp); 356 if (rc) 357 goto alloc_mem_err; 358 359 rc = bnxt_alloc_vnic_mem(bp); 360 if (rc) 361 goto alloc_mem_err; 362 363 rc = bnxt_alloc_vnic_attributes(bp); 364 if (rc) 365 goto alloc_mem_err; 366 367 rc = bnxt_alloc_filter_mem(bp); 368 if (rc) 369 goto alloc_mem_err; 370 371 rc = bnxt_alloc_async_cp_ring(bp); 372 if (rc) 373 goto alloc_mem_err; 374 375 rc = bnxt_alloc_rxtx_nq_ring(bp); 376 if (rc) 377 goto alloc_mem_err; 378 379 if (BNXT_FLOW_XSTATS_EN(bp)) { 380 rc = bnxt_alloc_flow_stats_info(bp); 381 if (rc) 382 goto alloc_mem_err; 383 } 384 385 return 0; 386 387 alloc_mem_err: 388 bnxt_free_mem(bp, reconfig); 389 return rc; 390 } 391 392 static int bnxt_setup_one_vnic(struct bnxt *bp, uint16_t vnic_id) 393 { 394 struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf; 395 struct bnxt_vnic_info *vnic = &bp->vnic_info[vnic_id]; 396 uint64_t rx_offloads = dev_conf->rxmode.offloads; 397 struct bnxt_rx_queue *rxq; 398 unsigned int j; 399 int rc; 400 401 rc = bnxt_vnic_grp_alloc(bp, vnic); 402 if (rc) 403 goto err_out; 404 405 PMD_DRV_LOG(DEBUG, "vnic[%d] = %p vnic->fw_grp_ids = %p\n", 406 vnic_id, vnic, vnic->fw_grp_ids); 407 408 rc = bnxt_hwrm_vnic_alloc(bp, vnic); 409 if (rc) 410 goto err_out; 411 412 /* Alloc RSS context only if RSS mode is enabled */ 413 if (dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS) { 414 int j, nr_ctxs = bnxt_rss_ctxts(bp); 415 416 if (bp->rx_nr_rings > BNXT_RSS_TBL_SIZE_P5) { 417 PMD_DRV_LOG(ERR, "RxQ cnt %d > reta_size %d\n", 418 bp->rx_nr_rings, BNXT_RSS_TBL_SIZE_P5); 419 PMD_DRV_LOG(ERR, 420 "Only queues 0-%d will be in RSS table\n", 421 BNXT_RSS_TBL_SIZE_P5 - 1); 422 } 423 424 rc = 0; 425 for (j = 0; j < nr_ctxs; j++) { 426 rc = bnxt_hwrm_vnic_ctx_alloc(bp, vnic, j); 427 if (rc) 428 break; 429 } 430 if (rc) { 431 PMD_DRV_LOG(ERR, 432 "HWRM vnic %d ctx %d alloc failure rc: %x\n", 433 vnic_id, j, rc); 434 goto err_out; 435 } 436 vnic->num_lb_ctxts = nr_ctxs; 437 } 438 439 /* 440 * Firmware sets pf pair in default vnic cfg. If the VLAN strip 441 * setting is not available at this time, it will not be 442 * configured correctly in the CFA. 443 */ 444 if (rx_offloads & DEV_RX_OFFLOAD_VLAN_STRIP) 445 vnic->vlan_strip = true; 446 else 447 vnic->vlan_strip = false; 448 449 rc = bnxt_hwrm_vnic_cfg(bp, vnic); 450 if (rc) 451 goto err_out; 452 453 rc = bnxt_set_hwrm_vnic_filters(bp, vnic); 454 if (rc) 455 goto err_out; 456 457 for (j = 0; j < bp->rx_num_qs_per_vnic; j++) { 458 rxq = bp->eth_dev->data->rx_queues[j]; 459 460 PMD_DRV_LOG(DEBUG, 461 "rxq[%d]->vnic=%p vnic->fw_grp_ids=%p\n", 462 j, rxq->vnic, rxq->vnic->fw_grp_ids); 463 464 if (BNXT_HAS_RING_GRPS(bp) && rxq->rx_deferred_start) 465 rxq->vnic->fw_grp_ids[j] = INVALID_HW_RING_ID; 466 else 467 vnic->rx_queue_cnt++; 468 } 469 470 PMD_DRV_LOG(DEBUG, "vnic->rx_queue_cnt = %d\n", vnic->rx_queue_cnt); 471 472 rc = bnxt_vnic_rss_configure(bp, vnic); 473 if (rc) 474 goto err_out; 475 476 bnxt_hwrm_vnic_plcmode_cfg(bp, vnic); 477 478 if (rx_offloads & DEV_RX_OFFLOAD_TCP_LRO) 479 bnxt_hwrm_vnic_tpa_cfg(bp, vnic, 1); 480 else 481 bnxt_hwrm_vnic_tpa_cfg(bp, vnic, 0); 482 483 return 0; 484 err_out: 485 PMD_DRV_LOG(ERR, "HWRM vnic %d cfg failure rc: %x\n", 486 vnic_id, rc); 487 return rc; 488 } 489 490 static int bnxt_register_fc_ctx_mem(struct bnxt *bp) 491 { 492 int rc = 0; 493 494 rc = bnxt_hwrm_ctx_rgtr(bp, bp->flow_stat->rx_fc_in_tbl.dma, 495 &bp->flow_stat->rx_fc_in_tbl.ctx_id); 496 if (rc) 497 return rc; 498 499 PMD_DRV_LOG(DEBUG, 500 "rx_fc_in_tbl.va = %p rx_fc_in_tbl.dma = %p" 501 " rx_fc_in_tbl.ctx_id = %d\n", 502 bp->flow_stat->rx_fc_in_tbl.va, 503 (void *)((uintptr_t)bp->flow_stat->rx_fc_in_tbl.dma), 504 bp->flow_stat->rx_fc_in_tbl.ctx_id); 505 506 rc = bnxt_hwrm_ctx_rgtr(bp, bp->flow_stat->rx_fc_out_tbl.dma, 507 &bp->flow_stat->rx_fc_out_tbl.ctx_id); 508 if (rc) 509 return rc; 510 511 PMD_DRV_LOG(DEBUG, 512 "rx_fc_out_tbl.va = %p rx_fc_out_tbl.dma = %p" 513 " rx_fc_out_tbl.ctx_id = %d\n", 514 bp->flow_stat->rx_fc_out_tbl.va, 515 (void *)((uintptr_t)bp->flow_stat->rx_fc_out_tbl.dma), 516 bp->flow_stat->rx_fc_out_tbl.ctx_id); 517 518 rc = bnxt_hwrm_ctx_rgtr(bp, bp->flow_stat->tx_fc_in_tbl.dma, 519 &bp->flow_stat->tx_fc_in_tbl.ctx_id); 520 if (rc) 521 return rc; 522 523 PMD_DRV_LOG(DEBUG, 524 "tx_fc_in_tbl.va = %p tx_fc_in_tbl.dma = %p" 525 " tx_fc_in_tbl.ctx_id = %d\n", 526 bp->flow_stat->tx_fc_in_tbl.va, 527 (void *)((uintptr_t)bp->flow_stat->tx_fc_in_tbl.dma), 528 bp->flow_stat->tx_fc_in_tbl.ctx_id); 529 530 rc = bnxt_hwrm_ctx_rgtr(bp, bp->flow_stat->tx_fc_out_tbl.dma, 531 &bp->flow_stat->tx_fc_out_tbl.ctx_id); 532 if (rc) 533 return rc; 534 535 PMD_DRV_LOG(DEBUG, 536 "tx_fc_out_tbl.va = %p tx_fc_out_tbl.dma = %p" 537 " tx_fc_out_tbl.ctx_id = %d\n", 538 bp->flow_stat->tx_fc_out_tbl.va, 539 (void *)((uintptr_t)bp->flow_stat->tx_fc_out_tbl.dma), 540 bp->flow_stat->tx_fc_out_tbl.ctx_id); 541 542 memset(bp->flow_stat->rx_fc_out_tbl.va, 543 0, 544 bp->flow_stat->rx_fc_out_tbl.size); 545 rc = bnxt_hwrm_cfa_counter_cfg(bp, BNXT_DIR_RX, 546 CFA_COUNTER_CFG_IN_COUNTER_TYPE_FC, 547 bp->flow_stat->rx_fc_out_tbl.ctx_id, 548 bp->flow_stat->max_fc, 549 true); 550 if (rc) 551 return rc; 552 553 memset(bp->flow_stat->tx_fc_out_tbl.va, 554 0, 555 bp->flow_stat->tx_fc_out_tbl.size); 556 rc = bnxt_hwrm_cfa_counter_cfg(bp, BNXT_DIR_TX, 557 CFA_COUNTER_CFG_IN_COUNTER_TYPE_FC, 558 bp->flow_stat->tx_fc_out_tbl.ctx_id, 559 bp->flow_stat->max_fc, 560 true); 561 562 return rc; 563 } 564 565 static int bnxt_alloc_ctx_mem_buf(char *type, size_t size, 566 struct bnxt_ctx_mem_buf_info *ctx) 567 { 568 if (!ctx) 569 return -EINVAL; 570 571 ctx->va = rte_zmalloc(type, size, 0); 572 if (ctx->va == NULL) 573 return -ENOMEM; 574 rte_mem_lock_page(ctx->va); 575 ctx->size = size; 576 ctx->dma = rte_mem_virt2iova(ctx->va); 577 if (ctx->dma == RTE_BAD_IOVA) 578 return -ENOMEM; 579 580 return 0; 581 } 582 583 static int bnxt_init_fc_ctx_mem(struct bnxt *bp) 584 { 585 struct rte_pci_device *pdev = bp->pdev; 586 char type[RTE_MEMZONE_NAMESIZE]; 587 uint16_t max_fc; 588 int rc = 0; 589 590 max_fc = bp->flow_stat->max_fc; 591 592 sprintf(type, "bnxt_rx_fc_in_" PCI_PRI_FMT, pdev->addr.domain, 593 pdev->addr.bus, pdev->addr.devid, pdev->addr.function); 594 /* 4 bytes for each counter-id */ 595 rc = bnxt_alloc_ctx_mem_buf(type, 596 max_fc * 4, 597 &bp->flow_stat->rx_fc_in_tbl); 598 if (rc) 599 return rc; 600 601 sprintf(type, "bnxt_rx_fc_out_" PCI_PRI_FMT, pdev->addr.domain, 602 pdev->addr.bus, pdev->addr.devid, pdev->addr.function); 603 /* 16 bytes for each counter - 8 bytes pkt_count, 8 bytes byte_count */ 604 rc = bnxt_alloc_ctx_mem_buf(type, 605 max_fc * 16, 606 &bp->flow_stat->rx_fc_out_tbl); 607 if (rc) 608 return rc; 609 610 sprintf(type, "bnxt_tx_fc_in_" PCI_PRI_FMT, pdev->addr.domain, 611 pdev->addr.bus, pdev->addr.devid, pdev->addr.function); 612 /* 4 bytes for each counter-id */ 613 rc = bnxt_alloc_ctx_mem_buf(type, 614 max_fc * 4, 615 &bp->flow_stat->tx_fc_in_tbl); 616 if (rc) 617 return rc; 618 619 sprintf(type, "bnxt_tx_fc_out_" PCI_PRI_FMT, pdev->addr.domain, 620 pdev->addr.bus, pdev->addr.devid, pdev->addr.function); 621 /* 16 bytes for each counter - 8 bytes pkt_count, 8 bytes byte_count */ 622 rc = bnxt_alloc_ctx_mem_buf(type, 623 max_fc * 16, 624 &bp->flow_stat->tx_fc_out_tbl); 625 if (rc) 626 return rc; 627 628 rc = bnxt_register_fc_ctx_mem(bp); 629 630 return rc; 631 } 632 633 static int bnxt_init_ctx_mem(struct bnxt *bp) 634 { 635 int rc = 0; 636 637 if (!(bp->fw_cap & BNXT_FW_CAP_ADV_FLOW_COUNTERS) || 638 !(BNXT_PF(bp) || BNXT_VF_IS_TRUSTED(bp)) || 639 !BNXT_FLOW_XSTATS_EN(bp)) 640 return 0; 641 642 rc = bnxt_hwrm_cfa_counter_qcaps(bp, &bp->flow_stat->max_fc); 643 if (rc) 644 return rc; 645 646 rc = bnxt_init_fc_ctx_mem(bp); 647 648 return rc; 649 } 650 651 static int bnxt_update_phy_setting(struct bnxt *bp) 652 { 653 struct rte_eth_link new; 654 int rc; 655 656 rc = bnxt_get_hwrm_link_config(bp, &new); 657 if (rc) { 658 PMD_DRV_LOG(ERR, "Failed to get link settings\n"); 659 return rc; 660 } 661 662 /* 663 * On BCM957508-N2100 adapters, FW will not allow any user other 664 * than BMC to shutdown the port. bnxt_get_hwrm_link_config() call 665 * always returns link up. Force phy update always in that case. 666 */ 667 if (!new.link_status || IS_BNXT_DEV_957508_N2100(bp)) { 668 rc = bnxt_set_hwrm_link_config(bp, true); 669 if (rc) { 670 PMD_DRV_LOG(ERR, "Failed to update PHY settings\n"); 671 return rc; 672 } 673 } 674 675 return rc; 676 } 677 678 static int bnxt_init_chip(struct bnxt *bp) 679 { 680 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(bp->eth_dev); 681 struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; 682 uint32_t intr_vector = 0; 683 uint32_t queue_id, base = BNXT_MISC_VEC_ID; 684 uint32_t vec = BNXT_MISC_VEC_ID; 685 unsigned int i, j; 686 int rc; 687 688 if (bp->eth_dev->data->mtu > RTE_ETHER_MTU) { 689 bp->eth_dev->data->dev_conf.rxmode.offloads |= 690 DEV_RX_OFFLOAD_JUMBO_FRAME; 691 bp->flags |= BNXT_FLAG_JUMBO; 692 } else { 693 bp->eth_dev->data->dev_conf.rxmode.offloads &= 694 ~DEV_RX_OFFLOAD_JUMBO_FRAME; 695 bp->flags &= ~BNXT_FLAG_JUMBO; 696 } 697 698 /* THOR does not support ring groups. 699 * But we will use the array to save RSS context IDs. 700 */ 701 if (BNXT_CHIP_P5(bp)) 702 bp->max_ring_grps = BNXT_MAX_RSS_CTXTS_P5; 703 704 rc = bnxt_alloc_all_hwrm_stat_ctxs(bp); 705 if (rc) { 706 PMD_DRV_LOG(ERR, "HWRM stat ctx alloc failure rc: %x\n", rc); 707 goto err_out; 708 } 709 710 rc = bnxt_alloc_hwrm_rings(bp); 711 if (rc) { 712 PMD_DRV_LOG(ERR, "HWRM ring alloc failure rc: %x\n", rc); 713 goto err_out; 714 } 715 716 rc = bnxt_alloc_all_hwrm_ring_grps(bp); 717 if (rc) { 718 PMD_DRV_LOG(ERR, "HWRM ring grp alloc failure: %x\n", rc); 719 goto err_out; 720 } 721 722 if (!(bp->vnic_cap_flags & BNXT_VNIC_CAP_COS_CLASSIFY)) 723 goto skip_cosq_cfg; 724 725 for (j = 0, i = 0; i < BNXT_COS_QUEUE_COUNT; i++) { 726 if (bp->rx_cos_queue[i].id != 0xff) { 727 struct bnxt_vnic_info *vnic = &bp->vnic_info[j++]; 728 729 if (!vnic) { 730 PMD_DRV_LOG(ERR, 731 "Num pools more than FW profile\n"); 732 rc = -EINVAL; 733 goto err_out; 734 } 735 vnic->cos_queue_id = bp->rx_cos_queue[i].id; 736 bp->rx_cosq_cnt++; 737 } 738 } 739 740 skip_cosq_cfg: 741 rc = bnxt_mq_rx_configure(bp); 742 if (rc) { 743 PMD_DRV_LOG(ERR, "MQ mode configure failure rc: %x\n", rc); 744 goto err_out; 745 } 746 747 /* VNIC configuration */ 748 for (i = 0; i < bp->nr_vnics; i++) { 749 rc = bnxt_setup_one_vnic(bp, i); 750 if (rc) 751 goto err_out; 752 } 753 754 rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, &bp->vnic_info[0], 0, NULL); 755 if (rc) { 756 PMD_DRV_LOG(ERR, 757 "HWRM cfa l2 rx mask failure rc: %x\n", rc); 758 goto err_out; 759 } 760 761 /* check and configure queue intr-vector mapping */ 762 if ((rte_intr_cap_multiple(intr_handle) || 763 !RTE_ETH_DEV_SRIOV(bp->eth_dev).active) && 764 bp->eth_dev->data->dev_conf.intr_conf.rxq != 0) { 765 intr_vector = bp->eth_dev->data->nb_rx_queues; 766 PMD_DRV_LOG(DEBUG, "intr_vector = %d\n", intr_vector); 767 if (intr_vector > bp->rx_cp_nr_rings) { 768 PMD_DRV_LOG(ERR, "At most %d intr queues supported", 769 bp->rx_cp_nr_rings); 770 return -ENOTSUP; 771 } 772 rc = rte_intr_efd_enable(intr_handle, intr_vector); 773 if (rc) 774 return rc; 775 } 776 777 if (rte_intr_dp_is_en(intr_handle) && !intr_handle->intr_vec) { 778 intr_handle->intr_vec = 779 rte_zmalloc("intr_vec", 780 bp->eth_dev->data->nb_rx_queues * 781 sizeof(int), 0); 782 if (intr_handle->intr_vec == NULL) { 783 PMD_DRV_LOG(ERR, "Failed to allocate %d rx_queues" 784 " intr_vec", bp->eth_dev->data->nb_rx_queues); 785 rc = -ENOMEM; 786 goto err_disable; 787 } 788 PMD_DRV_LOG(DEBUG, "intr_handle->intr_vec = %p " 789 "intr_handle->nb_efd = %d intr_handle->max_intr = %d\n", 790 intr_handle->intr_vec, intr_handle->nb_efd, 791 intr_handle->max_intr); 792 for (queue_id = 0; queue_id < bp->eth_dev->data->nb_rx_queues; 793 queue_id++) { 794 intr_handle->intr_vec[queue_id] = 795 vec + BNXT_RX_VEC_START; 796 if (vec < base + intr_handle->nb_efd - 1) 797 vec++; 798 } 799 } 800 801 /* enable uio/vfio intr/eventfd mapping */ 802 rc = rte_intr_enable(intr_handle); 803 #ifndef RTE_EXEC_ENV_FREEBSD 804 /* In FreeBSD OS, nic_uio driver does not support interrupts */ 805 if (rc) 806 goto err_free; 807 #endif 808 809 rc = bnxt_update_phy_setting(bp); 810 if (rc) 811 goto err_free; 812 813 bp->mark_table = rte_zmalloc("bnxt_mark_table", BNXT_MARK_TABLE_SZ, 0); 814 if (!bp->mark_table) 815 PMD_DRV_LOG(ERR, "Allocation of mark table failed\n"); 816 817 return 0; 818 819 err_free: 820 rte_free(intr_handle->intr_vec); 821 err_disable: 822 rte_intr_efd_disable(intr_handle); 823 err_out: 824 /* Some of the error status returned by FW may not be from errno.h */ 825 if (rc > 0) 826 rc = -EIO; 827 828 return rc; 829 } 830 831 static int bnxt_shutdown_nic(struct bnxt *bp) 832 { 833 bnxt_free_all_hwrm_resources(bp); 834 bnxt_free_all_filters(bp); 835 bnxt_free_all_vnics(bp); 836 return 0; 837 } 838 839 /* 840 * Device configuration and status function 841 */ 842 843 uint32_t bnxt_get_speed_capabilities(struct bnxt *bp) 844 { 845 uint32_t link_speed = bp->link_info->support_speeds; 846 uint32_t speed_capa = 0; 847 848 /* If PAM4 is configured, use PAM4 supported speed */ 849 if (link_speed == 0 && bp->link_info->support_pam4_speeds > 0) 850 link_speed = bp->link_info->support_pam4_speeds; 851 852 if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100MB) 853 speed_capa |= ETH_LINK_SPEED_100M; 854 if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100MBHD) 855 speed_capa |= ETH_LINK_SPEED_100M_HD; 856 if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_1GB) 857 speed_capa |= ETH_LINK_SPEED_1G; 858 if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_2_5GB) 859 speed_capa |= ETH_LINK_SPEED_2_5G; 860 if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10GB) 861 speed_capa |= ETH_LINK_SPEED_10G; 862 if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_20GB) 863 speed_capa |= ETH_LINK_SPEED_20G; 864 if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_25GB) 865 speed_capa |= ETH_LINK_SPEED_25G; 866 if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_40GB) 867 speed_capa |= ETH_LINK_SPEED_40G; 868 if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_50GB) 869 speed_capa |= ETH_LINK_SPEED_50G; 870 if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100GB) 871 speed_capa |= ETH_LINK_SPEED_100G; 872 if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_PAM4_SPEEDS_50G) 873 speed_capa |= ETH_LINK_SPEED_50G; 874 if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_PAM4_SPEEDS_100G) 875 speed_capa |= ETH_LINK_SPEED_100G; 876 if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_PAM4_SPEEDS_200G) 877 speed_capa |= ETH_LINK_SPEED_200G; 878 879 if (bp->link_info->auto_mode == 880 HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_NONE) 881 speed_capa |= ETH_LINK_SPEED_FIXED; 882 else 883 speed_capa |= ETH_LINK_SPEED_AUTONEG; 884 885 return speed_capa; 886 } 887 888 static int bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev, 889 struct rte_eth_dev_info *dev_info) 890 { 891 struct rte_pci_device *pdev = RTE_DEV_TO_PCI(eth_dev->device); 892 struct bnxt *bp = eth_dev->data->dev_private; 893 uint16_t max_vnics, i, j, vpool, vrxq; 894 unsigned int max_rx_rings; 895 int rc; 896 897 rc = is_bnxt_in_error(bp); 898 if (rc) 899 return rc; 900 901 /* MAC Specifics */ 902 dev_info->max_mac_addrs = bp->max_l2_ctx; 903 dev_info->max_hash_mac_addrs = 0; 904 905 /* PF/VF specifics */ 906 if (BNXT_PF(bp)) 907 dev_info->max_vfs = pdev->max_vfs; 908 909 max_rx_rings = bnxt_max_rings(bp); 910 /* For the sake of symmetry, max_rx_queues = max_tx_queues */ 911 dev_info->max_rx_queues = max_rx_rings; 912 dev_info->max_tx_queues = max_rx_rings; 913 dev_info->reta_size = bnxt_rss_hash_tbl_size(bp); 914 dev_info->hash_key_size = 40; 915 max_vnics = bp->max_vnics; 916 917 /* MTU specifics */ 918 dev_info->min_mtu = RTE_ETHER_MIN_MTU; 919 dev_info->max_mtu = BNXT_MAX_MTU; 920 921 /* Fast path specifics */ 922 dev_info->min_rx_bufsize = 1; 923 dev_info->max_rx_pktlen = BNXT_MAX_PKT_LEN; 924 925 dev_info->rx_offload_capa = BNXT_DEV_RX_OFFLOAD_SUPPORT; 926 if (bp->flags & BNXT_FLAG_PTP_SUPPORTED) 927 dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_TIMESTAMP; 928 dev_info->tx_queue_offload_capa = DEV_TX_OFFLOAD_MBUF_FAST_FREE; 929 dev_info->tx_offload_capa = BNXT_DEV_TX_OFFLOAD_SUPPORT | 930 dev_info->tx_queue_offload_capa; 931 dev_info->flow_type_rss_offloads = BNXT_ETH_RSS_SUPPORT; 932 933 dev_info->speed_capa = bnxt_get_speed_capabilities(bp); 934 935 /* *INDENT-OFF* */ 936 dev_info->default_rxconf = (struct rte_eth_rxconf) { 937 .rx_thresh = { 938 .pthresh = 8, 939 .hthresh = 8, 940 .wthresh = 0, 941 }, 942 .rx_free_thresh = 32, 943 .rx_drop_en = BNXT_DEFAULT_RX_DROP_EN, 944 }; 945 946 dev_info->default_txconf = (struct rte_eth_txconf) { 947 .tx_thresh = { 948 .pthresh = 32, 949 .hthresh = 0, 950 .wthresh = 0, 951 }, 952 .tx_free_thresh = 32, 953 .tx_rs_thresh = 32, 954 }; 955 eth_dev->data->dev_conf.intr_conf.lsc = 1; 956 957 eth_dev->data->dev_conf.intr_conf.rxq = 1; 958 dev_info->rx_desc_lim.nb_min = BNXT_MIN_RING_DESC; 959 dev_info->rx_desc_lim.nb_max = BNXT_MAX_RX_RING_DESC; 960 dev_info->tx_desc_lim.nb_min = BNXT_MIN_RING_DESC; 961 dev_info->tx_desc_lim.nb_max = BNXT_MAX_TX_RING_DESC; 962 963 if (BNXT_PF(bp) || BNXT_VF_IS_TRUSTED(bp)) { 964 dev_info->switch_info.name = eth_dev->device->name; 965 dev_info->switch_info.domain_id = bp->switch_domain_id; 966 dev_info->switch_info.port_id = 967 BNXT_PF(bp) ? BNXT_SWITCH_PORT_ID_PF : 968 BNXT_SWITCH_PORT_ID_TRUSTED_VF; 969 } 970 971 /* *INDENT-ON* */ 972 973 /* 974 * TODO: default_rxconf, default_txconf, rx_desc_lim, and tx_desc_lim 975 * need further investigation. 976 */ 977 978 /* VMDq resources */ 979 vpool = 64; /* ETH_64_POOLS */ 980 vrxq = 128; /* ETH_VMDQ_DCB_NUM_QUEUES */ 981 for (i = 0; i < 4; vpool >>= 1, i++) { 982 if (max_vnics > vpool) { 983 for (j = 0; j < 5; vrxq >>= 1, j++) { 984 if (dev_info->max_rx_queues > vrxq) { 985 if (vpool > vrxq) 986 vpool = vrxq; 987 goto found; 988 } 989 } 990 /* Not enough resources to support VMDq */ 991 break; 992 } 993 } 994 /* Not enough resources to support VMDq */ 995 vpool = 0; 996 vrxq = 0; 997 found: 998 dev_info->max_vmdq_pools = vpool; 999 dev_info->vmdq_queue_num = vrxq; 1000 1001 dev_info->vmdq_pool_base = 0; 1002 dev_info->vmdq_queue_base = 0; 1003 1004 return 0; 1005 } 1006 1007 /* Configure the device based on the configuration provided */ 1008 static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev) 1009 { 1010 struct bnxt *bp = eth_dev->data->dev_private; 1011 uint64_t rx_offloads = eth_dev->data->dev_conf.rxmode.offloads; 1012 int rc; 1013 1014 bp->rx_queues = (void *)eth_dev->data->rx_queues; 1015 bp->tx_queues = (void *)eth_dev->data->tx_queues; 1016 bp->tx_nr_rings = eth_dev->data->nb_tx_queues; 1017 bp->rx_nr_rings = eth_dev->data->nb_rx_queues; 1018 1019 rc = is_bnxt_in_error(bp); 1020 if (rc) 1021 return rc; 1022 1023 if (BNXT_VF(bp) && (bp->flags & BNXT_FLAG_NEW_RM)) { 1024 rc = bnxt_hwrm_check_vf_rings(bp); 1025 if (rc) { 1026 PMD_DRV_LOG(ERR, "HWRM insufficient resources\n"); 1027 return -ENOSPC; 1028 } 1029 1030 /* If a resource has already been allocated - in this case 1031 * it is the async completion ring, free it. Reallocate it after 1032 * resource reservation. This will ensure the resource counts 1033 * are calculated correctly. 1034 */ 1035 1036 pthread_mutex_lock(&bp->def_cp_lock); 1037 1038 if (!BNXT_HAS_NQ(bp) && bp->async_cp_ring) { 1039 bnxt_disable_int(bp); 1040 bnxt_free_cp_ring(bp, bp->async_cp_ring); 1041 } 1042 1043 rc = bnxt_hwrm_func_reserve_vf_resc(bp, false); 1044 if (rc) { 1045 PMD_DRV_LOG(ERR, "HWRM resource alloc fail:%x\n", rc); 1046 pthread_mutex_unlock(&bp->def_cp_lock); 1047 return -ENOSPC; 1048 } 1049 1050 if (!BNXT_HAS_NQ(bp) && bp->async_cp_ring) { 1051 rc = bnxt_alloc_async_cp_ring(bp); 1052 if (rc) { 1053 pthread_mutex_unlock(&bp->def_cp_lock); 1054 return rc; 1055 } 1056 bnxt_enable_int(bp); 1057 } 1058 1059 pthread_mutex_unlock(&bp->def_cp_lock); 1060 } 1061 1062 /* Inherit new configurations */ 1063 if (eth_dev->data->nb_rx_queues > bp->max_rx_rings || 1064 eth_dev->data->nb_tx_queues > bp->max_tx_rings || 1065 eth_dev->data->nb_rx_queues + eth_dev->data->nb_tx_queues 1066 + BNXT_NUM_ASYNC_CPR(bp) > bp->max_cp_rings || 1067 eth_dev->data->nb_rx_queues + eth_dev->data->nb_tx_queues > 1068 bp->max_stat_ctx) 1069 goto resource_error; 1070 1071 if (BNXT_HAS_RING_GRPS(bp) && 1072 (uint32_t)(eth_dev->data->nb_rx_queues) > bp->max_ring_grps) 1073 goto resource_error; 1074 1075 if (!(eth_dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_RSS) && 1076 bp->max_vnics < eth_dev->data->nb_rx_queues) 1077 goto resource_error; 1078 1079 bp->rx_cp_nr_rings = bp->rx_nr_rings; 1080 bp->tx_cp_nr_rings = bp->tx_nr_rings; 1081 1082 if (eth_dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG) 1083 rx_offloads |= DEV_RX_OFFLOAD_RSS_HASH; 1084 eth_dev->data->dev_conf.rxmode.offloads = rx_offloads; 1085 1086 if (rx_offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) { 1087 eth_dev->data->mtu = 1088 eth_dev->data->dev_conf.rxmode.max_rx_pkt_len - 1089 RTE_ETHER_HDR_LEN - RTE_ETHER_CRC_LEN - VLAN_TAG_SIZE * 1090 BNXT_NUM_VLANS; 1091 bnxt_mtu_set_op(eth_dev, eth_dev->data->mtu); 1092 } 1093 return 0; 1094 1095 resource_error: 1096 PMD_DRV_LOG(ERR, 1097 "Insufficient resources to support requested config\n"); 1098 PMD_DRV_LOG(ERR, 1099 "Num Queues Requested: Tx %d, Rx %d\n", 1100 eth_dev->data->nb_tx_queues, 1101 eth_dev->data->nb_rx_queues); 1102 PMD_DRV_LOG(ERR, 1103 "MAX: TxQ %d, RxQ %d, CQ %d Stat %d, Grp %d, Vnic %d\n", 1104 bp->max_tx_rings, bp->max_rx_rings, bp->max_cp_rings, 1105 bp->max_stat_ctx, bp->max_ring_grps, bp->max_vnics); 1106 return -ENOSPC; 1107 } 1108 1109 void bnxt_print_link_info(struct rte_eth_dev *eth_dev) 1110 { 1111 struct rte_eth_link *link = ð_dev->data->dev_link; 1112 1113 if (link->link_status) 1114 PMD_DRV_LOG(INFO, "Port %d Link Up - speed %u Mbps - %s\n", 1115 eth_dev->data->port_id, 1116 (uint32_t)link->link_speed, 1117 (link->link_duplex == ETH_LINK_FULL_DUPLEX) ? 1118 ("full-duplex") : ("half-duplex\n")); 1119 else 1120 PMD_DRV_LOG(INFO, "Port %d Link Down\n", 1121 eth_dev->data->port_id); 1122 } 1123 1124 /* 1125 * Determine whether the current configuration requires support for scattered 1126 * receive; return 1 if scattered receive is required and 0 if not. 1127 */ 1128 static int bnxt_scattered_rx(struct rte_eth_dev *eth_dev) 1129 { 1130 uint16_t buf_size; 1131 int i; 1132 1133 if (eth_dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_SCATTER) 1134 return 1; 1135 1136 for (i = 0; i < eth_dev->data->nb_rx_queues; i++) { 1137 struct bnxt_rx_queue *rxq = eth_dev->data->rx_queues[i]; 1138 1139 buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mb_pool) - 1140 RTE_PKTMBUF_HEADROOM); 1141 if (eth_dev->data->dev_conf.rxmode.max_rx_pkt_len > buf_size) 1142 return 1; 1143 } 1144 return 0; 1145 } 1146 1147 static eth_rx_burst_t 1148 bnxt_receive_function(struct rte_eth_dev *eth_dev) 1149 { 1150 struct bnxt *bp = eth_dev->data->dev_private; 1151 1152 #if defined(RTE_ARCH_X86) || defined(RTE_ARCH_ARM64) 1153 #ifndef RTE_LIBRTE_IEEE1588 1154 /* 1155 * Vector mode receive can be enabled only if scatter rx is not 1156 * in use and rx offloads are limited to VLAN stripping and 1157 * CRC stripping. 1158 */ 1159 if (!eth_dev->data->scattered_rx && 1160 !(eth_dev->data->dev_conf.rxmode.offloads & 1161 ~(DEV_RX_OFFLOAD_VLAN_STRIP | 1162 DEV_RX_OFFLOAD_KEEP_CRC | 1163 DEV_RX_OFFLOAD_JUMBO_FRAME | 1164 DEV_RX_OFFLOAD_IPV4_CKSUM | 1165 DEV_RX_OFFLOAD_UDP_CKSUM | 1166 DEV_RX_OFFLOAD_TCP_CKSUM | 1167 DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM | 1168 DEV_RX_OFFLOAD_OUTER_UDP_CKSUM | 1169 DEV_RX_OFFLOAD_RSS_HASH | 1170 DEV_RX_OFFLOAD_VLAN_FILTER)) && 1171 !BNXT_TRUFLOW_EN(bp) && BNXT_NUM_ASYNC_CPR(bp) && 1172 rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128) { 1173 PMD_DRV_LOG(INFO, "Using vector mode receive for port %d\n", 1174 eth_dev->data->port_id); 1175 bp->flags |= BNXT_FLAG_RX_VECTOR_PKT_MODE; 1176 return bnxt_recv_pkts_vec; 1177 } 1178 PMD_DRV_LOG(INFO, "Vector mode receive disabled for port %d\n", 1179 eth_dev->data->port_id); 1180 PMD_DRV_LOG(INFO, 1181 "Port %d scatter: %d rx offload: %" PRIX64 "\n", 1182 eth_dev->data->port_id, 1183 eth_dev->data->scattered_rx, 1184 eth_dev->data->dev_conf.rxmode.offloads); 1185 #endif 1186 #endif 1187 bp->flags &= ~BNXT_FLAG_RX_VECTOR_PKT_MODE; 1188 return bnxt_recv_pkts; 1189 } 1190 1191 static eth_tx_burst_t 1192 bnxt_transmit_function(__rte_unused struct rte_eth_dev *eth_dev) 1193 { 1194 #if defined(RTE_ARCH_X86) || defined(RTE_ARCH_ARM64) 1195 #ifndef RTE_LIBRTE_IEEE1588 1196 uint64_t offloads = eth_dev->data->dev_conf.txmode.offloads; 1197 struct bnxt *bp = eth_dev->data->dev_private; 1198 1199 /* 1200 * Vector mode transmit can be enabled only if not using scatter rx 1201 * or tx offloads. 1202 */ 1203 if (!eth_dev->data->scattered_rx && 1204 !(offloads & ~DEV_TX_OFFLOAD_MBUF_FAST_FREE) && 1205 !BNXT_TRUFLOW_EN(bp) && 1206 rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128) { 1207 PMD_DRV_LOG(INFO, "Using vector mode transmit for port %d\n", 1208 eth_dev->data->port_id); 1209 return bnxt_xmit_pkts_vec; 1210 } 1211 PMD_DRV_LOG(INFO, "Vector mode transmit disabled for port %d\n", 1212 eth_dev->data->port_id); 1213 PMD_DRV_LOG(INFO, 1214 "Port %d scatter: %d tx offload: %" PRIX64 "\n", 1215 eth_dev->data->port_id, 1216 eth_dev->data->scattered_rx, 1217 offloads); 1218 #endif 1219 #endif 1220 return bnxt_xmit_pkts; 1221 } 1222 1223 static int bnxt_handle_if_change_status(struct bnxt *bp) 1224 { 1225 int rc; 1226 1227 /* Since fw has undergone a reset and lost all contexts, 1228 * set fatal flag to not issue hwrm during cleanup 1229 */ 1230 bp->flags |= BNXT_FLAG_FATAL_ERROR; 1231 bnxt_uninit_resources(bp, true); 1232 1233 /* clear fatal flag so that re-init happens */ 1234 bp->flags &= ~BNXT_FLAG_FATAL_ERROR; 1235 rc = bnxt_init_resources(bp, true); 1236 1237 bp->flags &= ~BNXT_FLAG_IF_CHANGE_HOT_FW_RESET_DONE; 1238 1239 return rc; 1240 } 1241 1242 static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev) 1243 { 1244 struct bnxt *bp = eth_dev->data->dev_private; 1245 uint64_t rx_offloads = eth_dev->data->dev_conf.rxmode.offloads; 1246 int vlan_mask = 0; 1247 int rc, retry_cnt = BNXT_IF_CHANGE_RETRY_COUNT; 1248 1249 if (!eth_dev->data->nb_tx_queues || !eth_dev->data->nb_rx_queues) { 1250 PMD_DRV_LOG(ERR, "Queues are not configured yet!\n"); 1251 return -EINVAL; 1252 } 1253 1254 if (bp->rx_cp_nr_rings > RTE_ETHDEV_QUEUE_STAT_CNTRS) 1255 PMD_DRV_LOG(ERR, 1256 "RxQ cnt %d > RTE_ETHDEV_QUEUE_STAT_CNTRS %d\n", 1257 bp->rx_cp_nr_rings, RTE_ETHDEV_QUEUE_STAT_CNTRS); 1258 1259 do { 1260 rc = bnxt_hwrm_if_change(bp, true); 1261 if (rc == 0 || rc != -EAGAIN) 1262 break; 1263 1264 rte_delay_ms(BNXT_IF_CHANGE_RETRY_INTERVAL); 1265 } while (retry_cnt--); 1266 1267 if (rc) 1268 return rc; 1269 1270 if (bp->flags & BNXT_FLAG_IF_CHANGE_HOT_FW_RESET_DONE) { 1271 rc = bnxt_handle_if_change_status(bp); 1272 if (rc) 1273 return rc; 1274 } 1275 1276 bnxt_enable_int(bp); 1277 1278 rc = bnxt_init_chip(bp); 1279 if (rc) 1280 goto error; 1281 1282 eth_dev->data->scattered_rx = bnxt_scattered_rx(eth_dev); 1283 eth_dev->data->dev_started = 1; 1284 1285 bnxt_link_update_op(eth_dev, 1); 1286 1287 if (rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER) 1288 vlan_mask |= ETH_VLAN_FILTER_MASK; 1289 if (rx_offloads & DEV_RX_OFFLOAD_VLAN_STRIP) 1290 vlan_mask |= ETH_VLAN_STRIP_MASK; 1291 rc = bnxt_vlan_offload_set_op(eth_dev, vlan_mask); 1292 if (rc) 1293 goto error; 1294 1295 /* Initialize bnxt ULP port details */ 1296 rc = bnxt_ulp_port_init(bp); 1297 if (rc) 1298 goto error; 1299 1300 eth_dev->rx_pkt_burst = bnxt_receive_function(eth_dev); 1301 eth_dev->tx_pkt_burst = bnxt_transmit_function(eth_dev); 1302 1303 bnxt_schedule_fw_health_check(bp); 1304 1305 return 0; 1306 1307 error: 1308 bnxt_shutdown_nic(bp); 1309 bnxt_free_tx_mbufs(bp); 1310 bnxt_free_rx_mbufs(bp); 1311 bnxt_hwrm_if_change(bp, false); 1312 eth_dev->data->dev_started = 0; 1313 return rc; 1314 } 1315 1316 static int bnxt_dev_set_link_up_op(struct rte_eth_dev *eth_dev) 1317 { 1318 struct bnxt *bp = eth_dev->data->dev_private; 1319 int rc = 0; 1320 1321 if (!bp->link_info->link_up) 1322 rc = bnxt_set_hwrm_link_config(bp, true); 1323 if (!rc) 1324 eth_dev->data->dev_link.link_status = 1; 1325 1326 bnxt_print_link_info(eth_dev); 1327 return rc; 1328 } 1329 1330 static int bnxt_dev_set_link_down_op(struct rte_eth_dev *eth_dev) 1331 { 1332 struct bnxt *bp = eth_dev->data->dev_private; 1333 1334 eth_dev->data->dev_link.link_status = 0; 1335 bnxt_set_hwrm_link_config(bp, false); 1336 bp->link_info->link_up = 0; 1337 1338 return 0; 1339 } 1340 1341 static void bnxt_free_switch_domain(struct bnxt *bp) 1342 { 1343 int rc = 0; 1344 1345 if (bp->switch_domain_id) { 1346 rc = rte_eth_switch_domain_free(bp->switch_domain_id); 1347 if (rc) 1348 PMD_DRV_LOG(ERR, "free switch domain:%d fail: %d\n", 1349 bp->switch_domain_id, rc); 1350 } 1351 } 1352 1353 /* Unload the driver, release resources */ 1354 static int bnxt_dev_stop_op(struct rte_eth_dev *eth_dev) 1355 { 1356 struct bnxt *bp = eth_dev->data->dev_private; 1357 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); 1358 struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; 1359 struct rte_eth_link link; 1360 int ret; 1361 1362 eth_dev->data->dev_started = 0; 1363 eth_dev->data->scattered_rx = 0; 1364 1365 /* Prevent crashes when queues are still in use */ 1366 eth_dev->rx_pkt_burst = &bnxt_dummy_recv_pkts; 1367 eth_dev->tx_pkt_burst = &bnxt_dummy_xmit_pkts; 1368 1369 bnxt_disable_int(bp); 1370 1371 /* disable uio/vfio intr/eventfd mapping */ 1372 rte_intr_disable(intr_handle); 1373 1374 /* Stop the child representors for this device */ 1375 ret = bnxt_rep_stop_all(bp); 1376 if (ret != 0) 1377 return ret; 1378 1379 /* delete the bnxt ULP port details */ 1380 bnxt_ulp_port_deinit(bp); 1381 1382 bnxt_cancel_fw_health_check(bp); 1383 1384 /* Do not bring link down during reset recovery */ 1385 if (!is_bnxt_in_error(bp)) { 1386 bnxt_dev_set_link_down_op(eth_dev); 1387 /* Wait for link to be reset */ 1388 if (BNXT_SINGLE_PF(bp)) 1389 rte_delay_ms(500); 1390 /* clear the recorded link status */ 1391 memset(&link, 0, sizeof(link)); 1392 rte_eth_linkstatus_set(eth_dev, &link); 1393 } 1394 1395 /* Clean queue intr-vector mapping */ 1396 rte_intr_efd_disable(intr_handle); 1397 if (intr_handle->intr_vec != NULL) { 1398 rte_free(intr_handle->intr_vec); 1399 intr_handle->intr_vec = NULL; 1400 } 1401 1402 bnxt_hwrm_port_clr_stats(bp); 1403 bnxt_free_tx_mbufs(bp); 1404 bnxt_free_rx_mbufs(bp); 1405 /* Process any remaining notifications in default completion queue */ 1406 bnxt_int_handler(eth_dev); 1407 bnxt_shutdown_nic(bp); 1408 bnxt_hwrm_if_change(bp, false); 1409 1410 rte_free(bp->mark_table); 1411 bp->mark_table = NULL; 1412 1413 bp->flags &= ~BNXT_FLAG_RX_VECTOR_PKT_MODE; 1414 bp->rx_cosq_cnt = 0; 1415 /* All filters are deleted on a port stop. */ 1416 if (BNXT_FLOW_XSTATS_EN(bp)) 1417 bp->flow_stat->flow_count = 0; 1418 1419 return 0; 1420 } 1421 1422 static int bnxt_dev_close_op(struct rte_eth_dev *eth_dev) 1423 { 1424 struct bnxt *bp = eth_dev->data->dev_private; 1425 int ret = 0; 1426 1427 if (rte_eal_process_type() != RTE_PROC_PRIMARY) 1428 return 0; 1429 1430 /* cancel the recovery handler before remove dev */ 1431 rte_eal_alarm_cancel(bnxt_dev_reset_and_resume, (void *)bp); 1432 rte_eal_alarm_cancel(bnxt_dev_recover, (void *)bp); 1433 bnxt_cancel_fc_thread(bp); 1434 1435 if (eth_dev->data->dev_started) 1436 ret = bnxt_dev_stop_op(eth_dev); 1437 1438 bnxt_free_switch_domain(bp); 1439 1440 bnxt_uninit_resources(bp, false); 1441 1442 bnxt_free_leds_info(bp); 1443 bnxt_free_cos_queues(bp); 1444 bnxt_free_link_info(bp); 1445 bnxt_free_pf_info(bp); 1446 bnxt_free_parent_info(bp); 1447 1448 rte_memzone_free((const struct rte_memzone *)bp->tx_mem_zone); 1449 bp->tx_mem_zone = NULL; 1450 rte_memzone_free((const struct rte_memzone *)bp->rx_mem_zone); 1451 bp->rx_mem_zone = NULL; 1452 1453 bnxt_hwrm_free_vf_info(bp); 1454 1455 rte_free(bp->grp_info); 1456 bp->grp_info = NULL; 1457 1458 return ret; 1459 } 1460 1461 static void bnxt_mac_addr_remove_op(struct rte_eth_dev *eth_dev, 1462 uint32_t index) 1463 { 1464 struct bnxt *bp = eth_dev->data->dev_private; 1465 uint64_t pool_mask = eth_dev->data->mac_pool_sel[index]; 1466 struct bnxt_vnic_info *vnic; 1467 struct bnxt_filter_info *filter, *temp_filter; 1468 uint32_t i; 1469 1470 if (is_bnxt_in_error(bp)) 1471 return; 1472 1473 /* 1474 * Loop through all VNICs from the specified filter flow pools to 1475 * remove the corresponding MAC addr filter 1476 */ 1477 for (i = 0; i < bp->nr_vnics; i++) { 1478 if (!(pool_mask & (1ULL << i))) 1479 continue; 1480 1481 vnic = &bp->vnic_info[i]; 1482 filter = STAILQ_FIRST(&vnic->filter); 1483 while (filter) { 1484 temp_filter = STAILQ_NEXT(filter, next); 1485 if (filter->mac_index == index) { 1486 STAILQ_REMOVE(&vnic->filter, filter, 1487 bnxt_filter_info, next); 1488 bnxt_hwrm_clear_l2_filter(bp, filter); 1489 bnxt_free_filter(bp, filter); 1490 } 1491 filter = temp_filter; 1492 } 1493 } 1494 } 1495 1496 static int bnxt_add_mac_filter(struct bnxt *bp, struct bnxt_vnic_info *vnic, 1497 struct rte_ether_addr *mac_addr, uint32_t index, 1498 uint32_t pool) 1499 { 1500 struct bnxt_filter_info *filter; 1501 int rc = 0; 1502 1503 /* Attach requested MAC address to the new l2_filter */ 1504 STAILQ_FOREACH(filter, &vnic->filter, next) { 1505 if (filter->mac_index == index) { 1506 PMD_DRV_LOG(DEBUG, 1507 "MAC addr already existed for pool %d\n", 1508 pool); 1509 return 0; 1510 } 1511 } 1512 1513 filter = bnxt_alloc_filter(bp); 1514 if (!filter) { 1515 PMD_DRV_LOG(ERR, "L2 filter alloc failed\n"); 1516 return -ENODEV; 1517 } 1518 1519 /* bnxt_alloc_filter copies default MAC to filter->l2_addr. So, 1520 * if the MAC that's been programmed now is a different one, then, 1521 * copy that addr to filter->l2_addr 1522 */ 1523 if (mac_addr) 1524 memcpy(filter->l2_addr, mac_addr, RTE_ETHER_ADDR_LEN); 1525 filter->flags |= HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_OUTERMOST; 1526 1527 rc = bnxt_hwrm_set_l2_filter(bp, vnic->fw_vnic_id, filter); 1528 if (!rc) { 1529 filter->mac_index = index; 1530 if (filter->mac_index == 0) 1531 STAILQ_INSERT_HEAD(&vnic->filter, filter, next); 1532 else 1533 STAILQ_INSERT_TAIL(&vnic->filter, filter, next); 1534 } else { 1535 bnxt_free_filter(bp, filter); 1536 } 1537 1538 return rc; 1539 } 1540 1541 static int bnxt_mac_addr_add_op(struct rte_eth_dev *eth_dev, 1542 struct rte_ether_addr *mac_addr, 1543 uint32_t index, uint32_t pool) 1544 { 1545 struct bnxt *bp = eth_dev->data->dev_private; 1546 struct bnxt_vnic_info *vnic = &bp->vnic_info[pool]; 1547 int rc = 0; 1548 1549 rc = is_bnxt_in_error(bp); 1550 if (rc) 1551 return rc; 1552 1553 if (BNXT_VF(bp) && !BNXT_VF_IS_TRUSTED(bp)) { 1554 PMD_DRV_LOG(ERR, "Cannot add MAC address to a VF interface\n"); 1555 return -ENOTSUP; 1556 } 1557 1558 if (!vnic) { 1559 PMD_DRV_LOG(ERR, "VNIC not found for pool %d!\n", pool); 1560 return -EINVAL; 1561 } 1562 1563 /* Filter settings will get applied when port is started */ 1564 if (!eth_dev->data->dev_started) 1565 return 0; 1566 1567 rc = bnxt_add_mac_filter(bp, vnic, mac_addr, index, pool); 1568 1569 return rc; 1570 } 1571 1572 int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete) 1573 { 1574 int rc = 0; 1575 struct bnxt *bp = eth_dev->data->dev_private; 1576 struct rte_eth_link new; 1577 int cnt = wait_to_complete ? BNXT_MAX_LINK_WAIT_CNT : 1578 BNXT_MIN_LINK_WAIT_CNT; 1579 1580 rc = is_bnxt_in_error(bp); 1581 if (rc) 1582 return rc; 1583 1584 memset(&new, 0, sizeof(new)); 1585 do { 1586 /* Retrieve link info from hardware */ 1587 rc = bnxt_get_hwrm_link_config(bp, &new); 1588 if (rc) { 1589 new.link_speed = ETH_LINK_SPEED_100M; 1590 new.link_duplex = ETH_LINK_FULL_DUPLEX; 1591 PMD_DRV_LOG(ERR, 1592 "Failed to retrieve link rc = 0x%x!\n", rc); 1593 goto out; 1594 } 1595 1596 if (!wait_to_complete || new.link_status) 1597 break; 1598 1599 rte_delay_ms(BNXT_LINK_WAIT_INTERVAL); 1600 } while (cnt--); 1601 1602 /* Only single function PF can bring phy down. 1603 * When port is stopped, report link down for VF/MH/NPAR functions. 1604 */ 1605 if (!BNXT_SINGLE_PF(bp) && !eth_dev->data->dev_started) 1606 memset(&new, 0, sizeof(new)); 1607 1608 out: 1609 /* Timed out or success */ 1610 if (new.link_status != eth_dev->data->dev_link.link_status || 1611 new.link_speed != eth_dev->data->dev_link.link_speed) { 1612 rte_eth_linkstatus_set(eth_dev, &new); 1613 1614 rte_eth_dev_callback_process(eth_dev, 1615 RTE_ETH_EVENT_INTR_LSC, 1616 NULL); 1617 1618 bnxt_print_link_info(eth_dev); 1619 } 1620 1621 return rc; 1622 } 1623 1624 static int bnxt_promiscuous_enable_op(struct rte_eth_dev *eth_dev) 1625 { 1626 struct bnxt *bp = eth_dev->data->dev_private; 1627 struct bnxt_vnic_info *vnic; 1628 uint32_t old_flags; 1629 int rc; 1630 1631 rc = is_bnxt_in_error(bp); 1632 if (rc) 1633 return rc; 1634 1635 /* Filter settings will get applied when port is started */ 1636 if (!eth_dev->data->dev_started) 1637 return 0; 1638 1639 if (bp->vnic_info == NULL) 1640 return 0; 1641 1642 vnic = BNXT_GET_DEFAULT_VNIC(bp); 1643 1644 old_flags = vnic->flags; 1645 vnic->flags |= BNXT_VNIC_INFO_PROMISC; 1646 rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL); 1647 if (rc != 0) 1648 vnic->flags = old_flags; 1649 1650 return rc; 1651 } 1652 1653 static int bnxt_promiscuous_disable_op(struct rte_eth_dev *eth_dev) 1654 { 1655 struct bnxt *bp = eth_dev->data->dev_private; 1656 struct bnxt_vnic_info *vnic; 1657 uint32_t old_flags; 1658 int rc; 1659 1660 rc = is_bnxt_in_error(bp); 1661 if (rc) 1662 return rc; 1663 1664 /* Filter settings will get applied when port is started */ 1665 if (!eth_dev->data->dev_started) 1666 return 0; 1667 1668 if (bp->vnic_info == NULL) 1669 return 0; 1670 1671 vnic = BNXT_GET_DEFAULT_VNIC(bp); 1672 1673 old_flags = vnic->flags; 1674 vnic->flags &= ~BNXT_VNIC_INFO_PROMISC; 1675 rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL); 1676 if (rc != 0) 1677 vnic->flags = old_flags; 1678 1679 return rc; 1680 } 1681 1682 static int bnxt_allmulticast_enable_op(struct rte_eth_dev *eth_dev) 1683 { 1684 struct bnxt *bp = eth_dev->data->dev_private; 1685 struct bnxt_vnic_info *vnic; 1686 uint32_t old_flags; 1687 int rc; 1688 1689 rc = is_bnxt_in_error(bp); 1690 if (rc) 1691 return rc; 1692 1693 /* Filter settings will get applied when port is started */ 1694 if (!eth_dev->data->dev_started) 1695 return 0; 1696 1697 if (bp->vnic_info == NULL) 1698 return 0; 1699 1700 vnic = BNXT_GET_DEFAULT_VNIC(bp); 1701 1702 old_flags = vnic->flags; 1703 vnic->flags |= BNXT_VNIC_INFO_ALLMULTI; 1704 rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL); 1705 if (rc != 0) 1706 vnic->flags = old_flags; 1707 1708 return rc; 1709 } 1710 1711 static int bnxt_allmulticast_disable_op(struct rte_eth_dev *eth_dev) 1712 { 1713 struct bnxt *bp = eth_dev->data->dev_private; 1714 struct bnxt_vnic_info *vnic; 1715 uint32_t old_flags; 1716 int rc; 1717 1718 rc = is_bnxt_in_error(bp); 1719 if (rc) 1720 return rc; 1721 1722 /* Filter settings will get applied when port is started */ 1723 if (!eth_dev->data->dev_started) 1724 return 0; 1725 1726 if (bp->vnic_info == NULL) 1727 return 0; 1728 1729 vnic = BNXT_GET_DEFAULT_VNIC(bp); 1730 1731 old_flags = vnic->flags; 1732 vnic->flags &= ~BNXT_VNIC_INFO_ALLMULTI; 1733 rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL); 1734 if (rc != 0) 1735 vnic->flags = old_flags; 1736 1737 return rc; 1738 } 1739 1740 /* Return bnxt_rx_queue pointer corresponding to a given rxq. */ 1741 static struct bnxt_rx_queue *bnxt_qid_to_rxq(struct bnxt *bp, uint16_t qid) 1742 { 1743 if (qid >= bp->rx_nr_rings) 1744 return NULL; 1745 1746 return bp->eth_dev->data->rx_queues[qid]; 1747 } 1748 1749 /* Return rxq corresponding to a given rss table ring/group ID. */ 1750 static uint16_t bnxt_rss_to_qid(struct bnxt *bp, uint16_t fwr) 1751 { 1752 struct bnxt_rx_queue *rxq; 1753 unsigned int i; 1754 1755 if (!BNXT_HAS_RING_GRPS(bp)) { 1756 for (i = 0; i < bp->rx_nr_rings; i++) { 1757 rxq = bp->eth_dev->data->rx_queues[i]; 1758 if (rxq->rx_ring->rx_ring_struct->fw_ring_id == fwr) 1759 return rxq->index; 1760 } 1761 } else { 1762 for (i = 0; i < bp->rx_nr_rings; i++) { 1763 if (bp->grp_info[i].fw_grp_id == fwr) 1764 return i; 1765 } 1766 } 1767 1768 return INVALID_HW_RING_ID; 1769 } 1770 1771 static int bnxt_reta_update_op(struct rte_eth_dev *eth_dev, 1772 struct rte_eth_rss_reta_entry64 *reta_conf, 1773 uint16_t reta_size) 1774 { 1775 struct bnxt *bp = eth_dev->data->dev_private; 1776 struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf; 1777 struct bnxt_vnic_info *vnic = BNXT_GET_DEFAULT_VNIC(bp); 1778 uint16_t tbl_size = bnxt_rss_hash_tbl_size(bp); 1779 uint16_t idx, sft; 1780 int i, rc; 1781 1782 rc = is_bnxt_in_error(bp); 1783 if (rc) 1784 return rc; 1785 1786 if (!vnic->rss_table) 1787 return -EINVAL; 1788 1789 if (!(dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG)) 1790 return -EINVAL; 1791 1792 if (reta_size != tbl_size) { 1793 PMD_DRV_LOG(ERR, "The configured hash table lookup size " 1794 "(%d) must equal the size supported by the hardware " 1795 "(%d)\n", reta_size, tbl_size); 1796 return -EINVAL; 1797 } 1798 1799 for (i = 0; i < reta_size; i++) { 1800 struct bnxt_rx_queue *rxq; 1801 1802 idx = i / RTE_RETA_GROUP_SIZE; 1803 sft = i % RTE_RETA_GROUP_SIZE; 1804 1805 if (!(reta_conf[idx].mask & (1ULL << sft))) 1806 continue; 1807 1808 rxq = bnxt_qid_to_rxq(bp, reta_conf[idx].reta[sft]); 1809 if (!rxq) { 1810 PMD_DRV_LOG(ERR, "Invalid ring in reta_conf.\n"); 1811 return -EINVAL; 1812 } 1813 1814 if (BNXT_CHIP_P5(bp)) { 1815 vnic->rss_table[i * 2] = 1816 rxq->rx_ring->rx_ring_struct->fw_ring_id; 1817 vnic->rss_table[i * 2 + 1] = 1818 rxq->cp_ring->cp_ring_struct->fw_ring_id; 1819 } else { 1820 vnic->rss_table[i] = 1821 vnic->fw_grp_ids[reta_conf[idx].reta[sft]]; 1822 } 1823 } 1824 1825 rc = bnxt_hwrm_vnic_rss_cfg(bp, vnic); 1826 return rc; 1827 } 1828 1829 static int bnxt_reta_query_op(struct rte_eth_dev *eth_dev, 1830 struct rte_eth_rss_reta_entry64 *reta_conf, 1831 uint16_t reta_size) 1832 { 1833 struct bnxt *bp = eth_dev->data->dev_private; 1834 struct bnxt_vnic_info *vnic = BNXT_GET_DEFAULT_VNIC(bp); 1835 uint16_t tbl_size = bnxt_rss_hash_tbl_size(bp); 1836 uint16_t idx, sft, i; 1837 int rc; 1838 1839 rc = is_bnxt_in_error(bp); 1840 if (rc) 1841 return rc; 1842 1843 /* Retrieve from the default VNIC */ 1844 if (!vnic) 1845 return -EINVAL; 1846 if (!vnic->rss_table) 1847 return -EINVAL; 1848 1849 if (reta_size != tbl_size) { 1850 PMD_DRV_LOG(ERR, "The configured hash table lookup size " 1851 "(%d) must equal the size supported by the hardware " 1852 "(%d)\n", reta_size, tbl_size); 1853 return -EINVAL; 1854 } 1855 1856 for (idx = 0, i = 0; i < reta_size; i++) { 1857 idx = i / RTE_RETA_GROUP_SIZE; 1858 sft = i % RTE_RETA_GROUP_SIZE; 1859 1860 if (reta_conf[idx].mask & (1ULL << sft)) { 1861 uint16_t qid; 1862 1863 if (BNXT_CHIP_P5(bp)) 1864 qid = bnxt_rss_to_qid(bp, 1865 vnic->rss_table[i * 2]); 1866 else 1867 qid = bnxt_rss_to_qid(bp, vnic->rss_table[i]); 1868 1869 if (qid == INVALID_HW_RING_ID) { 1870 PMD_DRV_LOG(ERR, "Inv. entry in rss table.\n"); 1871 return -EINVAL; 1872 } 1873 reta_conf[idx].reta[sft] = qid; 1874 } 1875 } 1876 1877 return 0; 1878 } 1879 1880 static int bnxt_rss_hash_update_op(struct rte_eth_dev *eth_dev, 1881 struct rte_eth_rss_conf *rss_conf) 1882 { 1883 struct bnxt *bp = eth_dev->data->dev_private; 1884 struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf; 1885 struct bnxt_vnic_info *vnic; 1886 int rc; 1887 1888 rc = is_bnxt_in_error(bp); 1889 if (rc) 1890 return rc; 1891 1892 /* 1893 * If RSS enablement were different than dev_configure, 1894 * then return -EINVAL 1895 */ 1896 if (dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG) { 1897 if (!rss_conf->rss_hf) 1898 PMD_DRV_LOG(ERR, "Hash type NONE\n"); 1899 } else { 1900 if (rss_conf->rss_hf & BNXT_ETH_RSS_SUPPORT) 1901 return -EINVAL; 1902 } 1903 1904 bp->flags |= BNXT_FLAG_UPDATE_HASH; 1905 memcpy(ð_dev->data->dev_conf.rx_adv_conf.rss_conf, 1906 rss_conf, 1907 sizeof(*rss_conf)); 1908 1909 /* Update the default RSS VNIC(s) */ 1910 vnic = BNXT_GET_DEFAULT_VNIC(bp); 1911 vnic->hash_type = bnxt_rte_to_hwrm_hash_types(rss_conf->rss_hf); 1912 vnic->hash_mode = 1913 bnxt_rte_to_hwrm_hash_level(bp, rss_conf->rss_hf, 1914 ETH_RSS_LEVEL(rss_conf->rss_hf)); 1915 1916 /* 1917 * If hashkey is not specified, use the previously configured 1918 * hashkey 1919 */ 1920 if (!rss_conf->rss_key) 1921 goto rss_config; 1922 1923 if (rss_conf->rss_key_len != HW_HASH_KEY_SIZE) { 1924 PMD_DRV_LOG(ERR, 1925 "Invalid hashkey length, should be 16 bytes\n"); 1926 return -EINVAL; 1927 } 1928 memcpy(vnic->rss_hash_key, rss_conf->rss_key, rss_conf->rss_key_len); 1929 1930 rss_config: 1931 rc = bnxt_hwrm_vnic_rss_cfg(bp, vnic); 1932 return rc; 1933 } 1934 1935 static int bnxt_rss_hash_conf_get_op(struct rte_eth_dev *eth_dev, 1936 struct rte_eth_rss_conf *rss_conf) 1937 { 1938 struct bnxt *bp = eth_dev->data->dev_private; 1939 struct bnxt_vnic_info *vnic = BNXT_GET_DEFAULT_VNIC(bp); 1940 int len, rc; 1941 uint32_t hash_types; 1942 1943 rc = is_bnxt_in_error(bp); 1944 if (rc) 1945 return rc; 1946 1947 /* RSS configuration is the same for all VNICs */ 1948 if (vnic && vnic->rss_hash_key) { 1949 if (rss_conf->rss_key) { 1950 len = rss_conf->rss_key_len <= HW_HASH_KEY_SIZE ? 1951 rss_conf->rss_key_len : HW_HASH_KEY_SIZE; 1952 memcpy(rss_conf->rss_key, vnic->rss_hash_key, len); 1953 } 1954 1955 hash_types = vnic->hash_type; 1956 rss_conf->rss_hf = 0; 1957 if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4) { 1958 rss_conf->rss_hf |= ETH_RSS_IPV4; 1959 hash_types &= ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4; 1960 } 1961 if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4) { 1962 rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP; 1963 hash_types &= 1964 ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4; 1965 } 1966 if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4) { 1967 rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP; 1968 hash_types &= 1969 ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4; 1970 } 1971 if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6) { 1972 rss_conf->rss_hf |= ETH_RSS_IPV6; 1973 hash_types &= ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6; 1974 } 1975 if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6) { 1976 rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP; 1977 hash_types &= 1978 ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6; 1979 } 1980 if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6) { 1981 rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP; 1982 hash_types &= 1983 ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6; 1984 } 1985 1986 rss_conf->rss_hf |= 1987 bnxt_hwrm_to_rte_rss_level(bp, vnic->hash_mode); 1988 1989 if (hash_types) { 1990 PMD_DRV_LOG(ERR, 1991 "Unknown RSS config from firmware (%08x), RSS disabled", 1992 vnic->hash_type); 1993 return -ENOTSUP; 1994 } 1995 } else { 1996 rss_conf->rss_hf = 0; 1997 } 1998 return 0; 1999 } 2000 2001 static int bnxt_flow_ctrl_get_op(struct rte_eth_dev *dev, 2002 struct rte_eth_fc_conf *fc_conf) 2003 { 2004 struct bnxt *bp = dev->data->dev_private; 2005 struct rte_eth_link link_info; 2006 int rc; 2007 2008 rc = is_bnxt_in_error(bp); 2009 if (rc) 2010 return rc; 2011 2012 rc = bnxt_get_hwrm_link_config(bp, &link_info); 2013 if (rc) 2014 return rc; 2015 2016 memset(fc_conf, 0, sizeof(*fc_conf)); 2017 if (bp->link_info->auto_pause) 2018 fc_conf->autoneg = 1; 2019 switch (bp->link_info->pause) { 2020 case 0: 2021 fc_conf->mode = RTE_FC_NONE; 2022 break; 2023 case HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX: 2024 fc_conf->mode = RTE_FC_TX_PAUSE; 2025 break; 2026 case HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX: 2027 fc_conf->mode = RTE_FC_RX_PAUSE; 2028 break; 2029 case (HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX | 2030 HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX): 2031 fc_conf->mode = RTE_FC_FULL; 2032 break; 2033 } 2034 return 0; 2035 } 2036 2037 static int bnxt_flow_ctrl_set_op(struct rte_eth_dev *dev, 2038 struct rte_eth_fc_conf *fc_conf) 2039 { 2040 struct bnxt *bp = dev->data->dev_private; 2041 int rc; 2042 2043 rc = is_bnxt_in_error(bp); 2044 if (rc) 2045 return rc; 2046 2047 if (!BNXT_SINGLE_PF(bp) || BNXT_VF(bp)) { 2048 PMD_DRV_LOG(ERR, "Flow Control Settings cannot be modified\n"); 2049 return -ENOTSUP; 2050 } 2051 2052 switch (fc_conf->mode) { 2053 case RTE_FC_NONE: 2054 bp->link_info->auto_pause = 0; 2055 bp->link_info->force_pause = 0; 2056 break; 2057 case RTE_FC_RX_PAUSE: 2058 if (fc_conf->autoneg) { 2059 bp->link_info->auto_pause = 2060 HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX; 2061 bp->link_info->force_pause = 0; 2062 } else { 2063 bp->link_info->auto_pause = 0; 2064 bp->link_info->force_pause = 2065 HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_RX; 2066 } 2067 break; 2068 case RTE_FC_TX_PAUSE: 2069 if (fc_conf->autoneg) { 2070 bp->link_info->auto_pause = 2071 HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_TX; 2072 bp->link_info->force_pause = 0; 2073 } else { 2074 bp->link_info->auto_pause = 0; 2075 bp->link_info->force_pause = 2076 HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_TX; 2077 } 2078 break; 2079 case RTE_FC_FULL: 2080 if (fc_conf->autoneg) { 2081 bp->link_info->auto_pause = 2082 HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_TX | 2083 HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX; 2084 bp->link_info->force_pause = 0; 2085 } else { 2086 bp->link_info->auto_pause = 0; 2087 bp->link_info->force_pause = 2088 HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_TX | 2089 HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_RX; 2090 } 2091 break; 2092 } 2093 return bnxt_set_hwrm_link_config(bp, true); 2094 } 2095 2096 /* Add UDP tunneling port */ 2097 static int 2098 bnxt_udp_tunnel_port_add_op(struct rte_eth_dev *eth_dev, 2099 struct rte_eth_udp_tunnel *udp_tunnel) 2100 { 2101 struct bnxt *bp = eth_dev->data->dev_private; 2102 uint16_t tunnel_type = 0; 2103 int rc = 0; 2104 2105 rc = is_bnxt_in_error(bp); 2106 if (rc) 2107 return rc; 2108 2109 switch (udp_tunnel->prot_type) { 2110 case RTE_TUNNEL_TYPE_VXLAN: 2111 if (bp->vxlan_port_cnt) { 2112 PMD_DRV_LOG(ERR, "Tunnel Port %d already programmed\n", 2113 udp_tunnel->udp_port); 2114 if (bp->vxlan_port != udp_tunnel->udp_port) { 2115 PMD_DRV_LOG(ERR, "Only one port allowed\n"); 2116 return -ENOSPC; 2117 } 2118 bp->vxlan_port_cnt++; 2119 return 0; 2120 } 2121 tunnel_type = 2122 HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN; 2123 bp->vxlan_port_cnt++; 2124 break; 2125 case RTE_TUNNEL_TYPE_GENEVE: 2126 if (bp->geneve_port_cnt) { 2127 PMD_DRV_LOG(ERR, "Tunnel Port %d already programmed\n", 2128 udp_tunnel->udp_port); 2129 if (bp->geneve_port != udp_tunnel->udp_port) { 2130 PMD_DRV_LOG(ERR, "Only one port allowed\n"); 2131 return -ENOSPC; 2132 } 2133 bp->geneve_port_cnt++; 2134 return 0; 2135 } 2136 tunnel_type = 2137 HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_GENEVE; 2138 bp->geneve_port_cnt++; 2139 break; 2140 default: 2141 PMD_DRV_LOG(ERR, "Tunnel type is not supported\n"); 2142 return -ENOTSUP; 2143 } 2144 rc = bnxt_hwrm_tunnel_dst_port_alloc(bp, udp_tunnel->udp_port, 2145 tunnel_type); 2146 return rc; 2147 } 2148 2149 static int 2150 bnxt_udp_tunnel_port_del_op(struct rte_eth_dev *eth_dev, 2151 struct rte_eth_udp_tunnel *udp_tunnel) 2152 { 2153 struct bnxt *bp = eth_dev->data->dev_private; 2154 uint16_t tunnel_type = 0; 2155 uint16_t port = 0; 2156 int rc = 0; 2157 2158 rc = is_bnxt_in_error(bp); 2159 if (rc) 2160 return rc; 2161 2162 switch (udp_tunnel->prot_type) { 2163 case RTE_TUNNEL_TYPE_VXLAN: 2164 if (!bp->vxlan_port_cnt) { 2165 PMD_DRV_LOG(ERR, "No Tunnel port configured yet\n"); 2166 return -EINVAL; 2167 } 2168 if (bp->vxlan_port != udp_tunnel->udp_port) { 2169 PMD_DRV_LOG(ERR, "Req Port: %d. Configured port: %d\n", 2170 udp_tunnel->udp_port, bp->vxlan_port); 2171 return -EINVAL; 2172 } 2173 if (--bp->vxlan_port_cnt) 2174 return 0; 2175 2176 tunnel_type = 2177 HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN; 2178 port = bp->vxlan_fw_dst_port_id; 2179 break; 2180 case RTE_TUNNEL_TYPE_GENEVE: 2181 if (!bp->geneve_port_cnt) { 2182 PMD_DRV_LOG(ERR, "No Tunnel port configured yet\n"); 2183 return -EINVAL; 2184 } 2185 if (bp->geneve_port != udp_tunnel->udp_port) { 2186 PMD_DRV_LOG(ERR, "Req Port: %d. Configured port: %d\n", 2187 udp_tunnel->udp_port, bp->geneve_port); 2188 return -EINVAL; 2189 } 2190 if (--bp->geneve_port_cnt) 2191 return 0; 2192 2193 tunnel_type = 2194 HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE; 2195 port = bp->geneve_fw_dst_port_id; 2196 break; 2197 default: 2198 PMD_DRV_LOG(ERR, "Tunnel type is not supported\n"); 2199 return -ENOTSUP; 2200 } 2201 2202 rc = bnxt_hwrm_tunnel_dst_port_free(bp, port, tunnel_type); 2203 return rc; 2204 } 2205 2206 static int bnxt_del_vlan_filter(struct bnxt *bp, uint16_t vlan_id) 2207 { 2208 struct bnxt_filter_info *filter; 2209 struct bnxt_vnic_info *vnic; 2210 int rc = 0; 2211 uint32_t chk = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN; 2212 2213 vnic = BNXT_GET_DEFAULT_VNIC(bp); 2214 filter = STAILQ_FIRST(&vnic->filter); 2215 while (filter) { 2216 /* Search for this matching MAC+VLAN filter */ 2217 if (bnxt_vlan_filter_exists(bp, filter, chk, vlan_id)) { 2218 /* Delete the filter */ 2219 rc = bnxt_hwrm_clear_l2_filter(bp, filter); 2220 if (rc) 2221 return rc; 2222 STAILQ_REMOVE(&vnic->filter, filter, 2223 bnxt_filter_info, next); 2224 bnxt_free_filter(bp, filter); 2225 PMD_DRV_LOG(INFO, 2226 "Deleted vlan filter for %d\n", 2227 vlan_id); 2228 return 0; 2229 } 2230 filter = STAILQ_NEXT(filter, next); 2231 } 2232 return -ENOENT; 2233 } 2234 2235 static int bnxt_add_vlan_filter(struct bnxt *bp, uint16_t vlan_id) 2236 { 2237 struct bnxt_filter_info *filter; 2238 struct bnxt_vnic_info *vnic; 2239 int rc = 0; 2240 uint32_t en = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN | 2241 HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN_MASK; 2242 uint32_t chk = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN; 2243 2244 /* Implementation notes on the use of VNIC in this command: 2245 * 2246 * By default, these filters belong to default vnic for the function. 2247 * Once these filters are set up, only destination VNIC can be modified. 2248 * If the destination VNIC is not specified in this command, 2249 * then the HWRM shall only create an l2 context id. 2250 */ 2251 2252 vnic = BNXT_GET_DEFAULT_VNIC(bp); 2253 filter = STAILQ_FIRST(&vnic->filter); 2254 /* Check if the VLAN has already been added */ 2255 while (filter) { 2256 if (bnxt_vlan_filter_exists(bp, filter, chk, vlan_id)) 2257 return -EEXIST; 2258 2259 filter = STAILQ_NEXT(filter, next); 2260 } 2261 2262 /* No match found. Alloc a fresh filter and issue the L2_FILTER_ALLOC 2263 * command to create MAC+VLAN filter with the right flags, enables set. 2264 */ 2265 filter = bnxt_alloc_filter(bp); 2266 if (!filter) { 2267 PMD_DRV_LOG(ERR, 2268 "MAC/VLAN filter alloc failed\n"); 2269 return -ENOMEM; 2270 } 2271 /* MAC + VLAN ID filter */ 2272 /* If l2_ivlan == 0 and l2_ivlan_mask != 0, only 2273 * untagged packets are received 2274 * 2275 * If l2_ivlan != 0 and l2_ivlan_mask != 0, untagged 2276 * packets and only the programmed vlan's packets are received 2277 */ 2278 filter->l2_ivlan = vlan_id; 2279 filter->l2_ivlan_mask = 0x0FFF; 2280 filter->enables |= en; 2281 filter->flags |= HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_OUTERMOST; 2282 2283 rc = bnxt_hwrm_set_l2_filter(bp, vnic->fw_vnic_id, filter); 2284 if (rc) { 2285 /* Free the newly allocated filter as we were 2286 * not able to create the filter in hardware. 2287 */ 2288 bnxt_free_filter(bp, filter); 2289 return rc; 2290 } 2291 2292 filter->mac_index = 0; 2293 /* Add this new filter to the list */ 2294 if (vlan_id == 0) 2295 STAILQ_INSERT_HEAD(&vnic->filter, filter, next); 2296 else 2297 STAILQ_INSERT_TAIL(&vnic->filter, filter, next); 2298 2299 PMD_DRV_LOG(INFO, 2300 "Added Vlan filter for %d\n", vlan_id); 2301 return rc; 2302 } 2303 2304 static int bnxt_vlan_filter_set_op(struct rte_eth_dev *eth_dev, 2305 uint16_t vlan_id, int on) 2306 { 2307 struct bnxt *bp = eth_dev->data->dev_private; 2308 int rc; 2309 2310 rc = is_bnxt_in_error(bp); 2311 if (rc) 2312 return rc; 2313 2314 if (!eth_dev->data->dev_started) { 2315 PMD_DRV_LOG(ERR, "port must be started before setting vlan\n"); 2316 return -EINVAL; 2317 } 2318 2319 /* These operations apply to ALL existing MAC/VLAN filters */ 2320 if (on) 2321 return bnxt_add_vlan_filter(bp, vlan_id); 2322 else 2323 return bnxt_del_vlan_filter(bp, vlan_id); 2324 } 2325 2326 static int bnxt_del_dflt_mac_filter(struct bnxt *bp, 2327 struct bnxt_vnic_info *vnic) 2328 { 2329 struct bnxt_filter_info *filter; 2330 int rc; 2331 2332 filter = STAILQ_FIRST(&vnic->filter); 2333 while (filter) { 2334 if (filter->mac_index == 0 && 2335 !memcmp(filter->l2_addr, bp->mac_addr, 2336 RTE_ETHER_ADDR_LEN)) { 2337 rc = bnxt_hwrm_clear_l2_filter(bp, filter); 2338 if (!rc) { 2339 STAILQ_REMOVE(&vnic->filter, filter, 2340 bnxt_filter_info, next); 2341 bnxt_free_filter(bp, filter); 2342 } 2343 return rc; 2344 } 2345 filter = STAILQ_NEXT(filter, next); 2346 } 2347 return 0; 2348 } 2349 2350 static int 2351 bnxt_config_vlan_hw_filter(struct bnxt *bp, uint64_t rx_offloads) 2352 { 2353 struct bnxt_vnic_info *vnic; 2354 unsigned int i; 2355 int rc; 2356 2357 vnic = BNXT_GET_DEFAULT_VNIC(bp); 2358 if (!(rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER)) { 2359 /* Remove any VLAN filters programmed */ 2360 for (i = 0; i < RTE_ETHER_MAX_VLAN_ID; i++) 2361 bnxt_del_vlan_filter(bp, i); 2362 2363 rc = bnxt_add_mac_filter(bp, vnic, NULL, 0, 0); 2364 if (rc) 2365 return rc; 2366 } else { 2367 /* Default filter will allow packets that match the 2368 * dest mac. So, it has to be deleted, otherwise, we 2369 * will endup receiving vlan packets for which the 2370 * filter is not programmed, when hw-vlan-filter 2371 * configuration is ON 2372 */ 2373 bnxt_del_dflt_mac_filter(bp, vnic); 2374 /* This filter will allow only untagged packets */ 2375 bnxt_add_vlan_filter(bp, 0); 2376 } 2377 PMD_DRV_LOG(DEBUG, "VLAN Filtering: %d\n", 2378 !!(rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER)); 2379 2380 return 0; 2381 } 2382 2383 static int bnxt_free_one_vnic(struct bnxt *bp, uint16_t vnic_id) 2384 { 2385 struct bnxt_vnic_info *vnic = &bp->vnic_info[vnic_id]; 2386 unsigned int i; 2387 int rc; 2388 2389 /* Destroy vnic filters and vnic */ 2390 if (bp->eth_dev->data->dev_conf.rxmode.offloads & 2391 DEV_RX_OFFLOAD_VLAN_FILTER) { 2392 for (i = 0; i < RTE_ETHER_MAX_VLAN_ID; i++) 2393 bnxt_del_vlan_filter(bp, i); 2394 } 2395 bnxt_del_dflt_mac_filter(bp, vnic); 2396 2397 rc = bnxt_hwrm_vnic_free(bp, vnic); 2398 if (rc) 2399 return rc; 2400 2401 rte_free(vnic->fw_grp_ids); 2402 vnic->fw_grp_ids = NULL; 2403 2404 vnic->rx_queue_cnt = 0; 2405 2406 return 0; 2407 } 2408 2409 static int 2410 bnxt_config_vlan_hw_stripping(struct bnxt *bp, uint64_t rx_offloads) 2411 { 2412 struct bnxt_vnic_info *vnic = BNXT_GET_DEFAULT_VNIC(bp); 2413 int rc; 2414 2415 /* Destroy, recreate and reconfigure the default vnic */ 2416 rc = bnxt_free_one_vnic(bp, 0); 2417 if (rc) 2418 return rc; 2419 2420 /* default vnic 0 */ 2421 rc = bnxt_setup_one_vnic(bp, 0); 2422 if (rc) 2423 return rc; 2424 2425 if (bp->eth_dev->data->dev_conf.rxmode.offloads & 2426 DEV_RX_OFFLOAD_VLAN_FILTER) { 2427 rc = bnxt_add_vlan_filter(bp, 0); 2428 if (rc) 2429 return rc; 2430 rc = bnxt_restore_vlan_filters(bp); 2431 if (rc) 2432 return rc; 2433 } else { 2434 rc = bnxt_add_mac_filter(bp, vnic, NULL, 0, 0); 2435 if (rc) 2436 return rc; 2437 } 2438 2439 rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL); 2440 if (rc) 2441 return rc; 2442 2443 PMD_DRV_LOG(DEBUG, "VLAN Strip Offload: %d\n", 2444 !!(rx_offloads & DEV_RX_OFFLOAD_VLAN_STRIP)); 2445 2446 return rc; 2447 } 2448 2449 static int 2450 bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask) 2451 { 2452 uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads; 2453 struct bnxt *bp = dev->data->dev_private; 2454 int rc; 2455 2456 rc = is_bnxt_in_error(bp); 2457 if (rc) 2458 return rc; 2459 2460 /* Filter settings will get applied when port is started */ 2461 if (!dev->data->dev_started) 2462 return 0; 2463 2464 if (mask & ETH_VLAN_FILTER_MASK) { 2465 /* Enable or disable VLAN filtering */ 2466 rc = bnxt_config_vlan_hw_filter(bp, rx_offloads); 2467 if (rc) 2468 return rc; 2469 } 2470 2471 if (mask & ETH_VLAN_STRIP_MASK) { 2472 /* Enable or disable VLAN stripping */ 2473 rc = bnxt_config_vlan_hw_stripping(bp, rx_offloads); 2474 if (rc) 2475 return rc; 2476 } 2477 2478 if (mask & ETH_VLAN_EXTEND_MASK) { 2479 if (rx_offloads & DEV_RX_OFFLOAD_VLAN_EXTEND) 2480 PMD_DRV_LOG(DEBUG, "Extend VLAN supported\n"); 2481 else 2482 PMD_DRV_LOG(INFO, "Extend VLAN unsupported\n"); 2483 } 2484 2485 return 0; 2486 } 2487 2488 static int 2489 bnxt_vlan_tpid_set_op(struct rte_eth_dev *dev, enum rte_vlan_type vlan_type, 2490 uint16_t tpid) 2491 { 2492 struct bnxt *bp = dev->data->dev_private; 2493 int qinq = dev->data->dev_conf.rxmode.offloads & 2494 DEV_RX_OFFLOAD_VLAN_EXTEND; 2495 2496 if (vlan_type != ETH_VLAN_TYPE_INNER && 2497 vlan_type != ETH_VLAN_TYPE_OUTER) { 2498 PMD_DRV_LOG(ERR, 2499 "Unsupported vlan type."); 2500 return -EINVAL; 2501 } 2502 if (!qinq) { 2503 PMD_DRV_LOG(ERR, 2504 "QinQ not enabled. Needs to be ON as we can " 2505 "accelerate only outer vlan\n"); 2506 return -EINVAL; 2507 } 2508 2509 if (vlan_type == ETH_VLAN_TYPE_OUTER) { 2510 switch (tpid) { 2511 case RTE_ETHER_TYPE_QINQ: 2512 bp->outer_tpid_bd = 2513 TX_BD_LONG_CFA_META_VLAN_TPID_TPID88A8; 2514 break; 2515 case RTE_ETHER_TYPE_VLAN: 2516 bp->outer_tpid_bd = 2517 TX_BD_LONG_CFA_META_VLAN_TPID_TPID8100; 2518 break; 2519 case RTE_ETHER_TYPE_QINQ1: 2520 bp->outer_tpid_bd = 2521 TX_BD_LONG_CFA_META_VLAN_TPID_TPID9100; 2522 break; 2523 case RTE_ETHER_TYPE_QINQ2: 2524 bp->outer_tpid_bd = 2525 TX_BD_LONG_CFA_META_VLAN_TPID_TPID9200; 2526 break; 2527 case RTE_ETHER_TYPE_QINQ3: 2528 bp->outer_tpid_bd = 2529 TX_BD_LONG_CFA_META_VLAN_TPID_TPID9300; 2530 break; 2531 default: 2532 PMD_DRV_LOG(ERR, "Invalid TPID: %x\n", tpid); 2533 return -EINVAL; 2534 } 2535 bp->outer_tpid_bd |= tpid; 2536 PMD_DRV_LOG(INFO, "outer_tpid_bd = %x\n", bp->outer_tpid_bd); 2537 } else if (vlan_type == ETH_VLAN_TYPE_INNER) { 2538 PMD_DRV_LOG(ERR, 2539 "Can accelerate only outer vlan in QinQ\n"); 2540 return -EINVAL; 2541 } 2542 2543 return 0; 2544 } 2545 2546 static int 2547 bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, 2548 struct rte_ether_addr *addr) 2549 { 2550 struct bnxt *bp = dev->data->dev_private; 2551 /* Default Filter is tied to VNIC 0 */ 2552 struct bnxt_vnic_info *vnic = BNXT_GET_DEFAULT_VNIC(bp); 2553 int rc; 2554 2555 rc = is_bnxt_in_error(bp); 2556 if (rc) 2557 return rc; 2558 2559 if (BNXT_VF(bp) && !BNXT_VF_IS_TRUSTED(bp)) 2560 return -EPERM; 2561 2562 if (rte_is_zero_ether_addr(addr)) 2563 return -EINVAL; 2564 2565 /* Filter settings will get applied when port is started */ 2566 if (!dev->data->dev_started) 2567 return 0; 2568 2569 /* Check if the requested MAC is already added */ 2570 if (memcmp(addr, bp->mac_addr, RTE_ETHER_ADDR_LEN) == 0) 2571 return 0; 2572 2573 /* Destroy filter and re-create it */ 2574 bnxt_del_dflt_mac_filter(bp, vnic); 2575 2576 memcpy(bp->mac_addr, addr, RTE_ETHER_ADDR_LEN); 2577 if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_VLAN_FILTER) { 2578 /* This filter will allow only untagged packets */ 2579 rc = bnxt_add_vlan_filter(bp, 0); 2580 } else { 2581 rc = bnxt_add_mac_filter(bp, vnic, addr, 0, 0); 2582 } 2583 2584 PMD_DRV_LOG(DEBUG, "Set MAC addr\n"); 2585 return rc; 2586 } 2587 2588 static int 2589 bnxt_dev_set_mc_addr_list_op(struct rte_eth_dev *eth_dev, 2590 struct rte_ether_addr *mc_addr_set, 2591 uint32_t nb_mc_addr) 2592 { 2593 struct bnxt *bp = eth_dev->data->dev_private; 2594 char *mc_addr_list = (char *)mc_addr_set; 2595 struct bnxt_vnic_info *vnic; 2596 uint32_t off = 0, i = 0; 2597 int rc; 2598 2599 rc = is_bnxt_in_error(bp); 2600 if (rc) 2601 return rc; 2602 2603 vnic = BNXT_GET_DEFAULT_VNIC(bp); 2604 2605 if (nb_mc_addr > BNXT_MAX_MC_ADDRS) { 2606 vnic->flags |= BNXT_VNIC_INFO_ALLMULTI; 2607 goto allmulti; 2608 } 2609 2610 /* TODO Check for Duplicate mcast addresses */ 2611 vnic->flags &= ~BNXT_VNIC_INFO_ALLMULTI; 2612 for (i = 0; i < nb_mc_addr; i++) { 2613 memcpy(vnic->mc_list + off, &mc_addr_list[i], 2614 RTE_ETHER_ADDR_LEN); 2615 off += RTE_ETHER_ADDR_LEN; 2616 } 2617 2618 vnic->mc_addr_cnt = i; 2619 if (vnic->mc_addr_cnt) 2620 vnic->flags |= BNXT_VNIC_INFO_MCAST; 2621 else 2622 vnic->flags &= ~BNXT_VNIC_INFO_MCAST; 2623 2624 allmulti: 2625 return bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL); 2626 } 2627 2628 static int 2629 bnxt_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size) 2630 { 2631 struct bnxt *bp = dev->data->dev_private; 2632 uint8_t fw_major = (bp->fw_ver >> 24) & 0xff; 2633 uint8_t fw_minor = (bp->fw_ver >> 16) & 0xff; 2634 uint8_t fw_updt = (bp->fw_ver >> 8) & 0xff; 2635 uint8_t fw_rsvd = bp->fw_ver & 0xff; 2636 int ret; 2637 2638 ret = snprintf(fw_version, fw_size, "%d.%d.%d.%d", 2639 fw_major, fw_minor, fw_updt, fw_rsvd); 2640 2641 ret += 1; /* add the size of '\0' */ 2642 if (fw_size < (uint32_t)ret) 2643 return ret; 2644 else 2645 return 0; 2646 } 2647 2648 static void 2649 bnxt_rxq_info_get_op(struct rte_eth_dev *dev, uint16_t queue_id, 2650 struct rte_eth_rxq_info *qinfo) 2651 { 2652 struct bnxt *bp = dev->data->dev_private; 2653 struct bnxt_rx_queue *rxq; 2654 2655 if (is_bnxt_in_error(bp)) 2656 return; 2657 2658 rxq = dev->data->rx_queues[queue_id]; 2659 2660 qinfo->mp = rxq->mb_pool; 2661 qinfo->scattered_rx = dev->data->scattered_rx; 2662 qinfo->nb_desc = rxq->nb_rx_desc; 2663 2664 qinfo->conf.rx_free_thresh = rxq->rx_free_thresh; 2665 qinfo->conf.rx_drop_en = rxq->drop_en; 2666 qinfo->conf.rx_deferred_start = rxq->rx_deferred_start; 2667 qinfo->conf.offloads = dev->data->dev_conf.rxmode.offloads; 2668 } 2669 2670 static void 2671 bnxt_txq_info_get_op(struct rte_eth_dev *dev, uint16_t queue_id, 2672 struct rte_eth_txq_info *qinfo) 2673 { 2674 struct bnxt *bp = dev->data->dev_private; 2675 struct bnxt_tx_queue *txq; 2676 2677 if (is_bnxt_in_error(bp)) 2678 return; 2679 2680 txq = dev->data->tx_queues[queue_id]; 2681 2682 qinfo->nb_desc = txq->nb_tx_desc; 2683 2684 qinfo->conf.tx_thresh.pthresh = txq->pthresh; 2685 qinfo->conf.tx_thresh.hthresh = txq->hthresh; 2686 qinfo->conf.tx_thresh.wthresh = txq->wthresh; 2687 2688 qinfo->conf.tx_free_thresh = txq->tx_free_thresh; 2689 qinfo->conf.tx_rs_thresh = 0; 2690 qinfo->conf.tx_deferred_start = txq->tx_deferred_start; 2691 qinfo->conf.offloads = txq->offloads; 2692 } 2693 2694 static const struct { 2695 eth_rx_burst_t pkt_burst; 2696 const char *info; 2697 } bnxt_rx_burst_info[] = { 2698 {bnxt_recv_pkts, "Scalar"}, 2699 #if defined(RTE_ARCH_X86) 2700 {bnxt_recv_pkts_vec, "Vector SSE"}, 2701 #elif defined(RTE_ARCH_ARM64) 2702 {bnxt_recv_pkts_vec, "Vector Neon"}, 2703 #endif 2704 }; 2705 2706 static int 2707 bnxt_rx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id, 2708 struct rte_eth_burst_mode *mode) 2709 { 2710 eth_rx_burst_t pkt_burst = dev->rx_pkt_burst; 2711 size_t i; 2712 2713 for (i = 0; i < RTE_DIM(bnxt_rx_burst_info); i++) { 2714 if (pkt_burst == bnxt_rx_burst_info[i].pkt_burst) { 2715 snprintf(mode->info, sizeof(mode->info), "%s", 2716 bnxt_rx_burst_info[i].info); 2717 return 0; 2718 } 2719 } 2720 2721 return -EINVAL; 2722 } 2723 2724 static const struct { 2725 eth_tx_burst_t pkt_burst; 2726 const char *info; 2727 } bnxt_tx_burst_info[] = { 2728 {bnxt_xmit_pkts, "Scalar"}, 2729 #if defined(RTE_ARCH_X86) 2730 {bnxt_xmit_pkts_vec, "Vector SSE"}, 2731 #elif defined(RTE_ARCH_ARM64) 2732 {bnxt_xmit_pkts_vec, "Vector Neon"}, 2733 #endif 2734 }; 2735 2736 static int 2737 bnxt_tx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id, 2738 struct rte_eth_burst_mode *mode) 2739 { 2740 eth_tx_burst_t pkt_burst = dev->tx_pkt_burst; 2741 size_t i; 2742 2743 for (i = 0; i < RTE_DIM(bnxt_tx_burst_info); i++) { 2744 if (pkt_burst == bnxt_tx_burst_info[i].pkt_burst) { 2745 snprintf(mode->info, sizeof(mode->info), "%s", 2746 bnxt_tx_burst_info[i].info); 2747 return 0; 2748 } 2749 } 2750 2751 return -EINVAL; 2752 } 2753 2754 int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu) 2755 { 2756 struct bnxt *bp = eth_dev->data->dev_private; 2757 uint32_t new_pkt_size; 2758 uint32_t rc = 0; 2759 uint32_t i; 2760 2761 rc = is_bnxt_in_error(bp); 2762 if (rc) 2763 return rc; 2764 2765 /* Exit if receive queues are not configured yet */ 2766 if (!eth_dev->data->nb_rx_queues) 2767 return rc; 2768 2769 new_pkt_size = new_mtu + RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + 2770 VLAN_TAG_SIZE * BNXT_NUM_VLANS; 2771 2772 /* 2773 * Disallow any MTU change that would require scattered receive support 2774 * if it is not already enabled. 2775 */ 2776 if (eth_dev->data->dev_started && 2777 !eth_dev->data->scattered_rx && 2778 (new_pkt_size > 2779 eth_dev->data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM)) { 2780 PMD_DRV_LOG(ERR, 2781 "MTU change would require scattered rx support. "); 2782 PMD_DRV_LOG(ERR, "Stop port before changing MTU.\n"); 2783 return -EINVAL; 2784 } 2785 2786 if (new_mtu > RTE_ETHER_MTU) { 2787 bp->flags |= BNXT_FLAG_JUMBO; 2788 bp->eth_dev->data->dev_conf.rxmode.offloads |= 2789 DEV_RX_OFFLOAD_JUMBO_FRAME; 2790 } else { 2791 bp->eth_dev->data->dev_conf.rxmode.offloads &= 2792 ~DEV_RX_OFFLOAD_JUMBO_FRAME; 2793 bp->flags &= ~BNXT_FLAG_JUMBO; 2794 } 2795 2796 /* Is there a change in mtu setting? */ 2797 if (eth_dev->data->dev_conf.rxmode.max_rx_pkt_len == new_pkt_size) 2798 return rc; 2799 2800 for (i = 0; i < bp->nr_vnics; i++) { 2801 struct bnxt_vnic_info *vnic = &bp->vnic_info[i]; 2802 uint16_t size = 0; 2803 2804 vnic->mru = BNXT_VNIC_MRU(new_mtu); 2805 rc = bnxt_hwrm_vnic_cfg(bp, vnic); 2806 if (rc) 2807 break; 2808 2809 size = rte_pktmbuf_data_room_size(bp->rx_queues[0]->mb_pool); 2810 size -= RTE_PKTMBUF_HEADROOM; 2811 2812 if (size < new_mtu) { 2813 rc = bnxt_hwrm_vnic_plcmode_cfg(bp, vnic); 2814 if (rc) 2815 return rc; 2816 } 2817 } 2818 2819 if (!rc) 2820 eth_dev->data->dev_conf.rxmode.max_rx_pkt_len = new_pkt_size; 2821 2822 PMD_DRV_LOG(INFO, "New MTU is %d\n", new_mtu); 2823 2824 return rc; 2825 } 2826 2827 static int 2828 bnxt_vlan_pvid_set_op(struct rte_eth_dev *dev, uint16_t pvid, int on) 2829 { 2830 struct bnxt *bp = dev->data->dev_private; 2831 uint16_t vlan = bp->vlan; 2832 int rc; 2833 2834 rc = is_bnxt_in_error(bp); 2835 if (rc) 2836 return rc; 2837 2838 if (!BNXT_SINGLE_PF(bp) || BNXT_VF(bp)) { 2839 PMD_DRV_LOG(ERR, 2840 "PVID cannot be modified for this function\n"); 2841 return -ENOTSUP; 2842 } 2843 bp->vlan = on ? pvid : 0; 2844 2845 rc = bnxt_hwrm_set_default_vlan(bp, 0, 0); 2846 if (rc) 2847 bp->vlan = vlan; 2848 return rc; 2849 } 2850 2851 static int 2852 bnxt_dev_led_on_op(struct rte_eth_dev *dev) 2853 { 2854 struct bnxt *bp = dev->data->dev_private; 2855 int rc; 2856 2857 rc = is_bnxt_in_error(bp); 2858 if (rc) 2859 return rc; 2860 2861 return bnxt_hwrm_port_led_cfg(bp, true); 2862 } 2863 2864 static int 2865 bnxt_dev_led_off_op(struct rte_eth_dev *dev) 2866 { 2867 struct bnxt *bp = dev->data->dev_private; 2868 int rc; 2869 2870 rc = is_bnxt_in_error(bp); 2871 if (rc) 2872 return rc; 2873 2874 return bnxt_hwrm_port_led_cfg(bp, false); 2875 } 2876 2877 static uint32_t 2878 bnxt_rx_queue_count_op(struct rte_eth_dev *dev, uint16_t rx_queue_id) 2879 { 2880 struct bnxt *bp = (struct bnxt *)dev->data->dev_private; 2881 uint32_t desc = 0, raw_cons = 0, cons; 2882 struct bnxt_cp_ring_info *cpr; 2883 struct bnxt_rx_queue *rxq; 2884 struct rx_pkt_cmpl *rxcmp; 2885 int rc; 2886 2887 rc = is_bnxt_in_error(bp); 2888 if (rc) 2889 return rc; 2890 2891 rxq = dev->data->rx_queues[rx_queue_id]; 2892 cpr = rxq->cp_ring; 2893 raw_cons = cpr->cp_raw_cons; 2894 2895 while (1) { 2896 cons = RING_CMP(cpr->cp_ring_struct, raw_cons); 2897 rte_prefetch0(&cpr->cp_desc_ring[cons]); 2898 rxcmp = (struct rx_pkt_cmpl *)&cpr->cp_desc_ring[cons]; 2899 2900 if (!CMP_VALID(rxcmp, raw_cons, cpr->cp_ring_struct)) { 2901 break; 2902 } else { 2903 raw_cons++; 2904 desc++; 2905 } 2906 } 2907 2908 return desc; 2909 } 2910 2911 static int 2912 bnxt_rx_descriptor_status_op(void *rx_queue, uint16_t offset) 2913 { 2914 struct bnxt_rx_queue *rxq = (struct bnxt_rx_queue *)rx_queue; 2915 struct bnxt_rx_ring_info *rxr; 2916 struct bnxt_cp_ring_info *cpr; 2917 struct rte_mbuf *rx_buf; 2918 struct rx_pkt_cmpl *rxcmp; 2919 uint32_t cons, cp_cons; 2920 int rc; 2921 2922 if (!rxq) 2923 return -EINVAL; 2924 2925 rc = is_bnxt_in_error(rxq->bp); 2926 if (rc) 2927 return rc; 2928 2929 cpr = rxq->cp_ring; 2930 rxr = rxq->rx_ring; 2931 2932 if (offset >= rxq->nb_rx_desc) 2933 return -EINVAL; 2934 2935 cons = RING_CMP(cpr->cp_ring_struct, offset); 2936 cp_cons = cpr->cp_raw_cons; 2937 rxcmp = (struct rx_pkt_cmpl *)&cpr->cp_desc_ring[cons]; 2938 2939 if (cons > cp_cons) { 2940 if (CMPL_VALID(rxcmp, cpr->valid)) 2941 return RTE_ETH_RX_DESC_DONE; 2942 } else { 2943 if (CMPL_VALID(rxcmp, !cpr->valid)) 2944 return RTE_ETH_RX_DESC_DONE; 2945 } 2946 rx_buf = rxr->rx_buf_ring[cons]; 2947 if (rx_buf == NULL || rx_buf == &rxq->fake_mbuf) 2948 return RTE_ETH_RX_DESC_UNAVAIL; 2949 2950 2951 return RTE_ETH_RX_DESC_AVAIL; 2952 } 2953 2954 static int 2955 bnxt_tx_descriptor_status_op(void *tx_queue, uint16_t offset) 2956 { 2957 struct bnxt_tx_queue *txq = (struct bnxt_tx_queue *)tx_queue; 2958 struct bnxt_tx_ring_info *txr; 2959 struct bnxt_cp_ring_info *cpr; 2960 struct bnxt_sw_tx_bd *tx_buf; 2961 struct tx_pkt_cmpl *txcmp; 2962 uint32_t cons, cp_cons; 2963 int rc; 2964 2965 if (!txq) 2966 return -EINVAL; 2967 2968 rc = is_bnxt_in_error(txq->bp); 2969 if (rc) 2970 return rc; 2971 2972 cpr = txq->cp_ring; 2973 txr = txq->tx_ring; 2974 2975 if (offset >= txq->nb_tx_desc) 2976 return -EINVAL; 2977 2978 cons = RING_CMP(cpr->cp_ring_struct, offset); 2979 txcmp = (struct tx_pkt_cmpl *)&cpr->cp_desc_ring[cons]; 2980 cp_cons = cpr->cp_raw_cons; 2981 2982 if (cons > cp_cons) { 2983 if (CMPL_VALID(txcmp, cpr->valid)) 2984 return RTE_ETH_TX_DESC_UNAVAIL; 2985 } else { 2986 if (CMPL_VALID(txcmp, !cpr->valid)) 2987 return RTE_ETH_TX_DESC_UNAVAIL; 2988 } 2989 tx_buf = &txr->tx_buf_ring[cons]; 2990 if (tx_buf->mbuf == NULL) 2991 return RTE_ETH_TX_DESC_DONE; 2992 2993 return RTE_ETH_TX_DESC_FULL; 2994 } 2995 2996 int 2997 bnxt_filter_ctrl_op(struct rte_eth_dev *dev, 2998 enum rte_filter_type filter_type, 2999 enum rte_filter_op filter_op, void *arg) 3000 { 3001 struct bnxt *bp = dev->data->dev_private; 3002 int ret = 0; 3003 3004 if (!bp) 3005 return -EIO; 3006 3007 if (BNXT_ETH_DEV_IS_REPRESENTOR(dev)) { 3008 struct bnxt_representor *vfr = dev->data->dev_private; 3009 bp = vfr->parent_dev->data->dev_private; 3010 /* parent is deleted while children are still valid */ 3011 if (!bp) { 3012 PMD_DRV_LOG(DEBUG, "BNXT Port:%d VFR Error %d:%d\n", 3013 dev->data->port_id, 3014 filter_type, 3015 filter_op); 3016 return -EIO; 3017 } 3018 } 3019 3020 ret = is_bnxt_in_error(bp); 3021 if (ret) 3022 return ret; 3023 3024 switch (filter_type) { 3025 case RTE_ETH_FILTER_GENERIC: 3026 if (filter_op != RTE_ETH_FILTER_GET) 3027 return -EINVAL; 3028 3029 /* PMD supports thread-safe flow operations. rte_flow API 3030 * functions can avoid mutex for multi-thread safety. 3031 */ 3032 dev->data->dev_flags |= RTE_ETH_DEV_FLOW_OPS_THREAD_SAFE; 3033 3034 if (BNXT_TRUFLOW_EN(bp)) 3035 *(const void **)arg = &bnxt_ulp_rte_flow_ops; 3036 else 3037 *(const void **)arg = &bnxt_flow_ops; 3038 break; 3039 default: 3040 PMD_DRV_LOG(ERR, 3041 "Filter type (%d) not supported", filter_type); 3042 ret = -EINVAL; 3043 break; 3044 } 3045 return ret; 3046 } 3047 3048 static const uint32_t * 3049 bnxt_dev_supported_ptypes_get_op(struct rte_eth_dev *dev) 3050 { 3051 static const uint32_t ptypes[] = { 3052 RTE_PTYPE_L2_ETHER_VLAN, 3053 RTE_PTYPE_L3_IPV4_EXT_UNKNOWN, 3054 RTE_PTYPE_L3_IPV6_EXT_UNKNOWN, 3055 RTE_PTYPE_L4_ICMP, 3056 RTE_PTYPE_L4_TCP, 3057 RTE_PTYPE_L4_UDP, 3058 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN, 3059 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN, 3060 RTE_PTYPE_INNER_L4_ICMP, 3061 RTE_PTYPE_INNER_L4_TCP, 3062 RTE_PTYPE_INNER_L4_UDP, 3063 RTE_PTYPE_UNKNOWN 3064 }; 3065 3066 if (!dev->rx_pkt_burst) 3067 return NULL; 3068 3069 return ptypes; 3070 } 3071 3072 static int bnxt_map_regs(struct bnxt *bp, uint32_t *reg_arr, int count, 3073 int reg_win) 3074 { 3075 uint32_t reg_base = *reg_arr & 0xfffff000; 3076 uint32_t win_off; 3077 int i; 3078 3079 for (i = 0; i < count; i++) { 3080 if ((reg_arr[i] & 0xfffff000) != reg_base) 3081 return -ERANGE; 3082 } 3083 win_off = BNXT_GRCPF_REG_WINDOW_BASE_OUT + (reg_win - 1) * 4; 3084 rte_write32(reg_base, (uint8_t *)bp->bar0 + win_off); 3085 return 0; 3086 } 3087 3088 static int bnxt_map_ptp_regs(struct bnxt *bp) 3089 { 3090 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 3091 uint32_t *reg_arr; 3092 int rc, i; 3093 3094 reg_arr = ptp->rx_regs; 3095 rc = bnxt_map_regs(bp, reg_arr, BNXT_PTP_RX_REGS, 5); 3096 if (rc) 3097 return rc; 3098 3099 reg_arr = ptp->tx_regs; 3100 rc = bnxt_map_regs(bp, reg_arr, BNXT_PTP_TX_REGS, 6); 3101 if (rc) 3102 return rc; 3103 3104 for (i = 0; i < BNXT_PTP_RX_REGS; i++) 3105 ptp->rx_mapped_regs[i] = 0x5000 + (ptp->rx_regs[i] & 0xfff); 3106 3107 for (i = 0; i < BNXT_PTP_TX_REGS; i++) 3108 ptp->tx_mapped_regs[i] = 0x6000 + (ptp->tx_regs[i] & 0xfff); 3109 3110 return 0; 3111 } 3112 3113 static void bnxt_unmap_ptp_regs(struct bnxt *bp) 3114 { 3115 rte_write32(0, (uint8_t *)bp->bar0 + 3116 BNXT_GRCPF_REG_WINDOW_BASE_OUT + 16); 3117 rte_write32(0, (uint8_t *)bp->bar0 + 3118 BNXT_GRCPF_REG_WINDOW_BASE_OUT + 20); 3119 } 3120 3121 static uint64_t bnxt_cc_read(struct bnxt *bp) 3122 { 3123 uint64_t ns; 3124 3125 ns = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 3126 BNXT_GRCPF_REG_SYNC_TIME)); 3127 ns |= (uint64_t)(rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 3128 BNXT_GRCPF_REG_SYNC_TIME + 4))) << 32; 3129 return ns; 3130 } 3131 3132 static int bnxt_get_tx_ts(struct bnxt *bp, uint64_t *ts) 3133 { 3134 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 3135 uint32_t fifo; 3136 3137 fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 3138 ptp->tx_mapped_regs[BNXT_PTP_TX_FIFO])); 3139 if (fifo & BNXT_PTP_TX_FIFO_EMPTY) 3140 return -EAGAIN; 3141 3142 fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 3143 ptp->tx_mapped_regs[BNXT_PTP_TX_FIFO])); 3144 *ts = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 3145 ptp->tx_mapped_regs[BNXT_PTP_TX_TS_L])); 3146 *ts |= (uint64_t)rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 3147 ptp->tx_mapped_regs[BNXT_PTP_TX_TS_H])) << 32; 3148 3149 return 0; 3150 } 3151 3152 static int bnxt_get_rx_ts(struct bnxt *bp, uint64_t *ts) 3153 { 3154 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 3155 struct bnxt_pf_info *pf = bp->pf; 3156 uint16_t port_id; 3157 uint32_t fifo; 3158 3159 if (!ptp) 3160 return -ENODEV; 3161 3162 fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 3163 ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO])); 3164 if (!(fifo & BNXT_PTP_RX_FIFO_PENDING)) 3165 return -EAGAIN; 3166 3167 port_id = pf->port_id; 3168 rte_write32(1 << port_id, (uint8_t *)bp->bar0 + 3169 ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO_ADV]); 3170 3171 fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 3172 ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO])); 3173 if (fifo & BNXT_PTP_RX_FIFO_PENDING) { 3174 /* bnxt_clr_rx_ts(bp); TBD */ 3175 return -EBUSY; 3176 } 3177 3178 *ts = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 3179 ptp->rx_mapped_regs[BNXT_PTP_RX_TS_L])); 3180 *ts |= (uint64_t)rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 3181 ptp->rx_mapped_regs[BNXT_PTP_RX_TS_H])) << 32; 3182 3183 return 0; 3184 } 3185 3186 static int 3187 bnxt_timesync_write_time(struct rte_eth_dev *dev, const struct timespec *ts) 3188 { 3189 uint64_t ns; 3190 struct bnxt *bp = dev->data->dev_private; 3191 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 3192 3193 if (!ptp) 3194 return 0; 3195 3196 ns = rte_timespec_to_ns(ts); 3197 /* Set the timecounters to a new value. */ 3198 ptp->tc.nsec = ns; 3199 3200 return 0; 3201 } 3202 3203 static int 3204 bnxt_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts) 3205 { 3206 struct bnxt *bp = dev->data->dev_private; 3207 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 3208 uint64_t ns, systime_cycles = 0; 3209 int rc = 0; 3210 3211 if (!ptp) 3212 return 0; 3213 3214 if (BNXT_CHIP_P5(bp)) 3215 rc = bnxt_hwrm_port_ts_query(bp, BNXT_PTP_FLAGS_CURRENT_TIME, 3216 &systime_cycles); 3217 else 3218 systime_cycles = bnxt_cc_read(bp); 3219 3220 ns = rte_timecounter_update(&ptp->tc, systime_cycles); 3221 *ts = rte_ns_to_timespec(ns); 3222 3223 return rc; 3224 } 3225 static int 3226 bnxt_timesync_enable(struct rte_eth_dev *dev) 3227 { 3228 struct bnxt *bp = dev->data->dev_private; 3229 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 3230 uint32_t shift = 0; 3231 int rc; 3232 3233 if (!ptp) 3234 return 0; 3235 3236 ptp->rx_filter = 1; 3237 ptp->tx_tstamp_en = 1; 3238 ptp->rxctl = BNXT_PTP_MSG_EVENTS; 3239 3240 rc = bnxt_hwrm_ptp_cfg(bp); 3241 if (rc) 3242 return rc; 3243 3244 memset(&ptp->tc, 0, sizeof(struct rte_timecounter)); 3245 memset(&ptp->rx_tstamp_tc, 0, sizeof(struct rte_timecounter)); 3246 memset(&ptp->tx_tstamp_tc, 0, sizeof(struct rte_timecounter)); 3247 3248 ptp->tc.cc_mask = BNXT_CYCLECOUNTER_MASK; 3249 ptp->tc.cc_shift = shift; 3250 ptp->tc.nsec_mask = (1ULL << shift) - 1; 3251 3252 ptp->rx_tstamp_tc.cc_mask = BNXT_CYCLECOUNTER_MASK; 3253 ptp->rx_tstamp_tc.cc_shift = shift; 3254 ptp->rx_tstamp_tc.nsec_mask = (1ULL << shift) - 1; 3255 3256 ptp->tx_tstamp_tc.cc_mask = BNXT_CYCLECOUNTER_MASK; 3257 ptp->tx_tstamp_tc.cc_shift = shift; 3258 ptp->tx_tstamp_tc.nsec_mask = (1ULL << shift) - 1; 3259 3260 if (!BNXT_CHIP_P5(bp)) 3261 bnxt_map_ptp_regs(bp); 3262 3263 return 0; 3264 } 3265 3266 static int 3267 bnxt_timesync_disable(struct rte_eth_dev *dev) 3268 { 3269 struct bnxt *bp = dev->data->dev_private; 3270 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 3271 3272 if (!ptp) 3273 return 0; 3274 3275 ptp->rx_filter = 0; 3276 ptp->tx_tstamp_en = 0; 3277 ptp->rxctl = 0; 3278 3279 bnxt_hwrm_ptp_cfg(bp); 3280 3281 if (!BNXT_CHIP_P5(bp)) 3282 bnxt_unmap_ptp_regs(bp); 3283 3284 return 0; 3285 } 3286 3287 static int 3288 bnxt_timesync_read_rx_timestamp(struct rte_eth_dev *dev, 3289 struct timespec *timestamp, 3290 uint32_t flags __rte_unused) 3291 { 3292 struct bnxt *bp = dev->data->dev_private; 3293 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 3294 uint64_t rx_tstamp_cycles = 0; 3295 uint64_t ns; 3296 3297 if (!ptp) 3298 return 0; 3299 3300 if (BNXT_CHIP_P5(bp)) 3301 rx_tstamp_cycles = ptp->rx_timestamp; 3302 else 3303 bnxt_get_rx_ts(bp, &rx_tstamp_cycles); 3304 3305 ns = rte_timecounter_update(&ptp->rx_tstamp_tc, rx_tstamp_cycles); 3306 *timestamp = rte_ns_to_timespec(ns); 3307 return 0; 3308 } 3309 3310 static int 3311 bnxt_timesync_read_tx_timestamp(struct rte_eth_dev *dev, 3312 struct timespec *timestamp) 3313 { 3314 struct bnxt *bp = dev->data->dev_private; 3315 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 3316 uint64_t tx_tstamp_cycles = 0; 3317 uint64_t ns; 3318 int rc = 0; 3319 3320 if (!ptp) 3321 return 0; 3322 3323 if (BNXT_CHIP_P5(bp)) 3324 rc = bnxt_hwrm_port_ts_query(bp, BNXT_PTP_FLAGS_PATH_TX, 3325 &tx_tstamp_cycles); 3326 else 3327 rc = bnxt_get_tx_ts(bp, &tx_tstamp_cycles); 3328 3329 ns = rte_timecounter_update(&ptp->tx_tstamp_tc, tx_tstamp_cycles); 3330 *timestamp = rte_ns_to_timespec(ns); 3331 3332 return rc; 3333 } 3334 3335 static int 3336 bnxt_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta) 3337 { 3338 struct bnxt *bp = dev->data->dev_private; 3339 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 3340 3341 if (!ptp) 3342 return 0; 3343 3344 ptp->tc.nsec += delta; 3345 3346 return 0; 3347 } 3348 3349 static int 3350 bnxt_get_eeprom_length_op(struct rte_eth_dev *dev) 3351 { 3352 struct bnxt *bp = dev->data->dev_private; 3353 int rc; 3354 uint32_t dir_entries; 3355 uint32_t entry_length; 3356 3357 rc = is_bnxt_in_error(bp); 3358 if (rc) 3359 return rc; 3360 3361 PMD_DRV_LOG(INFO, PCI_PRI_FMT "\n", 3362 bp->pdev->addr.domain, bp->pdev->addr.bus, 3363 bp->pdev->addr.devid, bp->pdev->addr.function); 3364 3365 rc = bnxt_hwrm_nvm_get_dir_info(bp, &dir_entries, &entry_length); 3366 if (rc != 0) 3367 return rc; 3368 3369 return dir_entries * entry_length; 3370 } 3371 3372 static int 3373 bnxt_get_eeprom_op(struct rte_eth_dev *dev, 3374 struct rte_dev_eeprom_info *in_eeprom) 3375 { 3376 struct bnxt *bp = dev->data->dev_private; 3377 uint32_t index; 3378 uint32_t offset; 3379 int rc; 3380 3381 rc = is_bnxt_in_error(bp); 3382 if (rc) 3383 return rc; 3384 3385 PMD_DRV_LOG(INFO, PCI_PRI_FMT " in_eeprom->offset = %d len = %d\n", 3386 bp->pdev->addr.domain, bp->pdev->addr.bus, 3387 bp->pdev->addr.devid, bp->pdev->addr.function, 3388 in_eeprom->offset, in_eeprom->length); 3389 3390 if (in_eeprom->offset == 0) /* special offset value to get directory */ 3391 return bnxt_get_nvram_directory(bp, in_eeprom->length, 3392 in_eeprom->data); 3393 3394 index = in_eeprom->offset >> 24; 3395 offset = in_eeprom->offset & 0xffffff; 3396 3397 if (index != 0) 3398 return bnxt_hwrm_get_nvram_item(bp, index - 1, offset, 3399 in_eeprom->length, in_eeprom->data); 3400 3401 return 0; 3402 } 3403 3404 static bool bnxt_dir_type_is_ape_bin_format(uint16_t dir_type) 3405 { 3406 switch (dir_type) { 3407 case BNX_DIR_TYPE_CHIMP_PATCH: 3408 case BNX_DIR_TYPE_BOOTCODE: 3409 case BNX_DIR_TYPE_BOOTCODE_2: 3410 case BNX_DIR_TYPE_APE_FW: 3411 case BNX_DIR_TYPE_APE_PATCH: 3412 case BNX_DIR_TYPE_KONG_FW: 3413 case BNX_DIR_TYPE_KONG_PATCH: 3414 case BNX_DIR_TYPE_BONO_FW: 3415 case BNX_DIR_TYPE_BONO_PATCH: 3416 /* FALLTHROUGH */ 3417 return true; 3418 } 3419 3420 return false; 3421 } 3422 3423 static bool bnxt_dir_type_is_other_exec_format(uint16_t dir_type) 3424 { 3425 switch (dir_type) { 3426 case BNX_DIR_TYPE_AVS: 3427 case BNX_DIR_TYPE_EXP_ROM_MBA: 3428 case BNX_DIR_TYPE_PCIE: 3429 case BNX_DIR_TYPE_TSCF_UCODE: 3430 case BNX_DIR_TYPE_EXT_PHY: 3431 case BNX_DIR_TYPE_CCM: 3432 case BNX_DIR_TYPE_ISCSI_BOOT: 3433 case BNX_DIR_TYPE_ISCSI_BOOT_IPV6: 3434 case BNX_DIR_TYPE_ISCSI_BOOT_IPV4N6: 3435 /* FALLTHROUGH */ 3436 return true; 3437 } 3438 3439 return false; 3440 } 3441 3442 static bool bnxt_dir_type_is_executable(uint16_t dir_type) 3443 { 3444 return bnxt_dir_type_is_ape_bin_format(dir_type) || 3445 bnxt_dir_type_is_other_exec_format(dir_type); 3446 } 3447 3448 static int 3449 bnxt_set_eeprom_op(struct rte_eth_dev *dev, 3450 struct rte_dev_eeprom_info *in_eeprom) 3451 { 3452 struct bnxt *bp = dev->data->dev_private; 3453 uint8_t index, dir_op; 3454 uint16_t type, ext, ordinal, attr; 3455 int rc; 3456 3457 rc = is_bnxt_in_error(bp); 3458 if (rc) 3459 return rc; 3460 3461 PMD_DRV_LOG(INFO, PCI_PRI_FMT " in_eeprom->offset = %d len = %d\n", 3462 bp->pdev->addr.domain, bp->pdev->addr.bus, 3463 bp->pdev->addr.devid, bp->pdev->addr.function, 3464 in_eeprom->offset, in_eeprom->length); 3465 3466 if (!BNXT_PF(bp)) { 3467 PMD_DRV_LOG(ERR, "NVM write not supported from a VF\n"); 3468 return -EINVAL; 3469 } 3470 3471 type = in_eeprom->magic >> 16; 3472 3473 if (type == 0xffff) { /* special value for directory operations */ 3474 index = in_eeprom->magic & 0xff; 3475 dir_op = in_eeprom->magic >> 8; 3476 if (index == 0) 3477 return -EINVAL; 3478 switch (dir_op) { 3479 case 0x0e: /* erase */ 3480 if (in_eeprom->offset != ~in_eeprom->magic) 3481 return -EINVAL; 3482 return bnxt_hwrm_erase_nvram_directory(bp, index - 1); 3483 default: 3484 return -EINVAL; 3485 } 3486 } 3487 3488 /* Create or re-write an NVM item: */ 3489 if (bnxt_dir_type_is_executable(type) == true) 3490 return -EOPNOTSUPP; 3491 ext = in_eeprom->magic & 0xffff; 3492 ordinal = in_eeprom->offset >> 16; 3493 attr = in_eeprom->offset & 0xffff; 3494 3495 return bnxt_hwrm_flash_nvram(bp, type, ordinal, ext, attr, 3496 in_eeprom->data, in_eeprom->length); 3497 } 3498 3499 /* 3500 * Initialization 3501 */ 3502 3503 static const struct eth_dev_ops bnxt_dev_ops = { 3504 .dev_infos_get = bnxt_dev_info_get_op, 3505 .dev_close = bnxt_dev_close_op, 3506 .dev_configure = bnxt_dev_configure_op, 3507 .dev_start = bnxt_dev_start_op, 3508 .dev_stop = bnxt_dev_stop_op, 3509 .dev_set_link_up = bnxt_dev_set_link_up_op, 3510 .dev_set_link_down = bnxt_dev_set_link_down_op, 3511 .stats_get = bnxt_stats_get_op, 3512 .stats_reset = bnxt_stats_reset_op, 3513 .rx_queue_setup = bnxt_rx_queue_setup_op, 3514 .rx_queue_release = bnxt_rx_queue_release_op, 3515 .tx_queue_setup = bnxt_tx_queue_setup_op, 3516 .tx_queue_release = bnxt_tx_queue_release_op, 3517 .rx_queue_intr_enable = bnxt_rx_queue_intr_enable_op, 3518 .rx_queue_intr_disable = bnxt_rx_queue_intr_disable_op, 3519 .reta_update = bnxt_reta_update_op, 3520 .reta_query = bnxt_reta_query_op, 3521 .rss_hash_update = bnxt_rss_hash_update_op, 3522 .rss_hash_conf_get = bnxt_rss_hash_conf_get_op, 3523 .link_update = bnxt_link_update_op, 3524 .promiscuous_enable = bnxt_promiscuous_enable_op, 3525 .promiscuous_disable = bnxt_promiscuous_disable_op, 3526 .allmulticast_enable = bnxt_allmulticast_enable_op, 3527 .allmulticast_disable = bnxt_allmulticast_disable_op, 3528 .mac_addr_add = bnxt_mac_addr_add_op, 3529 .mac_addr_remove = bnxt_mac_addr_remove_op, 3530 .flow_ctrl_get = bnxt_flow_ctrl_get_op, 3531 .flow_ctrl_set = bnxt_flow_ctrl_set_op, 3532 .udp_tunnel_port_add = bnxt_udp_tunnel_port_add_op, 3533 .udp_tunnel_port_del = bnxt_udp_tunnel_port_del_op, 3534 .vlan_filter_set = bnxt_vlan_filter_set_op, 3535 .vlan_offload_set = bnxt_vlan_offload_set_op, 3536 .vlan_tpid_set = bnxt_vlan_tpid_set_op, 3537 .vlan_pvid_set = bnxt_vlan_pvid_set_op, 3538 .mtu_set = bnxt_mtu_set_op, 3539 .mac_addr_set = bnxt_set_default_mac_addr_op, 3540 .xstats_get = bnxt_dev_xstats_get_op, 3541 .xstats_get_names = bnxt_dev_xstats_get_names_op, 3542 .xstats_reset = bnxt_dev_xstats_reset_op, 3543 .fw_version_get = bnxt_fw_version_get, 3544 .set_mc_addr_list = bnxt_dev_set_mc_addr_list_op, 3545 .rxq_info_get = bnxt_rxq_info_get_op, 3546 .txq_info_get = bnxt_txq_info_get_op, 3547 .rx_burst_mode_get = bnxt_rx_burst_mode_get, 3548 .tx_burst_mode_get = bnxt_tx_burst_mode_get, 3549 .dev_led_on = bnxt_dev_led_on_op, 3550 .dev_led_off = bnxt_dev_led_off_op, 3551 .rx_queue_start = bnxt_rx_queue_start, 3552 .rx_queue_stop = bnxt_rx_queue_stop, 3553 .tx_queue_start = bnxt_tx_queue_start, 3554 .tx_queue_stop = bnxt_tx_queue_stop, 3555 .filter_ctrl = bnxt_filter_ctrl_op, 3556 .dev_supported_ptypes_get = bnxt_dev_supported_ptypes_get_op, 3557 .get_eeprom_length = bnxt_get_eeprom_length_op, 3558 .get_eeprom = bnxt_get_eeprom_op, 3559 .set_eeprom = bnxt_set_eeprom_op, 3560 .timesync_enable = bnxt_timesync_enable, 3561 .timesync_disable = bnxt_timesync_disable, 3562 .timesync_read_time = bnxt_timesync_read_time, 3563 .timesync_write_time = bnxt_timesync_write_time, 3564 .timesync_adjust_time = bnxt_timesync_adjust_time, 3565 .timesync_read_rx_timestamp = bnxt_timesync_read_rx_timestamp, 3566 .timesync_read_tx_timestamp = bnxt_timesync_read_tx_timestamp, 3567 }; 3568 3569 static uint32_t bnxt_map_reset_regs(struct bnxt *bp, uint32_t reg) 3570 { 3571 uint32_t offset; 3572 3573 /* Only pre-map the reset GRC registers using window 3 */ 3574 rte_write32(reg & 0xfffff000, (uint8_t *)bp->bar0 + 3575 BNXT_GRCPF_REG_WINDOW_BASE_OUT + 8); 3576 3577 offset = BNXT_GRCP_WINDOW_3_BASE + (reg & 0xffc); 3578 3579 return offset; 3580 } 3581 3582 int bnxt_map_fw_health_status_regs(struct bnxt *bp) 3583 { 3584 struct bnxt_error_recovery_info *info = bp->recovery_info; 3585 uint32_t reg_base = 0xffffffff; 3586 int i; 3587 3588 /* Only pre-map the monitoring GRC registers using window 2 */ 3589 for (i = 0; i < BNXT_FW_STATUS_REG_CNT; i++) { 3590 uint32_t reg = info->status_regs[i]; 3591 3592 if (BNXT_FW_STATUS_REG_TYPE(reg) != BNXT_FW_STATUS_REG_TYPE_GRC) 3593 continue; 3594 3595 if (reg_base == 0xffffffff) 3596 reg_base = reg & 0xfffff000; 3597 if ((reg & 0xfffff000) != reg_base) 3598 return -ERANGE; 3599 3600 /* Use mask 0xffc as the Lower 2 bits indicates 3601 * address space location 3602 */ 3603 info->mapped_status_regs[i] = BNXT_GRCP_WINDOW_2_BASE + 3604 (reg & 0xffc); 3605 } 3606 3607 if (reg_base == 0xffffffff) 3608 return 0; 3609 3610 rte_write32(reg_base, (uint8_t *)bp->bar0 + 3611 BNXT_GRCPF_REG_WINDOW_BASE_OUT + 4); 3612 3613 return 0; 3614 } 3615 3616 static void bnxt_write_fw_reset_reg(struct bnxt *bp, uint32_t index) 3617 { 3618 struct bnxt_error_recovery_info *info = bp->recovery_info; 3619 uint32_t delay = info->delay_after_reset[index]; 3620 uint32_t val = info->reset_reg_val[index]; 3621 uint32_t reg = info->reset_reg[index]; 3622 uint32_t type, offset; 3623 3624 type = BNXT_FW_STATUS_REG_TYPE(reg); 3625 offset = BNXT_FW_STATUS_REG_OFF(reg); 3626 3627 switch (type) { 3628 case BNXT_FW_STATUS_REG_TYPE_CFG: 3629 rte_pci_write_config(bp->pdev, &val, sizeof(val), offset); 3630 break; 3631 case BNXT_FW_STATUS_REG_TYPE_GRC: 3632 offset = bnxt_map_reset_regs(bp, offset); 3633 rte_write32(val, (uint8_t *)bp->bar0 + offset); 3634 break; 3635 case BNXT_FW_STATUS_REG_TYPE_BAR0: 3636 rte_write32(val, (uint8_t *)bp->bar0 + offset); 3637 break; 3638 } 3639 /* wait on a specific interval of time until core reset is complete */ 3640 if (delay) 3641 rte_delay_ms(delay); 3642 } 3643 3644 static void bnxt_dev_cleanup(struct bnxt *bp) 3645 { 3646 bp->eth_dev->data->dev_link.link_status = 0; 3647 bp->link_info->link_up = 0; 3648 if (bp->eth_dev->data->dev_started) 3649 bnxt_dev_stop_op(bp->eth_dev); 3650 3651 bnxt_uninit_resources(bp, true); 3652 } 3653 3654 static int bnxt_restore_vlan_filters(struct bnxt *bp) 3655 { 3656 struct rte_eth_dev *dev = bp->eth_dev; 3657 struct rte_vlan_filter_conf *vfc; 3658 int vidx, vbit, rc; 3659 uint16_t vlan_id; 3660 3661 for (vlan_id = 1; vlan_id <= RTE_ETHER_MAX_VLAN_ID; vlan_id++) { 3662 vfc = &dev->data->vlan_filter_conf; 3663 vidx = vlan_id / 64; 3664 vbit = vlan_id % 64; 3665 3666 /* Each bit corresponds to a VLAN id */ 3667 if (vfc->ids[vidx] & (UINT64_C(1) << vbit)) { 3668 rc = bnxt_add_vlan_filter(bp, vlan_id); 3669 if (rc) 3670 return rc; 3671 } 3672 } 3673 3674 return 0; 3675 } 3676 3677 static int bnxt_restore_mac_filters(struct bnxt *bp) 3678 { 3679 struct rte_eth_dev *dev = bp->eth_dev; 3680 struct rte_eth_dev_info dev_info; 3681 struct rte_ether_addr *addr; 3682 uint64_t pool_mask; 3683 uint32_t pool = 0; 3684 uint16_t i; 3685 int rc; 3686 3687 if (BNXT_VF(bp) && !BNXT_VF_IS_TRUSTED(bp)) 3688 return 0; 3689 3690 rc = bnxt_dev_info_get_op(dev, &dev_info); 3691 if (rc) 3692 return rc; 3693 3694 /* replay MAC address configuration */ 3695 for (i = 1; i < dev_info.max_mac_addrs; i++) { 3696 addr = &dev->data->mac_addrs[i]; 3697 3698 /* skip zero address */ 3699 if (rte_is_zero_ether_addr(addr)) 3700 continue; 3701 3702 pool = 0; 3703 pool_mask = dev->data->mac_pool_sel[i]; 3704 3705 do { 3706 if (pool_mask & 1ULL) { 3707 rc = bnxt_mac_addr_add_op(dev, addr, i, pool); 3708 if (rc) 3709 return rc; 3710 } 3711 pool_mask >>= 1; 3712 pool++; 3713 } while (pool_mask); 3714 } 3715 3716 return 0; 3717 } 3718 3719 static int bnxt_restore_filters(struct bnxt *bp) 3720 { 3721 struct rte_eth_dev *dev = bp->eth_dev; 3722 int ret = 0; 3723 3724 if (dev->data->all_multicast) { 3725 ret = bnxt_allmulticast_enable_op(dev); 3726 if (ret) 3727 return ret; 3728 } 3729 if (dev->data->promiscuous) { 3730 ret = bnxt_promiscuous_enable_op(dev); 3731 if (ret) 3732 return ret; 3733 } 3734 3735 ret = bnxt_restore_mac_filters(bp); 3736 if (ret) 3737 return ret; 3738 3739 ret = bnxt_restore_vlan_filters(bp); 3740 /* TODO restore other filters as well */ 3741 return ret; 3742 } 3743 3744 static void bnxt_dev_recover(void *arg) 3745 { 3746 struct bnxt *bp = arg; 3747 int timeout = bp->fw_reset_max_msecs; 3748 int rc = 0; 3749 3750 /* Clear Error flag so that device re-init should happen */ 3751 bp->flags &= ~BNXT_FLAG_FATAL_ERROR; 3752 3753 do { 3754 rc = bnxt_hwrm_ver_get(bp, SHORT_HWRM_CMD_TIMEOUT); 3755 if (rc == 0) 3756 break; 3757 rte_delay_ms(BNXT_FW_READY_WAIT_INTERVAL); 3758 timeout -= BNXT_FW_READY_WAIT_INTERVAL; 3759 } while (rc && timeout); 3760 3761 if (rc) { 3762 PMD_DRV_LOG(ERR, "FW is not Ready after reset\n"); 3763 goto err; 3764 } 3765 3766 rc = bnxt_init_resources(bp, true); 3767 if (rc) { 3768 PMD_DRV_LOG(ERR, 3769 "Failed to initialize resources after reset\n"); 3770 goto err; 3771 } 3772 /* clear reset flag as the device is initialized now */ 3773 bp->flags &= ~BNXT_FLAG_FW_RESET; 3774 3775 rc = bnxt_dev_start_op(bp->eth_dev); 3776 if (rc) { 3777 PMD_DRV_LOG(ERR, "Failed to start port after reset\n"); 3778 goto err_start; 3779 } 3780 3781 rc = bnxt_restore_filters(bp); 3782 if (rc) 3783 goto err_start; 3784 3785 PMD_DRV_LOG(INFO, "Recovered from FW reset\n"); 3786 return; 3787 err_start: 3788 bnxt_dev_stop_op(bp->eth_dev); 3789 err: 3790 bp->flags |= BNXT_FLAG_FATAL_ERROR; 3791 bnxt_uninit_resources(bp, false); 3792 PMD_DRV_LOG(ERR, "Failed to recover from FW reset\n"); 3793 } 3794 3795 void bnxt_dev_reset_and_resume(void *arg) 3796 { 3797 struct bnxt *bp = arg; 3798 int rc; 3799 3800 bnxt_dev_cleanup(bp); 3801 3802 bnxt_wait_for_device_shutdown(bp); 3803 3804 rc = rte_eal_alarm_set(US_PER_MS * bp->fw_reset_min_msecs, 3805 bnxt_dev_recover, (void *)bp); 3806 if (rc) 3807 PMD_DRV_LOG(ERR, "Error setting recovery alarm"); 3808 } 3809 3810 uint32_t bnxt_read_fw_status_reg(struct bnxt *bp, uint32_t index) 3811 { 3812 struct bnxt_error_recovery_info *info = bp->recovery_info; 3813 uint32_t reg = info->status_regs[index]; 3814 uint32_t type, offset, val = 0; 3815 3816 type = BNXT_FW_STATUS_REG_TYPE(reg); 3817 offset = BNXT_FW_STATUS_REG_OFF(reg); 3818 3819 switch (type) { 3820 case BNXT_FW_STATUS_REG_TYPE_CFG: 3821 rte_pci_read_config(bp->pdev, &val, sizeof(val), offset); 3822 break; 3823 case BNXT_FW_STATUS_REG_TYPE_GRC: 3824 offset = info->mapped_status_regs[index]; 3825 /* FALLTHROUGH */ 3826 case BNXT_FW_STATUS_REG_TYPE_BAR0: 3827 val = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 3828 offset)); 3829 break; 3830 } 3831 3832 return val; 3833 } 3834 3835 static int bnxt_fw_reset_all(struct bnxt *bp) 3836 { 3837 struct bnxt_error_recovery_info *info = bp->recovery_info; 3838 uint32_t i; 3839 int rc = 0; 3840 3841 if (info->flags & BNXT_FLAG_ERROR_RECOVERY_HOST) { 3842 /* Reset through master function driver */ 3843 for (i = 0; i < info->reg_array_cnt; i++) 3844 bnxt_write_fw_reset_reg(bp, i); 3845 /* Wait for time specified by FW after triggering reset */ 3846 rte_delay_ms(info->master_func_wait_period_after_reset); 3847 } else if (info->flags & BNXT_FLAG_ERROR_RECOVERY_CO_CPU) { 3848 /* Reset with the help of Kong processor */ 3849 rc = bnxt_hwrm_fw_reset(bp); 3850 if (rc) 3851 PMD_DRV_LOG(ERR, "Failed to reset FW\n"); 3852 } 3853 3854 return rc; 3855 } 3856 3857 static void bnxt_fw_reset_cb(void *arg) 3858 { 3859 struct bnxt *bp = arg; 3860 struct bnxt_error_recovery_info *info = bp->recovery_info; 3861 int rc = 0; 3862 3863 /* Only Master function can do FW reset */ 3864 if (bnxt_is_master_func(bp) && 3865 bnxt_is_recovery_enabled(bp)) { 3866 rc = bnxt_fw_reset_all(bp); 3867 if (rc) { 3868 PMD_DRV_LOG(ERR, "Adapter recovery failed\n"); 3869 return; 3870 } 3871 } 3872 3873 /* if recovery method is ERROR_RECOVERY_CO_CPU, KONG will send 3874 * EXCEPTION_FATAL_ASYNC event to all the functions 3875 * (including MASTER FUNC). After receiving this Async, all the active 3876 * drivers should treat this case as FW initiated recovery 3877 */ 3878 if (info->flags & BNXT_FLAG_ERROR_RECOVERY_HOST) { 3879 bp->fw_reset_min_msecs = BNXT_MIN_FW_READY_TIMEOUT; 3880 bp->fw_reset_max_msecs = BNXT_MAX_FW_RESET_TIMEOUT; 3881 3882 /* To recover from error */ 3883 rte_eal_alarm_set(US_PER_MS, bnxt_dev_reset_and_resume, 3884 (void *)bp); 3885 } 3886 } 3887 3888 /* Driver should poll FW heartbeat, reset_counter with the frequency 3889 * advertised by FW in HWRM_ERROR_RECOVERY_QCFG. 3890 * When the driver detects heartbeat stop or change in reset_counter, 3891 * it has to trigger a reset to recover from the error condition. 3892 * A “master PF” is the function who will have the privilege to 3893 * initiate the chimp reset. The master PF will be elected by the 3894 * firmware and will be notified through async message. 3895 */ 3896 static void bnxt_check_fw_health(void *arg) 3897 { 3898 struct bnxt *bp = arg; 3899 struct bnxt_error_recovery_info *info = bp->recovery_info; 3900 uint32_t val = 0, wait_msec; 3901 3902 if (!info || !bnxt_is_recovery_enabled(bp) || 3903 is_bnxt_in_error(bp)) 3904 return; 3905 3906 val = bnxt_read_fw_status_reg(bp, BNXT_FW_HEARTBEAT_CNT_REG); 3907 if (val == info->last_heart_beat) 3908 goto reset; 3909 3910 info->last_heart_beat = val; 3911 3912 val = bnxt_read_fw_status_reg(bp, BNXT_FW_RECOVERY_CNT_REG); 3913 if (val != info->last_reset_counter) 3914 goto reset; 3915 3916 info->last_reset_counter = val; 3917 3918 rte_eal_alarm_set(US_PER_MS * info->driver_polling_freq, 3919 bnxt_check_fw_health, (void *)bp); 3920 3921 return; 3922 reset: 3923 /* Stop DMA to/from device */ 3924 bp->flags |= BNXT_FLAG_FATAL_ERROR; 3925 bp->flags |= BNXT_FLAG_FW_RESET; 3926 3927 PMD_DRV_LOG(ERR, "Detected FW dead condition\n"); 3928 3929 if (bnxt_is_master_func(bp)) 3930 wait_msec = info->master_func_wait_period; 3931 else 3932 wait_msec = info->normal_func_wait_period; 3933 3934 rte_eal_alarm_set(US_PER_MS * wait_msec, 3935 bnxt_fw_reset_cb, (void *)bp); 3936 } 3937 3938 void bnxt_schedule_fw_health_check(struct bnxt *bp) 3939 { 3940 uint32_t polling_freq; 3941 3942 pthread_mutex_lock(&bp->health_check_lock); 3943 3944 if (!bnxt_is_recovery_enabled(bp)) 3945 goto done; 3946 3947 if (bp->flags & BNXT_FLAG_FW_HEALTH_CHECK_SCHEDULED) 3948 goto done; 3949 3950 polling_freq = bp->recovery_info->driver_polling_freq; 3951 3952 rte_eal_alarm_set(US_PER_MS * polling_freq, 3953 bnxt_check_fw_health, (void *)bp); 3954 bp->flags |= BNXT_FLAG_FW_HEALTH_CHECK_SCHEDULED; 3955 3956 done: 3957 pthread_mutex_unlock(&bp->health_check_lock); 3958 } 3959 3960 static void bnxt_cancel_fw_health_check(struct bnxt *bp) 3961 { 3962 if (!bnxt_is_recovery_enabled(bp)) 3963 return; 3964 3965 rte_eal_alarm_cancel(bnxt_check_fw_health, (void *)bp); 3966 bp->flags &= ~BNXT_FLAG_FW_HEALTH_CHECK_SCHEDULED; 3967 } 3968 3969 static bool bnxt_vf_pciid(uint16_t device_id) 3970 { 3971 switch (device_id) { 3972 case BROADCOM_DEV_ID_57304_VF: 3973 case BROADCOM_DEV_ID_57406_VF: 3974 case BROADCOM_DEV_ID_5731X_VF: 3975 case BROADCOM_DEV_ID_5741X_VF: 3976 case BROADCOM_DEV_ID_57414_VF: 3977 case BROADCOM_DEV_ID_STRATUS_NIC_VF1: 3978 case BROADCOM_DEV_ID_STRATUS_NIC_VF2: 3979 case BROADCOM_DEV_ID_58802_VF: 3980 case BROADCOM_DEV_ID_57500_VF1: 3981 case BROADCOM_DEV_ID_57500_VF2: 3982 /* FALLTHROUGH */ 3983 return true; 3984 default: 3985 return false; 3986 } 3987 } 3988 3989 /* Phase 5 device */ 3990 static bool bnxt_p5_device(uint16_t device_id) 3991 { 3992 switch (device_id) { 3993 case BROADCOM_DEV_ID_57508: 3994 case BROADCOM_DEV_ID_57504: 3995 case BROADCOM_DEV_ID_57502: 3996 case BROADCOM_DEV_ID_57508_MF1: 3997 case BROADCOM_DEV_ID_57504_MF1: 3998 case BROADCOM_DEV_ID_57502_MF1: 3999 case BROADCOM_DEV_ID_57508_MF2: 4000 case BROADCOM_DEV_ID_57504_MF2: 4001 case BROADCOM_DEV_ID_57502_MF2: 4002 case BROADCOM_DEV_ID_57500_VF1: 4003 case BROADCOM_DEV_ID_57500_VF2: 4004 /* FALLTHROUGH */ 4005 return true; 4006 default: 4007 return false; 4008 } 4009 } 4010 4011 bool bnxt_stratus_device(struct bnxt *bp) 4012 { 4013 uint16_t device_id = bp->pdev->id.device_id; 4014 4015 switch (device_id) { 4016 case BROADCOM_DEV_ID_STRATUS_NIC: 4017 case BROADCOM_DEV_ID_STRATUS_NIC_VF1: 4018 case BROADCOM_DEV_ID_STRATUS_NIC_VF2: 4019 /* FALLTHROUGH */ 4020 return true; 4021 default: 4022 return false; 4023 } 4024 } 4025 4026 static int bnxt_init_board(struct rte_eth_dev *eth_dev) 4027 { 4028 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); 4029 struct bnxt *bp = eth_dev->data->dev_private; 4030 4031 /* enable device (incl. PCI PM wakeup), and bus-mastering */ 4032 bp->bar0 = (void *)pci_dev->mem_resource[0].addr; 4033 bp->doorbell_base = (void *)pci_dev->mem_resource[2].addr; 4034 if (!bp->bar0 || !bp->doorbell_base) { 4035 PMD_DRV_LOG(ERR, "Unable to access Hardware\n"); 4036 return -ENODEV; 4037 } 4038 4039 bp->eth_dev = eth_dev; 4040 bp->pdev = pci_dev; 4041 4042 return 0; 4043 } 4044 4045 static int bnxt_alloc_ctx_mem_blk(struct bnxt *bp, 4046 struct bnxt_ctx_pg_info *ctx_pg, 4047 uint32_t mem_size, 4048 const char *suffix, 4049 uint16_t idx) 4050 { 4051 struct bnxt_ring_mem_info *rmem = &ctx_pg->ring_mem; 4052 const struct rte_memzone *mz = NULL; 4053 char mz_name[RTE_MEMZONE_NAMESIZE]; 4054 rte_iova_t mz_phys_addr; 4055 uint64_t valid_bits = 0; 4056 uint32_t sz; 4057 int i; 4058 4059 if (!mem_size) 4060 return 0; 4061 4062 rmem->nr_pages = RTE_ALIGN_MUL_CEIL(mem_size, BNXT_PAGE_SIZE) / 4063 BNXT_PAGE_SIZE; 4064 rmem->page_size = BNXT_PAGE_SIZE; 4065 rmem->pg_arr = ctx_pg->ctx_pg_arr; 4066 rmem->dma_arr = ctx_pg->ctx_dma_arr; 4067 rmem->flags = BNXT_RMEM_VALID_PTE_FLAG; 4068 4069 valid_bits = PTU_PTE_VALID; 4070 4071 if (rmem->nr_pages > 1) { 4072 snprintf(mz_name, RTE_MEMZONE_NAMESIZE, 4073 "bnxt_ctx_pg_tbl%s_%x_%d", 4074 suffix, idx, bp->eth_dev->data->port_id); 4075 mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0; 4076 mz = rte_memzone_lookup(mz_name); 4077 if (!mz) { 4078 mz = rte_memzone_reserve_aligned(mz_name, 4079 rmem->nr_pages * 8, 4080 SOCKET_ID_ANY, 4081 RTE_MEMZONE_2MB | 4082 RTE_MEMZONE_SIZE_HINT_ONLY | 4083 RTE_MEMZONE_IOVA_CONTIG, 4084 BNXT_PAGE_SIZE); 4085 if (mz == NULL) 4086 return -ENOMEM; 4087 } 4088 4089 memset(mz->addr, 0, mz->len); 4090 mz_phys_addr = mz->iova; 4091 4092 rmem->pg_tbl = mz->addr; 4093 rmem->pg_tbl_map = mz_phys_addr; 4094 rmem->pg_tbl_mz = mz; 4095 } 4096 4097 snprintf(mz_name, RTE_MEMZONE_NAMESIZE, "bnxt_ctx_%s_%x_%d", 4098 suffix, idx, bp->eth_dev->data->port_id); 4099 mz = rte_memzone_lookup(mz_name); 4100 if (!mz) { 4101 mz = rte_memzone_reserve_aligned(mz_name, 4102 mem_size, 4103 SOCKET_ID_ANY, 4104 RTE_MEMZONE_1GB | 4105 RTE_MEMZONE_SIZE_HINT_ONLY | 4106 RTE_MEMZONE_IOVA_CONTIG, 4107 BNXT_PAGE_SIZE); 4108 if (mz == NULL) 4109 return -ENOMEM; 4110 } 4111 4112 memset(mz->addr, 0, mz->len); 4113 mz_phys_addr = mz->iova; 4114 4115 for (sz = 0, i = 0; sz < mem_size; sz += BNXT_PAGE_SIZE, i++) { 4116 rmem->pg_arr[i] = ((char *)mz->addr) + sz; 4117 rmem->dma_arr[i] = mz_phys_addr + sz; 4118 4119 if (rmem->nr_pages > 1) { 4120 if (i == rmem->nr_pages - 2 && 4121 (rmem->flags & BNXT_RMEM_RING_PTE_FLAG)) 4122 valid_bits |= PTU_PTE_NEXT_TO_LAST; 4123 else if (i == rmem->nr_pages - 1 && 4124 (rmem->flags & BNXT_RMEM_RING_PTE_FLAG)) 4125 valid_bits |= PTU_PTE_LAST; 4126 4127 rmem->pg_tbl[i] = rte_cpu_to_le_64(rmem->dma_arr[i] | 4128 valid_bits); 4129 } 4130 } 4131 4132 rmem->mz = mz; 4133 if (rmem->vmem_size) 4134 rmem->vmem = (void **)mz->addr; 4135 rmem->dma_arr[0] = mz_phys_addr; 4136 return 0; 4137 } 4138 4139 static void bnxt_free_ctx_mem(struct bnxt *bp) 4140 { 4141 int i; 4142 4143 if (!bp->ctx || !(bp->ctx->flags & BNXT_CTX_FLAG_INITED)) 4144 return; 4145 4146 bp->ctx->flags &= ~BNXT_CTX_FLAG_INITED; 4147 rte_memzone_free(bp->ctx->qp_mem.ring_mem.mz); 4148 rte_memzone_free(bp->ctx->srq_mem.ring_mem.mz); 4149 rte_memzone_free(bp->ctx->cq_mem.ring_mem.mz); 4150 rte_memzone_free(bp->ctx->vnic_mem.ring_mem.mz); 4151 rte_memzone_free(bp->ctx->stat_mem.ring_mem.mz); 4152 rte_memzone_free(bp->ctx->qp_mem.ring_mem.pg_tbl_mz); 4153 rte_memzone_free(bp->ctx->srq_mem.ring_mem.pg_tbl_mz); 4154 rte_memzone_free(bp->ctx->cq_mem.ring_mem.pg_tbl_mz); 4155 rte_memzone_free(bp->ctx->vnic_mem.ring_mem.pg_tbl_mz); 4156 rte_memzone_free(bp->ctx->stat_mem.ring_mem.pg_tbl_mz); 4157 4158 for (i = 0; i < bp->ctx->tqm_fp_rings_count + 1; i++) { 4159 if (bp->ctx->tqm_mem[i]) 4160 rte_memzone_free(bp->ctx->tqm_mem[i]->ring_mem.mz); 4161 } 4162 4163 rte_free(bp->ctx); 4164 bp->ctx = NULL; 4165 } 4166 4167 #define bnxt_roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) 4168 4169 #define min_t(type, x, y) ({ \ 4170 type __min1 = (x); \ 4171 type __min2 = (y); \ 4172 __min1 < __min2 ? __min1 : __min2; }) 4173 4174 #define max_t(type, x, y) ({ \ 4175 type __max1 = (x); \ 4176 type __max2 = (y); \ 4177 __max1 > __max2 ? __max1 : __max2; }) 4178 4179 #define clamp_t(type, _x, min, max) min_t(type, max_t(type, _x, min), max) 4180 4181 int bnxt_alloc_ctx_mem(struct bnxt *bp) 4182 { 4183 struct bnxt_ctx_pg_info *ctx_pg; 4184 struct bnxt_ctx_mem_info *ctx; 4185 uint32_t mem_size, ena, entries; 4186 uint32_t entries_sp, min; 4187 int i, rc; 4188 4189 rc = bnxt_hwrm_func_backing_store_qcaps(bp); 4190 if (rc) { 4191 PMD_DRV_LOG(ERR, "Query context mem capability failed\n"); 4192 return rc; 4193 } 4194 ctx = bp->ctx; 4195 if (!ctx || (ctx->flags & BNXT_CTX_FLAG_INITED)) 4196 return 0; 4197 4198 ctx_pg = &ctx->qp_mem; 4199 ctx_pg->entries = ctx->qp_min_qp1_entries + ctx->qp_max_l2_entries; 4200 mem_size = ctx->qp_entry_size * ctx_pg->entries; 4201 rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, mem_size, "qp_mem", 0); 4202 if (rc) 4203 return rc; 4204 4205 ctx_pg = &ctx->srq_mem; 4206 ctx_pg->entries = ctx->srq_max_l2_entries; 4207 mem_size = ctx->srq_entry_size * ctx_pg->entries; 4208 rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, mem_size, "srq_mem", 0); 4209 if (rc) 4210 return rc; 4211 4212 ctx_pg = &ctx->cq_mem; 4213 ctx_pg->entries = ctx->cq_max_l2_entries; 4214 mem_size = ctx->cq_entry_size * ctx_pg->entries; 4215 rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, mem_size, "cq_mem", 0); 4216 if (rc) 4217 return rc; 4218 4219 ctx_pg = &ctx->vnic_mem; 4220 ctx_pg->entries = ctx->vnic_max_vnic_entries + 4221 ctx->vnic_max_ring_table_entries; 4222 mem_size = ctx->vnic_entry_size * ctx_pg->entries; 4223 rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, mem_size, "vnic_mem", 0); 4224 if (rc) 4225 return rc; 4226 4227 ctx_pg = &ctx->stat_mem; 4228 ctx_pg->entries = ctx->stat_max_entries; 4229 mem_size = ctx->stat_entry_size * ctx_pg->entries; 4230 rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, mem_size, "stat_mem", 0); 4231 if (rc) 4232 return rc; 4233 4234 min = ctx->tqm_min_entries_per_ring; 4235 4236 entries_sp = ctx->qp_max_l2_entries + 4237 ctx->vnic_max_vnic_entries + 4238 2 * ctx->qp_min_qp1_entries + min; 4239 entries_sp = bnxt_roundup(entries_sp, ctx->tqm_entries_multiple); 4240 4241 entries = ctx->qp_max_l2_entries + ctx->qp_min_qp1_entries; 4242 entries = bnxt_roundup(entries, ctx->tqm_entries_multiple); 4243 entries = clamp_t(uint32_t, entries, min, 4244 ctx->tqm_max_entries_per_ring); 4245 for (i = 0, ena = 0; i < ctx->tqm_fp_rings_count + 1; i++) { 4246 ctx_pg = ctx->tqm_mem[i]; 4247 ctx_pg->entries = i ? entries : entries_sp; 4248 mem_size = ctx->tqm_entry_size * ctx_pg->entries; 4249 rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, mem_size, "tqm_mem", i); 4250 if (rc) 4251 return rc; 4252 ena |= HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_TQM_SP << i; 4253 } 4254 4255 ena |= FUNC_BACKING_STORE_CFG_INPUT_DFLT_ENABLES; 4256 rc = bnxt_hwrm_func_backing_store_cfg(bp, ena); 4257 if (rc) 4258 PMD_DRV_LOG(ERR, 4259 "Failed to configure context mem: rc = %d\n", rc); 4260 else 4261 ctx->flags |= BNXT_CTX_FLAG_INITED; 4262 4263 return rc; 4264 } 4265 4266 static int bnxt_alloc_stats_mem(struct bnxt *bp) 4267 { 4268 struct rte_pci_device *pci_dev = bp->pdev; 4269 char mz_name[RTE_MEMZONE_NAMESIZE]; 4270 const struct rte_memzone *mz = NULL; 4271 uint32_t total_alloc_len; 4272 rte_iova_t mz_phys_addr; 4273 4274 if (pci_dev->id.device_id == BROADCOM_DEV_ID_NS2) 4275 return 0; 4276 4277 snprintf(mz_name, RTE_MEMZONE_NAMESIZE, 4278 "bnxt_" PCI_PRI_FMT "-%s", pci_dev->addr.domain, 4279 pci_dev->addr.bus, pci_dev->addr.devid, 4280 pci_dev->addr.function, "rx_port_stats"); 4281 mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0; 4282 mz = rte_memzone_lookup(mz_name); 4283 total_alloc_len = 4284 RTE_CACHE_LINE_ROUNDUP(sizeof(struct rx_port_stats) + 4285 sizeof(struct rx_port_stats_ext) + 512); 4286 if (!mz) { 4287 mz = rte_memzone_reserve(mz_name, total_alloc_len, 4288 SOCKET_ID_ANY, 4289 RTE_MEMZONE_2MB | 4290 RTE_MEMZONE_SIZE_HINT_ONLY | 4291 RTE_MEMZONE_IOVA_CONTIG); 4292 if (mz == NULL) 4293 return -ENOMEM; 4294 } 4295 memset(mz->addr, 0, mz->len); 4296 mz_phys_addr = mz->iova; 4297 4298 bp->rx_mem_zone = (const void *)mz; 4299 bp->hw_rx_port_stats = mz->addr; 4300 bp->hw_rx_port_stats_map = mz_phys_addr; 4301 4302 snprintf(mz_name, RTE_MEMZONE_NAMESIZE, 4303 "bnxt_" PCI_PRI_FMT "-%s", pci_dev->addr.domain, 4304 pci_dev->addr.bus, pci_dev->addr.devid, 4305 pci_dev->addr.function, "tx_port_stats"); 4306 mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0; 4307 mz = rte_memzone_lookup(mz_name); 4308 total_alloc_len = 4309 RTE_CACHE_LINE_ROUNDUP(sizeof(struct tx_port_stats) + 4310 sizeof(struct tx_port_stats_ext) + 512); 4311 if (!mz) { 4312 mz = rte_memzone_reserve(mz_name, 4313 total_alloc_len, 4314 SOCKET_ID_ANY, 4315 RTE_MEMZONE_2MB | 4316 RTE_MEMZONE_SIZE_HINT_ONLY | 4317 RTE_MEMZONE_IOVA_CONTIG); 4318 if (mz == NULL) 4319 return -ENOMEM; 4320 } 4321 memset(mz->addr, 0, mz->len); 4322 mz_phys_addr = mz->iova; 4323 4324 bp->tx_mem_zone = (const void *)mz; 4325 bp->hw_tx_port_stats = mz->addr; 4326 bp->hw_tx_port_stats_map = mz_phys_addr; 4327 bp->flags |= BNXT_FLAG_PORT_STATS; 4328 4329 /* Display extended statistics if FW supports it */ 4330 if (bp->hwrm_spec_code < HWRM_SPEC_CODE_1_8_4 || 4331 bp->hwrm_spec_code == HWRM_SPEC_CODE_1_9_0 || 4332 !(bp->flags & BNXT_FLAG_EXT_STATS_SUPPORTED)) 4333 return 0; 4334 4335 bp->hw_rx_port_stats_ext = (void *) 4336 ((uint8_t *)bp->hw_rx_port_stats + 4337 sizeof(struct rx_port_stats)); 4338 bp->hw_rx_port_stats_ext_map = bp->hw_rx_port_stats_map + 4339 sizeof(struct rx_port_stats); 4340 bp->flags |= BNXT_FLAG_EXT_RX_PORT_STATS; 4341 4342 if (bp->hwrm_spec_code < HWRM_SPEC_CODE_1_9_2 || 4343 bp->flags & BNXT_FLAG_EXT_STATS_SUPPORTED) { 4344 bp->hw_tx_port_stats_ext = (void *) 4345 ((uint8_t *)bp->hw_tx_port_stats + 4346 sizeof(struct tx_port_stats)); 4347 bp->hw_tx_port_stats_ext_map = 4348 bp->hw_tx_port_stats_map + 4349 sizeof(struct tx_port_stats); 4350 bp->flags |= BNXT_FLAG_EXT_TX_PORT_STATS; 4351 } 4352 4353 return 0; 4354 } 4355 4356 static int bnxt_setup_mac_addr(struct rte_eth_dev *eth_dev) 4357 { 4358 struct bnxt *bp = eth_dev->data->dev_private; 4359 int rc = 0; 4360 4361 eth_dev->data->mac_addrs = rte_zmalloc("bnxt_mac_addr_tbl", 4362 RTE_ETHER_ADDR_LEN * 4363 bp->max_l2_ctx, 4364 0); 4365 if (eth_dev->data->mac_addrs == NULL) { 4366 PMD_DRV_LOG(ERR, "Failed to alloc MAC addr tbl\n"); 4367 return -ENOMEM; 4368 } 4369 4370 if (!BNXT_HAS_DFLT_MAC_SET(bp)) { 4371 if (BNXT_PF(bp)) 4372 return -EINVAL; 4373 4374 /* Generate a random MAC address, if none was assigned by PF */ 4375 PMD_DRV_LOG(INFO, "VF MAC address not assigned by Host PF\n"); 4376 bnxt_eth_hw_addr_random(bp->mac_addr); 4377 PMD_DRV_LOG(INFO, 4378 "Assign random MAC:%02X:%02X:%02X:%02X:%02X:%02X\n", 4379 bp->mac_addr[0], bp->mac_addr[1], bp->mac_addr[2], 4380 bp->mac_addr[3], bp->mac_addr[4], bp->mac_addr[5]); 4381 4382 rc = bnxt_hwrm_set_mac(bp); 4383 if (rc) 4384 return rc; 4385 } 4386 4387 /* Copy the permanent MAC from the FUNC_QCAPS response */ 4388 memcpy(ð_dev->data->mac_addrs[0], bp->mac_addr, RTE_ETHER_ADDR_LEN); 4389 4390 return rc; 4391 } 4392 4393 static int bnxt_restore_dflt_mac(struct bnxt *bp) 4394 { 4395 int rc = 0; 4396 4397 /* MAC is already configured in FW */ 4398 if (BNXT_HAS_DFLT_MAC_SET(bp)) 4399 return 0; 4400 4401 /* Restore the old MAC configured */ 4402 rc = bnxt_hwrm_set_mac(bp); 4403 if (rc) 4404 PMD_DRV_LOG(ERR, "Failed to restore MAC address\n"); 4405 4406 return rc; 4407 } 4408 4409 static void bnxt_config_vf_req_fwd(struct bnxt *bp) 4410 { 4411 if (!BNXT_PF(bp)) 4412 return; 4413 4414 memset(bp->pf->vf_req_fwd, 0, sizeof(bp->pf->vf_req_fwd)); 4415 4416 if (!(bp->fw_cap & BNXT_FW_CAP_LINK_ADMIN)) 4417 BNXT_HWRM_CMD_TO_FORWARD(HWRM_PORT_PHY_QCFG); 4418 BNXT_HWRM_CMD_TO_FORWARD(HWRM_FUNC_CFG); 4419 BNXT_HWRM_CMD_TO_FORWARD(HWRM_FUNC_VF_CFG); 4420 BNXT_HWRM_CMD_TO_FORWARD(HWRM_CFA_L2_FILTER_ALLOC); 4421 BNXT_HWRM_CMD_TO_FORWARD(HWRM_OEM_CMD); 4422 } 4423 4424 uint16_t 4425 bnxt_get_svif(uint16_t port_id, bool func_svif, 4426 enum bnxt_ulp_intf_type type) 4427 { 4428 struct rte_eth_dev *eth_dev; 4429 struct bnxt *bp; 4430 4431 eth_dev = &rte_eth_devices[port_id]; 4432 if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) { 4433 struct bnxt_representor *vfr = eth_dev->data->dev_private; 4434 if (!vfr) 4435 return 0; 4436 4437 if (type == BNXT_ULP_INTF_TYPE_VF_REP) 4438 return vfr->svif; 4439 4440 eth_dev = vfr->parent_dev; 4441 } 4442 4443 bp = eth_dev->data->dev_private; 4444 4445 return func_svif ? bp->func_svif : bp->port_svif; 4446 } 4447 4448 uint16_t 4449 bnxt_get_vnic_id(uint16_t port, enum bnxt_ulp_intf_type type) 4450 { 4451 struct rte_eth_dev *eth_dev; 4452 struct bnxt_vnic_info *vnic; 4453 struct bnxt *bp; 4454 4455 eth_dev = &rte_eth_devices[port]; 4456 if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) { 4457 struct bnxt_representor *vfr = eth_dev->data->dev_private; 4458 if (!vfr) 4459 return 0; 4460 4461 if (type == BNXT_ULP_INTF_TYPE_VF_REP) 4462 return vfr->dflt_vnic_id; 4463 4464 eth_dev = vfr->parent_dev; 4465 } 4466 4467 bp = eth_dev->data->dev_private; 4468 4469 vnic = BNXT_GET_DEFAULT_VNIC(bp); 4470 4471 return vnic->fw_vnic_id; 4472 } 4473 4474 uint16_t 4475 bnxt_get_fw_func_id(uint16_t port, enum bnxt_ulp_intf_type type) 4476 { 4477 struct rte_eth_dev *eth_dev; 4478 struct bnxt *bp; 4479 4480 eth_dev = &rte_eth_devices[port]; 4481 if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) { 4482 struct bnxt_representor *vfr = eth_dev->data->dev_private; 4483 if (!vfr) 4484 return 0; 4485 4486 if (type == BNXT_ULP_INTF_TYPE_VF_REP) 4487 return vfr->fw_fid; 4488 4489 eth_dev = vfr->parent_dev; 4490 } 4491 4492 bp = eth_dev->data->dev_private; 4493 4494 return bp->fw_fid; 4495 } 4496 4497 enum bnxt_ulp_intf_type 4498 bnxt_get_interface_type(uint16_t port) 4499 { 4500 struct rte_eth_dev *eth_dev; 4501 struct bnxt *bp; 4502 4503 eth_dev = &rte_eth_devices[port]; 4504 if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) 4505 return BNXT_ULP_INTF_TYPE_VF_REP; 4506 4507 bp = eth_dev->data->dev_private; 4508 if (BNXT_PF(bp)) 4509 return BNXT_ULP_INTF_TYPE_PF; 4510 else if (BNXT_VF_IS_TRUSTED(bp)) 4511 return BNXT_ULP_INTF_TYPE_TRUSTED_VF; 4512 else if (BNXT_VF(bp)) 4513 return BNXT_ULP_INTF_TYPE_VF; 4514 4515 return BNXT_ULP_INTF_TYPE_INVALID; 4516 } 4517 4518 uint16_t 4519 bnxt_get_phy_port_id(uint16_t port_id) 4520 { 4521 struct bnxt_representor *vfr; 4522 struct rte_eth_dev *eth_dev; 4523 struct bnxt *bp; 4524 4525 eth_dev = &rte_eth_devices[port_id]; 4526 if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) { 4527 vfr = eth_dev->data->dev_private; 4528 if (!vfr) 4529 return 0; 4530 4531 eth_dev = vfr->parent_dev; 4532 } 4533 4534 bp = eth_dev->data->dev_private; 4535 4536 return BNXT_PF(bp) ? bp->pf->port_id : bp->parent->port_id; 4537 } 4538 4539 uint16_t 4540 bnxt_get_parif(uint16_t port_id, enum bnxt_ulp_intf_type type) 4541 { 4542 struct rte_eth_dev *eth_dev; 4543 struct bnxt *bp; 4544 4545 eth_dev = &rte_eth_devices[port_id]; 4546 if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) { 4547 struct bnxt_representor *vfr = eth_dev->data->dev_private; 4548 if (!vfr) 4549 return 0; 4550 4551 if (type == BNXT_ULP_INTF_TYPE_VF_REP) 4552 return vfr->fw_fid - 1; 4553 4554 eth_dev = vfr->parent_dev; 4555 } 4556 4557 bp = eth_dev->data->dev_private; 4558 4559 return BNXT_PF(bp) ? bp->fw_fid - 1 : bp->parent->fid - 1; 4560 } 4561 4562 uint16_t 4563 bnxt_get_vport(uint16_t port_id) 4564 { 4565 return (1 << bnxt_get_phy_port_id(port_id)); 4566 } 4567 4568 static void bnxt_alloc_error_recovery_info(struct bnxt *bp) 4569 { 4570 struct bnxt_error_recovery_info *info = bp->recovery_info; 4571 4572 if (info) { 4573 if (!(bp->fw_cap & BNXT_FW_CAP_HCOMM_FW_STATUS)) 4574 memset(info, 0, sizeof(*info)); 4575 return; 4576 } 4577 4578 if (!(bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY)) 4579 return; 4580 4581 info = rte_zmalloc("bnxt_hwrm_error_recovery_qcfg", 4582 sizeof(*info), 0); 4583 if (!info) 4584 bp->fw_cap &= ~BNXT_FW_CAP_ERROR_RECOVERY; 4585 4586 bp->recovery_info = info; 4587 } 4588 4589 static void bnxt_check_fw_status(struct bnxt *bp) 4590 { 4591 uint32_t fw_status; 4592 4593 if (!(bp->recovery_info && 4594 (bp->fw_cap & BNXT_FW_CAP_HCOMM_FW_STATUS))) 4595 return; 4596 4597 fw_status = bnxt_read_fw_status_reg(bp, BNXT_FW_STATUS_REG); 4598 if (fw_status != BNXT_FW_STATUS_HEALTHY) 4599 PMD_DRV_LOG(ERR, "Firmware not responding, status: %#x\n", 4600 fw_status); 4601 } 4602 4603 static int bnxt_map_hcomm_fw_status_reg(struct bnxt *bp) 4604 { 4605 struct bnxt_error_recovery_info *info = bp->recovery_info; 4606 uint32_t status_loc; 4607 uint32_t sig_ver; 4608 4609 rte_write32(HCOMM_STATUS_STRUCT_LOC, (uint8_t *)bp->bar0 + 4610 BNXT_GRCPF_REG_WINDOW_BASE_OUT + 4); 4611 sig_ver = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 4612 BNXT_GRCP_WINDOW_2_BASE + 4613 offsetof(struct hcomm_status, 4614 sig_ver))); 4615 /* If the signature is absent, then FW does not support this feature */ 4616 if ((sig_ver & HCOMM_STATUS_SIGNATURE_MASK) != 4617 HCOMM_STATUS_SIGNATURE_VAL) 4618 return 0; 4619 4620 if (!info) { 4621 info = rte_zmalloc("bnxt_hwrm_error_recovery_qcfg", 4622 sizeof(*info), 0); 4623 if (!info) 4624 return -ENOMEM; 4625 bp->recovery_info = info; 4626 } else { 4627 memset(info, 0, sizeof(*info)); 4628 } 4629 4630 status_loc = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 4631 BNXT_GRCP_WINDOW_2_BASE + 4632 offsetof(struct hcomm_status, 4633 fw_status_loc))); 4634 4635 /* Only pre-map the FW health status GRC register */ 4636 if (BNXT_FW_STATUS_REG_TYPE(status_loc) != BNXT_FW_STATUS_REG_TYPE_GRC) 4637 return 0; 4638 4639 info->status_regs[BNXT_FW_STATUS_REG] = status_loc; 4640 info->mapped_status_regs[BNXT_FW_STATUS_REG] = 4641 BNXT_GRCP_WINDOW_2_BASE + (status_loc & BNXT_GRCP_OFFSET_MASK); 4642 4643 rte_write32((status_loc & BNXT_GRCP_BASE_MASK), (uint8_t *)bp->bar0 + 4644 BNXT_GRCPF_REG_WINDOW_BASE_OUT + 4); 4645 4646 bp->fw_cap |= BNXT_FW_CAP_HCOMM_FW_STATUS; 4647 4648 return 0; 4649 } 4650 4651 static int bnxt_init_fw(struct bnxt *bp) 4652 { 4653 uint16_t mtu; 4654 int rc = 0; 4655 4656 bp->fw_cap = 0; 4657 4658 rc = bnxt_map_hcomm_fw_status_reg(bp); 4659 if (rc) 4660 return rc; 4661 4662 rc = bnxt_hwrm_ver_get(bp, DFLT_HWRM_CMD_TIMEOUT); 4663 if (rc) { 4664 bnxt_check_fw_status(bp); 4665 return rc; 4666 } 4667 4668 rc = bnxt_hwrm_func_reset(bp); 4669 if (rc) 4670 return -EIO; 4671 4672 rc = bnxt_hwrm_vnic_qcaps(bp); 4673 if (rc) 4674 return rc; 4675 4676 rc = bnxt_hwrm_queue_qportcfg(bp); 4677 if (rc) 4678 return rc; 4679 4680 /* Get the MAX capabilities for this function. 4681 * This function also allocates context memory for TQM rings and 4682 * informs the firmware about this allocated backing store memory. 4683 */ 4684 rc = bnxt_hwrm_func_qcaps(bp); 4685 if (rc) 4686 return rc; 4687 4688 rc = bnxt_hwrm_func_qcfg(bp, &mtu); 4689 if (rc) 4690 return rc; 4691 4692 bnxt_hwrm_port_mac_qcfg(bp); 4693 4694 bnxt_hwrm_parent_pf_qcfg(bp); 4695 4696 bnxt_hwrm_port_phy_qcaps(bp); 4697 4698 bnxt_alloc_error_recovery_info(bp); 4699 /* Get the adapter error recovery support info */ 4700 rc = bnxt_hwrm_error_recovery_qcfg(bp); 4701 if (rc) 4702 bp->fw_cap &= ~BNXT_FW_CAP_ERROR_RECOVERY; 4703 4704 bnxt_hwrm_port_led_qcaps(bp); 4705 4706 return 0; 4707 } 4708 4709 static int 4710 bnxt_init_locks(struct bnxt *bp) 4711 { 4712 int err; 4713 4714 err = pthread_mutex_init(&bp->flow_lock, NULL); 4715 if (err) { 4716 PMD_DRV_LOG(ERR, "Unable to initialize flow_lock\n"); 4717 return err; 4718 } 4719 4720 err = pthread_mutex_init(&bp->def_cp_lock, NULL); 4721 if (err) { 4722 PMD_DRV_LOG(ERR, "Unable to initialize def_cp_lock\n"); 4723 return err; 4724 } 4725 4726 err = pthread_mutex_init(&bp->health_check_lock, NULL); 4727 if (err) 4728 PMD_DRV_LOG(ERR, "Unable to initialize health_check_lock\n"); 4729 return err; 4730 } 4731 4732 static int bnxt_init_resources(struct bnxt *bp, bool reconfig_dev) 4733 { 4734 int rc = 0; 4735 4736 rc = bnxt_init_fw(bp); 4737 if (rc) 4738 return rc; 4739 4740 if (!reconfig_dev) { 4741 rc = bnxt_setup_mac_addr(bp->eth_dev); 4742 if (rc) 4743 return rc; 4744 } else { 4745 rc = bnxt_restore_dflt_mac(bp); 4746 if (rc) 4747 return rc; 4748 } 4749 4750 bnxt_config_vf_req_fwd(bp); 4751 4752 rc = bnxt_hwrm_func_driver_register(bp); 4753 if (rc) { 4754 PMD_DRV_LOG(ERR, "Failed to register driver"); 4755 return -EBUSY; 4756 } 4757 4758 if (BNXT_PF(bp)) { 4759 if (bp->pdev->max_vfs) { 4760 rc = bnxt_hwrm_allocate_vfs(bp, bp->pdev->max_vfs); 4761 if (rc) { 4762 PMD_DRV_LOG(ERR, "Failed to allocate VFs\n"); 4763 return rc; 4764 } 4765 } else { 4766 rc = bnxt_hwrm_allocate_pf_only(bp); 4767 if (rc) { 4768 PMD_DRV_LOG(ERR, 4769 "Failed to allocate PF resources"); 4770 return rc; 4771 } 4772 } 4773 } 4774 4775 rc = bnxt_alloc_mem(bp, reconfig_dev); 4776 if (rc) 4777 return rc; 4778 4779 rc = bnxt_setup_int(bp); 4780 if (rc) 4781 return rc; 4782 4783 rc = bnxt_request_int(bp); 4784 if (rc) 4785 return rc; 4786 4787 rc = bnxt_init_ctx_mem(bp); 4788 if (rc) { 4789 PMD_DRV_LOG(ERR, "Failed to init adv_flow_counters\n"); 4790 return rc; 4791 } 4792 4793 rc = bnxt_init_locks(bp); 4794 if (rc) 4795 return rc; 4796 4797 return 0; 4798 } 4799 4800 static int 4801 bnxt_parse_devarg_truflow(__rte_unused const char *key, 4802 const char *value, void *opaque_arg) 4803 { 4804 struct bnxt *bp = opaque_arg; 4805 unsigned long truflow; 4806 char *end = NULL; 4807 4808 if (!value || !opaque_arg) { 4809 PMD_DRV_LOG(ERR, 4810 "Invalid parameter passed to truflow devargs.\n"); 4811 return -EINVAL; 4812 } 4813 4814 truflow = strtoul(value, &end, 10); 4815 if (end == NULL || *end != '\0' || 4816 (truflow == ULONG_MAX && errno == ERANGE)) { 4817 PMD_DRV_LOG(ERR, 4818 "Invalid parameter passed to truflow devargs.\n"); 4819 return -EINVAL; 4820 } 4821 4822 if (BNXT_DEVARG_TRUFLOW_INVALID(truflow)) { 4823 PMD_DRV_LOG(ERR, 4824 "Invalid value passed to truflow devargs.\n"); 4825 return -EINVAL; 4826 } 4827 4828 if (truflow) { 4829 bp->flags |= BNXT_FLAG_TRUFLOW_EN; 4830 PMD_DRV_LOG(INFO, "Host-based truflow feature enabled.\n"); 4831 } else { 4832 bp->flags &= ~BNXT_FLAG_TRUFLOW_EN; 4833 PMD_DRV_LOG(INFO, "Host-based truflow feature disabled.\n"); 4834 } 4835 4836 return 0; 4837 } 4838 4839 static int 4840 bnxt_parse_devarg_flow_xstat(__rte_unused const char *key, 4841 const char *value, void *opaque_arg) 4842 { 4843 struct bnxt *bp = opaque_arg; 4844 unsigned long flow_xstat; 4845 char *end = NULL; 4846 4847 if (!value || !opaque_arg) { 4848 PMD_DRV_LOG(ERR, 4849 "Invalid parameter passed to flow_xstat devarg.\n"); 4850 return -EINVAL; 4851 } 4852 4853 flow_xstat = strtoul(value, &end, 10); 4854 if (end == NULL || *end != '\0' || 4855 (flow_xstat == ULONG_MAX && errno == ERANGE)) { 4856 PMD_DRV_LOG(ERR, 4857 "Invalid parameter passed to flow_xstat devarg.\n"); 4858 return -EINVAL; 4859 } 4860 4861 if (BNXT_DEVARG_FLOW_XSTAT_INVALID(flow_xstat)) { 4862 PMD_DRV_LOG(ERR, 4863 "Invalid value passed to flow_xstat devarg.\n"); 4864 return -EINVAL; 4865 } 4866 4867 bp->flags |= BNXT_FLAG_FLOW_XSTATS_EN; 4868 if (BNXT_FLOW_XSTATS_EN(bp)) 4869 PMD_DRV_LOG(INFO, "flow_xstat feature enabled.\n"); 4870 4871 return 0; 4872 } 4873 4874 static int 4875 bnxt_parse_devarg_max_num_kflows(__rte_unused const char *key, 4876 const char *value, void *opaque_arg) 4877 { 4878 struct bnxt *bp = opaque_arg; 4879 unsigned long max_num_kflows; 4880 char *end = NULL; 4881 4882 if (!value || !opaque_arg) { 4883 PMD_DRV_LOG(ERR, 4884 "Invalid parameter passed to max_num_kflows devarg.\n"); 4885 return -EINVAL; 4886 } 4887 4888 max_num_kflows = strtoul(value, &end, 10); 4889 if (end == NULL || *end != '\0' || 4890 (max_num_kflows == ULONG_MAX && errno == ERANGE)) { 4891 PMD_DRV_LOG(ERR, 4892 "Invalid parameter passed to max_num_kflows devarg.\n"); 4893 return -EINVAL; 4894 } 4895 4896 if (bnxt_devarg_max_num_kflow_invalid(max_num_kflows)) { 4897 PMD_DRV_LOG(ERR, 4898 "Invalid value passed to max_num_kflows devarg.\n"); 4899 return -EINVAL; 4900 } 4901 4902 bp->max_num_kflows = max_num_kflows; 4903 if (bp->max_num_kflows) 4904 PMD_DRV_LOG(INFO, "max_num_kflows set as %ldK.\n", 4905 max_num_kflows); 4906 4907 return 0; 4908 } 4909 4910 static int 4911 bnxt_parse_devarg_rep_is_pf(__rte_unused const char *key, 4912 const char *value, void *opaque_arg) 4913 { 4914 struct bnxt_representor *vfr_bp = opaque_arg; 4915 unsigned long rep_is_pf; 4916 char *end = NULL; 4917 4918 if (!value || !opaque_arg) { 4919 PMD_DRV_LOG(ERR, 4920 "Invalid parameter passed to rep_is_pf devargs.\n"); 4921 return -EINVAL; 4922 } 4923 4924 rep_is_pf = strtoul(value, &end, 10); 4925 if (end == NULL || *end != '\0' || 4926 (rep_is_pf == ULONG_MAX && errno == ERANGE)) { 4927 PMD_DRV_LOG(ERR, 4928 "Invalid parameter passed to rep_is_pf devargs.\n"); 4929 return -EINVAL; 4930 } 4931 4932 if (BNXT_DEVARG_REP_IS_PF_INVALID(rep_is_pf)) { 4933 PMD_DRV_LOG(ERR, 4934 "Invalid value passed to rep_is_pf devargs.\n"); 4935 return -EINVAL; 4936 } 4937 4938 vfr_bp->flags |= rep_is_pf; 4939 if (BNXT_REP_PF(vfr_bp)) 4940 PMD_DRV_LOG(INFO, "PF representor\n"); 4941 else 4942 PMD_DRV_LOG(INFO, "VF representor\n"); 4943 4944 return 0; 4945 } 4946 4947 static int 4948 bnxt_parse_devarg_rep_based_pf(__rte_unused const char *key, 4949 const char *value, void *opaque_arg) 4950 { 4951 struct bnxt_representor *vfr_bp = opaque_arg; 4952 unsigned long rep_based_pf; 4953 char *end = NULL; 4954 4955 if (!value || !opaque_arg) { 4956 PMD_DRV_LOG(ERR, 4957 "Invalid parameter passed to rep_based_pf " 4958 "devargs.\n"); 4959 return -EINVAL; 4960 } 4961 4962 rep_based_pf = strtoul(value, &end, 10); 4963 if (end == NULL || *end != '\0' || 4964 (rep_based_pf == ULONG_MAX && errno == ERANGE)) { 4965 PMD_DRV_LOG(ERR, 4966 "Invalid parameter passed to rep_based_pf " 4967 "devargs.\n"); 4968 return -EINVAL; 4969 } 4970 4971 if (BNXT_DEVARG_REP_BASED_PF_INVALID(rep_based_pf)) { 4972 PMD_DRV_LOG(ERR, 4973 "Invalid value passed to rep_based_pf devargs.\n"); 4974 return -EINVAL; 4975 } 4976 4977 vfr_bp->rep_based_pf = rep_based_pf; 4978 vfr_bp->flags |= BNXT_REP_BASED_PF_VALID; 4979 4980 PMD_DRV_LOG(INFO, "rep-based-pf = %d\n", vfr_bp->rep_based_pf); 4981 4982 return 0; 4983 } 4984 4985 static int 4986 bnxt_parse_devarg_rep_q_r2f(__rte_unused const char *key, 4987 const char *value, void *opaque_arg) 4988 { 4989 struct bnxt_representor *vfr_bp = opaque_arg; 4990 unsigned long rep_q_r2f; 4991 char *end = NULL; 4992 4993 if (!value || !opaque_arg) { 4994 PMD_DRV_LOG(ERR, 4995 "Invalid parameter passed to rep_q_r2f " 4996 "devargs.\n"); 4997 return -EINVAL; 4998 } 4999 5000 rep_q_r2f = strtoul(value, &end, 10); 5001 if (end == NULL || *end != '\0' || 5002 (rep_q_r2f == ULONG_MAX && errno == ERANGE)) { 5003 PMD_DRV_LOG(ERR, 5004 "Invalid parameter passed to rep_q_r2f " 5005 "devargs.\n"); 5006 return -EINVAL; 5007 } 5008 5009 if (BNXT_DEVARG_REP_Q_R2F_INVALID(rep_q_r2f)) { 5010 PMD_DRV_LOG(ERR, 5011 "Invalid value passed to rep_q_r2f devargs.\n"); 5012 return -EINVAL; 5013 } 5014 5015 vfr_bp->rep_q_r2f = rep_q_r2f; 5016 vfr_bp->flags |= BNXT_REP_Q_R2F_VALID; 5017 PMD_DRV_LOG(INFO, "rep-q-r2f = %d\n", vfr_bp->rep_q_r2f); 5018 5019 return 0; 5020 } 5021 5022 static int 5023 bnxt_parse_devarg_rep_q_f2r(__rte_unused const char *key, 5024 const char *value, void *opaque_arg) 5025 { 5026 struct bnxt_representor *vfr_bp = opaque_arg; 5027 unsigned long rep_q_f2r; 5028 char *end = NULL; 5029 5030 if (!value || !opaque_arg) { 5031 PMD_DRV_LOG(ERR, 5032 "Invalid parameter passed to rep_q_f2r " 5033 "devargs.\n"); 5034 return -EINVAL; 5035 } 5036 5037 rep_q_f2r = strtoul(value, &end, 10); 5038 if (end == NULL || *end != '\0' || 5039 (rep_q_f2r == ULONG_MAX && errno == ERANGE)) { 5040 PMD_DRV_LOG(ERR, 5041 "Invalid parameter passed to rep_q_f2r " 5042 "devargs.\n"); 5043 return -EINVAL; 5044 } 5045 5046 if (BNXT_DEVARG_REP_Q_F2R_INVALID(rep_q_f2r)) { 5047 PMD_DRV_LOG(ERR, 5048 "Invalid value passed to rep_q_f2r devargs.\n"); 5049 return -EINVAL; 5050 } 5051 5052 vfr_bp->rep_q_f2r = rep_q_f2r; 5053 vfr_bp->flags |= BNXT_REP_Q_F2R_VALID; 5054 PMD_DRV_LOG(INFO, "rep-q-f2r = %d\n", vfr_bp->rep_q_f2r); 5055 5056 return 0; 5057 } 5058 5059 static int 5060 bnxt_parse_devarg_rep_fc_r2f(__rte_unused const char *key, 5061 const char *value, void *opaque_arg) 5062 { 5063 struct bnxt_representor *vfr_bp = opaque_arg; 5064 unsigned long rep_fc_r2f; 5065 char *end = NULL; 5066 5067 if (!value || !opaque_arg) { 5068 PMD_DRV_LOG(ERR, 5069 "Invalid parameter passed to rep_fc_r2f " 5070 "devargs.\n"); 5071 return -EINVAL; 5072 } 5073 5074 rep_fc_r2f = strtoul(value, &end, 10); 5075 if (end == NULL || *end != '\0' || 5076 (rep_fc_r2f == ULONG_MAX && errno == ERANGE)) { 5077 PMD_DRV_LOG(ERR, 5078 "Invalid parameter passed to rep_fc_r2f " 5079 "devargs.\n"); 5080 return -EINVAL; 5081 } 5082 5083 if (BNXT_DEVARG_REP_FC_R2F_INVALID(rep_fc_r2f)) { 5084 PMD_DRV_LOG(ERR, 5085 "Invalid value passed to rep_fc_r2f devargs.\n"); 5086 return -EINVAL; 5087 } 5088 5089 vfr_bp->flags |= BNXT_REP_FC_R2F_VALID; 5090 vfr_bp->rep_fc_r2f = rep_fc_r2f; 5091 PMD_DRV_LOG(INFO, "rep-fc-r2f = %lu\n", rep_fc_r2f); 5092 5093 return 0; 5094 } 5095 5096 static int 5097 bnxt_parse_devarg_rep_fc_f2r(__rte_unused const char *key, 5098 const char *value, void *opaque_arg) 5099 { 5100 struct bnxt_representor *vfr_bp = opaque_arg; 5101 unsigned long rep_fc_f2r; 5102 char *end = NULL; 5103 5104 if (!value || !opaque_arg) { 5105 PMD_DRV_LOG(ERR, 5106 "Invalid parameter passed to rep_fc_f2r " 5107 "devargs.\n"); 5108 return -EINVAL; 5109 } 5110 5111 rep_fc_f2r = strtoul(value, &end, 10); 5112 if (end == NULL || *end != '\0' || 5113 (rep_fc_f2r == ULONG_MAX && errno == ERANGE)) { 5114 PMD_DRV_LOG(ERR, 5115 "Invalid parameter passed to rep_fc_f2r " 5116 "devargs.\n"); 5117 return -EINVAL; 5118 } 5119 5120 if (BNXT_DEVARG_REP_FC_F2R_INVALID(rep_fc_f2r)) { 5121 PMD_DRV_LOG(ERR, 5122 "Invalid value passed to rep_fc_f2r devargs.\n"); 5123 return -EINVAL; 5124 } 5125 5126 vfr_bp->flags |= BNXT_REP_FC_F2R_VALID; 5127 vfr_bp->rep_fc_f2r = rep_fc_f2r; 5128 PMD_DRV_LOG(INFO, "rep-fc-f2r = %lu\n", rep_fc_f2r); 5129 5130 return 0; 5131 } 5132 5133 static void 5134 bnxt_parse_dev_args(struct bnxt *bp, struct rte_devargs *devargs) 5135 { 5136 struct rte_kvargs *kvlist; 5137 5138 if (devargs == NULL) 5139 return; 5140 5141 kvlist = rte_kvargs_parse(devargs->args, bnxt_dev_args); 5142 if (kvlist == NULL) 5143 return; 5144 5145 /* 5146 * Handler for "truflow" devarg. 5147 * Invoked as for ex: "-a 0000:00:0d.0,host-based-truflow=1" 5148 */ 5149 rte_kvargs_process(kvlist, BNXT_DEVARG_TRUFLOW, 5150 bnxt_parse_devarg_truflow, bp); 5151 5152 /* 5153 * Handler for "flow_xstat" devarg. 5154 * Invoked as for ex: "-a 0000:00:0d.0,flow_xstat=1" 5155 */ 5156 rte_kvargs_process(kvlist, BNXT_DEVARG_FLOW_XSTAT, 5157 bnxt_parse_devarg_flow_xstat, bp); 5158 5159 /* 5160 * Handler for "max_num_kflows" devarg. 5161 * Invoked as for ex: "-a 000:00:0d.0,max_num_kflows=32" 5162 */ 5163 rte_kvargs_process(kvlist, BNXT_DEVARG_MAX_NUM_KFLOWS, 5164 bnxt_parse_devarg_max_num_kflows, bp); 5165 5166 rte_kvargs_free(kvlist); 5167 } 5168 5169 static int bnxt_alloc_switch_domain(struct bnxt *bp) 5170 { 5171 int rc = 0; 5172 5173 if (BNXT_PF(bp) || BNXT_VF_IS_TRUSTED(bp)) { 5174 rc = rte_eth_switch_domain_alloc(&bp->switch_domain_id); 5175 if (rc) 5176 PMD_DRV_LOG(ERR, 5177 "Failed to alloc switch domain: %d\n", rc); 5178 else 5179 PMD_DRV_LOG(INFO, 5180 "Switch domain allocated %d\n", 5181 bp->switch_domain_id); 5182 } 5183 5184 return rc; 5185 } 5186 5187 static int 5188 bnxt_dev_init(struct rte_eth_dev *eth_dev, void *params __rte_unused) 5189 { 5190 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); 5191 static int version_printed; 5192 struct bnxt *bp; 5193 int rc; 5194 5195 if (version_printed++ == 0) 5196 PMD_DRV_LOG(INFO, "%s\n", bnxt_version); 5197 5198 eth_dev->dev_ops = &bnxt_dev_ops; 5199 eth_dev->rx_queue_count = bnxt_rx_queue_count_op; 5200 eth_dev->rx_descriptor_status = bnxt_rx_descriptor_status_op; 5201 eth_dev->tx_descriptor_status = bnxt_tx_descriptor_status_op; 5202 eth_dev->rx_pkt_burst = &bnxt_recv_pkts; 5203 eth_dev->tx_pkt_burst = &bnxt_xmit_pkts; 5204 5205 /* 5206 * For secondary processes, we don't initialise any further 5207 * as primary has already done this work. 5208 */ 5209 if (rte_eal_process_type() != RTE_PROC_PRIMARY) 5210 return 0; 5211 5212 rte_eth_copy_pci_info(eth_dev, pci_dev); 5213 eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS; 5214 5215 bp = eth_dev->data->dev_private; 5216 5217 /* Parse dev arguments passed on when starting the DPDK application. */ 5218 bnxt_parse_dev_args(bp, pci_dev->device.devargs); 5219 5220 bp->flags &= ~BNXT_FLAG_RX_VECTOR_PKT_MODE; 5221 5222 if (bnxt_vf_pciid(pci_dev->id.device_id)) 5223 bp->flags |= BNXT_FLAG_VF; 5224 5225 if (bnxt_p5_device(pci_dev->id.device_id)) 5226 bp->flags |= BNXT_FLAG_CHIP_P5; 5227 5228 if (pci_dev->id.device_id == BROADCOM_DEV_ID_58802 || 5229 pci_dev->id.device_id == BROADCOM_DEV_ID_58804 || 5230 pci_dev->id.device_id == BROADCOM_DEV_ID_58808 || 5231 pci_dev->id.device_id == BROADCOM_DEV_ID_58802_VF) 5232 bp->flags |= BNXT_FLAG_STINGRAY; 5233 5234 if (BNXT_TRUFLOW_EN(bp)) { 5235 /* extra mbuf field is required to store CFA code from mark */ 5236 static const struct rte_mbuf_dynfield bnxt_cfa_code_dynfield_desc = { 5237 .name = RTE_PMD_BNXT_CFA_CODE_DYNFIELD_NAME, 5238 .size = sizeof(bnxt_cfa_code_dynfield_t), 5239 .align = __alignof__(bnxt_cfa_code_dynfield_t), 5240 }; 5241 bnxt_cfa_code_dynfield_offset = 5242 rte_mbuf_dynfield_register(&bnxt_cfa_code_dynfield_desc); 5243 if (bnxt_cfa_code_dynfield_offset < 0) { 5244 PMD_DRV_LOG(ERR, 5245 "Failed to register mbuf field for TruFlow mark\n"); 5246 return -rte_errno; 5247 } 5248 } 5249 5250 rc = bnxt_init_board(eth_dev); 5251 if (rc) { 5252 PMD_DRV_LOG(ERR, 5253 "Failed to initialize board rc: %x\n", rc); 5254 return rc; 5255 } 5256 5257 rc = bnxt_alloc_pf_info(bp); 5258 if (rc) 5259 goto error_free; 5260 5261 rc = bnxt_alloc_link_info(bp); 5262 if (rc) 5263 goto error_free; 5264 5265 rc = bnxt_alloc_parent_info(bp); 5266 if (rc) 5267 goto error_free; 5268 5269 rc = bnxt_alloc_hwrm_resources(bp); 5270 if (rc) { 5271 PMD_DRV_LOG(ERR, 5272 "Failed to allocate hwrm resource rc: %x\n", rc); 5273 goto error_free; 5274 } 5275 rc = bnxt_alloc_leds_info(bp); 5276 if (rc) 5277 goto error_free; 5278 5279 rc = bnxt_alloc_cos_queues(bp); 5280 if (rc) 5281 goto error_free; 5282 5283 rc = bnxt_init_resources(bp, false); 5284 if (rc) 5285 goto error_free; 5286 5287 rc = bnxt_alloc_stats_mem(bp); 5288 if (rc) 5289 goto error_free; 5290 5291 bnxt_alloc_switch_domain(bp); 5292 5293 PMD_DRV_LOG(INFO, 5294 DRV_MODULE_NAME "found at mem %" PRIX64 ", node addr %pM\n", 5295 pci_dev->mem_resource[0].phys_addr, 5296 pci_dev->mem_resource[0].addr); 5297 5298 return 0; 5299 5300 error_free: 5301 bnxt_dev_uninit(eth_dev); 5302 return rc; 5303 } 5304 5305 5306 static void bnxt_free_ctx_mem_buf(struct bnxt_ctx_mem_buf_info *ctx) 5307 { 5308 if (!ctx) 5309 return; 5310 5311 if (ctx->va) 5312 rte_free(ctx->va); 5313 5314 ctx->va = NULL; 5315 ctx->dma = RTE_BAD_IOVA; 5316 ctx->ctx_id = BNXT_CTX_VAL_INVAL; 5317 } 5318 5319 static void bnxt_unregister_fc_ctx_mem(struct bnxt *bp) 5320 { 5321 bnxt_hwrm_cfa_counter_cfg(bp, BNXT_DIR_RX, 5322 CFA_COUNTER_CFG_IN_COUNTER_TYPE_FC, 5323 bp->flow_stat->rx_fc_out_tbl.ctx_id, 5324 bp->flow_stat->max_fc, 5325 false); 5326 5327 bnxt_hwrm_cfa_counter_cfg(bp, BNXT_DIR_TX, 5328 CFA_COUNTER_CFG_IN_COUNTER_TYPE_FC, 5329 bp->flow_stat->tx_fc_out_tbl.ctx_id, 5330 bp->flow_stat->max_fc, 5331 false); 5332 5333 if (bp->flow_stat->rx_fc_in_tbl.ctx_id != BNXT_CTX_VAL_INVAL) 5334 bnxt_hwrm_ctx_unrgtr(bp, bp->flow_stat->rx_fc_in_tbl.ctx_id); 5335 bp->flow_stat->rx_fc_in_tbl.ctx_id = BNXT_CTX_VAL_INVAL; 5336 5337 if (bp->flow_stat->rx_fc_out_tbl.ctx_id != BNXT_CTX_VAL_INVAL) 5338 bnxt_hwrm_ctx_unrgtr(bp, bp->flow_stat->rx_fc_out_tbl.ctx_id); 5339 bp->flow_stat->rx_fc_out_tbl.ctx_id = BNXT_CTX_VAL_INVAL; 5340 5341 if (bp->flow_stat->tx_fc_in_tbl.ctx_id != BNXT_CTX_VAL_INVAL) 5342 bnxt_hwrm_ctx_unrgtr(bp, bp->flow_stat->tx_fc_in_tbl.ctx_id); 5343 bp->flow_stat->tx_fc_in_tbl.ctx_id = BNXT_CTX_VAL_INVAL; 5344 5345 if (bp->flow_stat->tx_fc_out_tbl.ctx_id != BNXT_CTX_VAL_INVAL) 5346 bnxt_hwrm_ctx_unrgtr(bp, bp->flow_stat->tx_fc_out_tbl.ctx_id); 5347 bp->flow_stat->tx_fc_out_tbl.ctx_id = BNXT_CTX_VAL_INVAL; 5348 } 5349 5350 static void bnxt_uninit_fc_ctx_mem(struct bnxt *bp) 5351 { 5352 bnxt_unregister_fc_ctx_mem(bp); 5353 5354 bnxt_free_ctx_mem_buf(&bp->flow_stat->rx_fc_in_tbl); 5355 bnxt_free_ctx_mem_buf(&bp->flow_stat->rx_fc_out_tbl); 5356 bnxt_free_ctx_mem_buf(&bp->flow_stat->tx_fc_in_tbl); 5357 bnxt_free_ctx_mem_buf(&bp->flow_stat->tx_fc_out_tbl); 5358 } 5359 5360 static void bnxt_uninit_ctx_mem(struct bnxt *bp) 5361 { 5362 if (BNXT_FLOW_XSTATS_EN(bp)) 5363 bnxt_uninit_fc_ctx_mem(bp); 5364 } 5365 5366 static void 5367 bnxt_free_error_recovery_info(struct bnxt *bp) 5368 { 5369 rte_free(bp->recovery_info); 5370 bp->recovery_info = NULL; 5371 bp->fw_cap &= ~BNXT_FW_CAP_ERROR_RECOVERY; 5372 } 5373 5374 static void 5375 bnxt_uninit_locks(struct bnxt *bp) 5376 { 5377 pthread_mutex_destroy(&bp->flow_lock); 5378 pthread_mutex_destroy(&bp->def_cp_lock); 5379 pthread_mutex_destroy(&bp->health_check_lock); 5380 if (bp->rep_info) { 5381 pthread_mutex_destroy(&bp->rep_info->vfr_lock); 5382 pthread_mutex_destroy(&bp->rep_info->vfr_start_lock); 5383 } 5384 } 5385 5386 static int 5387 bnxt_uninit_resources(struct bnxt *bp, bool reconfig_dev) 5388 { 5389 int rc; 5390 5391 bnxt_free_int(bp); 5392 bnxt_free_mem(bp, reconfig_dev); 5393 5394 bnxt_hwrm_func_buf_unrgtr(bp); 5395 rte_free(bp->pf->vf_req_buf); 5396 5397 rc = bnxt_hwrm_func_driver_unregister(bp, 0); 5398 bp->flags &= ~BNXT_FLAG_REGISTERED; 5399 bnxt_free_ctx_mem(bp); 5400 if (!reconfig_dev) { 5401 bnxt_free_hwrm_resources(bp); 5402 bnxt_free_error_recovery_info(bp); 5403 } 5404 5405 bnxt_uninit_ctx_mem(bp); 5406 5407 bnxt_uninit_locks(bp); 5408 bnxt_free_flow_stats_info(bp); 5409 bnxt_free_rep_info(bp); 5410 rte_free(bp->ptp_cfg); 5411 bp->ptp_cfg = NULL; 5412 return rc; 5413 } 5414 5415 static int 5416 bnxt_dev_uninit(struct rte_eth_dev *eth_dev) 5417 { 5418 if (rte_eal_process_type() != RTE_PROC_PRIMARY) 5419 return -EPERM; 5420 5421 PMD_DRV_LOG(DEBUG, "Calling Device uninit\n"); 5422 5423 if (eth_dev->state != RTE_ETH_DEV_UNUSED) 5424 bnxt_dev_close_op(eth_dev); 5425 5426 return 0; 5427 } 5428 5429 static int bnxt_pci_remove_dev_with_reps(struct rte_eth_dev *eth_dev) 5430 { 5431 struct bnxt *bp = eth_dev->data->dev_private; 5432 struct rte_eth_dev *vf_rep_eth_dev; 5433 int ret = 0, i; 5434 5435 if (!bp) 5436 return -EINVAL; 5437 5438 for (i = 0; i < bp->num_reps; i++) { 5439 vf_rep_eth_dev = bp->rep_info[i].vfr_eth_dev; 5440 if (!vf_rep_eth_dev) 5441 continue; 5442 PMD_DRV_LOG(DEBUG, "BNXT Port:%d VFR pci remove\n", 5443 vf_rep_eth_dev->data->port_id); 5444 rte_eth_dev_destroy(vf_rep_eth_dev, bnxt_representor_uninit); 5445 } 5446 PMD_DRV_LOG(DEBUG, "BNXT Port:%d pci remove\n", 5447 eth_dev->data->port_id); 5448 ret = rte_eth_dev_destroy(eth_dev, bnxt_dev_uninit); 5449 5450 return ret; 5451 } 5452 5453 static void bnxt_free_rep_info(struct bnxt *bp) 5454 { 5455 rte_free(bp->rep_info); 5456 bp->rep_info = NULL; 5457 rte_free(bp->cfa_code_map); 5458 bp->cfa_code_map = NULL; 5459 } 5460 5461 static int bnxt_init_rep_info(struct bnxt *bp) 5462 { 5463 int i = 0, rc; 5464 5465 if (bp->rep_info) 5466 return 0; 5467 5468 bp->rep_info = rte_zmalloc("bnxt_rep_info", 5469 sizeof(bp->rep_info[0]) * BNXT_MAX_VF_REPS, 5470 0); 5471 if (!bp->rep_info) { 5472 PMD_DRV_LOG(ERR, "Failed to alloc memory for rep info\n"); 5473 return -ENOMEM; 5474 } 5475 bp->cfa_code_map = rte_zmalloc("bnxt_cfa_code_map", 5476 sizeof(*bp->cfa_code_map) * 5477 BNXT_MAX_CFA_CODE, 0); 5478 if (!bp->cfa_code_map) { 5479 PMD_DRV_LOG(ERR, "Failed to alloc memory for cfa_code_map\n"); 5480 bnxt_free_rep_info(bp); 5481 return -ENOMEM; 5482 } 5483 5484 for (i = 0; i < BNXT_MAX_CFA_CODE; i++) 5485 bp->cfa_code_map[i] = BNXT_VF_IDX_INVALID; 5486 5487 rc = pthread_mutex_init(&bp->rep_info->vfr_lock, NULL); 5488 if (rc) { 5489 PMD_DRV_LOG(ERR, "Unable to initialize vfr_lock\n"); 5490 bnxt_free_rep_info(bp); 5491 return rc; 5492 } 5493 5494 rc = pthread_mutex_init(&bp->rep_info->vfr_start_lock, NULL); 5495 if (rc) { 5496 PMD_DRV_LOG(ERR, "Unable to initialize vfr_start_lock\n"); 5497 bnxt_free_rep_info(bp); 5498 return rc; 5499 } 5500 5501 return rc; 5502 } 5503 5504 static int bnxt_rep_port_probe(struct rte_pci_device *pci_dev, 5505 struct rte_eth_devargs *eth_da, 5506 struct rte_eth_dev *backing_eth_dev, 5507 const char *dev_args) 5508 { 5509 struct rte_eth_dev *vf_rep_eth_dev; 5510 char name[RTE_ETH_NAME_MAX_LEN]; 5511 struct bnxt *backing_bp; 5512 uint16_t num_rep; 5513 int i, ret = 0; 5514 struct rte_kvargs *kvlist = NULL; 5515 5516 num_rep = eth_da->nb_representor_ports; 5517 if (num_rep > BNXT_MAX_VF_REPS) { 5518 PMD_DRV_LOG(ERR, "nb_representor_ports = %d > %d MAX VF REPS\n", 5519 num_rep, BNXT_MAX_VF_REPS); 5520 return -EINVAL; 5521 } 5522 5523 if (num_rep >= RTE_MAX_ETHPORTS) { 5524 PMD_DRV_LOG(ERR, 5525 "nb_representor_ports = %d > %d MAX ETHPORTS\n", 5526 num_rep, RTE_MAX_ETHPORTS); 5527 return -EINVAL; 5528 } 5529 5530 backing_bp = backing_eth_dev->data->dev_private; 5531 5532 if (!(BNXT_PF(backing_bp) || BNXT_VF_IS_TRUSTED(backing_bp))) { 5533 PMD_DRV_LOG(ERR, 5534 "Not a PF or trusted VF. No Representor support\n"); 5535 /* Returning an error is not an option. 5536 * Applications are not handling this correctly 5537 */ 5538 return 0; 5539 } 5540 5541 if (bnxt_init_rep_info(backing_bp)) 5542 return 0; 5543 5544 for (i = 0; i < num_rep; i++) { 5545 struct bnxt_representor representor = { 5546 .vf_id = eth_da->representor_ports[i], 5547 .switch_domain_id = backing_bp->switch_domain_id, 5548 .parent_dev = backing_eth_dev 5549 }; 5550 5551 if (representor.vf_id >= BNXT_MAX_VF_REPS) { 5552 PMD_DRV_LOG(ERR, "VF-Rep id %d >= %d MAX VF ID\n", 5553 representor.vf_id, BNXT_MAX_VF_REPS); 5554 continue; 5555 } 5556 5557 /* representor port net_bdf_port */ 5558 snprintf(name, sizeof(name), "net_%s_representor_%d", 5559 pci_dev->device.name, eth_da->representor_ports[i]); 5560 5561 kvlist = rte_kvargs_parse(dev_args, bnxt_dev_args); 5562 if (kvlist) { 5563 /* 5564 * Handler for "rep_is_pf" devarg. 5565 * Invoked as for ex: "-a 000:00:0d.0, 5566 * rep-based-pf=<pf index> rep-is-pf=<VF=0 or PF=1>" 5567 */ 5568 ret = rte_kvargs_process(kvlist, BNXT_DEVARG_REP_IS_PF, 5569 bnxt_parse_devarg_rep_is_pf, 5570 (void *)&representor); 5571 if (ret) { 5572 ret = -EINVAL; 5573 goto err; 5574 } 5575 /* 5576 * Handler for "rep_based_pf" devarg. 5577 * Invoked as for ex: "-a 000:00:0d.0, 5578 * rep-based-pf=<pf index> rep-is-pf=<VF=0 or PF=1>" 5579 */ 5580 ret = rte_kvargs_process(kvlist, 5581 BNXT_DEVARG_REP_BASED_PF, 5582 bnxt_parse_devarg_rep_based_pf, 5583 (void *)&representor); 5584 if (ret) { 5585 ret = -EINVAL; 5586 goto err; 5587 } 5588 /* 5589 * Handler for "rep_based_pf" devarg. 5590 * Invoked as for ex: "-a 000:00:0d.0, 5591 * rep-based-pf=<pf index> rep-is-pf=<VF=0 or PF=1>" 5592 */ 5593 ret = rte_kvargs_process(kvlist, BNXT_DEVARG_REP_Q_R2F, 5594 bnxt_parse_devarg_rep_q_r2f, 5595 (void *)&representor); 5596 if (ret) { 5597 ret = -EINVAL; 5598 goto err; 5599 } 5600 /* 5601 * Handler for "rep_based_pf" devarg. 5602 * Invoked as for ex: "-a 000:00:0d.0, 5603 * rep-based-pf=<pf index> rep-is-pf=<VF=0 or PF=1>" 5604 */ 5605 ret = rte_kvargs_process(kvlist, BNXT_DEVARG_REP_Q_F2R, 5606 bnxt_parse_devarg_rep_q_f2r, 5607 (void *)&representor); 5608 if (ret) { 5609 ret = -EINVAL; 5610 goto err; 5611 } 5612 /* 5613 * Handler for "rep_based_pf" devarg. 5614 * Invoked as for ex: "-a 000:00:0d.0, 5615 * rep-based-pf=<pf index> rep-is-pf=<VF=0 or PF=1>" 5616 */ 5617 ret = rte_kvargs_process(kvlist, BNXT_DEVARG_REP_FC_R2F, 5618 bnxt_parse_devarg_rep_fc_r2f, 5619 (void *)&representor); 5620 if (ret) { 5621 ret = -EINVAL; 5622 goto err; 5623 } 5624 /* 5625 * Handler for "rep_based_pf" devarg. 5626 * Invoked as for ex: "-a 000:00:0d.0, 5627 * rep-based-pf=<pf index> rep-is-pf=<VF=0 or PF=1>" 5628 */ 5629 ret = rte_kvargs_process(kvlist, BNXT_DEVARG_REP_FC_F2R, 5630 bnxt_parse_devarg_rep_fc_f2r, 5631 (void *)&representor); 5632 if (ret) { 5633 ret = -EINVAL; 5634 goto err; 5635 } 5636 } 5637 5638 ret = rte_eth_dev_create(&pci_dev->device, name, 5639 sizeof(struct bnxt_representor), 5640 NULL, NULL, 5641 bnxt_representor_init, 5642 &representor); 5643 if (ret) { 5644 PMD_DRV_LOG(ERR, "failed to create bnxt vf " 5645 "representor %s.", name); 5646 goto err; 5647 } 5648 5649 vf_rep_eth_dev = rte_eth_dev_allocated(name); 5650 if (!vf_rep_eth_dev) { 5651 PMD_DRV_LOG(ERR, "Failed to find the eth_dev" 5652 " for VF-Rep: %s.", name); 5653 ret = -ENODEV; 5654 goto err; 5655 } 5656 5657 PMD_DRV_LOG(DEBUG, "BNXT Port:%d VFR pci probe\n", 5658 backing_eth_dev->data->port_id); 5659 backing_bp->rep_info[representor.vf_id].vfr_eth_dev = 5660 vf_rep_eth_dev; 5661 backing_bp->num_reps++; 5662 5663 } 5664 5665 rte_kvargs_free(kvlist); 5666 return 0; 5667 5668 err: 5669 /* If num_rep > 1, then rollback already created 5670 * ports, since we'll be failing the probe anyway 5671 */ 5672 if (num_rep > 1) 5673 bnxt_pci_remove_dev_with_reps(backing_eth_dev); 5674 rte_errno = -ret; 5675 rte_kvargs_free(kvlist); 5676 5677 return ret; 5678 } 5679 5680 static int bnxt_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, 5681 struct rte_pci_device *pci_dev) 5682 { 5683 struct rte_eth_devargs eth_da = { .nb_representor_ports = 0 }; 5684 struct rte_eth_dev *backing_eth_dev; 5685 uint16_t num_rep; 5686 int ret = 0; 5687 5688 if (pci_dev->device.devargs) { 5689 ret = rte_eth_devargs_parse(pci_dev->device.devargs->args, 5690 ð_da); 5691 if (ret) 5692 return ret; 5693 } 5694 5695 num_rep = eth_da.nb_representor_ports; 5696 PMD_DRV_LOG(DEBUG, "nb_representor_ports = %d\n", 5697 num_rep); 5698 5699 /* We could come here after first level of probe is already invoked 5700 * as part of an application bringup(OVS-DPDK vswitchd), so first check 5701 * for already allocated eth_dev for the backing device (PF/Trusted VF) 5702 */ 5703 backing_eth_dev = rte_eth_dev_allocated(pci_dev->device.name); 5704 if (backing_eth_dev == NULL) { 5705 ret = rte_eth_dev_create(&pci_dev->device, pci_dev->device.name, 5706 sizeof(struct bnxt), 5707 eth_dev_pci_specific_init, pci_dev, 5708 bnxt_dev_init, NULL); 5709 5710 if (ret || !num_rep) 5711 return ret; 5712 5713 backing_eth_dev = rte_eth_dev_allocated(pci_dev->device.name); 5714 } 5715 PMD_DRV_LOG(DEBUG, "BNXT Port:%d pci probe\n", 5716 backing_eth_dev->data->port_id); 5717 5718 if (!num_rep) 5719 return ret; 5720 5721 /* probe representor ports now */ 5722 ret = bnxt_rep_port_probe(pci_dev, ð_da, backing_eth_dev, 5723 pci_dev->device.devargs->args); 5724 5725 return ret; 5726 } 5727 5728 static int bnxt_pci_remove(struct rte_pci_device *pci_dev) 5729 { 5730 struct rte_eth_dev *eth_dev; 5731 5732 eth_dev = rte_eth_dev_allocated(pci_dev->device.name); 5733 if (!eth_dev) 5734 return 0; /* Invoked typically only by OVS-DPDK, by the 5735 * time it comes here the eth_dev is already 5736 * deleted by rte_eth_dev_close(), so returning 5737 * +ve value will at least help in proper cleanup 5738 */ 5739 5740 PMD_DRV_LOG(DEBUG, "BNXT Port:%d pci remove\n", eth_dev->data->port_id); 5741 if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 5742 if (eth_dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR) 5743 return rte_eth_dev_destroy(eth_dev, 5744 bnxt_representor_uninit); 5745 else 5746 return rte_eth_dev_destroy(eth_dev, 5747 bnxt_dev_uninit); 5748 } else { 5749 return rte_eth_dev_pci_generic_remove(pci_dev, NULL); 5750 } 5751 } 5752 5753 static struct rte_pci_driver bnxt_rte_pmd = { 5754 .id_table = bnxt_pci_id_map, 5755 .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC | 5756 RTE_PCI_DRV_PROBE_AGAIN, /* Needed in case of VF-REPs 5757 * and OVS-DPDK 5758 */ 5759 .probe = bnxt_pci_probe, 5760 .remove = bnxt_pci_remove, 5761 }; 5762 5763 static bool 5764 is_device_supported(struct rte_eth_dev *dev, struct rte_pci_driver *drv) 5765 { 5766 if (strcmp(dev->device->driver->name, drv->driver.name)) 5767 return false; 5768 5769 return true; 5770 } 5771 5772 bool is_bnxt_supported(struct rte_eth_dev *dev) 5773 { 5774 return is_device_supported(dev, &bnxt_rte_pmd); 5775 } 5776 5777 RTE_LOG_REGISTER(bnxt_logtype_driver, pmd.net.bnxt.driver, NOTICE); 5778 RTE_PMD_REGISTER_PCI(net_bnxt, bnxt_rte_pmd); 5779 RTE_PMD_REGISTER_PCI_TABLE(net_bnxt, bnxt_pci_id_map); 5780 RTE_PMD_REGISTER_KMOD_DEP(net_bnxt, "* igb_uio | uio_pci_generic | vfio-pci"); 5781