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