1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2014-2021 Broadcom
6 #include <rte_malloc.h>
9 #include "bnxt_tf_common.h"
10 #include "ulp_port_db.h"
13 ulp_port_db_allocate_ifindex(struct bnxt_ulp_port_db *port_db)
17 while (idx < port_db->ulp_intf_list_size &&
18 port_db->ulp_intf_list[idx].type != BNXT_ULP_INTF_TYPE_INVALID)
21 if (idx >= port_db->ulp_intf_list_size) {
22 BNXT_TF_DBG(ERR, "Port DB interface list is full\n");
29 * Initialize the port database. Memory is allocated in this
30 * call and assigned to the port database.
32 * ulp_ctxt [in] Ptr to ulp context
34 * Returns 0 on success or negative number on failure.
36 int32_t ulp_port_db_init(struct bnxt_ulp_context *ulp_ctxt, uint8_t port_cnt)
38 struct bnxt_ulp_port_db *port_db;
40 port_db = rte_zmalloc("bnxt_ulp_port_db",
41 sizeof(struct bnxt_ulp_port_db), 0);
44 "Failed to allocate memory for port db\n");
48 /* Attach the port database to the ulp context. */
49 bnxt_ulp_cntxt_ptr2_port_db_set(ulp_ctxt, port_db);
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),
58 if (!port_db->ulp_intf_list) {
60 "Failed to allocate mem for port interface list\n");
64 /* Allocate the phy port list */
65 port_db->phy_port_list = rte_zmalloc("bnxt_ulp_phy_port_list",
67 sizeof(struct ulp_phy_port_info),
69 if (!port_db->phy_port_list) {
71 "Failed to allocate mem for phy port list\n");
74 port_db->phy_port_cnt = port_cnt;
78 ulp_port_db_deinit(ulp_ctxt);
83 * Deinitialize the port database. Memory is deallocated in
86 * ulp_ctxt [in] Ptr to ulp context
88 * Returns 0 on success.
90 int32_t ulp_port_db_deinit(struct bnxt_ulp_context *ulp_ctxt)
92 struct bnxt_ulp_port_db *port_db;
94 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
96 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
100 /* Detach the flow database from the ulp context. */
101 bnxt_ulp_cntxt_ptr2_port_db_set(ulp_ctxt, NULL);
103 /* Free up all the memory. */
104 rte_free(port_db->phy_port_list);
105 rte_free(port_db->ulp_intf_list);
111 * Update the port database.This api is called when the port
112 * details are available during the startup.
114 * ulp_ctxt [in] Ptr to ulp context
115 * bp [in]. ptr to the device function.
117 * Returns 0 on success or negative number on failure.
119 int32_t ulp_port_db_dev_port_intf_update(struct bnxt_ulp_context *ulp_ctxt,
120 struct rte_eth_dev *eth_dev)
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;
130 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
132 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
136 rc = ulp_port_db_dev_port_to_ulp_index(ulp_ctxt, port_id, &ifindex);
138 /* port not found, allocate one */
139 ifindex = ulp_port_db_allocate_ifindex(port_db);
142 port_db->dev_port_list[port_id] = ifindex;
143 } else if (rc == -EINVAL) {
147 /* update the interface details */
148 intf = &port_db->ulp_intf_list[ifindex];
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);
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);
160 bnxt_get_parif(port_id, BNXT_ULP_INTF_TYPE_INVALID);
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;
168 if (intf->type == BNXT_ULP_INTF_TYPE_VF_REP) {
170 bnxt_get_fw_func_id(port_id, BNXT_ULP_INTF_TYPE_VF_REP);
172 func = &port_db->ulp_func_id_tbl[intf->vf_func_id];
174 bnxt_get_svif(port_id, true, BNXT_ULP_INTF_TYPE_VF_REP);
176 bnxt_get_phy_port_id(port_id);
178 bnxt_get_parif(port_id, BNXT_ULP_INTF_TYPE_INVALID);
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;
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;
201 * Api to get the ulp ifindex for a given device port.
203 * ulp_ctxt [in] Ptr to ulp context
204 * port_id [in].device port id
205 * ifindex [out] ulp ifindex
207 * Returns 0 on success or negative number on failure.
210 ulp_port_db_dev_port_to_ulp_index(struct bnxt_ulp_context *ulp_ctxt,
214 struct bnxt_ulp_port_db *port_db;
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");
222 if (!port_db->dev_port_list[port_id])
225 *ifindex = port_db->dev_port_list[port_id];
230 * Api to get the function id for a given ulp ifindex.
232 * ulp_ctxt [in] Ptr to ulp context
233 * ifindex [in] ulp ifindex
234 * func_id [out] the function id of the given ifindex.
236 * Returns 0 on success or negative number on failure.
239 ulp_port_db_function_id_get(struct bnxt_ulp_context *ulp_ctxt,
244 struct bnxt_ulp_port_db *port_db;
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");
252 if (fid_type == BNXT_ULP_DRV_FUNC_FID)
253 *func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
255 *func_id = port_db->ulp_intf_list[ifindex].vf_func_id;
261 * Api to get the svif for a given ulp ifindex.
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.
268 * Returns 0 on success or negative number on failure.
271 ulp_port_db_svif_get(struct bnxt_ulp_context *ulp_ctxt,
276 struct bnxt_ulp_port_db *port_db;
277 uint16_t phy_port_id, func_id;
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");
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;
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;
301 * Api to get the spif for a given ulp ifindex.
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.
308 * Returns 0 on success or negative number on failure.
311 ulp_port_db_spif_get(struct bnxt_ulp_context *ulp_ctxt,
316 struct bnxt_ulp_port_db *port_db;
317 uint16_t phy_port_id, func_id;
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");
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;
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;
341 * Api to get the parif for a given ulp ifindex.
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.
348 * Returns 0 on success or negative number on failure.
351 ulp_port_db_parif_get(struct bnxt_ulp_context *ulp_ctxt,
356 struct bnxt_ulp_port_db *port_db;
357 uint16_t phy_port_id, func_id;
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");
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;
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;
375 /* Parif needs to be reset to a free partition */
376 *parif += BNXT_ULP_FREE_PARIF_BASE;
382 * Api to get the vnic id for a given ulp ifindex.
384 * ulp_ctxt [in] Ptr to ulp context
385 * ifindex [in] ulp ifindex
386 * vnic [out] the vnic of the given ifindex.
388 * Returns 0 on success or negative number on failure.
391 ulp_port_db_default_vnic_get(struct bnxt_ulp_context *ulp_ctxt,
396 struct bnxt_ulp_port_db *port_db;
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");
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;
409 func_id = port_db->ulp_intf_list[ifindex].vf_func_id;
410 *vnic = port_db->ulp_func_id_tbl[func_id].func_vnic;
417 * Api to get the vport id for a given ulp ifindex.
419 * ulp_ctxt [in] Ptr to ulp context
420 * ifindex [in] ulp ifindex
421 * vport [out] the port of the given ifindex.
423 * Returns 0 on success or negative number on failure.
426 ulp_port_db_vport_get(struct bnxt_ulp_context *ulp_ctxt,
427 uint32_t ifindex, uint16_t *vport)
429 struct bnxt_ulp_port_db *port_db;
430 uint16_t phy_port_id, func_id;
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");
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;
445 * Api to get the vport for a given physical port.
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
451 * Returns 0 on success or negative number on failure.
454 ulp_port_db_phy_port_vport_get(struct bnxt_ulp_context *ulp_ctxt,
458 struct bnxt_ulp_port_db *port_db;
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");
465 *out_port = port_db->phy_port_list[phy_port].port_vport;
470 * Api to get the svif for a given physical port.
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
476 * Returns 0 on success or negative number on failure.
479 ulp_port_db_phy_port_svif_get(struct bnxt_ulp_context *ulp_ctxt,
483 struct bnxt_ulp_port_db *port_db;
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");
490 *svif = port_db->phy_port_list[phy_port].port_svif;
495 * Api to get the port type for a given ulp ifindex.
497 * ulp_ctxt [in] Ptr to ulp context
498 * ifindex [in] ulp ifindex
502 enum bnxt_ulp_intf_type
503 ulp_port_db_port_type_get(struct bnxt_ulp_context *ulp_ctxt,
506 struct bnxt_ulp_port_db *port_db;
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;
513 return port_db->ulp_intf_list[ifindex].type;
517 * Api to get the ulp ifindex for a given function id.
519 * ulp_ctxt [in] Ptr to ulp context
520 * func_id [in].device func id
521 * ifindex [out] ulp ifindex
523 * Returns 0 on success or negative number on failure.
526 ulp_port_db_dev_func_id_to_ulp_index(struct bnxt_ulp_context *ulp_ctxt,
527 uint32_t func_id, uint32_t *ifindex)
529 struct bnxt_ulp_port_db *port_db;
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");
537 if (!port_db->ulp_func_id_tbl[func_id].func_valid)
540 *ifindex = port_db->ulp_func_id_tbl[func_id].ifindex;
545 * Api to get the function id for a given port id.
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.
551 * Returns 0 on success or negative number on failure.
554 ulp_port_db_port_func_id_get(struct bnxt_ulp_context *ulp_ctxt,
555 uint16_t port_id, uint16_t *func_id)
557 struct bnxt_ulp_port_db *port_db;
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");
565 ifindex = port_db->dev_port_list[port_id];
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;
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;