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