1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2014-2021 Broadcom 3 * All rights reserved. 4 */ 5 6 #include <rte_malloc.h> 7 #include "bnxt.h" 8 #include "bnxt_vnic.h" 9 #include "bnxt_tf_common.h" 10 #include "bnxt_tf_pmd_shim.h" 11 #include "ulp_port_db.h" 12 #include "tfp.h" 13 14 #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG 15 #include "ulp_tf_debug.h" 16 #endif 17 18 static uint32_t 19 ulp_port_db_allocate_ifindex(struct bnxt_ulp_port_db *port_db) 20 { 21 uint32_t idx = 1; 22 23 while (idx < port_db->ulp_intf_list_size && 24 port_db->ulp_intf_list[idx].type != BNXT_ULP_INTF_TYPE_INVALID) 25 idx++; 26 27 if (idx >= port_db->ulp_intf_list_size) { 28 BNXT_TF_DBG(ERR, "Port DB interface list is full\n"); 29 return 0; 30 } 31 return idx; 32 } 33 34 /* 35 * Initialize the port database. Memory is allocated in this 36 * call and assigned to the port database. 37 * 38 * ulp_ctxt [in] Ptr to ulp context 39 * 40 * Returns 0 on success or negative number on failure. 41 */ 42 int32_t ulp_port_db_init(struct bnxt_ulp_context *ulp_ctxt, uint8_t port_cnt) 43 { 44 struct bnxt_ulp_port_db *port_db; 45 46 port_db = rte_zmalloc("bnxt_ulp_port_db", 47 sizeof(struct bnxt_ulp_port_db), 0); 48 if (!port_db) { 49 BNXT_TF_DBG(ERR, 50 "Failed to allocate memory for port db\n"); 51 return -ENOMEM; 52 } 53 54 /* Attach the port database to the ulp context. */ 55 bnxt_ulp_cntxt_ptr2_port_db_set(ulp_ctxt, port_db); 56 57 /* index 0 is not being used hence add 1 to size */ 58 port_db->ulp_intf_list_size = BNXT_PORT_DB_MAX_INTF_LIST + 1; 59 /* Allocate the port tables */ 60 port_db->ulp_intf_list = rte_zmalloc("bnxt_ulp_port_db_intf_list", 61 port_db->ulp_intf_list_size * 62 sizeof(struct ulp_interface_info), 63 0); 64 if (!port_db->ulp_intf_list) { 65 BNXT_TF_DBG(ERR, 66 "Failed to allocate mem for port interface list\n"); 67 goto error_free; 68 } 69 70 /* Allocate the phy port list */ 71 port_db->phy_port_list = rte_zmalloc("bnxt_ulp_phy_port_list", 72 port_cnt * 73 sizeof(struct ulp_phy_port_info), 74 0); 75 if (!port_db->phy_port_list) { 76 BNXT_TF_DBG(ERR, 77 "Failed to allocate mem for phy port list\n"); 78 goto error_free; 79 } 80 port_db->phy_port_cnt = port_cnt; 81 return 0; 82 83 error_free: 84 ulp_port_db_deinit(ulp_ctxt); 85 return -ENOMEM; 86 } 87 88 /* 89 * Deinitialize the port database. Memory is deallocated in 90 * this call. 91 * 92 * ulp_ctxt [in] Ptr to ulp context 93 * 94 * Returns 0 on success. 95 */ 96 int32_t ulp_port_db_deinit(struct bnxt_ulp_context *ulp_ctxt) 97 { 98 struct bnxt_ulp_port_db *port_db; 99 100 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 101 if (!port_db) { 102 BNXT_TF_DBG(ERR, "Invalid Arguments\n"); 103 return -EINVAL; 104 } 105 106 /* Detach the flow database from the ulp context. */ 107 bnxt_ulp_cntxt_ptr2_port_db_set(ulp_ctxt, NULL); 108 109 /* Free up all the memory. */ 110 rte_free(port_db->phy_port_list); 111 rte_free(port_db->ulp_intf_list); 112 rte_free(port_db); 113 return 0; 114 } 115 116 /* 117 * Update the port database.This api is called when the port 118 * details are available during the startup. 119 * 120 * ulp_ctxt [in] Ptr to ulp context 121 * bp [in]. ptr to the device function. 122 * 123 * Returns 0 on success or negative number on failure. 124 */ 125 int32_t ulp_port_db_dev_port_intf_update(struct bnxt_ulp_context *ulp_ctxt, 126 struct rte_eth_dev *eth_dev) 127 { 128 uint32_t port_id = eth_dev->data->port_id; 129 struct ulp_phy_port_info *port_data; 130 struct bnxt_ulp_port_db *port_db; 131 struct ulp_interface_info *intf; 132 struct ulp_func_if_info *func; 133 uint32_t ifindex; 134 int32_t rc; 135 136 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 137 if (!port_db) { 138 BNXT_TF_DBG(ERR, "Invalid Arguments\n"); 139 return -EINVAL; 140 } 141 142 rc = ulp_port_db_dev_port_to_ulp_index(ulp_ctxt, port_id, &ifindex); 143 if (rc == -ENOENT) { 144 /* port not found, allocate one */ 145 ifindex = ulp_port_db_allocate_ifindex(port_db); 146 if (!ifindex) 147 return -ENOMEM; 148 port_db->dev_port_list[port_id] = ifindex; 149 } else if (rc == -EINVAL) { 150 return -EINVAL; 151 } 152 153 /* update the interface details */ 154 intf = &port_db->ulp_intf_list[ifindex]; 155 156 intf->type = bnxt_pmd_get_interface_type(port_id); 157 intf->drv_func_id = bnxt_pmd_get_fw_func_id(port_id, 158 BNXT_ULP_INTF_TYPE_INVALID); 159 160 func = &port_db->ulp_func_id_tbl[intf->drv_func_id]; 161 if (!func->func_valid) { 162 func->func_svif = bnxt_pmd_get_svif(port_id, true, 163 BNXT_ULP_INTF_TYPE_INVALID); 164 func->func_spif = bnxt_pmd_get_phy_port_id(port_id); 165 func->func_parif = 166 bnxt_pmd_get_parif(port_id, BNXT_ULP_INTF_TYPE_INVALID); 167 func->func_vnic = 168 bnxt_pmd_get_vnic_id(port_id, BNXT_ULP_INTF_TYPE_INVALID); 169 func->phy_port_id = bnxt_pmd_get_phy_port_id(port_id); 170 func->func_valid = true; 171 func->ifindex = ifindex; 172 } 173 174 if (intf->type == BNXT_ULP_INTF_TYPE_VF_REP) { 175 intf->vf_func_id = 176 bnxt_pmd_get_fw_func_id(port_id, BNXT_ULP_INTF_TYPE_VF_REP); 177 178 func = &port_db->ulp_func_id_tbl[intf->vf_func_id]; 179 func->func_svif = 180 bnxt_pmd_get_svif(port_id, true, BNXT_ULP_INTF_TYPE_VF_REP); 181 func->func_spif = 182 bnxt_pmd_get_phy_port_id(port_id); 183 func->func_parif = 184 bnxt_pmd_get_parif(port_id, BNXT_ULP_INTF_TYPE_INVALID); 185 func->func_vnic = 186 bnxt_pmd_get_vnic_id(port_id, BNXT_ULP_INTF_TYPE_VF_REP); 187 func->phy_port_id = bnxt_pmd_get_phy_port_id(port_id); 188 func->ifindex = ifindex; 189 } 190 191 /* When there is no match, the default action is to send the packet to 192 * the kernel. And to send it to the kernel, we need the PF's vnic id. 193 */ 194 func->func_parent_vnic = bnxt_pmd_get_parent_vnic_id(port_id, intf->type); 195 func->func_parent_vnic = tfp_cpu_to_be_16(func->func_parent_vnic); 196 bnxt_pmd_get_iface_mac(port_id, intf->type, func->func_mac, 197 func->func_parent_mac); 198 199 port_data = &port_db->phy_port_list[func->phy_port_id]; 200 if (!port_data->port_valid) { 201 port_data->port_svif = 202 bnxt_pmd_get_svif(port_id, false, BNXT_ULP_INTF_TYPE_INVALID); 203 port_data->port_spif = bnxt_pmd_get_phy_port_id(port_id); 204 port_data->port_parif = 205 bnxt_pmd_get_parif(port_id, BNXT_ULP_INTF_TYPE_INVALID); 206 port_data->port_vport = bnxt_pmd_get_vport(port_id); 207 port_data->port_valid = true; 208 } 209 #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG 210 #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG_PORT 211 ulp_port_db_dump(port_db, intf, port_id); 212 #endif 213 #endif 214 return 0; 215 } 216 217 /* 218 * Api to get the ulp ifindex for a given device port. 219 * 220 * ulp_ctxt [in] Ptr to ulp context 221 * port_id [in].device port id 222 * ifindex [out] ulp ifindex 223 * 224 * Returns 0 on success or negative number on failure. 225 */ 226 int32_t 227 ulp_port_db_dev_port_to_ulp_index(struct bnxt_ulp_context *ulp_ctxt, 228 uint32_t port_id, 229 uint32_t *ifindex) 230 { 231 struct bnxt_ulp_port_db *port_db; 232 233 *ifindex = 0; 234 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 235 if (!port_db || port_id >= RTE_MAX_ETHPORTS) { 236 BNXT_TF_DBG(ERR, "Invalid Arguments\n"); 237 return -EINVAL; 238 } 239 if (!port_db->dev_port_list[port_id]) 240 return -ENOENT; 241 242 *ifindex = port_db->dev_port_list[port_id]; 243 return 0; 244 } 245 246 /* 247 * Api to get the function id for a given ulp ifindex. 248 * 249 * ulp_ctxt [in] Ptr to ulp context 250 * ifindex [in] ulp ifindex 251 * func_id [out] the function id of the given ifindex. 252 * 253 * Returns 0 on success or negative number on failure. 254 */ 255 int32_t 256 ulp_port_db_function_id_get(struct bnxt_ulp_context *ulp_ctxt, 257 uint32_t ifindex, 258 uint32_t fid_type, 259 uint16_t *func_id) 260 { 261 struct bnxt_ulp_port_db *port_db; 262 263 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 264 if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) { 265 BNXT_TF_DBG(ERR, "Invalid Arguments\n"); 266 return -EINVAL; 267 } 268 269 if (fid_type == BNXT_ULP_DRV_FUNC_FID) 270 *func_id = port_db->ulp_intf_list[ifindex].drv_func_id; 271 else 272 *func_id = port_db->ulp_intf_list[ifindex].vf_func_id; 273 274 return 0; 275 } 276 277 /* 278 * Api to get the svif for a given ulp ifindex. 279 * 280 * ulp_ctxt [in] Ptr to ulp context 281 * ifindex [in] ulp ifindex 282 * svif_type [in] the svif type of the given ifindex. 283 * svif [out] the svif of the given ifindex. 284 * 285 * Returns 0 on success or negative number on failure. 286 */ 287 int32_t 288 ulp_port_db_svif_get(struct bnxt_ulp_context *ulp_ctxt, 289 uint32_t ifindex, 290 uint32_t svif_type, 291 uint16_t *svif) 292 { 293 struct bnxt_ulp_port_db *port_db; 294 uint16_t phy_port_id, func_id; 295 296 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 297 if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) { 298 BNXT_TF_DBG(ERR, "Invalid Arguments\n"); 299 return -EINVAL; 300 } 301 302 if (svif_type == BNXT_ULP_DRV_FUNC_SVIF) { 303 func_id = port_db->ulp_intf_list[ifindex].drv_func_id; 304 *svif = port_db->ulp_func_id_tbl[func_id].func_svif; 305 } else if (svif_type == BNXT_ULP_VF_FUNC_SVIF) { 306 func_id = port_db->ulp_intf_list[ifindex].vf_func_id; 307 *svif = port_db->ulp_func_id_tbl[func_id].func_svif; 308 } else { 309 func_id = port_db->ulp_intf_list[ifindex].drv_func_id; 310 phy_port_id = port_db->ulp_func_id_tbl[func_id].phy_port_id; 311 *svif = port_db->phy_port_list[phy_port_id].port_svif; 312 } 313 314 return 0; 315 } 316 317 /* 318 * Api to get the spif for a given ulp ifindex. 319 * 320 * ulp_ctxt [in] Ptr to ulp context 321 * ifindex [in] ulp ifindex 322 * spif_type [in] the spif type of the given ifindex. 323 * spif [out] the spif of the given ifindex. 324 * 325 * Returns 0 on success or negative number on failure. 326 */ 327 int32_t 328 ulp_port_db_spif_get(struct bnxt_ulp_context *ulp_ctxt, 329 uint32_t ifindex, 330 uint32_t spif_type, 331 uint16_t *spif) 332 { 333 struct bnxt_ulp_port_db *port_db; 334 uint16_t phy_port_id, func_id; 335 336 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 337 if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) { 338 BNXT_TF_DBG(ERR, "Invalid Arguments\n"); 339 return -EINVAL; 340 } 341 342 if (spif_type == BNXT_ULP_DRV_FUNC_SPIF) { 343 func_id = port_db->ulp_intf_list[ifindex].drv_func_id; 344 *spif = port_db->ulp_func_id_tbl[func_id].func_spif; 345 } else if (spif_type == BNXT_ULP_VF_FUNC_SPIF) { 346 func_id = port_db->ulp_intf_list[ifindex].vf_func_id; 347 *spif = port_db->ulp_func_id_tbl[func_id].func_spif; 348 } else { 349 func_id = port_db->ulp_intf_list[ifindex].drv_func_id; 350 phy_port_id = port_db->ulp_func_id_tbl[func_id].phy_port_id; 351 *spif = port_db->phy_port_list[phy_port_id].port_spif; 352 } 353 354 return 0; 355 } 356 357 /* 358 * Api to get the parif for a given ulp ifindex. 359 * 360 * ulp_ctxt [in] Ptr to ulp context 361 * ifindex [in] ulp ifindex 362 * parif_type [in] the parif type of the given ifindex. 363 * parif [out] the parif of the given ifindex. 364 * 365 * Returns 0 on success or negative number on failure. 366 */ 367 int32_t 368 ulp_port_db_parif_get(struct bnxt_ulp_context *ulp_ctxt, 369 uint32_t ifindex, 370 uint32_t parif_type, 371 uint16_t *parif) 372 { 373 struct bnxt_ulp_port_db *port_db; 374 uint16_t phy_port_id, func_id; 375 376 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 377 if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) { 378 BNXT_TF_DBG(ERR, "Invalid Arguments\n"); 379 return -EINVAL; 380 } 381 if (parif_type == BNXT_ULP_DRV_FUNC_PARIF) { 382 func_id = port_db->ulp_intf_list[ifindex].drv_func_id; 383 *parif = port_db->ulp_func_id_tbl[func_id].func_parif; 384 } else if (parif_type == BNXT_ULP_VF_FUNC_PARIF) { 385 func_id = port_db->ulp_intf_list[ifindex].vf_func_id; 386 *parif = port_db->ulp_func_id_tbl[func_id].func_parif; 387 } else { 388 func_id = port_db->ulp_intf_list[ifindex].drv_func_id; 389 phy_port_id = port_db->ulp_func_id_tbl[func_id].phy_port_id; 390 *parif = port_db->phy_port_list[phy_port_id].port_parif; 391 } 392 /* Parif needs to be reset to a free partition */ 393 *parif += BNXT_ULP_FREE_PARIF_BASE; 394 395 return 0; 396 } 397 398 /* 399 * Api to get the vnic id for a given ulp ifindex. 400 * 401 * ulp_ctxt [in] Ptr to ulp context 402 * ifindex [in] ulp ifindex 403 * vnic [out] the vnic of the given ifindex. 404 * 405 * Returns 0 on success or negative number on failure. 406 */ 407 int32_t 408 ulp_port_db_default_vnic_get(struct bnxt_ulp_context *ulp_ctxt, 409 uint32_t ifindex, 410 uint32_t vnic_type, 411 uint16_t *vnic) 412 { 413 struct bnxt_ulp_port_db *port_db; 414 uint16_t func_id; 415 416 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 417 if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) { 418 BNXT_TF_DBG(ERR, "Invalid Arguments\n"); 419 return -EINVAL; 420 } 421 422 if (vnic_type == BNXT_ULP_DRV_FUNC_VNIC) { 423 func_id = port_db->ulp_intf_list[ifindex].drv_func_id; 424 *vnic = port_db->ulp_func_id_tbl[func_id].func_vnic; 425 } else { 426 func_id = port_db->ulp_intf_list[ifindex].vf_func_id; 427 *vnic = port_db->ulp_func_id_tbl[func_id].func_vnic; 428 } 429 430 return 0; 431 } 432 433 /* 434 * Api to get the vport id for a given ulp ifindex. 435 * 436 * ulp_ctxt [in] Ptr to ulp context 437 * ifindex [in] ulp ifindex 438 * vport [out] the port of the given ifindex. 439 * 440 * Returns 0 on success or negative number on failure. 441 */ 442 int32_t 443 ulp_port_db_vport_get(struct bnxt_ulp_context *ulp_ctxt, 444 uint32_t ifindex, uint16_t *vport) 445 { 446 struct bnxt_ulp_port_db *port_db; 447 uint16_t phy_port_id, func_id; 448 449 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 450 if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) { 451 BNXT_TF_DBG(ERR, "Invalid Arguments\n"); 452 return -EINVAL; 453 } 454 455 func_id = port_db->ulp_intf_list[ifindex].drv_func_id; 456 phy_port_id = port_db->ulp_func_id_tbl[func_id].phy_port_id; 457 *vport = port_db->phy_port_list[phy_port_id].port_vport; 458 return 0; 459 } 460 461 /* 462 * Api to get the vport for a given physical port. 463 * 464 * ulp_ctxt [in] Ptr to ulp context 465 * phy_port [in] physical port index 466 * out_port [out] the port of the given physical index 467 * 468 * Returns 0 on success or negative number on failure. 469 */ 470 int32_t 471 ulp_port_db_phy_port_vport_get(struct bnxt_ulp_context *ulp_ctxt, 472 uint32_t phy_port, 473 uint16_t *out_port) 474 { 475 struct bnxt_ulp_port_db *port_db; 476 477 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 478 if (!port_db || phy_port >= port_db->phy_port_cnt) { 479 BNXT_TF_DBG(ERR, "Invalid Arguments\n"); 480 return -EINVAL; 481 } 482 *out_port = port_db->phy_port_list[phy_port].port_vport; 483 return 0; 484 } 485 486 /* 487 * Api to get the svif for a given physical port. 488 * 489 * ulp_ctxt [in] Ptr to ulp context 490 * phy_port [in] physical port index 491 * svif [out] the svif of the given physical index 492 * 493 * Returns 0 on success or negative number on failure. 494 */ 495 int32_t 496 ulp_port_db_phy_port_svif_get(struct bnxt_ulp_context *ulp_ctxt, 497 uint32_t phy_port, 498 uint16_t *svif) 499 { 500 struct bnxt_ulp_port_db *port_db; 501 502 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 503 if (!port_db || phy_port >= port_db->phy_port_cnt) { 504 BNXT_TF_DBG(ERR, "Invalid Arguments\n"); 505 return -EINVAL; 506 } 507 *svif = port_db->phy_port_list[phy_port].port_svif; 508 return 0; 509 } 510 511 /* 512 * Api to get the port type for a given ulp ifindex. 513 * 514 * ulp_ctxt [in] Ptr to ulp context 515 * ifindex [in] ulp ifindex 516 * 517 * Returns port type. 518 */ 519 enum bnxt_ulp_intf_type 520 ulp_port_db_port_type_get(struct bnxt_ulp_context *ulp_ctxt, 521 uint32_t ifindex) 522 { 523 struct bnxt_ulp_port_db *port_db; 524 525 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 526 if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) { 527 BNXT_TF_DBG(ERR, "Invalid Arguments\n"); 528 return BNXT_ULP_INTF_TYPE_INVALID; 529 } 530 return port_db->ulp_intf_list[ifindex].type; 531 } 532 533 /* 534 * Api to get the ulp ifindex for a given function id. 535 * 536 * ulp_ctxt [in] Ptr to ulp context 537 * func_id [in].device func id 538 * ifindex [out] ulp ifindex 539 * 540 * Returns 0 on success or negative number on failure. 541 */ 542 int32_t 543 ulp_port_db_dev_func_id_to_ulp_index(struct bnxt_ulp_context *ulp_ctxt, 544 uint32_t func_id, uint32_t *ifindex) 545 { 546 struct bnxt_ulp_port_db *port_db; 547 548 *ifindex = 0; 549 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 550 if (!port_db || func_id >= BNXT_PORT_DB_MAX_FUNC) { 551 BNXT_TF_DBG(ERR, "Invalid Arguments\n"); 552 return -EINVAL; 553 } 554 if (!port_db->ulp_func_id_tbl[func_id].func_valid) 555 return -ENOENT; 556 557 *ifindex = port_db->ulp_func_id_tbl[func_id].ifindex; 558 return 0; 559 } 560 561 /* 562 * Api to get the function id for a given port id. 563 * 564 * ulp_ctxt [in] Ptr to ulp context 565 * port_id [in] dpdk port id 566 * func_id [out] the function id of the given ifindex. 567 * 568 * Returns 0 on success or negative number on failure. 569 */ 570 int32_t 571 ulp_port_db_port_func_id_get(struct bnxt_ulp_context *ulp_ctxt, 572 uint16_t port_id, uint16_t *func_id) 573 { 574 struct bnxt_ulp_port_db *port_db; 575 uint32_t ifindex; 576 577 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 578 if (!port_db || port_id >= RTE_MAX_ETHPORTS) { 579 BNXT_TF_DBG(ERR, "Invalid Arguments\n"); 580 return -EINVAL; 581 } 582 ifindex = port_db->dev_port_list[port_id]; 583 if (!ifindex) 584 return -ENOENT; 585 586 switch (port_db->ulp_intf_list[ifindex].type) { 587 case BNXT_ULP_INTF_TYPE_TRUSTED_VF: 588 case BNXT_ULP_INTF_TYPE_PF: 589 *func_id = port_db->ulp_intf_list[ifindex].drv_func_id; 590 break; 591 case BNXT_ULP_INTF_TYPE_VF: 592 case BNXT_ULP_INTF_TYPE_VF_REP: 593 *func_id = port_db->ulp_intf_list[ifindex].vf_func_id; 594 break; 595 default: 596 *func_id = 0; 597 break; 598 } 599 return 0; 600 } 601 602 /* internal function to get the */ 603 static struct ulp_func_if_info* 604 ulp_port_db_func_if_info_get(struct bnxt_ulp_context *ulp_ctxt, 605 uint32_t port_id) 606 { 607 struct bnxt_ulp_port_db *port_db; 608 uint16_t func_id; 609 610 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 611 if (ulp_port_db_port_func_id_get(ulp_ctxt, port_id, &func_id)) { 612 BNXT_TF_DBG(ERR, "Invalid port_id %x\n", port_id); 613 return NULL; 614 } 615 616 if (!port_db->ulp_func_id_tbl[func_id].func_valid) { 617 BNXT_TF_DBG(ERR, "Invalid func_id %x\n", func_id); 618 return NULL; 619 } 620 return &port_db->ulp_func_id_tbl[func_id]; 621 } 622 623 /* 624 * Api to get the parent mac address for a given port id. 625 * 626 * ulp_ctxt [in] Ptr to ulp context 627 * port_id [in] device port id 628 * mac_addr [out] mac address 629 * 630 * Returns 0 on success or negative number on failure. 631 */ 632 int32_t 633 ulp_port_db_parent_mac_addr_get(struct bnxt_ulp_context *ulp_ctxt, 634 uint32_t port_id, uint8_t **mac_addr) 635 { 636 struct ulp_func_if_info *info; 637 638 info = ulp_port_db_func_if_info_get(ulp_ctxt, port_id); 639 if (info) { 640 *mac_addr = info->func_parent_mac; 641 return 0; 642 } 643 return -EINVAL; 644 } 645 646 /* 647 * Api to get the mac address for a given port id. 648 * 649 * ulp_ctxt [in] Ptr to ulp context 650 * port_id [in] device port id 651 * mac_addr [out] mac address 652 * 653 * Returns 0 on success or negative number on failure. 654 */ 655 int32_t 656 ulp_port_db_drv_mac_addr_get(struct bnxt_ulp_context *ulp_ctxt, 657 uint32_t port_id, uint8_t **mac_addr) 658 { 659 struct ulp_func_if_info *info; 660 661 info = ulp_port_db_func_if_info_get(ulp_ctxt, port_id); 662 if (info) { 663 *mac_addr = info->func_mac; 664 return 0; 665 } 666 return -EINVAL; 667 } 668 669 /* 670 * Api to get the parent vnic for a given port id. 671 * 672 * ulp_ctxt [in] Ptr to ulp context 673 * port_id [in] device port id 674 * vnic [out] parent vnic 675 * 676 * Returns 0 on success or negative number on failure. 677 */ 678 int32_t 679 ulp_port_db_parent_vnic_get(struct bnxt_ulp_context *ulp_ctxt, 680 uint32_t port_id, uint8_t **vnic) 681 { 682 struct ulp_func_if_info *info; 683 684 info = ulp_port_db_func_if_info_get(ulp_ctxt, port_id); 685 if (info) { 686 *vnic = (uint8_t *)&info->func_parent_vnic; 687 return 0; 688 } 689 return -EINVAL; 690 } 691