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