1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2014-2023 Broadcom 3 * All rights reserved. 4 */ 5 6 #include "bnxt.h" 7 #include "bnxt_ring.h" 8 #include "bnxt_reps.h" 9 #include "bnxt_rxq.h" 10 #include "bnxt_rxr.h" 11 #include "bnxt_txq.h" 12 #include "bnxt_txr.h" 13 #include "bnxt_hwrm.h" 14 #include "hsi_struct_def_dpdk.h" 15 #include "bnxt_tf_common.h" 16 #include "bnxt_ulp_utils.h" 17 #include "ulp_port_db.h" 18 #include "ulp_flow_db.h" 19 20 static const struct eth_dev_ops bnxt_rep_dev_ops = { 21 .dev_infos_get = bnxt_rep_dev_info_get_op, 22 .dev_configure = bnxt_rep_dev_configure_op, 23 .dev_start = bnxt_rep_dev_start_op, 24 .rx_queue_setup = bnxt_rep_rx_queue_setup_op, 25 .rx_queue_release = bnxt_rep_rx_queue_release_op, 26 .tx_queue_setup = bnxt_rep_tx_queue_setup_op, 27 .tx_queue_release = bnxt_rep_tx_queue_release_op, 28 .link_update = bnxt_rep_link_update_op, 29 .dev_close = bnxt_rep_dev_close_op, 30 .dev_stop = bnxt_rep_dev_stop_op, 31 .stats_get = bnxt_rep_stats_get_op, 32 .stats_reset = bnxt_rep_stats_reset_op, 33 .flow_ops_get = bnxt_flow_ops_get_op 34 }; 35 36 static bool bnxt_rep_check_parent(struct bnxt_representor *rep) 37 { 38 if (!rep->parent_dev->data || !rep->parent_dev->data->dev_private) 39 return false; 40 41 return true; 42 } 43 44 uint16_t 45 bnxt_vfr_recv(uint16_t port_id, uint16_t queue_id, struct rte_mbuf *mbuf) 46 { 47 struct bnxt_representor *vfr_bp = NULL; 48 struct bnxt_rx_ring_info *rep_rxr; 49 struct rte_eth_dev *vfr_eth_dev; 50 struct rte_mbuf **prod_rx_buf; 51 struct bnxt_rx_queue *rep_rxq; 52 uint16_t mask; 53 uint8_t que; 54 55 vfr_eth_dev = &rte_eth_devices[port_id]; 56 vfr_bp = vfr_eth_dev ? vfr_eth_dev->data->dev_private : NULL; 57 58 if (unlikely(vfr_bp == NULL)) 59 return 1; 60 61 /* If rxq_id happens to be > nr_rings, use ring 0 */ 62 que = queue_id < vfr_bp->rx_nr_rings ? queue_id : 0; 63 rep_rxq = vfr_bp->rx_queues[que]; 64 /* Ideally should not happen now, paranoid check */ 65 if (!rep_rxq) 66 return 1; 67 rep_rxr = rep_rxq->rx_ring; 68 mask = rep_rxr->rx_ring_struct->ring_mask; 69 70 /* Put this mbuf on the RxQ of the Representor */ 71 prod_rx_buf = &rep_rxr->rx_buf_ring[rep_rxr->rx_raw_prod & mask]; 72 if (*prod_rx_buf == NULL) { 73 *prod_rx_buf = mbuf; 74 vfr_bp->rx_bytes[que] += mbuf->pkt_len; 75 vfr_bp->rx_pkts[que]++; 76 rep_rxr->rx_raw_prod++; 77 } else { 78 /* Representor Rx ring full, drop pkt */ 79 vfr_bp->rx_drop_bytes[que] += mbuf->pkt_len; 80 vfr_bp->rx_drop_pkts[que]++; 81 rte_mbuf_raw_free(mbuf); 82 } 83 84 return 0; 85 } 86 87 static uint16_t 88 bnxt_rep_rx_burst(void *rx_queue, 89 struct rte_mbuf **rx_pkts, 90 uint16_t nb_pkts) 91 { 92 struct bnxt_rx_queue *rxq = rx_queue; 93 struct rte_mbuf **cons_rx_buf; 94 struct bnxt_rx_ring_info *rxr; 95 uint16_t nb_rx_pkts = 0; 96 uint16_t mask, i; 97 98 if (!rxq) 99 return 0; 100 101 rxr = rxq->rx_ring; 102 mask = rxr->rx_ring_struct->ring_mask; 103 for (i = 0; i < nb_pkts; i++) { 104 cons_rx_buf = &rxr->rx_buf_ring[rxr->rx_cons & mask]; 105 if (*cons_rx_buf == NULL) 106 return nb_rx_pkts; 107 rx_pkts[nb_rx_pkts] = *cons_rx_buf; 108 rx_pkts[nb_rx_pkts]->port = rxq->port_id; 109 *cons_rx_buf = NULL; 110 nb_rx_pkts++; 111 rxr->rx_cons++; 112 } 113 114 return nb_rx_pkts; 115 } 116 117 static uint16_t 118 bnxt_rep_tx_burst(void *tx_queue, 119 struct rte_mbuf **tx_pkts, 120 uint16_t nb_pkts) 121 { 122 struct bnxt_vf_rep_tx_queue *vfr_txq = tx_queue; 123 struct bnxt_tx_queue *ptxq; 124 struct bnxt *parent; 125 struct bnxt_representor *vf_rep_bp; 126 int qid; 127 int rc; 128 int i; 129 130 if (!vfr_txq) 131 return 0; 132 133 qid = vfr_txq->txq->queue_id; 134 vf_rep_bp = vfr_txq->bp; 135 parent = vf_rep_bp->parent_dev->data->dev_private; 136 ptxq = parent->tx_queues[qid]; 137 pthread_mutex_lock(&ptxq->txq_lock); 138 139 ptxq->vfr_tx_cfa_action = vf_rep_bp->vfr_tx_cfa_action; 140 141 for (i = 0; i < nb_pkts; i++) { 142 vf_rep_bp->tx_bytes[qid] += tx_pkts[i]->pkt_len; 143 vf_rep_bp->tx_pkts[qid]++; 144 } 145 146 rc = _bnxt_xmit_pkts(ptxq, tx_pkts, nb_pkts); 147 ptxq->vfr_tx_cfa_action = 0; 148 pthread_mutex_unlock(&ptxq->txq_lock); 149 150 return rc; 151 } 152 153 static int 154 bnxt_get_dflt_vnic_svif(struct bnxt *bp, struct bnxt_representor *vf_rep_bp) 155 { 156 struct bnxt_rep_info *rep_info; 157 int rc; 158 159 rc = bnxt_hwrm_get_dflt_vnic_svif(bp, vf_rep_bp->fw_fid, 160 &vf_rep_bp->dflt_vnic_id, 161 &vf_rep_bp->svif); 162 if (rc) { 163 PMD_DRV_LOG_LINE(ERR, "Failed to get default vnic id of VF"); 164 vf_rep_bp->dflt_vnic_id = BNXT_DFLT_VNIC_ID_INVALID; 165 vf_rep_bp->svif = BNXT_SVIF_INVALID; 166 } else { 167 PMD_DRV_LOG_LINE(INFO, "vf_rep->dflt_vnic_id = %d", 168 vf_rep_bp->dflt_vnic_id); 169 } 170 if (vf_rep_bp->dflt_vnic_id != BNXT_DFLT_VNIC_ID_INVALID && 171 vf_rep_bp->svif != BNXT_SVIF_INVALID) { 172 rep_info = &bp->rep_info[vf_rep_bp->vf_id]; 173 rep_info->conduit_valid = true; 174 } 175 176 return rc; 177 } 178 179 int bnxt_representor_init(struct rte_eth_dev *eth_dev, void *params) 180 { 181 struct bnxt_representor *vf_rep_bp = eth_dev->data->dev_private; 182 struct bnxt_representor *rep_params = 183 (struct bnxt_representor *)params; 184 struct rte_eth_link *link; 185 struct bnxt *parent_bp; 186 uint16_t first_vf_id; 187 int rc = 0; 188 189 PMD_DRV_LOG_LINE(DEBUG, "BNXT Port:%d VFR init", eth_dev->data->port_id); 190 vf_rep_bp->vf_id = rep_params->vf_id; 191 vf_rep_bp->switch_domain_id = rep_params->switch_domain_id; 192 vf_rep_bp->parent_dev = rep_params->parent_dev; 193 vf_rep_bp->rep_based_pf = rep_params->rep_based_pf; 194 vf_rep_bp->flags = rep_params->flags; 195 vf_rep_bp->rep_q_r2f = rep_params->rep_q_r2f; 196 vf_rep_bp->rep_q_f2r = rep_params->rep_q_f2r; 197 vf_rep_bp->rep_fc_r2f = rep_params->rep_fc_r2f; 198 vf_rep_bp->rep_fc_f2r = rep_params->rep_fc_f2r; 199 200 eth_dev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR | 201 RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS; 202 eth_dev->data->representor_id = rep_params->vf_id; 203 eth_dev->data->backer_port_id = rep_params->parent_dev->data->port_id; 204 205 rte_eth_random_addr(vf_rep_bp->dflt_mac_addr); 206 memcpy(vf_rep_bp->mac_addr, vf_rep_bp->dflt_mac_addr, 207 sizeof(vf_rep_bp->mac_addr)); 208 eth_dev->data->mac_addrs = 209 (struct rte_ether_addr *)&vf_rep_bp->mac_addr; 210 eth_dev->dev_ops = &bnxt_rep_dev_ops; 211 212 /* No data-path, but need stub Rx/Tx functions to avoid crash 213 * when testing with ovs-dpdk 214 */ 215 eth_dev->rx_pkt_burst = bnxt_rep_rx_burst; 216 eth_dev->tx_pkt_burst = bnxt_rep_tx_burst; 217 /* Link state. Inherited from PF or trusted VF */ 218 parent_bp = vf_rep_bp->parent_dev->data->dev_private; 219 link = &parent_bp->eth_dev->data->dev_link; 220 221 eth_dev->data->dev_link.link_speed = link->link_speed; 222 eth_dev->data->dev_link.link_duplex = link->link_duplex; 223 eth_dev->data->dev_link.link_status = link->link_status; 224 eth_dev->data->dev_link.link_autoneg = link->link_autoneg; 225 226 bnxt_print_link_info(eth_dev); 227 228 PMD_DRV_LOG_LINE(INFO, 229 "Switch domain id %d: Representor Device %d init done", 230 vf_rep_bp->switch_domain_id, vf_rep_bp->vf_id); 231 232 if (BNXT_REP_BASED_PF(vf_rep_bp)) { 233 vf_rep_bp->fw_fid = vf_rep_bp->rep_based_pf + 1; 234 vf_rep_bp->parent_pf_idx = vf_rep_bp->rep_based_pf; 235 if (!(BNXT_REP_PF(vf_rep_bp))) { 236 /* VF representor for the remote PF,get first_vf_id */ 237 rc = bnxt_hwrm_first_vf_id_query(parent_bp, 238 vf_rep_bp->fw_fid, 239 &first_vf_id); 240 if (rc) 241 return rc; 242 if (first_vf_id == 0xffff) { 243 PMD_DRV_LOG_LINE(ERR, 244 "Invalid first_vf_id fid:%x", 245 vf_rep_bp->fw_fid); 246 return -EINVAL; 247 } 248 PMD_DRV_LOG_LINE(INFO, "first_vf_id = %x parent_fid:%x", 249 first_vf_id, vf_rep_bp->fw_fid); 250 vf_rep_bp->fw_fid = rep_params->vf_id + first_vf_id; 251 } 252 } else { 253 vf_rep_bp->fw_fid = rep_params->vf_id + parent_bp->first_vf_id; 254 if (BNXT_VF_IS_TRUSTED(parent_bp)) 255 vf_rep_bp->parent_pf_idx = parent_bp->parent->fid - 1; 256 else 257 vf_rep_bp->parent_pf_idx = parent_bp->fw_fid - 1; 258 } 259 260 PMD_DRV_LOG_LINE(INFO, "vf_rep->fw_fid = %d", vf_rep_bp->fw_fid); 261 262 return 0; 263 } 264 265 int bnxt_representor_uninit(struct rte_eth_dev *eth_dev) 266 { 267 struct bnxt *parent_bp; 268 struct bnxt_representor *rep = 269 (struct bnxt_representor *)eth_dev->data->dev_private; 270 uint16_t vf_id; 271 272 if (rte_eal_process_type() != RTE_PROC_PRIMARY) 273 return 0; 274 275 PMD_DRV_LOG_LINE(DEBUG, "BNXT Port:%d VFR uninit", eth_dev->data->port_id); 276 eth_dev->data->mac_addrs = NULL; 277 278 if (!bnxt_rep_check_parent(rep)) { 279 PMD_DRV_LOG_LINE(DEBUG, "BNXT Port:%d already freed", 280 eth_dev->data->port_id); 281 return 0; 282 } 283 parent_bp = rep->parent_dev->data->dev_private; 284 285 parent_bp->num_reps--; 286 vf_id = rep->vf_id; 287 if (parent_bp->rep_info) 288 memset(&parent_bp->rep_info[vf_id], 0, 289 sizeof(parent_bp->rep_info[vf_id])); 290 /* mark that this representor has been freed */ 291 return 0; 292 } 293 294 int bnxt_rep_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_compl) 295 { 296 struct bnxt *parent_bp; 297 struct bnxt_representor *rep = 298 (struct bnxt_representor *)eth_dev->data->dev_private; 299 struct rte_eth_link *link; 300 int rc; 301 302 parent_bp = rep->parent_dev->data->dev_private; 303 if (!parent_bp) 304 return 0; 305 306 rc = bnxt_link_update_op(parent_bp->eth_dev, wait_to_compl); 307 308 /* Link state. Inherited from PF or trusted VF */ 309 link = &parent_bp->eth_dev->data->dev_link; 310 311 eth_dev->data->dev_link.link_speed = link->link_speed; 312 eth_dev->data->dev_link.link_duplex = link->link_duplex; 313 eth_dev->data->dev_link.link_status = link->link_status; 314 eth_dev->data->dev_link.link_autoneg = link->link_autoneg; 315 bnxt_print_link_info(eth_dev); 316 317 return rc; 318 } 319 320 static int bnxt_tf_vfr_alloc(struct rte_eth_dev *vfr_ethdev) 321 { 322 int rc; 323 struct bnxt_representor *vfr = vfr_ethdev->data->dev_private; 324 struct rte_eth_dev *parent_dev = vfr->parent_dev; 325 struct bnxt *parent_bp = parent_dev->data->dev_private; 326 327 if (!parent_bp || !parent_bp->ulp_ctx) { 328 PMD_DRV_LOG_LINE(ERR, "Invalid arguments"); 329 return 0; 330 } 331 /* update the port id so you can backtrack to ethdev */ 332 vfr->dpdk_port_id = vfr_ethdev->data->port_id; 333 334 /* If pair is present, then delete the pair */ 335 if (!BNXT_CHIP_P7(parent_bp)) 336 if (bnxt_hwrm_cfa_pair_exists(parent_bp, vfr)) 337 (void)bnxt_hwrm_cfa_pair_free(parent_bp, vfr); 338 339 /* Update the ULP portdata base with the new VFR interface */ 340 rc = ulp_port_db_port_update(parent_bp->ulp_ctx, vfr_ethdev); 341 if (rc) { 342 PMD_DRV_LOG_LINE(ERR, "Failed to update ulp port details vfr:%u", 343 vfr->vf_id); 344 return rc; 345 } 346 347 /* Create the default rules for the VFR */ 348 rc = bnxt_ulp_create_vfr_default_rules(vfr_ethdev); 349 if (rc) { 350 PMD_DRV_LOG_LINE(ERR, "Failed to create VFR default rules vfr:%u", 351 vfr->vf_id); 352 return rc; 353 } 354 /* update the port id so you can backtrack to ethdev */ 355 vfr->dpdk_port_id = vfr_ethdev->data->port_id; 356 357 if (BNXT_CHIP_P7(parent_bp)) { 358 rc = bnxt_hwrm_release_afm_func(parent_bp, 359 vfr->fw_fid, 360 parent_bp->fw_fid, 361 HWRM_CFA_RELEASE_AFM_FUNC_INPUT_TYPE_EFID, 362 0); 363 364 if (rc) { 365 PMD_DRV_LOG_LINE(ERR, 366 "Failed to release EFID:%d from RFID:%d rc=%d", 367 vfr->vf_id, parent_bp->fw_fid, rc); 368 goto error_del_rules; 369 } 370 PMD_DRV_LOG_LINE(DEBUG, "Released EFID:%d from RFID:%d", 371 vfr->fw_fid, parent_bp->fw_fid); 372 373 } else { 374 rc = bnxt_hwrm_cfa_pair_alloc(parent_bp, vfr); 375 if (rc) { 376 PMD_DRV_LOG_LINE(ERR, 377 "Failed in hwrm vfr alloc vfr:%u rc=%d", 378 vfr->vf_id, rc); 379 goto error_del_rules; 380 } 381 } 382 383 /* if supported, it will add the vfr endpoint to the session, otherwise 384 * it returns success 385 */ 386 rc = bnxt_ulp_vfr_session_fid_add(parent_bp->ulp_ctx, vfr->fw_fid); 387 if (rc) 388 goto error_del_rules; 389 else 390 PMD_DRV_LOG_LINE(DEBUG, 391 "BNXT Port:%d VFR created and initialized", 392 vfr->dpdk_port_id); 393 return rc; 394 error_del_rules: 395 (void)bnxt_ulp_delete_vfr_default_rules(vfr); 396 return rc; 397 } 398 399 static int bnxt_vfr_alloc(struct rte_eth_dev *vfr_ethdev) 400 { 401 int rc = 0; 402 struct bnxt_representor *vfr = vfr_ethdev->data->dev_private; 403 struct bnxt *parent_bp; 404 405 if (!vfr || !vfr->parent_dev) { 406 PMD_DRV_LOG_LINE(ERR, 407 "No memory allocated for representor"); 408 return -ENOMEM; 409 } 410 411 parent_bp = vfr->parent_dev->data->dev_private; 412 if (parent_bp && !parent_bp->ulp_ctx) { 413 PMD_DRV_LOG_LINE(ERR, 414 "ulp context not allocated for parent"); 415 return -EIO; 416 } 417 418 /* Check if representor has been already allocated in FW */ 419 if (vfr->vfr_tx_cfa_action) 420 return 0; 421 422 /* 423 * Alloc VF rep rules in CFA after default VNIC is created. 424 * Otherwise the FW will create the VF-rep rules with 425 * default drop action. 426 */ 427 rc = bnxt_tf_vfr_alloc(vfr_ethdev); 428 if (!rc) 429 PMD_DRV_LOG_LINE(DEBUG, "allocated representor %d in FW", 430 vfr->vf_id); 431 else 432 PMD_DRV_LOG_LINE(ERR, 433 "Failed to alloc representor %d in FW", 434 vfr->vf_id); 435 436 return rc; 437 } 438 439 static void bnxt_vfr_rx_queue_release_mbufs(struct bnxt_rx_queue *rxq) 440 { 441 struct rte_mbuf **sw_ring; 442 unsigned int i; 443 444 if (!rxq || !rxq->rx_ring) 445 return; 446 447 sw_ring = rxq->rx_ring->rx_buf_ring; 448 if (sw_ring) { 449 for (i = 0; i < rxq->rx_ring->rx_ring_struct->ring_size; i++) { 450 if (sw_ring[i]) { 451 if (sw_ring[i] != &rxq->fake_mbuf) 452 rte_pktmbuf_free_seg(sw_ring[i]); 453 sw_ring[i] = NULL; 454 } 455 } 456 } 457 } 458 459 static void bnxt_rep_free_rx_mbufs(struct bnxt_representor *rep_bp) 460 { 461 struct bnxt_rx_queue *rxq; 462 unsigned int i; 463 464 for (i = 0; i < rep_bp->rx_nr_rings; i++) { 465 rxq = rep_bp->rx_queues[i]; 466 bnxt_vfr_rx_queue_release_mbufs(rxq); 467 } 468 } 469 470 int bnxt_rep_dev_start_op(struct rte_eth_dev *eth_dev) 471 { 472 struct bnxt_representor *rep_bp = eth_dev->data->dev_private; 473 struct bnxt_rep_info *rep_info; 474 struct bnxt *parent_bp; 475 int rc; 476 477 parent_bp = rep_bp->parent_dev->data->dev_private; 478 rep_info = &parent_bp->rep_info[rep_bp->vf_id]; 479 480 PMD_DRV_LOG_LINE(DEBUG, "BNXT Port:%d VFR start", 481 eth_dev->data->port_id); 482 pthread_mutex_lock(&rep_info->vfr_start_lock); 483 if (!rep_info->conduit_valid) { 484 rc = bnxt_get_dflt_vnic_svif(parent_bp, rep_bp); 485 if (rc || !rep_info->conduit_valid) { 486 pthread_mutex_unlock(&rep_info->vfr_start_lock); 487 return rc; 488 } 489 } 490 pthread_mutex_unlock(&rep_info->vfr_start_lock); 491 492 rc = bnxt_vfr_alloc(eth_dev); 493 if (rc) { 494 eth_dev->data->dev_link.link_status = 0; 495 bnxt_rep_free_rx_mbufs(rep_bp); 496 return rc; 497 } 498 eth_dev->rx_pkt_burst = &bnxt_rep_rx_burst; 499 eth_dev->tx_pkt_burst = &bnxt_rep_tx_burst; 500 bnxt_rep_link_update_op(eth_dev, 1); 501 502 return 0; 503 } 504 505 static int bnxt_tf_vfr_free(struct bnxt_representor *vfr) 506 { 507 struct bnxt *parent_bp; 508 int32_t rc; 509 510 PMD_DRV_LOG_LINE(DEBUG, "BNXT Port:%d VFR ulp free", vfr->dpdk_port_id); 511 rc = bnxt_ulp_delete_vfr_default_rules(vfr); 512 if (rc) 513 PMD_DRV_LOG_LINE(ERR, 514 "Failed to delete dflt rules from Port:%d VFR", 515 vfr->dpdk_port_id); 516 517 /* Need to remove the vfr fid from the session regardless */ 518 parent_bp = vfr->parent_dev->data->dev_private; 519 if (!parent_bp) { 520 PMD_DRV_LOG_LINE(DEBUG, "BNXT Port:%d VFR already freed", 521 vfr->dpdk_port_id); 522 return 0; 523 } 524 rc = bnxt_ulp_vfr_session_fid_rem(parent_bp->ulp_ctx, vfr->fw_fid); 525 if (rc) 526 PMD_DRV_LOG_LINE(ERR, 527 "Failed to remove BNXT Port:%d VFR from session", 528 vfr->dpdk_port_id); 529 return rc; 530 } 531 532 static int bnxt_vfr_free(struct bnxt_representor *vfr) 533 { 534 int rc = 0; 535 struct bnxt *parent_bp; 536 537 if (!vfr || !vfr->parent_dev) { 538 PMD_DRV_LOG_LINE(ERR, 539 "No memory allocated for representor"); 540 return -ENOMEM; 541 } 542 543 if (!bnxt_rep_check_parent(vfr)) { 544 PMD_DRV_LOG_LINE(DEBUG, "BNXT Port:%d VFR already freed", 545 vfr->dpdk_port_id); 546 return 0; 547 } 548 parent_bp = vfr->parent_dev->data->dev_private; 549 550 /* Check if representor has been already freed in FW */ 551 if (!vfr->vfr_tx_cfa_action) 552 return 0; 553 554 rc = bnxt_tf_vfr_free(vfr); 555 if (rc) { 556 PMD_DRV_LOG_LINE(ERR, 557 "Failed to free representor %d in FW", 558 vfr->vf_id); 559 } 560 561 PMD_DRV_LOG_LINE(DEBUG, "freed representor %d in FW", 562 vfr->vf_id); 563 vfr->vfr_tx_cfa_action = 0; 564 565 if (!BNXT_CHIP_P7(parent_bp)) 566 rc = bnxt_hwrm_cfa_pair_free(parent_bp, vfr); 567 568 return rc; 569 } 570 571 int bnxt_rep_dev_stop_op(struct rte_eth_dev *eth_dev) 572 { 573 struct bnxt_representor *vfr_bp = eth_dev->data->dev_private; 574 575 /* Avoid crashes as we are about to free queues */ 576 bnxt_stop_rxtx(eth_dev); 577 578 PMD_DRV_LOG_LINE(DEBUG, "BNXT Port:%d VFR stop", 579 eth_dev->data->port_id); 580 581 bnxt_vfr_free(vfr_bp); 582 583 if (eth_dev->data->dev_started) 584 eth_dev->data->dev_link.link_status = 0; 585 586 bnxt_rep_free_rx_mbufs(vfr_bp); 587 588 return 0; 589 } 590 591 int bnxt_rep_dev_close_op(struct rte_eth_dev *eth_dev) 592 { 593 PMD_DRV_LOG_LINE(DEBUG, "BNXT Port:%d VFR close", 594 eth_dev->data->port_id); 595 bnxt_representor_uninit(eth_dev); 596 return 0; 597 } 598 599 int bnxt_rep_dev_info_get_op(struct rte_eth_dev *eth_dev, 600 struct rte_eth_dev_info *dev_info) 601 { 602 struct bnxt_representor *rep_bp = eth_dev->data->dev_private; 603 struct bnxt *parent_bp; 604 unsigned int max_rx_rings; 605 606 /* MAC Specifics */ 607 if (!bnxt_rep_check_parent(rep_bp)) { 608 PMD_DRV_LOG_LINE(INFO, "Rep parent port does not exist"); 609 /* Need be an error scenario, if parent is removed first */ 610 if (eth_dev->device->driver == NULL) 611 return -ENODEV; 612 /* Need not be an error scenario, if parent is closed first */ 613 return 0; 614 } 615 parent_bp = rep_bp->parent_dev->data->dev_private; 616 PMD_DRV_LOG_LINE(DEBUG, "Representor dev_info_get_op"); 617 dev_info->max_mac_addrs = parent_bp->max_l2_ctx; 618 dev_info->max_hash_mac_addrs = 0; 619 620 max_rx_rings = parent_bp->rx_nr_rings ? 621 RTE_MIN(parent_bp->rx_nr_rings, BNXT_MAX_VF_REP_RINGS) : 622 BNXT_MAX_VF_REP_RINGS; 623 624 /* For the sake of symmetry, max_rx_queues = max_tx_queues */ 625 dev_info->max_rx_queues = max_rx_rings; 626 dev_info->max_tx_queues = max_rx_rings; 627 dev_info->reta_size = bnxt_rss_hash_tbl_size(parent_bp); 628 dev_info->hash_key_size = 40; 629 dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP; 630 631 /* MTU specifics */ 632 dev_info->min_mtu = RTE_ETHER_MIN_MTU; 633 dev_info->max_mtu = BNXT_MAX_MTU; 634 635 /* Fast path specifics */ 636 dev_info->min_rx_bufsize = 1; 637 dev_info->max_rx_pktlen = BNXT_MAX_PKT_LEN; 638 639 dev_info->rx_offload_capa = bnxt_get_rx_port_offloads(parent_bp); 640 dev_info->tx_offload_capa = bnxt_get_tx_port_offloads(parent_bp); 641 dev_info->flow_type_rss_offloads = bnxt_eth_rss_support(parent_bp); 642 643 dev_info->switch_info.name = eth_dev->device->name; 644 dev_info->switch_info.domain_id = rep_bp->switch_domain_id; 645 dev_info->switch_info.port_id = 646 rep_bp->vf_id & BNXT_SWITCH_PORT_ID_VF_MASK; 647 648 return 0; 649 } 650 651 int bnxt_rep_dev_configure_op(struct rte_eth_dev *eth_dev) 652 { 653 struct bnxt_representor *rep_bp = eth_dev->data->dev_private; 654 655 PMD_DRV_LOG_LINE(DEBUG, "Representor dev_configure_op"); 656 rep_bp->rx_queues = (void *)eth_dev->data->rx_queues; 657 rep_bp->tx_nr_rings = eth_dev->data->nb_tx_queues; 658 rep_bp->rx_nr_rings = eth_dev->data->nb_rx_queues; 659 660 return 0; 661 } 662 663 static int bnxt_init_rep_rx_ring(struct bnxt_rx_queue *rxq, 664 unsigned int socket_id) 665 { 666 struct bnxt_rx_ring_info *rxr; 667 struct bnxt_ring *ring; 668 669 rxr = rte_zmalloc_socket("bnxt_rep_rx_ring", 670 sizeof(struct bnxt_rx_ring_info), 671 RTE_CACHE_LINE_SIZE, socket_id); 672 if (rxr == NULL) 673 return -ENOMEM; 674 rxq->rx_ring = rxr; 675 676 ring = rte_zmalloc_socket("bnxt_rep_rx_ring_struct", 677 sizeof(struct bnxt_ring), 678 RTE_CACHE_LINE_SIZE, socket_id); 679 if (ring == NULL) 680 return -ENOMEM; 681 rxr->rx_ring_struct = ring; 682 ring->ring_size = rte_align32pow2(rxq->nb_rx_desc); 683 ring->ring_mask = ring->ring_size - 1; 684 685 return 0; 686 } 687 688 int bnxt_rep_rx_queue_setup_op(struct rte_eth_dev *eth_dev, 689 uint16_t queue_idx, 690 uint16_t nb_desc, 691 unsigned int socket_id, 692 __rte_unused const struct rte_eth_rxconf *rx_conf, 693 __rte_unused struct rte_mempool *mp) 694 { 695 struct bnxt_representor *rep_bp = eth_dev->data->dev_private; 696 struct bnxt *parent_bp = rep_bp->parent_dev->data->dev_private; 697 struct bnxt_rx_queue *parent_rxq; 698 struct bnxt_rx_queue *rxq; 699 struct rte_mbuf **buf_ring; 700 int rc = 0; 701 702 if (queue_idx >= rep_bp->rx_nr_rings) { 703 PMD_DRV_LOG_LINE(ERR, 704 "Cannot create Rx ring %d. %d rings available", 705 queue_idx, rep_bp->rx_nr_rings); 706 return -EINVAL; 707 } 708 709 if (!nb_desc || nb_desc > MAX_RX_DESC_CNT) { 710 PMD_DRV_LOG_LINE(ERR, "nb_desc %d is invalid", nb_desc); 711 return -EINVAL; 712 } 713 714 if (!parent_bp->rx_queues) { 715 PMD_DRV_LOG_LINE(ERR, "Parent Rx qs not configured yet"); 716 return -EINVAL; 717 } 718 719 parent_rxq = parent_bp->rx_queues[queue_idx]; 720 if (!parent_rxq) { 721 PMD_DRV_LOG_LINE(ERR, "Parent RxQ has not been configured yet"); 722 return -EINVAL; 723 } 724 725 if (nb_desc != parent_rxq->nb_rx_desc) { 726 PMD_DRV_LOG_LINE(ERR, "nb_desc %d do not match parent rxq", nb_desc); 727 return -EINVAL; 728 } 729 730 if (eth_dev->data->rx_queues) { 731 rxq = eth_dev->data->rx_queues[queue_idx]; 732 if (rxq) 733 bnxt_rx_queue_release_op(eth_dev, queue_idx); 734 } 735 736 rxq = rte_zmalloc_socket("bnxt_vfr_rx_queue", 737 sizeof(struct bnxt_rx_queue), 738 RTE_CACHE_LINE_SIZE, socket_id); 739 if (!rxq) { 740 PMD_DRV_LOG_LINE(ERR, "bnxt_vfr_rx_queue allocation failed!"); 741 return -ENOMEM; 742 } 743 744 eth_dev->data->rx_queues[queue_idx] = rxq; 745 746 rxq->nb_rx_desc = nb_desc; 747 748 rc = bnxt_init_rep_rx_ring(rxq, socket_id); 749 if (rc) 750 goto out; 751 752 buf_ring = rte_zmalloc_socket("bnxt_rx_vfr_buf_ring", 753 sizeof(struct rte_mbuf *) * 754 rxq->rx_ring->rx_ring_struct->ring_size, 755 RTE_CACHE_LINE_SIZE, socket_id); 756 if (!buf_ring) { 757 PMD_DRV_LOG_LINE(ERR, "bnxt_rx_vfr_buf_ring allocation failed!"); 758 rc = -ENOMEM; 759 goto out; 760 } 761 762 rxq->rx_ring->rx_buf_ring = buf_ring; 763 rxq->queue_id = queue_idx; 764 rxq->port_id = eth_dev->data->port_id; 765 766 return 0; 767 768 out: 769 if (rxq) { 770 #if (RTE_VERSION_NUM(21, 8, 0, 0) < RTE_VERSION) 771 bnxt_rep_rx_queue_release_op(eth_dev, queue_idx); 772 #else 773 bnxt_rx_queue_release_op(rxq); 774 #endif 775 } 776 777 return rc; 778 } 779 780 void bnxt_rep_rx_queue_release_op(struct rte_eth_dev *dev, uint16_t queue_idx) 781 { 782 struct bnxt_rx_queue *rxq = dev->data->rx_queues[queue_idx]; 783 784 if (!rxq) 785 return; 786 787 bnxt_rx_queue_release_mbufs(rxq); 788 789 bnxt_free_ring(rxq->rx_ring->rx_ring_struct); 790 rte_free(rxq->rx_ring->rx_ring_struct); 791 rte_free(rxq->rx_ring); 792 793 rte_free(rxq); 794 } 795 796 int bnxt_rep_tx_queue_setup_op(struct rte_eth_dev *eth_dev, 797 uint16_t queue_idx, 798 uint16_t nb_desc, 799 unsigned int socket_id, 800 __rte_unused const struct rte_eth_txconf *tx_conf) 801 { 802 struct bnxt_representor *rep_bp = eth_dev->data->dev_private; 803 struct bnxt *parent_bp = rep_bp->parent_dev->data->dev_private; 804 struct bnxt_tx_queue *parent_txq, *txq; 805 struct bnxt_vf_rep_tx_queue *vfr_txq; 806 807 if (queue_idx >= rep_bp->tx_nr_rings) { 808 PMD_DRV_LOG_LINE(ERR, 809 "Cannot create Tx rings %d. %d rings available", 810 queue_idx, rep_bp->tx_nr_rings); 811 return -EINVAL; 812 } 813 814 if (!nb_desc || nb_desc > MAX_TX_DESC_CNT) { 815 PMD_DRV_LOG_LINE(ERR, "nb_desc %d is invalid", nb_desc); 816 return -EINVAL; 817 } 818 819 if (!parent_bp->tx_queues) { 820 PMD_DRV_LOG_LINE(ERR, "Parent Tx qs not configured yet"); 821 return -EINVAL; 822 } 823 824 parent_txq = parent_bp->tx_queues[queue_idx]; 825 if (!parent_txq) { 826 PMD_DRV_LOG_LINE(ERR, "Parent TxQ has not been configured yet"); 827 return -EINVAL; 828 } 829 830 if (nb_desc != parent_txq->nb_tx_desc) { 831 PMD_DRV_LOG_LINE(ERR, "nb_desc %d do not match parent txq", nb_desc); 832 return -EINVAL; 833 } 834 835 if (eth_dev->data->tx_queues) { 836 vfr_txq = eth_dev->data->tx_queues[queue_idx]; 837 if (vfr_txq != NULL) 838 bnxt_rep_tx_queue_release_op(eth_dev, queue_idx); 839 } 840 841 vfr_txq = rte_zmalloc_socket("bnxt_vfr_tx_queue", 842 sizeof(struct bnxt_vf_rep_tx_queue), 843 RTE_CACHE_LINE_SIZE, socket_id); 844 if (!vfr_txq) { 845 PMD_DRV_LOG_LINE(ERR, "bnxt_vfr_tx_queue allocation failed!"); 846 return -ENOMEM; 847 } 848 txq = rte_zmalloc_socket("bnxt_tx_queue", 849 sizeof(struct bnxt_tx_queue), 850 RTE_CACHE_LINE_SIZE, socket_id); 851 if (!txq) { 852 PMD_DRV_LOG_LINE(ERR, "bnxt_tx_queue allocation failed!"); 853 rte_free(vfr_txq); 854 return -ENOMEM; 855 } 856 857 txq->nb_tx_desc = nb_desc; 858 txq->queue_id = queue_idx; 859 txq->port_id = eth_dev->data->port_id; 860 vfr_txq->txq = txq; 861 vfr_txq->bp = rep_bp; 862 eth_dev->data->tx_queues[queue_idx] = vfr_txq; 863 864 return 0; 865 } 866 867 void bnxt_rep_tx_queue_release_op(struct rte_eth_dev *dev, uint16_t queue_idx) 868 { 869 struct bnxt_vf_rep_tx_queue *vfr_txq = dev->data->tx_queues[queue_idx]; 870 871 if (!vfr_txq) 872 return; 873 874 rte_free(vfr_txq->txq); 875 rte_free(vfr_txq); 876 dev->data->tx_queues[queue_idx] = NULL; 877 } 878 879 int bnxt_rep_stats_get_op(struct rte_eth_dev *eth_dev, 880 struct rte_eth_stats *stats) 881 { 882 struct bnxt_representor *rep_bp = eth_dev->data->dev_private; 883 unsigned int i; 884 885 memset(stats, 0, sizeof(*stats)); 886 for (i = 0; i < rep_bp->rx_nr_rings; i++) { 887 stats->obytes += rep_bp->tx_bytes[i]; 888 stats->opackets += rep_bp->tx_pkts[i]; 889 stats->ibytes += rep_bp->rx_bytes[i]; 890 stats->ipackets += rep_bp->rx_pkts[i]; 891 stats->imissed += rep_bp->rx_drop_pkts[i]; 892 893 stats->q_ipackets[i] = rep_bp->rx_pkts[i]; 894 stats->q_ibytes[i] = rep_bp->rx_bytes[i]; 895 stats->q_opackets[i] = rep_bp->tx_pkts[i]; 896 stats->q_obytes[i] = rep_bp->tx_bytes[i]; 897 stats->q_errors[i] = rep_bp->rx_drop_pkts[i]; 898 } 899 900 return 0; 901 } 902 903 int bnxt_rep_stats_reset_op(struct rte_eth_dev *eth_dev) 904 { 905 struct bnxt_representor *rep_bp = eth_dev->data->dev_private; 906 unsigned int i; 907 908 for (i = 0; i < rep_bp->rx_nr_rings; i++) { 909 rep_bp->tx_pkts[i] = 0; 910 rep_bp->tx_bytes[i] = 0; 911 rep_bp->rx_pkts[i] = 0; 912 rep_bp->rx_bytes[i] = 0; 913 rep_bp->rx_drop_pkts[i] = 0; 914 } 915 return 0; 916 } 917 918 int bnxt_rep_stop_all(struct bnxt *bp) 919 { 920 uint16_t vf_id; 921 struct rte_eth_dev *rep_eth_dev; 922 int ret; 923 924 /* No vfrep ports just exit */ 925 if (!bp->rep_info) 926 return 0; 927 928 for (vf_id = 0; vf_id < BNXT_MAX_VF_REPS(bp); vf_id++) { 929 rep_eth_dev = bp->rep_info[vf_id].vfr_eth_dev; 930 if (!rep_eth_dev) 931 continue; 932 ret = bnxt_rep_dev_stop_op(rep_eth_dev); 933 if (ret != 0) 934 return ret; 935 } 936 937 return 0; 938 } 939