1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2019-2020 Broadcom 3 * All rights reserved. 4 */ 5 6 #include <rte_log.h> 7 #include <rte_malloc.h> 8 #include <rte_flow.h> 9 #include <rte_flow_driver.h> 10 #include <rte_tailq.h> 11 12 #include "bnxt_ulp.h" 13 #include "bnxt_tf_common.h" 14 #include "bnxt.h" 15 #include "tf_core.h" 16 #include "tf_ext_flow_handle.h" 17 18 #include "ulp_template_db_enum.h" 19 #include "ulp_template_struct.h" 20 #include "ulp_mark_mgr.h" 21 #include "ulp_flow_db.h" 22 #include "ulp_mapper.h" 23 #include "ulp_port_db.h" 24 25 /* Linked list of all TF sessions. */ 26 STAILQ_HEAD(, bnxt_ulp_session_state) bnxt_ulp_session_list = 27 STAILQ_HEAD_INITIALIZER(bnxt_ulp_session_list); 28 29 /* Mutex to synchronize bnxt_ulp_session_list operations. */ 30 static pthread_mutex_t bnxt_ulp_global_mutex = PTHREAD_MUTEX_INITIALIZER; 31 32 /* 33 * Allow the deletion of context only for the bnxt device that 34 * created the session 35 * TBD - The implementation of the function should change to 36 * using the reference count once tf_session_attach functionality 37 * is fixed. 38 */ 39 bool 40 ulp_ctx_deinit_allowed(void *ptr) 41 { 42 struct bnxt *bp = (struct bnxt *)ptr; 43 44 if (!bp) 45 return 0; 46 47 if (&bp->tfp == bp->ulp_ctx->g_tfp) 48 return 1; 49 50 return 0; 51 } 52 53 /* 54 * Initialize an ULP session. 55 * An ULP session will contain all the resources needed to support rte flow 56 * offloads. A session is initialized as part of rte_eth_device start. 57 * A single vswitch instance can have multiple uplinks which means 58 * rte_eth_device start will be called for each of these devices. 59 * ULP session manager will make sure that a single ULP session is only 60 * initialized once. Apart from this, it also initializes MARK database, 61 * EEM table & flow database. ULP session manager also manages a list of 62 * all opened ULP sessions. 63 */ 64 static int32_t 65 ulp_ctx_session_open(struct bnxt *bp, 66 struct bnxt_ulp_session_state *session) 67 { 68 struct rte_eth_dev *ethdev = bp->eth_dev; 69 int32_t rc = 0; 70 struct tf_open_session_parms params; 71 72 memset(¶ms, 0, sizeof(params)); 73 74 rc = rte_eth_dev_get_name_by_port(ethdev->data->port_id, 75 params.ctrl_chan_name); 76 if (rc) { 77 BNXT_TF_DBG(ERR, "Invalid port %d, rc = %d\n", 78 ethdev->data->port_id, rc); 79 return rc; 80 } 81 82 rc = tf_open_session(&bp->tfp, ¶ms); 83 if (rc) { 84 BNXT_TF_DBG(ERR, "Failed to open TF session - %s, rc = %d\n", 85 params.ctrl_chan_name, rc); 86 return -EINVAL; 87 } 88 session->session_opened = 1; 89 session->g_tfp = &bp->tfp; 90 return rc; 91 } 92 93 /* 94 * Close the ULP session. 95 * It takes the ulp context pointer. 96 */ 97 static void 98 ulp_ctx_session_close(struct bnxt *bp, 99 struct bnxt_ulp_session_state *session) 100 { 101 /* close the session in the hardware */ 102 if (session->session_opened) 103 tf_close_session(&bp->tfp); 104 session->session_opened = 0; 105 session->g_tfp = NULL; 106 bp->ulp_ctx->g_tfp = NULL; 107 } 108 109 static void 110 bnxt_init_tbl_scope_parms(struct bnxt *bp, 111 struct tf_alloc_tbl_scope_parms *params) 112 { 113 struct bnxt_ulp_device_params *dparms; 114 uint32_t dev_id; 115 int rc; 116 117 rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &dev_id); 118 if (rc) 119 /* TBD: For now, just use default. */ 120 dparms = 0; 121 else 122 dparms = bnxt_ulp_device_params_get(dev_id); 123 124 /* 125 * Set the flush timer for EEM entries. The value is in 100ms intervals, 126 * so 100 is 10s. 127 */ 128 params->hw_flow_cache_flush_timer = 100; 129 130 if (!dparms) { 131 params->rx_max_key_sz_in_bits = BNXT_ULP_DFLT_RX_MAX_KEY; 132 params->rx_max_action_entry_sz_in_bits = 133 BNXT_ULP_DFLT_RX_MAX_ACTN_ENTRY; 134 params->rx_mem_size_in_mb = BNXT_ULP_DFLT_RX_MEM; 135 params->rx_num_flows_in_k = BNXT_ULP_RX_NUM_FLOWS; 136 params->rx_tbl_if_id = BNXT_ULP_RX_TBL_IF_ID; 137 138 params->tx_max_key_sz_in_bits = BNXT_ULP_DFLT_TX_MAX_KEY; 139 params->tx_max_action_entry_sz_in_bits = 140 BNXT_ULP_DFLT_TX_MAX_ACTN_ENTRY; 141 params->tx_mem_size_in_mb = BNXT_ULP_DFLT_TX_MEM; 142 params->tx_num_flows_in_k = BNXT_ULP_TX_NUM_FLOWS; 143 params->tx_tbl_if_id = BNXT_ULP_TX_TBL_IF_ID; 144 } else { 145 params->rx_max_key_sz_in_bits = BNXT_ULP_DFLT_RX_MAX_KEY; 146 params->rx_max_action_entry_sz_in_bits = 147 BNXT_ULP_DFLT_RX_MAX_ACTN_ENTRY; 148 params->rx_mem_size_in_mb = BNXT_ULP_DFLT_RX_MEM; 149 params->rx_num_flows_in_k = dparms->flow_db_num_entries / 1024; 150 params->rx_tbl_if_id = BNXT_ULP_RX_TBL_IF_ID; 151 152 params->tx_max_key_sz_in_bits = BNXT_ULP_DFLT_TX_MAX_KEY; 153 params->tx_max_action_entry_sz_in_bits = 154 BNXT_ULP_DFLT_TX_MAX_ACTN_ENTRY; 155 params->tx_mem_size_in_mb = BNXT_ULP_DFLT_TX_MEM; 156 params->tx_num_flows_in_k = dparms->flow_db_num_entries / 1024; 157 params->tx_tbl_if_id = BNXT_ULP_TX_TBL_IF_ID; 158 } 159 } 160 161 /* Initialize Extended Exact Match host memory. */ 162 static int32_t 163 ulp_eem_tbl_scope_init(struct bnxt *bp) 164 { 165 struct tf_alloc_tbl_scope_parms params = {0}; 166 int rc; 167 168 bnxt_init_tbl_scope_parms(bp, ¶ms); 169 170 rc = tf_alloc_tbl_scope(&bp->tfp, ¶ms); 171 if (rc) { 172 BNXT_TF_DBG(ERR, "Unable to allocate eem table scope rc = %d\n", 173 rc); 174 return rc; 175 } 176 177 rc = bnxt_ulp_cntxt_tbl_scope_id_set(bp->ulp_ctx, params.tbl_scope_id); 178 if (rc) { 179 BNXT_TF_DBG(ERR, "Unable to set table scope id\n"); 180 return rc; 181 } 182 183 return 0; 184 } 185 186 /* Free Extended Exact Match host memory */ 187 static int32_t 188 ulp_eem_tbl_scope_deinit(struct bnxt *bp, struct bnxt_ulp_context *ulp_ctx) 189 { 190 struct tf_free_tbl_scope_parms params = {0}; 191 struct tf *tfp; 192 int32_t rc = 0; 193 194 if (!ulp_ctx || !ulp_ctx->cfg_data) 195 return -EINVAL; 196 197 /* Free the resources for the last device */ 198 if (!ulp_ctx_deinit_allowed(bp)) 199 return rc; 200 201 tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx); 202 if (!tfp) { 203 BNXT_TF_DBG(ERR, "Failed to get the truflow pointer\n"); 204 return -EINVAL; 205 } 206 207 rc = bnxt_ulp_cntxt_tbl_scope_id_get(ulp_ctx, ¶ms.tbl_scope_id); 208 if (rc) { 209 BNXT_TF_DBG(ERR, "Failed to get the table scope id\n"); 210 return -EINVAL; 211 } 212 213 rc = tf_free_tbl_scope(tfp, ¶ms); 214 if (rc) { 215 BNXT_TF_DBG(ERR, "Unable to free table scope\n"); 216 return -EINVAL; 217 } 218 return rc; 219 } 220 221 /* The function to free and deinit the ulp context data. */ 222 static int32_t 223 ulp_ctx_deinit(struct bnxt *bp, 224 struct bnxt_ulp_session_state *session) 225 { 226 if (!session || !bp) { 227 BNXT_TF_DBG(ERR, "Invalid Arguments\n"); 228 return -EINVAL; 229 } 230 231 /* close the tf session */ 232 ulp_ctx_session_close(bp, session); 233 234 /* Free the contents */ 235 if (session->cfg_data) { 236 rte_free(session->cfg_data); 237 bp->ulp_ctx->cfg_data = NULL; 238 session->cfg_data = NULL; 239 } 240 return 0; 241 } 242 243 /* The function to allocate and initialize the ulp context data. */ 244 static int32_t 245 ulp_ctx_init(struct bnxt *bp, 246 struct bnxt_ulp_session_state *session) 247 { 248 struct bnxt_ulp_data *ulp_data; 249 int32_t rc = 0; 250 251 if (!session || !bp) { 252 BNXT_TF_DBG(ERR, "Invalid Arguments\n"); 253 return -EINVAL; 254 } 255 256 /* Allocate memory to hold ulp context data. */ 257 ulp_data = rte_zmalloc("bnxt_ulp_data", 258 sizeof(struct bnxt_ulp_data), 0); 259 if (!ulp_data) { 260 BNXT_TF_DBG(ERR, "Failed to allocate memory for ulp data\n"); 261 return -ENOMEM; 262 } 263 264 /* Increment the ulp context data reference count usage. */ 265 bp->ulp_ctx->cfg_data = ulp_data; 266 session->cfg_data = ulp_data; 267 ulp_data->ref_cnt++; 268 269 /* Open the ulp session. */ 270 rc = ulp_ctx_session_open(bp, session); 271 if (rc) { 272 (void)ulp_ctx_deinit(bp, session); 273 return rc; 274 } 275 bnxt_ulp_cntxt_tfp_set(bp->ulp_ctx, session->g_tfp); 276 return rc; 277 } 278 279 /* The function to initialize ulp dparms with devargs */ 280 static int32_t 281 ulp_dparms_init(struct bnxt *bp, 282 struct bnxt_ulp_context *ulp_ctx) 283 { 284 struct bnxt_ulp_device_params *dparms; 285 uint32_t dev_id; 286 287 if (!bp->max_num_kflows) 288 return -EINVAL; 289 290 if (bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id)) { 291 BNXT_TF_DBG(DEBUG, "Failed to get device id\n"); 292 return -EINVAL; 293 } 294 295 dparms = bnxt_ulp_device_params_get(dev_id); 296 if (!dparms) { 297 BNXT_TF_DBG(DEBUG, "Failed to get device parms\n"); 298 return -EINVAL; 299 } 300 301 /* num_flows = max_num_kflows * 1024 */ 302 dparms->flow_db_num_entries = bp->max_num_kflows * 1024; 303 /* GFID = 2 * num_flows */ 304 dparms->mark_db_gfid_entries = dparms->flow_db_num_entries * 2; 305 BNXT_TF_DBG(DEBUG, "Set the number of flows = %"PRIu64"\n", 306 dparms->flow_db_num_entries); 307 308 return 0; 309 } 310 311 /* The function to initialize bp flags with truflow features */ 312 static int32_t 313 ulp_dparms_dev_port_intf_update(struct bnxt *bp, 314 struct bnxt_ulp_context *ulp_ctx) 315 { 316 struct bnxt_ulp_device_params *dparms; 317 uint32_t dev_id; 318 319 if (bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id)) { 320 BNXT_TF_DBG(DEBUG, "Failed to get device id\n"); 321 return -EINVAL; 322 } 323 324 dparms = bnxt_ulp_device_params_get(dev_id); 325 if (!dparms) { 326 BNXT_TF_DBG(DEBUG, "Failed to get device parms\n"); 327 return -EINVAL; 328 } 329 330 /* Update the bp flag with gfid flag */ 331 if (dparms->flow_mem_type == BNXT_ULP_FLOW_MEM_TYPE_EXT) 332 bp->flags |= BNXT_FLAG_GFID_ENABLE; 333 334 return 0; 335 } 336 337 static int32_t 338 ulp_ctx_attach(struct bnxt_ulp_context *ulp_ctx, 339 struct bnxt_ulp_session_state *session) 340 { 341 if (!ulp_ctx || !session) { 342 BNXT_TF_DBG(ERR, "Invalid Arguments\n"); 343 return -EINVAL; 344 } 345 346 /* Increment the ulp context data reference count usage. */ 347 ulp_ctx->cfg_data = session->cfg_data; 348 ulp_ctx->cfg_data->ref_cnt++; 349 350 /* TBD call TF_session_attach. */ 351 ulp_ctx->g_tfp = session->g_tfp; 352 return 0; 353 } 354 355 static int32_t 356 ulp_ctx_detach(struct bnxt *bp, 357 struct bnxt_ulp_session_state *session) 358 { 359 struct bnxt_ulp_context *ulp_ctx; 360 361 if (!bp || !session) { 362 BNXT_TF_DBG(ERR, "Invalid Arguments\n"); 363 return -EINVAL; 364 } 365 ulp_ctx = bp->ulp_ctx; 366 367 if (!ulp_ctx->cfg_data) 368 return 0; 369 370 /* TBD call TF_session_detach */ 371 372 /* Increment the ulp context data reference count usage. */ 373 if (ulp_ctx->cfg_data->ref_cnt >= 1) { 374 ulp_ctx->cfg_data->ref_cnt--; 375 if (ulp_ctx_deinit_allowed(bp)) 376 ulp_ctx_deinit(bp, session); 377 ulp_ctx->cfg_data = NULL; 378 ulp_ctx->g_tfp = NULL; 379 return 0; 380 } 381 BNXT_TF_DBG(ERR, "context deatach on invalid data\n"); 382 return 0; 383 } 384 385 /* 386 * Initialize the state of an ULP session. 387 * If the state of an ULP session is not initialized, set it's state to 388 * initialized. If the state is already initialized, do nothing. 389 */ 390 static void 391 ulp_context_initialized(struct bnxt_ulp_session_state *session, bool *init) 392 { 393 pthread_mutex_lock(&session->bnxt_ulp_mutex); 394 395 if (!session->bnxt_ulp_init) { 396 session->bnxt_ulp_init = true; 397 *init = false; 398 } else { 399 *init = true; 400 } 401 402 pthread_mutex_unlock(&session->bnxt_ulp_mutex); 403 } 404 405 /* 406 * Check if an ULP session is already allocated for a specific PCI 407 * domain & bus. If it is already allocated simply return the session 408 * pointer, otherwise allocate a new session. 409 */ 410 static struct bnxt_ulp_session_state * 411 ulp_get_session(struct rte_pci_addr *pci_addr) 412 { 413 struct bnxt_ulp_session_state *session; 414 415 STAILQ_FOREACH(session, &bnxt_ulp_session_list, next) { 416 if (session->pci_info.domain == pci_addr->domain && 417 session->pci_info.bus == pci_addr->bus) { 418 return session; 419 } 420 } 421 return NULL; 422 } 423 424 /* 425 * Allocate and Initialize an ULP session and set it's state to INITIALIZED. 426 * If it's already initialized simply return the already existing session. 427 */ 428 static struct bnxt_ulp_session_state * 429 ulp_session_init(struct bnxt *bp, 430 bool *init) 431 { 432 struct rte_pci_device *pci_dev; 433 struct rte_pci_addr *pci_addr; 434 struct bnxt_ulp_session_state *session; 435 436 if (!bp) 437 return NULL; 438 439 pci_dev = RTE_DEV_TO_PCI(bp->eth_dev->device); 440 pci_addr = &pci_dev->addr; 441 442 pthread_mutex_lock(&bnxt_ulp_global_mutex); 443 444 session = ulp_get_session(pci_addr); 445 if (!session) { 446 /* Not Found the session Allocate a new one */ 447 session = rte_zmalloc("bnxt_ulp_session", 448 sizeof(struct bnxt_ulp_session_state), 449 0); 450 if (!session) { 451 BNXT_TF_DBG(ERR, 452 "Allocation failed for bnxt_ulp_session\n"); 453 pthread_mutex_unlock(&bnxt_ulp_global_mutex); 454 return NULL; 455 456 } else { 457 /* Add it to the queue */ 458 session->pci_info.domain = pci_addr->domain; 459 session->pci_info.bus = pci_addr->bus; 460 pthread_mutex_init(&session->bnxt_ulp_mutex, NULL); 461 STAILQ_INSERT_TAIL(&bnxt_ulp_session_list, 462 session, next); 463 } 464 } 465 ulp_context_initialized(session, init); 466 pthread_mutex_unlock(&bnxt_ulp_global_mutex); 467 return session; 468 } 469 470 /* 471 * When a device is closed, remove it's associated session from the global 472 * session list. 473 */ 474 static void 475 ulp_session_deinit(struct bnxt_ulp_session_state *session) 476 { 477 if (!session) 478 return; 479 480 if (!session->cfg_data) { 481 pthread_mutex_lock(&bnxt_ulp_global_mutex); 482 STAILQ_REMOVE(&bnxt_ulp_session_list, session, 483 bnxt_ulp_session_state, next); 484 pthread_mutex_destroy(&session->bnxt_ulp_mutex); 485 rte_free(session); 486 pthread_mutex_unlock(&bnxt_ulp_global_mutex); 487 } 488 } 489 490 /* 491 * When a port is initialized by dpdk. This functions is called 492 * and this function initializes the ULP context and rest of the 493 * infrastructure associated with it. 494 */ 495 int32_t 496 bnxt_ulp_init(struct bnxt *bp) 497 { 498 struct bnxt_ulp_session_state *session; 499 bool init; 500 int rc; 501 502 if (bp->ulp_ctx) { 503 BNXT_TF_DBG(ERR, "ulp ctx already allocated\n"); 504 return -EINVAL; 505 } 506 507 /* 508 * Multiple uplink ports can be associated with a single vswitch. 509 * Make sure only the port that is started first will initialize 510 * the TF session. 511 */ 512 session = ulp_session_init(bp, &init); 513 if (!session) { 514 BNXT_TF_DBG(ERR, "Failed to initialize the tf session\n"); 515 return -EINVAL; 516 } 517 518 bp->ulp_ctx = rte_zmalloc("bnxt_ulp_ctx", 519 sizeof(struct bnxt_ulp_context), 0); 520 if (!bp->ulp_ctx) { 521 BNXT_TF_DBG(ERR, "Failed to allocate ulp ctx\n"); 522 ulp_session_deinit(session); 523 return -ENOMEM; 524 } 525 526 /* 527 * If ULP is already initialized for a specific domain then simply 528 * assign the ulp context to this rte_eth_dev. 529 */ 530 if (init) { 531 rc = ulp_ctx_attach(bp->ulp_ctx, session); 532 if (rc) { 533 BNXT_TF_DBG(ERR, 534 "Failed to attach the ulp context\n"); 535 ulp_session_deinit(session); 536 rte_free(bp->ulp_ctx); 537 return rc; 538 } 539 540 /* Update bnxt driver flags */ 541 rc = ulp_dparms_dev_port_intf_update(bp, bp->ulp_ctx); 542 if (rc) { 543 BNXT_TF_DBG(ERR, "Failed to update driver flags\n"); 544 ulp_ctx_detach(bp, session); 545 ulp_session_deinit(session); 546 rte_free(bp->ulp_ctx); 547 return rc; 548 } 549 550 /* update the port database */ 551 rc = ulp_port_db_dev_port_intf_update(bp->ulp_ctx, bp); 552 if (rc) { 553 BNXT_TF_DBG(ERR, 554 "Failed to update port database\n"); 555 ulp_ctx_detach(bp, session); 556 ulp_session_deinit(session); 557 rte_free(bp->ulp_ctx); 558 } 559 return rc; 560 } 561 562 /* Allocate and Initialize the ulp context. */ 563 rc = ulp_ctx_init(bp, session); 564 if (rc) { 565 BNXT_TF_DBG(ERR, "Failed to create the ulp context\n"); 566 goto jump_to_error; 567 } 568 569 /* Initialize ulp dparms with values devargs passed */ 570 rc = ulp_dparms_init(bp, bp->ulp_ctx); 571 572 /* create the port database */ 573 rc = ulp_port_db_init(bp->ulp_ctx); 574 if (rc) { 575 BNXT_TF_DBG(ERR, "Failed to create the port database\n"); 576 goto jump_to_error; 577 } 578 579 /* Update bnxt driver flags */ 580 rc = ulp_dparms_dev_port_intf_update(bp, bp->ulp_ctx); 581 if (rc) { 582 BNXT_TF_DBG(ERR, "Failed to update driver flags\n"); 583 goto jump_to_error; 584 } 585 586 /* update the port database */ 587 rc = ulp_port_db_dev_port_intf_update(bp->ulp_ctx, bp); 588 if (rc) { 589 BNXT_TF_DBG(ERR, "Failed to update port database\n"); 590 goto jump_to_error; 591 } 592 593 /* Create the Mark database. */ 594 rc = ulp_mark_db_init(bp->ulp_ctx); 595 if (rc) { 596 BNXT_TF_DBG(ERR, "Failed to create the mark database\n"); 597 goto jump_to_error; 598 } 599 600 /* Create the flow database. */ 601 rc = ulp_flow_db_init(bp->ulp_ctx); 602 if (rc) { 603 BNXT_TF_DBG(ERR, "Failed to create the flow database\n"); 604 goto jump_to_error; 605 } 606 607 /* Create the eem table scope. */ 608 rc = ulp_eem_tbl_scope_init(bp); 609 if (rc) { 610 BNXT_TF_DBG(ERR, "Failed to create the eem scope table\n"); 611 goto jump_to_error; 612 } 613 614 rc = ulp_mapper_init(bp->ulp_ctx); 615 if (rc) { 616 BNXT_TF_DBG(ERR, "Failed to initialize ulp mapper\n"); 617 goto jump_to_error; 618 } 619 620 return rc; 621 622 jump_to_error: 623 bnxt_ulp_deinit(bp); 624 return -ENOMEM; 625 } 626 627 /* Below are the access functions to access internal data of ulp context. */ 628 629 /* 630 * When a port is deinit'ed by dpdk. This function is called 631 * and this function clears the ULP context and rest of the 632 * infrastructure associated with it. 633 */ 634 void 635 bnxt_ulp_deinit(struct bnxt *bp) 636 { 637 struct bnxt_ulp_session_state *session; 638 struct rte_pci_device *pci_dev; 639 struct rte_pci_addr *pci_addr; 640 641 /* Get the session first */ 642 pci_dev = RTE_DEV_TO_PCI(bp->eth_dev->device); 643 pci_addr = &pci_dev->addr; 644 pthread_mutex_lock(&bnxt_ulp_global_mutex); 645 session = ulp_get_session(pci_addr); 646 pthread_mutex_unlock(&bnxt_ulp_global_mutex); 647 648 /* session not found then just exit */ 649 if (!session) 650 return; 651 652 /* clean up regular flows */ 653 ulp_flow_db_flush_flows(bp->ulp_ctx, BNXT_ULP_REGULAR_FLOW_TABLE); 654 655 /* cleanup the eem table scope */ 656 ulp_eem_tbl_scope_deinit(bp, bp->ulp_ctx); 657 658 /* cleanup the flow database */ 659 ulp_flow_db_deinit(bp->ulp_ctx); 660 661 /* Delete the Mark database */ 662 ulp_mark_db_deinit(bp->ulp_ctx); 663 664 /* cleanup the ulp mapper */ 665 ulp_mapper_deinit(bp->ulp_ctx); 666 667 /* Delete the Port database */ 668 ulp_port_db_deinit(bp->ulp_ctx); 669 670 /* Delete the ulp context and tf session */ 671 ulp_ctx_detach(bp, session); 672 673 /* Finally delete the bnxt session*/ 674 ulp_session_deinit(session); 675 676 rte_free(bp->ulp_ctx); 677 } 678 679 /* Function to set the Mark DB into the context */ 680 int32_t 681 bnxt_ulp_cntxt_ptr2_mark_db_set(struct bnxt_ulp_context *ulp_ctx, 682 struct bnxt_ulp_mark_tbl *mark_tbl) 683 { 684 if (!ulp_ctx || !ulp_ctx->cfg_data) { 685 BNXT_TF_DBG(ERR, "Invalid ulp context data\n"); 686 return -EINVAL; 687 } 688 689 ulp_ctx->cfg_data->mark_tbl = mark_tbl; 690 691 return 0; 692 } 693 694 /* Function to retrieve the Mark DB from the context. */ 695 struct bnxt_ulp_mark_tbl * 696 bnxt_ulp_cntxt_ptr2_mark_db_get(struct bnxt_ulp_context *ulp_ctx) 697 { 698 if (!ulp_ctx || !ulp_ctx->cfg_data) 699 return NULL; 700 701 return ulp_ctx->cfg_data->mark_tbl; 702 } 703 704 /* Function to set the device id of the hardware. */ 705 int32_t 706 bnxt_ulp_cntxt_dev_id_set(struct bnxt_ulp_context *ulp_ctx, 707 uint32_t dev_id) 708 { 709 if (ulp_ctx && ulp_ctx->cfg_data) { 710 ulp_ctx->cfg_data->dev_id = dev_id; 711 return 0; 712 } 713 714 return -EINVAL; 715 } 716 717 /* Function to get the device id of the hardware. */ 718 int32_t 719 bnxt_ulp_cntxt_dev_id_get(struct bnxt_ulp_context *ulp_ctx, 720 uint32_t *dev_id) 721 { 722 if (ulp_ctx && ulp_ctx->cfg_data) { 723 *dev_id = ulp_ctx->cfg_data->dev_id; 724 return 0; 725 } 726 727 return -EINVAL; 728 } 729 730 /* Function to get the table scope id of the EEM table. */ 731 int32_t 732 bnxt_ulp_cntxt_tbl_scope_id_get(struct bnxt_ulp_context *ulp_ctx, 733 uint32_t *tbl_scope_id) 734 { 735 if (ulp_ctx && ulp_ctx->cfg_data) { 736 *tbl_scope_id = ulp_ctx->cfg_data->tbl_scope_id; 737 return 0; 738 } 739 740 return -EINVAL; 741 } 742 743 /* Function to set the table scope id of the EEM table. */ 744 int32_t 745 bnxt_ulp_cntxt_tbl_scope_id_set(struct bnxt_ulp_context *ulp_ctx, 746 uint32_t tbl_scope_id) 747 { 748 if (ulp_ctx && ulp_ctx->cfg_data) { 749 ulp_ctx->cfg_data->tbl_scope_id = tbl_scope_id; 750 return 0; 751 } 752 753 return -EINVAL; 754 } 755 756 /* Function to set the tfp session details from the ulp context. */ 757 int32_t 758 bnxt_ulp_cntxt_tfp_set(struct bnxt_ulp_context *ulp, struct tf *tfp) 759 { 760 if (!ulp) { 761 BNXT_TF_DBG(ERR, "Invalid arguments\n"); 762 return -EINVAL; 763 } 764 765 /* TBD The tfp should be removed once tf_attach is implemented. */ 766 ulp->g_tfp = tfp; 767 return 0; 768 } 769 770 /* Function to get the tfp session details from the ulp context. */ 771 struct tf * 772 bnxt_ulp_cntxt_tfp_get(struct bnxt_ulp_context *ulp) 773 { 774 if (!ulp) { 775 BNXT_TF_DBG(ERR, "Invalid arguments\n"); 776 return NULL; 777 } 778 /* TBD The tfp should be removed once tf_attach is implemented. */ 779 return ulp->g_tfp; 780 } 781 782 /* 783 * Get the device table entry based on the device id. 784 * 785 * dev_id [in] The device id of the hardware 786 * 787 * Returns the pointer to the device parameters. 788 */ 789 struct bnxt_ulp_device_params * 790 bnxt_ulp_device_params_get(uint32_t dev_id) 791 { 792 if (dev_id < BNXT_ULP_MAX_NUM_DEVICES) 793 return &ulp_device_params[dev_id]; 794 return NULL; 795 } 796 797 /* Function to set the flow database to the ulp context. */ 798 int32_t 799 bnxt_ulp_cntxt_ptr2_flow_db_set(struct bnxt_ulp_context *ulp_ctx, 800 struct bnxt_ulp_flow_db *flow_db) 801 { 802 if (!ulp_ctx || !ulp_ctx->cfg_data) 803 return -EINVAL; 804 805 ulp_ctx->cfg_data->flow_db = flow_db; 806 return 0; 807 } 808 809 /* Function to get the flow database from the ulp context. */ 810 struct bnxt_ulp_flow_db * 811 bnxt_ulp_cntxt_ptr2_flow_db_get(struct bnxt_ulp_context *ulp_ctx) 812 { 813 if (!ulp_ctx || !ulp_ctx->cfg_data) 814 return NULL; 815 816 return ulp_ctx->cfg_data->flow_db; 817 } 818 819 /* Function to get the ulp context from eth device. */ 820 struct bnxt_ulp_context * 821 bnxt_ulp_eth_dev_ptr2_cntxt_get(struct rte_eth_dev *dev) 822 { 823 struct bnxt *bp; 824 825 bp = (struct bnxt *)dev->data->dev_private; 826 if (!bp) { 827 BNXT_TF_DBG(ERR, "Bnxt private data is not initialized\n"); 828 return NULL; 829 } 830 return bp->ulp_ctx; 831 } 832 833 int32_t 834 bnxt_ulp_cntxt_ptr2_mapper_data_set(struct bnxt_ulp_context *ulp_ctx, 835 void *mapper_data) 836 { 837 if (!ulp_ctx || !ulp_ctx->cfg_data) { 838 BNXT_TF_DBG(ERR, "Invalid ulp context data\n"); 839 return -EINVAL; 840 } 841 842 ulp_ctx->cfg_data->mapper_data = mapper_data; 843 return 0; 844 } 845 846 void * 847 bnxt_ulp_cntxt_ptr2_mapper_data_get(struct bnxt_ulp_context *ulp_ctx) 848 { 849 if (!ulp_ctx || !ulp_ctx->cfg_data) { 850 BNXT_TF_DBG(ERR, "Invalid ulp context data\n"); 851 return NULL; 852 } 853 854 return ulp_ctx->cfg_data->mapper_data; 855 } 856 857 /* Function to set the port database to the ulp context. */ 858 int32_t 859 bnxt_ulp_cntxt_ptr2_port_db_set(struct bnxt_ulp_context *ulp_ctx, 860 struct bnxt_ulp_port_db *port_db) 861 { 862 if (!ulp_ctx || !ulp_ctx->cfg_data) 863 return -EINVAL; 864 865 ulp_ctx->cfg_data->port_db = port_db; 866 return 0; 867 } 868 869 /* Function to get the port database from the ulp context. */ 870 struct bnxt_ulp_port_db * 871 bnxt_ulp_cntxt_ptr2_port_db_get(struct bnxt_ulp_context *ulp_ctx) 872 { 873 if (!ulp_ctx || !ulp_ctx->cfg_data) 874 return NULL; 875 876 return ulp_ctx->cfg_data->port_db; 877 } 878