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"
14 ulp_port_db_allocate_ifindex(struct bnxt_ulp_port_db *port_db)
18 while (idx < port_db->ulp_intf_list_size &&
19 port_db->ulp_intf_list[idx].type != BNXT_ULP_INTF_TYPE_INVALID)
22 if (idx >= port_db->ulp_intf_list_size) {
23 BNXT_TF_DBG(ERR, "Port DB interface list is full\n");
30 * Initialize the port database. Memory is allocated in this
31 * call and assigned to the port database.
33 * ulp_ctxt [in] Ptr to ulp context
35 * Returns 0 on success or negative number on failure.
37 int32_t ulp_port_db_init(struct bnxt_ulp_context *ulp_ctxt, uint8_t port_cnt)
39 struct bnxt_ulp_port_db *port_db;
41 port_db = rte_zmalloc("bnxt_ulp_port_db",
42 sizeof(struct bnxt_ulp_port_db), 0);
45 "Failed to allocate memory for port db\n");
49 /* Attach the port database to the ulp context. */
50 bnxt_ulp_cntxt_ptr2_port_db_set(ulp_ctxt, port_db);
52 /* index 0 is not being used hence add 1 to size */
53 port_db->ulp_intf_list_size = BNXT_PORT_DB_MAX_INTF_LIST + 1;
54 /* Allocate the port tables */
55 port_db->ulp_intf_list = rte_zmalloc("bnxt_ulp_port_db_intf_list",
56 port_db->ulp_intf_list_size *
57 sizeof(struct ulp_interface_info),
59 if (!port_db->ulp_intf_list) {
61 "Failed to allocate mem for port interface list\n");
65 /* Allocate the phy port list */
66 port_db->phy_port_list = rte_zmalloc("bnxt_ulp_phy_port_list",
68 sizeof(struct ulp_phy_port_info),
70 if (!port_db->phy_port_list) {
72 "Failed to allocate mem for phy port list\n");
75 port_db->phy_port_cnt = port_cnt;
79 ulp_port_db_deinit(ulp_ctxt);
84 * Deinitialize the port database. Memory is deallocated in
87 * ulp_ctxt [in] Ptr to ulp context
89 * Returns 0 on success.
91 int32_t ulp_port_db_deinit(struct bnxt_ulp_context *ulp_ctxt)
93 struct bnxt_ulp_port_db *port_db;
95 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
97 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
101 /* Detach the flow database from the ulp context. */
102 bnxt_ulp_cntxt_ptr2_port_db_set(ulp_ctxt, NULL);
104 /* Free up all the memory. */
105 rte_free(port_db->phy_port_list);
106 rte_free(port_db->ulp_intf_list);
112 * Update the port database.This api is called when the port
113 * details are available during the startup.
115 * ulp_ctxt [in] Ptr to ulp context
116 * bp [in]. ptr to the device function.
118 * Returns 0 on success or negative number on failure.
120 int32_t ulp_port_db_dev_port_intf_update(struct bnxt_ulp_context *ulp_ctxt,
121 struct rte_eth_dev *eth_dev)
123 uint32_t port_id = eth_dev->data->port_id;
124 struct ulp_phy_port_info *port_data;
125 struct bnxt_ulp_port_db *port_db;
126 struct ulp_interface_info *intf;
127 struct ulp_func_if_info *func;
131 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
133 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
137 rc = ulp_port_db_dev_port_to_ulp_index(ulp_ctxt, port_id, &ifindex);
139 /* port not found, allocate one */
140 ifindex = ulp_port_db_allocate_ifindex(port_db);
143 port_db->dev_port_list[port_id] = ifindex;
144 } else if (rc == -EINVAL) {
148 /* update the interface details */
149 intf = &port_db->ulp_intf_list[ifindex];
151 intf->type = bnxt_get_interface_type(port_id);
152 intf->drv_func_id = bnxt_get_fw_func_id(port_id,
153 BNXT_ULP_INTF_TYPE_INVALID);
155 func = &port_db->ulp_func_id_tbl[intf->drv_func_id];
156 if (!func->func_valid) {
157 func->func_svif = bnxt_get_svif(port_id, true,
158 BNXT_ULP_INTF_TYPE_INVALID);
159 func->func_spif = bnxt_get_phy_port_id(port_id);
161 bnxt_get_parif(port_id, BNXT_ULP_INTF_TYPE_INVALID);
163 bnxt_get_vnic_id(port_id, BNXT_ULP_INTF_TYPE_INVALID);
164 func->phy_port_id = bnxt_get_phy_port_id(port_id);
165 func->func_valid = true;
166 func->ifindex = ifindex;
169 if (intf->type == BNXT_ULP_INTF_TYPE_VF_REP) {
171 bnxt_get_fw_func_id(port_id, BNXT_ULP_INTF_TYPE_VF_REP);
173 func = &port_db->ulp_func_id_tbl[intf->vf_func_id];
175 bnxt_get_svif(port_id, true, BNXT_ULP_INTF_TYPE_VF_REP);
177 bnxt_get_phy_port_id(port_id);
179 bnxt_get_parif(port_id, BNXT_ULP_INTF_TYPE_INVALID);
181 bnxt_get_vnic_id(port_id, BNXT_ULP_INTF_TYPE_VF_REP);
182 func->phy_port_id = bnxt_get_phy_port_id(port_id);
183 func->ifindex = ifindex;
186 /* When there is no match, the default action is to send the packet to
187 * the kernel. And to send it to the kernel, we need the PF's vnic id.
189 func->func_parent_vnic = bnxt_get_parent_vnic_id(port_id, intf->type);
190 func->func_parent_vnic = tfp_cpu_to_be_16(func->func_parent_vnic);
191 bnxt_get_iface_mac(port_id, intf->type, func->func_mac,
192 func->func_parent_mac);
194 port_data = &port_db->phy_port_list[func->phy_port_id];
195 if (!port_data->port_valid) {
196 port_data->port_svif =
197 bnxt_get_svif(port_id, false, BNXT_ULP_INTF_TYPE_INVALID);
198 port_data->port_spif = bnxt_get_phy_port_id(port_id);
199 port_data->port_parif =
200 bnxt_get_parif(port_id, BNXT_ULP_INTF_TYPE_INVALID);
201 port_data->port_vport = bnxt_get_vport(port_id);
202 port_data->port_valid = true;
208 * Api to get the ulp ifindex for a given device port.
210 * ulp_ctxt [in] Ptr to ulp context
211 * port_id [in].device port id
212 * ifindex [out] ulp ifindex
214 * Returns 0 on success or negative number on failure.
217 ulp_port_db_dev_port_to_ulp_index(struct bnxt_ulp_context *ulp_ctxt,
221 struct bnxt_ulp_port_db *port_db;
224 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
225 if (!port_db || port_id >= RTE_MAX_ETHPORTS) {
226 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
229 if (!port_db->dev_port_list[port_id])
232 *ifindex = port_db->dev_port_list[port_id];
237 * Api to get the function id for a given ulp ifindex.
239 * ulp_ctxt [in] Ptr to ulp context
240 * ifindex [in] ulp ifindex
241 * func_id [out] the function id of the given ifindex.
243 * Returns 0 on success or negative number on failure.
246 ulp_port_db_function_id_get(struct bnxt_ulp_context *ulp_ctxt,
251 struct bnxt_ulp_port_db *port_db;
253 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
254 if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
255 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
259 if (fid_type == BNXT_ULP_DRV_FUNC_FID)
260 *func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
262 *func_id = port_db->ulp_intf_list[ifindex].vf_func_id;
268 * Api to get the svif for a given ulp ifindex.
270 * ulp_ctxt [in] Ptr to ulp context
271 * ifindex [in] ulp ifindex
272 * svif_type [in] the svif type of the given ifindex.
273 * svif [out] the svif of the given ifindex.
275 * Returns 0 on success or negative number on failure.
278 ulp_port_db_svif_get(struct bnxt_ulp_context *ulp_ctxt,
283 struct bnxt_ulp_port_db *port_db;
284 uint16_t phy_port_id, func_id;
286 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
287 if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
288 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
292 if (svif_type == BNXT_ULP_DRV_FUNC_SVIF) {
293 func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
294 *svif = port_db->ulp_func_id_tbl[func_id].func_svif;
295 } else if (svif_type == BNXT_ULP_VF_FUNC_SVIF) {
296 func_id = port_db->ulp_intf_list[ifindex].vf_func_id;
297 *svif = port_db->ulp_func_id_tbl[func_id].func_svif;
299 func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
300 phy_port_id = port_db->ulp_func_id_tbl[func_id].phy_port_id;
301 *svif = port_db->phy_port_list[phy_port_id].port_svif;
308 * Api to get the spif for a given ulp ifindex.
310 * ulp_ctxt [in] Ptr to ulp context
311 * ifindex [in] ulp ifindex
312 * spif_type [in] the spif type of the given ifindex.
313 * spif [out] the spif of the given ifindex.
315 * Returns 0 on success or negative number on failure.
318 ulp_port_db_spif_get(struct bnxt_ulp_context *ulp_ctxt,
323 struct bnxt_ulp_port_db *port_db;
324 uint16_t phy_port_id, func_id;
326 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
327 if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
328 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
332 if (spif_type == BNXT_ULP_DRV_FUNC_SPIF) {
333 func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
334 *spif = port_db->ulp_func_id_tbl[func_id].func_spif;
335 } else if (spif_type == BNXT_ULP_VF_FUNC_SPIF) {
336 func_id = port_db->ulp_intf_list[ifindex].vf_func_id;
337 *spif = port_db->ulp_func_id_tbl[func_id].func_spif;
339 func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
340 phy_port_id = port_db->ulp_func_id_tbl[func_id].phy_port_id;
341 *spif = port_db->phy_port_list[phy_port_id].port_spif;
348 * Api to get the parif for a given ulp ifindex.
350 * ulp_ctxt [in] Ptr to ulp context
351 * ifindex [in] ulp ifindex
352 * parif_type [in] the parif type of the given ifindex.
353 * parif [out] the parif of the given ifindex.
355 * Returns 0 on success or negative number on failure.
358 ulp_port_db_parif_get(struct bnxt_ulp_context *ulp_ctxt,
363 struct bnxt_ulp_port_db *port_db;
364 uint16_t phy_port_id, func_id;
366 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
367 if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
368 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
371 if (parif_type == BNXT_ULP_DRV_FUNC_PARIF) {
372 func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
373 *parif = port_db->ulp_func_id_tbl[func_id].func_parif;
374 } else if (parif_type == BNXT_ULP_VF_FUNC_PARIF) {
375 func_id = port_db->ulp_intf_list[ifindex].vf_func_id;
376 *parif = port_db->ulp_func_id_tbl[func_id].func_parif;
378 func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
379 phy_port_id = port_db->ulp_func_id_tbl[func_id].phy_port_id;
380 *parif = port_db->phy_port_list[phy_port_id].port_parif;
382 /* Parif needs to be reset to a free partition */
383 *parif += BNXT_ULP_FREE_PARIF_BASE;
389 * Api to get the vnic id for a given ulp ifindex.
391 * ulp_ctxt [in] Ptr to ulp context
392 * ifindex [in] ulp ifindex
393 * vnic [out] the vnic of the given ifindex.
395 * Returns 0 on success or negative number on failure.
398 ulp_port_db_default_vnic_get(struct bnxt_ulp_context *ulp_ctxt,
403 struct bnxt_ulp_port_db *port_db;
406 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
407 if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
408 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
412 if (vnic_type == BNXT_ULP_DRV_FUNC_VNIC) {
413 func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
414 *vnic = port_db->ulp_func_id_tbl[func_id].func_vnic;
416 func_id = port_db->ulp_intf_list[ifindex].vf_func_id;
417 *vnic = port_db->ulp_func_id_tbl[func_id].func_vnic;
424 * Api to get the vport id for a given ulp ifindex.
426 * ulp_ctxt [in] Ptr to ulp context
427 * ifindex [in] ulp ifindex
428 * vport [out] the port of the given ifindex.
430 * Returns 0 on success or negative number on failure.
433 ulp_port_db_vport_get(struct bnxt_ulp_context *ulp_ctxt,
434 uint32_t ifindex, uint16_t *vport)
436 struct bnxt_ulp_port_db *port_db;
437 uint16_t phy_port_id, func_id;
439 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
440 if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
441 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
445 func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
446 phy_port_id = port_db->ulp_func_id_tbl[func_id].phy_port_id;
447 *vport = port_db->phy_port_list[phy_port_id].port_vport;
452 * Api to get the vport for a given physical port.
454 * ulp_ctxt [in] Ptr to ulp context
455 * phy_port [in] physical port index
456 * out_port [out] the port of the given physical index
458 * Returns 0 on success or negative number on failure.
461 ulp_port_db_phy_port_vport_get(struct bnxt_ulp_context *ulp_ctxt,
465 struct bnxt_ulp_port_db *port_db;
467 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
468 if (!port_db || phy_port >= port_db->phy_port_cnt) {
469 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
472 *out_port = port_db->phy_port_list[phy_port].port_vport;
477 * Api to get the svif for a given physical port.
479 * ulp_ctxt [in] Ptr to ulp context
480 * phy_port [in] physical port index
481 * svif [out] the svif of the given physical index
483 * Returns 0 on success or negative number on failure.
486 ulp_port_db_phy_port_svif_get(struct bnxt_ulp_context *ulp_ctxt,
490 struct bnxt_ulp_port_db *port_db;
492 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
493 if (!port_db || phy_port >= port_db->phy_port_cnt) {
494 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
497 *svif = port_db->phy_port_list[phy_port].port_svif;
502 * Api to get the port type for a given ulp ifindex.
504 * ulp_ctxt [in] Ptr to ulp context
505 * ifindex [in] ulp ifindex
509 enum bnxt_ulp_intf_type
510 ulp_port_db_port_type_get(struct bnxt_ulp_context *ulp_ctxt,
513 struct bnxt_ulp_port_db *port_db;
515 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
516 if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
517 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
518 return BNXT_ULP_INTF_TYPE_INVALID;
520 return port_db->ulp_intf_list[ifindex].type;
524 * Api to get the ulp ifindex for a given function id.
526 * ulp_ctxt [in] Ptr to ulp context
527 * func_id [in].device func id
528 * ifindex [out] ulp ifindex
530 * Returns 0 on success or negative number on failure.
533 ulp_port_db_dev_func_id_to_ulp_index(struct bnxt_ulp_context *ulp_ctxt,
534 uint32_t func_id, uint32_t *ifindex)
536 struct bnxt_ulp_port_db *port_db;
539 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
540 if (!port_db || func_id >= BNXT_PORT_DB_MAX_FUNC) {
541 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
544 if (!port_db->ulp_func_id_tbl[func_id].func_valid)
547 *ifindex = port_db->ulp_func_id_tbl[func_id].ifindex;
552 * Api to get the function id for a given port id.
554 * ulp_ctxt [in] Ptr to ulp context
555 * port_id [in] dpdk port id
556 * func_id [out] the function id of the given ifindex.
558 * Returns 0 on success or negative number on failure.
561 ulp_port_db_port_func_id_get(struct bnxt_ulp_context *ulp_ctxt,
562 uint16_t port_id, uint16_t *func_id)
564 struct bnxt_ulp_port_db *port_db;
567 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
568 if (!port_db || port_id >= RTE_MAX_ETHPORTS) {
569 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
572 ifindex = port_db->dev_port_list[port_id];
576 switch (port_db->ulp_intf_list[ifindex].type) {
577 case BNXT_ULP_INTF_TYPE_TRUSTED_VF:
578 case BNXT_ULP_INTF_TYPE_PF:
579 *func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
581 case BNXT_ULP_INTF_TYPE_VF:
582 case BNXT_ULP_INTF_TYPE_VF_REP:
583 *func_id = port_db->ulp_intf_list[ifindex].vf_func_id;
592 /* internal function to get the */
593 static struct ulp_func_if_info*
594 ulp_port_db_func_if_info_get(struct bnxt_ulp_context *ulp_ctxt,
597 struct bnxt_ulp_port_db *port_db;
600 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
601 if (ulp_port_db_port_func_id_get(ulp_ctxt, port_id, &func_id)) {
602 BNXT_TF_DBG(ERR, "Invalid port_id %x\n", port_id);
606 if (!port_db->ulp_func_id_tbl[func_id].func_valid) {
607 BNXT_TF_DBG(ERR, "Invalid func_id %x\n", func_id);
610 return &port_db->ulp_func_id_tbl[func_id];
614 * Api to get the parent mac address for a given port id.
616 * ulp_ctxt [in] Ptr to ulp context
617 * port_id [in] device port id
618 * mac_addr [out] mac address
620 * Returns 0 on success or negative number on failure.
623 ulp_port_db_parent_mac_addr_get(struct bnxt_ulp_context *ulp_ctxt,
624 uint32_t port_id, uint8_t **mac_addr)
626 struct ulp_func_if_info *info;
628 info = ulp_port_db_func_if_info_get(ulp_ctxt, port_id);
630 *mac_addr = info->func_parent_mac;
637 * Api to get the mac address for a given port id.
639 * ulp_ctxt [in] Ptr to ulp context
640 * port_id [in] device port id
641 * mac_addr [out] mac address
643 * Returns 0 on success or negative number on failure.
646 ulp_port_db_drv_mac_addr_get(struct bnxt_ulp_context *ulp_ctxt,
647 uint32_t port_id, uint8_t **mac_addr)
649 struct ulp_func_if_info *info;
651 info = ulp_port_db_func_if_info_get(ulp_ctxt, port_id);
653 *mac_addr = info->func_mac;
660 * Api to get the parent vnic for a given port id.
662 * ulp_ctxt [in] Ptr to ulp context
663 * port_id [in] device port id
664 * vnic [out] parent vnic
666 * Returns 0 on success or negative number on failure.
669 ulp_port_db_parent_vnic_get(struct bnxt_ulp_context *ulp_ctxt,
670 uint32_t port_id, uint8_t **vnic)
672 struct ulp_func_if_info *info;
674 info = ulp_port_db_func_if_info_get(ulp_ctxt, port_id);
676 *vnic = (uint8_t *)&info->func_parent_vnic;