1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2014-2023 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_ulp_utils.h" 11 #include "bnxt_tf_pmd_shim.h" 12 #include "ulp_port_db.h" 13 #include "tfp.h" 14 15 static uint32_t 16 ulp_port_db_allocate_ifindex(struct bnxt_ulp_port_db *port_db) 17 { 18 uint32_t idx = 1; 19 20 while (idx < port_db->ulp_intf_list_size && 21 port_db->ulp_intf_list[idx].type != BNXT_ULP_INTF_TYPE_INVALID) 22 idx++; 23 24 if (idx >= port_db->ulp_intf_list_size) { 25 BNXT_DRV_DBG(ERR, "Port DB interface list is full\n"); 26 return 0; 27 } 28 return idx; 29 } 30 31 /* 32 * Initialize the port database. Memory is allocated in this 33 * call and assigned to the port database. 34 * 35 * ulp_ctxt [in] Ptr to ulp context 36 * 37 * Returns 0 on success or negative number on failure. 38 */ 39 int32_t ulp_port_db_init(struct bnxt_ulp_context *ulp_ctxt, uint8_t port_cnt) 40 { 41 struct bnxt_ulp_port_db *port_db; 42 43 port_db = rte_zmalloc("bnxt_ulp_port_db", 44 sizeof(struct bnxt_ulp_port_db), 0); 45 if (!port_db) { 46 BNXT_DRV_DBG(ERR, "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 /* 256 VFs + PFs etc. so making it 512*/ 54 port_db->ulp_intf_list_size = BNXT_PORT_DB_MAX_INTF_LIST * 2; 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_DRV_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_DRV_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_DRV_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_port_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 uint8_t tsid; 131 int32_t rc; 132 133 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 134 if (!port_db) { 135 BNXT_DRV_DBG(ERR, "Invalid Arguments\n"); 136 return -EINVAL; 137 } 138 139 rc = ulp_port_db_dev_port_to_ulp_index(ulp_ctxt, port_id, &ifindex); 140 if (rc == -ENOENT) { 141 /* port not found, allocate one */ 142 ifindex = ulp_port_db_allocate_ifindex(port_db); 143 if (!ifindex) 144 return -ENOMEM; 145 port_db->dev_port_list[port_id] = ifindex; 146 } else if (rc == -EINVAL) { 147 return -EINVAL; 148 } 149 150 /* update the interface details */ 151 intf = &port_db->ulp_intf_list[ifindex]; 152 153 intf->type = bnxt_pmd_get_interface_type(port_id); 154 if (intf->type == BNXT_ULP_INTF_TYPE_PF) 155 intf->type_is_pf = 1; 156 else 157 intf->type_is_pf = 0; 158 159 intf->drv_func_id = bnxt_pmd_get_fw_func_id(port_id, 160 BNXT_ULP_INTF_TYPE_INVALID); 161 162 func = &port_db->ulp_func_id_tbl[intf->drv_func_id]; 163 if (!func->func_valid) { 164 func->func_svif = bnxt_pmd_get_svif(port_id, true, 165 BNXT_ULP_INTF_TYPE_INVALID); 166 func->func_spif = bnxt_pmd_get_phy_port_id(port_id); 167 func->func_parif = 168 bnxt_pmd_get_parif(port_id, BNXT_ULP_INTF_TYPE_INVALID); 169 func->func_vnic = 170 bnxt_pmd_get_vnic_id(port_id, BNXT_ULP_INTF_TYPE_INVALID); 171 func->phy_port_id = bnxt_pmd_get_phy_port_id(port_id); 172 func->func_valid = true; 173 func->ifindex = ifindex; 174 /* Table scope is defined for all devices, ignore failures. */ 175 if (!bnxt_ulp_cntxt_tsid_get(ulp_ctxt, &tsid)) 176 func->table_scope = tsid; 177 } 178 179 if (intf->type == BNXT_ULP_INTF_TYPE_VF_REP) { 180 intf->vf_func_id = 181 bnxt_pmd_get_fw_func_id(port_id, BNXT_ULP_INTF_TYPE_VF_REP); 182 183 func = &port_db->ulp_func_id_tbl[intf->vf_func_id]; 184 func->func_svif = 185 bnxt_pmd_get_svif(port_id, true, BNXT_ULP_INTF_TYPE_VF_REP); 186 func->func_spif = 187 bnxt_pmd_get_phy_port_id(port_id); 188 func->func_parif = 189 bnxt_pmd_get_parif(port_id, BNXT_ULP_INTF_TYPE_INVALID); 190 func->func_vnic = 191 bnxt_pmd_get_vnic_id(port_id, BNXT_ULP_INTF_TYPE_VF_REP); 192 func->phy_port_id = bnxt_pmd_get_phy_port_id(port_id); 193 func->ifindex = ifindex; 194 func->func_valid = true; 195 func->vf_meta_data = tfp_cpu_to_be_16(BNXT_ULP_META_VF_FLAG | 196 intf->vf_func_id); 197 if (!bnxt_ulp_cntxt_tsid_get(ulp_ctxt, &tsid)) 198 func->table_scope = tsid; 199 } 200 201 /* When there is no match, the default action is to send the packet to 202 * the kernel. And to send it to the kernel, we need the PF's vnic id. 203 */ 204 func->func_parent_vnic = bnxt_pmd_get_parent_vnic_id(port_id, intf->type); 205 func->func_parent_vnic = tfp_cpu_to_be_16(func->func_parent_vnic); 206 bnxt_pmd_get_iface_mac(port_id, intf->type, func->func_mac, 207 func->func_parent_mac); 208 209 port_data = &port_db->phy_port_list[func->phy_port_id]; 210 if (!port_data->port_valid) { 211 port_data->port_svif = 212 bnxt_pmd_get_svif(port_id, false, BNXT_ULP_INTF_TYPE_INVALID); 213 port_data->port_spif = bnxt_pmd_get_phy_port_id(port_id); 214 port_data->port_parif = 215 bnxt_pmd_get_parif(port_id, BNXT_ULP_INTF_TYPE_INVALID); 216 port_data->port_vport = bnxt_pmd_get_vport(port_id); 217 port_data->port_valid = true; 218 } 219 return 0; 220 } 221 222 /* 223 * Api to get the ulp ifindex for a given device port. 224 * 225 * ulp_ctxt [in] Ptr to ulp context 226 * port_id [in].device port id 227 * ifindex [out] ulp ifindex 228 * 229 * Returns 0 on success or negative number on failure. 230 */ 231 int32_t 232 ulp_port_db_dev_port_to_ulp_index(struct bnxt_ulp_context *ulp_ctxt, 233 uint32_t port_id, 234 uint32_t *ifindex) 235 { 236 struct bnxt_ulp_port_db *port_db; 237 238 *ifindex = 0; 239 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 240 if (!port_db || port_id >= RTE_MAX_ETHPORTS) { 241 BNXT_DRV_DBG(ERR, "Invalid Arguments\n"); 242 return -EINVAL; 243 } 244 if (!port_db->dev_port_list[port_id]) 245 return -ENOENT; 246 247 *ifindex = port_db->dev_port_list[port_id]; 248 return 0; 249 } 250 251 /* 252 * Api to get the function id for a given ulp ifindex. 253 * 254 * ulp_ctxt [in] Ptr to ulp context 255 * ifindex [in] ulp ifindex 256 * func_id [out] the function id of the given ifindex. 257 * 258 * Returns 0 on success or negative number on failure. 259 */ 260 int32_t 261 ulp_port_db_function_id_get(struct bnxt_ulp_context *ulp_ctxt, 262 uint32_t ifindex, 263 uint32_t fid_type, 264 uint16_t *func_id) 265 { 266 struct bnxt_ulp_port_db *port_db; 267 268 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 269 if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) { 270 BNXT_DRV_DBG(ERR, "Invalid Arguments\n"); 271 return -EINVAL; 272 } 273 274 if (fid_type == BNXT_ULP_DRV_FUNC_FID) 275 *func_id = port_db->ulp_intf_list[ifindex].drv_func_id; 276 else 277 *func_id = port_db->ulp_intf_list[ifindex].vf_func_id; 278 279 return 0; 280 } 281 282 /* 283 * Api to get the svif for a given ulp ifindex. 284 * 285 * ulp_ctxt [in] Ptr to ulp context 286 * ifindex [in] ulp ifindex 287 * svif_type [in] the svif type of the given ifindex. 288 * svif [out] the svif of the given ifindex. 289 * 290 * Returns 0 on success or negative number on failure. 291 */ 292 int32_t 293 ulp_port_db_svif_get(struct bnxt_ulp_context *ulp_ctxt, 294 uint32_t ifindex, 295 uint32_t svif_type, 296 uint16_t *svif) 297 { 298 struct bnxt_ulp_port_db *port_db; 299 uint16_t phy_port_id, func_id; 300 301 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 302 if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) { 303 BNXT_DRV_DBG(ERR, "Invalid Arguments\n"); 304 return -EINVAL; 305 } 306 307 if (svif_type == BNXT_ULP_DRV_FUNC_SVIF) { 308 func_id = port_db->ulp_intf_list[ifindex].drv_func_id; 309 *svif = port_db->ulp_func_id_tbl[func_id].func_svif; 310 } else if (svif_type == BNXT_ULP_VF_FUNC_SVIF) { 311 func_id = port_db->ulp_intf_list[ifindex].vf_func_id; 312 *svif = port_db->ulp_func_id_tbl[func_id].func_svif; 313 } else { 314 func_id = port_db->ulp_intf_list[ifindex].drv_func_id; 315 phy_port_id = port_db->ulp_func_id_tbl[func_id].phy_port_id; 316 *svif = port_db->phy_port_list[phy_port_id].port_svif; 317 } 318 319 return 0; 320 } 321 322 /* 323 * Api to get the spif for a given ulp ifindex. 324 * 325 * ulp_ctxt [in] Ptr to ulp context 326 * ifindex [in] ulp ifindex 327 * spif_type [in] the spif type of the given ifindex. 328 * spif [out] the spif of the given ifindex. 329 * 330 * Returns 0 on success or negative number on failure. 331 */ 332 int32_t 333 ulp_port_db_spif_get(struct bnxt_ulp_context *ulp_ctxt, 334 uint32_t ifindex, 335 uint32_t spif_type, 336 uint16_t *spif) 337 { 338 struct bnxt_ulp_port_db *port_db; 339 uint16_t phy_port_id, func_id; 340 341 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 342 if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) { 343 BNXT_DRV_DBG(ERR, "Invalid Arguments\n"); 344 return -EINVAL; 345 } 346 347 if (spif_type == BNXT_ULP_DRV_FUNC_SPIF) { 348 func_id = port_db->ulp_intf_list[ifindex].drv_func_id; 349 *spif = port_db->ulp_func_id_tbl[func_id].func_spif; 350 } else if (spif_type == BNXT_ULP_VF_FUNC_SPIF) { 351 func_id = port_db->ulp_intf_list[ifindex].vf_func_id; 352 *spif = port_db->ulp_func_id_tbl[func_id].func_spif; 353 } else { 354 func_id = port_db->ulp_intf_list[ifindex].drv_func_id; 355 phy_port_id = port_db->ulp_func_id_tbl[func_id].phy_port_id; 356 *spif = port_db->phy_port_list[phy_port_id].port_spif; 357 } 358 359 return 0; 360 } 361 362 /* 363 * Api to get the parif for a given ulp ifindex. 364 * 365 * ulp_ctxt [in] Ptr to ulp context 366 * ifindex [in] ulp ifindex 367 * parif_type [in] the parif type of the given ifindex. 368 * parif [out] the parif of the given ifindex. 369 * 370 * Returns 0 on success or negative number on failure. 371 */ 372 int32_t 373 ulp_port_db_parif_get(struct bnxt_ulp_context *ulp_ctxt, 374 uint32_t ifindex, 375 uint32_t parif_type, 376 uint16_t *parif) 377 { 378 struct bnxt_ulp_port_db *port_db; 379 uint16_t phy_port_id, func_id; 380 381 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 382 if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) { 383 BNXT_DRV_DBG(ERR, "Invalid Arguments\n"); 384 return -EINVAL; 385 } 386 if (parif_type == BNXT_ULP_DRV_FUNC_PARIF) { 387 func_id = port_db->ulp_intf_list[ifindex].drv_func_id; 388 *parif = port_db->ulp_func_id_tbl[func_id].func_parif; 389 } else if (parif_type == BNXT_ULP_VF_FUNC_PARIF) { 390 func_id = port_db->ulp_intf_list[ifindex].vf_func_id; 391 *parif = port_db->ulp_func_id_tbl[func_id].func_parif; 392 } else { 393 func_id = port_db->ulp_intf_list[ifindex].drv_func_id; 394 phy_port_id = port_db->ulp_func_id_tbl[func_id].phy_port_id; 395 *parif = port_db->phy_port_list[phy_port_id].port_parif; 396 } 397 /* Parif needs to be reset to a free partition */ 398 *parif += BNXT_ULP_FREE_PARIF_BASE; 399 400 return 0; 401 } 402 403 /* 404 * Api to get the vnic id for a given ulp ifindex. 405 * 406 * ulp_ctxt [in] Ptr to ulp context 407 * ifindex [in] ulp ifindex 408 * vnic [out] the vnic of the given ifindex. 409 * 410 * Returns 0 on success or negative number on failure. 411 */ 412 int32_t 413 ulp_port_db_default_vnic_get(struct bnxt_ulp_context *ulp_ctxt, 414 uint32_t ifindex, 415 uint32_t vnic_type, 416 uint16_t *vnic) 417 { 418 struct bnxt_ulp_port_db *port_db; 419 uint16_t func_id; 420 421 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 422 if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) { 423 BNXT_DRV_DBG(ERR, "Invalid Arguments\n"); 424 return -EINVAL; 425 } 426 427 if (vnic_type == BNXT_ULP_DRV_FUNC_VNIC) { 428 func_id = port_db->ulp_intf_list[ifindex].drv_func_id; 429 *vnic = port_db->ulp_func_id_tbl[func_id].func_vnic; 430 } else { 431 func_id = port_db->ulp_intf_list[ifindex].vf_func_id; 432 *vnic = port_db->ulp_func_id_tbl[func_id].func_vnic; 433 } 434 435 return 0; 436 } 437 438 /* 439 * Api to get the vport id for a given ulp ifindex. 440 * 441 * ulp_ctxt [in] Ptr to ulp context 442 * ifindex [in] ulp ifindex 443 * vport [out] the port of the given ifindex. 444 * 445 * Returns 0 on success or negative number on failure. 446 */ 447 int32_t 448 ulp_port_db_vport_get(struct bnxt_ulp_context *ulp_ctxt, 449 uint32_t ifindex, uint16_t *vport) 450 { 451 struct bnxt_ulp_port_db *port_db; 452 uint16_t phy_port_id, func_id; 453 454 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 455 if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) { 456 BNXT_DRV_DBG(ERR, "Invalid Arguments\n"); 457 return -EINVAL; 458 } 459 460 func_id = port_db->ulp_intf_list[ifindex].drv_func_id; 461 phy_port_id = port_db->ulp_func_id_tbl[func_id].phy_port_id; 462 *vport = port_db->phy_port_list[phy_port_id].port_vport; 463 return 0; 464 } 465 466 /* 467 * Api to get the vport for a given physical port. 468 * 469 * ulp_ctxt [in] Ptr to ulp context 470 * phy_port [in] physical port index 471 * out_port [out] the port of the given physical index 472 * 473 * Returns 0 on success or negative number on failure. 474 */ 475 int32_t 476 ulp_port_db_phy_port_vport_get(struct bnxt_ulp_context *ulp_ctxt, 477 uint32_t phy_port, 478 uint16_t *out_port) 479 { 480 struct bnxt_ulp_port_db *port_db; 481 482 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 483 if (!port_db || phy_port >= port_db->phy_port_cnt) { 484 BNXT_DRV_DBG(ERR, "Invalid Arguments\n"); 485 return -EINVAL; 486 } 487 *out_port = port_db->phy_port_list[phy_port].port_vport; 488 return 0; 489 } 490 491 /* 492 * Api to get the svif for a given physical port. 493 * 494 * ulp_ctxt [in] Ptr to ulp context 495 * phy_port [in] physical port index 496 * svif [out] the svif of the given physical index 497 * 498 * Returns 0 on success or negative number on failure. 499 */ 500 int32_t 501 ulp_port_db_phy_port_svif_get(struct bnxt_ulp_context *ulp_ctxt, 502 uint32_t phy_port, 503 uint16_t *svif) 504 { 505 struct bnxt_ulp_port_db *port_db; 506 507 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 508 if (!port_db || phy_port >= port_db->phy_port_cnt) { 509 BNXT_DRV_DBG(ERR, "Invalid Arguments\n"); 510 return -EINVAL; 511 } 512 *svif = port_db->phy_port_list[phy_port].port_svif; 513 return 0; 514 } 515 516 /* 517 * Api to get the socket direct svif for a given device port. 518 * 519 * ulp_ctxt [in] Ptr to ulp context 520 * port_id [in] device port id 521 * svif [out] the socket direct svif of the given device index 522 * 523 * Returns 0 on success or negative number on failure. 524 */ 525 int32_t 526 ulp_port_db_dev_port_socket_direct_svif_get(struct bnxt_ulp_context *ulp_ctxt, 527 uint32_t port_id, 528 uint16_t *svif) 529 { 530 struct bnxt_ulp_port_db *port_db; 531 uint32_t ifindex; 532 uint16_t phy_port_id, func_id; 533 534 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 535 536 if (!port_db || port_id >= RTE_MAX_ETHPORTS) { 537 BNXT_DRV_DBG(ERR, "Invalid Arguments\n"); 538 return -EINVAL; 539 } 540 if (!port_db->dev_port_list[port_id]) 541 return -ENOENT; 542 543 /* Get physical port id */ 544 ifindex = port_db->dev_port_list[port_id]; 545 func_id = port_db->ulp_intf_list[ifindex].drv_func_id; 546 phy_port_id = port_db->ulp_func_id_tbl[func_id].phy_port_id; 547 548 /* Calculate physical port id for socket direct port */ 549 phy_port_id = phy_port_id ? 0 : 1; 550 if (phy_port_id >= port_db->phy_port_cnt) { 551 BNXT_DRV_DBG(ERR, "Invalid Arguments\n"); 552 return -EINVAL; 553 } 554 555 *svif = port_db->phy_port_list[phy_port_id].port_svif; 556 return 0; 557 } 558 559 /* 560 * Api to get the port type for a given ulp ifindex. 561 * 562 * ulp_ctxt [in] Ptr to ulp context 563 * ifindex [in] ulp ifindex 564 * 565 * Returns port type. 566 */ 567 enum bnxt_ulp_intf_type 568 ulp_port_db_port_type_get(struct bnxt_ulp_context *ulp_ctxt, 569 uint32_t ifindex) 570 { 571 struct bnxt_ulp_port_db *port_db; 572 573 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 574 if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) { 575 BNXT_DRV_DBG(ERR, "Invalid Arguments\n"); 576 return BNXT_ULP_INTF_TYPE_INVALID; 577 } 578 return port_db->ulp_intf_list[ifindex].type; 579 } 580 581 /* 582 * Api to get the ulp ifindex for a given function id. 583 * 584 * ulp_ctxt [in] Ptr to ulp context 585 * func_id [in].device func id 586 * ifindex [out] ulp ifindex 587 * 588 * Returns 0 on success or negative number on failure. 589 */ 590 int32_t 591 ulp_port_db_dev_func_id_to_ulp_index(struct bnxt_ulp_context *ulp_ctxt, 592 uint32_t func_id, uint32_t *ifindex) 593 { 594 struct bnxt_ulp_port_db *port_db; 595 596 *ifindex = 0; 597 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 598 if (!port_db || func_id >= BNXT_PORT_DB_MAX_FUNC) { 599 BNXT_DRV_DBG(ERR, "Invalid Arguments\n"); 600 return -EINVAL; 601 } 602 if (!port_db->ulp_func_id_tbl[func_id].func_valid) 603 return -ENOENT; 604 605 *ifindex = port_db->ulp_func_id_tbl[func_id].ifindex; 606 return 0; 607 } 608 609 /* 610 * Api to get the function id for a given port id. 611 * 612 * ulp_ctxt [in] Ptr to ulp context 613 * port_id [in] dpdk port id 614 * func_id [out] the function id of the given ifindex. 615 * 616 * Returns 0 on success or negative number on failure. 617 */ 618 int32_t 619 ulp_port_db_port_func_id_get(struct bnxt_ulp_context *ulp_ctxt, 620 uint16_t port_id, uint16_t *func_id) 621 { 622 struct bnxt_ulp_port_db *port_db; 623 uint32_t ifindex; 624 625 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 626 if (!port_db || port_id >= RTE_MAX_ETHPORTS) { 627 BNXT_DRV_DBG(ERR, "Invalid Arguments\n"); 628 return -EINVAL; 629 } 630 ifindex = port_db->dev_port_list[port_id]; 631 if (!ifindex) 632 return -ENOENT; 633 634 switch (port_db->ulp_intf_list[ifindex].type) { 635 case BNXT_ULP_INTF_TYPE_TRUSTED_VF: 636 case BNXT_ULP_INTF_TYPE_PF: 637 *func_id = port_db->ulp_intf_list[ifindex].drv_func_id; 638 break; 639 case BNXT_ULP_INTF_TYPE_VF: 640 case BNXT_ULP_INTF_TYPE_VF_REP: 641 *func_id = port_db->ulp_intf_list[ifindex].vf_func_id; 642 break; 643 default: 644 *func_id = 0; 645 break; 646 } 647 return 0; 648 } 649 650 /* internal function to get the */ 651 static struct ulp_func_if_info* 652 ulp_port_db_func_if_info_get(struct bnxt_ulp_context *ulp_ctxt, 653 uint32_t port_id) 654 { 655 struct bnxt_ulp_port_db *port_db; 656 uint16_t func_id; 657 658 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 659 if (ulp_port_db_port_func_id_get(ulp_ctxt, port_id, &func_id)) { 660 BNXT_DRV_DBG(ERR, "Invalid port_id %x\n", port_id); 661 return NULL; 662 } 663 664 if (!port_db->ulp_func_id_tbl[func_id].func_valid) { 665 BNXT_DRV_DBG(ERR, "Invalid func_id %x\n", func_id); 666 return NULL; 667 } 668 return &port_db->ulp_func_id_tbl[func_id]; 669 } 670 671 /* 672 * Api to get the parent mac address for a given port id. 673 * 674 * ulp_ctxt [in] Ptr to ulp context 675 * port_id [in] device port id 676 * mac_addr [out] mac address 677 * 678 * Returns 0 on success or negative number on failure. 679 */ 680 int32_t 681 ulp_port_db_parent_mac_addr_get(struct bnxt_ulp_context *ulp_ctxt, 682 uint32_t port_id, uint8_t **mac_addr) 683 { 684 struct ulp_func_if_info *info; 685 686 info = ulp_port_db_func_if_info_get(ulp_ctxt, port_id); 687 if (info) { 688 *mac_addr = info->func_parent_mac; 689 return 0; 690 } 691 return -EINVAL; 692 } 693 694 /* 695 * Api to get the mac address for a given port id. 696 * 697 * ulp_ctxt [in] Ptr to ulp context 698 * port_id [in] device port id 699 * mac_addr [out] mac address 700 * 701 * Returns 0 on success or negative number on failure. 702 */ 703 int32_t 704 ulp_port_db_drv_mac_addr_get(struct bnxt_ulp_context *ulp_ctxt, 705 uint32_t port_id, uint8_t **mac_addr) 706 { 707 struct ulp_func_if_info *info; 708 709 info = ulp_port_db_func_if_info_get(ulp_ctxt, port_id); 710 if (info) { 711 *mac_addr = info->func_mac; 712 return 0; 713 } 714 return -EINVAL; 715 } 716 717 /* 718 * Api to get the parent vnic for a given port id. 719 * 720 * ulp_ctxt [in] Ptr to ulp context 721 * port_id [in] device port id 722 * vnic [out] parent vnic 723 * 724 * Returns 0 on success or negative number on failure. 725 */ 726 int32_t 727 ulp_port_db_parent_vnic_get(struct bnxt_ulp_context *ulp_ctxt, 728 uint32_t port_id, uint8_t **vnic) 729 { 730 struct ulp_func_if_info *info; 731 732 info = ulp_port_db_func_if_info_get(ulp_ctxt, port_id); 733 if (info) { 734 *vnic = (uint8_t *)&info->func_parent_vnic; 735 return 0; 736 } 737 return -EINVAL; 738 } 739 740 /* 741 * Api to get the phy port for a given port id. 742 * 743 * ulp_ctxt [in] Ptr to ulp context 744 * port_id [in] device port id 745 * phy_port [out] phy_port of the dpdk port_id 746 * 747 * Returns 0 on success or negative number on failure. 748 */ 749 int32_t 750 ulp_port_db_phy_port_get(struct bnxt_ulp_context *ulp_ctxt, 751 uint32_t port_id, uint16_t *phy_port) 752 { 753 struct ulp_func_if_info *info; 754 755 info = ulp_port_db_func_if_info_get(ulp_ctxt, port_id); 756 if (info) { 757 *phy_port = info->phy_port_id; 758 return 0; 759 } 760 return -EINVAL; 761 } 762 763 /* 764 * Api to get the port type for a given port id. 765 * 766 * ulp_ctxt [in] Ptr to ulp context 767 * port_id [in] device port id 768 * type [out] type if pf or not 769 * 770 * Returns 0 on success or negative number on failure. 771 */ 772 int32_t 773 ulp_port_db_port_is_pf_get(struct bnxt_ulp_context *ulp_ctxt, 774 uint32_t port_id, uint8_t **type) 775 { 776 struct ulp_func_if_info *info; 777 struct bnxt_ulp_port_db *port_db; 778 uint16_t pid; 779 780 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 781 info = ulp_port_db_func_if_info_get(ulp_ctxt, port_id); 782 if (info) { 783 pid = info->ifindex; 784 *type = &port_db->ulp_intf_list[pid].type_is_pf; 785 return 0; 786 } 787 return -EINVAL; 788 } 789 790 /* 791 * Api to get the meta data for a given port id. 792 * 793 * ulp_ctxt [in] Ptr to ulp context 794 * port_id [in] dpdk port id 795 * meta data [out] the meta data of the given port 796 * 797 * Returns 0 on success or negative number on failure. 798 */ 799 int32_t 800 ulp_port_db_port_meta_data_get(struct bnxt_ulp_context *ulp_ctxt, 801 uint16_t port_id, uint8_t **meta_data) 802 { 803 struct ulp_func_if_info *info; 804 805 info = ulp_port_db_func_if_info_get(ulp_ctxt, port_id); 806 if (info) { 807 *meta_data = (uint8_t *)&info->vf_meta_data; 808 return 0; 809 } 810 return -EINVAL; 811 } 812 813 /* Api to get the function id for a given port id 814 * 815 * ulp_ctxt [in] Ptr to ulp context 816 * port_id [in] dpdk port id 817 * fid_data [out] the function id of the given port 818 * 819 * Returns 0 on success or negative number on failure. 820 */ 821 int32_t 822 ulp_port_db_port_vf_fid_get(struct bnxt_ulp_context *ulp_ctxt, 823 uint16_t port_id, uint8_t **fid_data) 824 { 825 struct bnxt_ulp_port_db *port_db; 826 uint32_t ifindex; 827 828 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 829 if (!port_db || port_id >= RTE_MAX_ETHPORTS) { 830 BNXT_DRV_DBG(ERR, "Invalid Arguments\n"); 831 return -EINVAL; 832 } 833 ifindex = port_db->dev_port_list[port_id]; 834 if (!ifindex) 835 return -ENOENT; 836 837 if (port_db->ulp_intf_list[ifindex].type != BNXT_ULP_INTF_TYPE_VF && 838 port_db->ulp_intf_list[ifindex].type != BNXT_ULP_INTF_TYPE_VF_REP) 839 return -EINVAL; 840 841 *fid_data = (uint8_t *)&port_db->ulp_intf_list[ifindex].vf_func_id; 842 return 0; 843 } 844 845 int32_t 846 ulp_port_db_port_table_scope_get(struct bnxt_ulp_context *ulp_ctxt, 847 uint16_t port_id, uint8_t **tsid) 848 { 849 struct ulp_func_if_info *info; 850 851 info = ulp_port_db_func_if_info_get(ulp_ctxt, port_id); 852 if (info) { 853 *tsid = &info->table_scope; 854 return 0; 855 } 856 return -EINVAL; 857 } 858 859 /* Api to get the PF Mirror Id for a given port id 860 * 861 * ulp_ctxt [in] Ptr to ulp context 862 * port_id [in] dpdk port id 863 * mirror id [in] mirror id 864 * 865 * Returns 0 on success or negative number on failure. 866 */ 867 int32_t 868 ulp_port_db_port_table_mirror_set(struct bnxt_ulp_context *ulp_ctxt, 869 uint16_t port_id, uint32_t mirror_id) 870 { 871 struct ulp_phy_port_info *port_data; 872 struct bnxt_ulp_port_db *port_db; 873 struct ulp_interface_info *intf; 874 struct ulp_func_if_info *func; 875 uint32_t ifindex; 876 877 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt); 878 if (!port_db) { 879 BNXT_DRV_DBG(ERR, "Invalid Arguments\n"); 880 return -EINVAL; 881 } 882 883 if (ulp_port_db_dev_port_to_ulp_index(ulp_ctxt, port_id, &ifindex)) { 884 BNXT_DRV_DBG(ERR, "Invalid port id %u\n", port_id); 885 return -EINVAL; 886 } 887 888 intf = &port_db->ulp_intf_list[ifindex]; 889 func = &port_db->ulp_func_id_tbl[intf->drv_func_id]; 890 if (!func->func_valid) { 891 BNXT_DRV_DBG(ERR, "Invalid func for port id %u\n", port_id); 892 return -EINVAL; 893 } 894 895 port_data = &port_db->phy_port_list[func->phy_port_id]; 896 if (!port_data->port_valid) { 897 BNXT_DRV_DBG(ERR, "Invalid phy port\n"); 898 return -EINVAL; 899 } 900 901 port_data->port_mirror_id = mirror_id; 902 return 0; 903 } 904