1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2014-2020 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;
167 if (intf->type == BNXT_ULP_INTF_TYPE_VF_REP) {
169 bnxt_get_fw_func_id(port_id, BNXT_ULP_INTF_TYPE_VF_REP);
171 func = &port_db->ulp_func_id_tbl[intf->vf_func_id];
173 bnxt_get_svif(port_id, true, BNXT_ULP_INTF_TYPE_VF_REP);
175 bnxt_get_phy_port_id(port_id);
177 bnxt_get_parif(port_id, BNXT_ULP_INTF_TYPE_INVALID);
179 bnxt_get_vnic_id(port_id, BNXT_ULP_INTF_TYPE_VF_REP);
180 func->phy_port_id = bnxt_get_phy_port_id(port_id);
183 port_data = &port_db->phy_port_list[func->phy_port_id];
184 if (!port_data->port_valid) {
185 port_data->port_svif =
186 bnxt_get_svif(port_id, false,
187 BNXT_ULP_INTF_TYPE_INVALID);
188 port_data->port_spif = bnxt_get_phy_port_id(port_id);
189 port_data->port_parif =
190 bnxt_get_parif(port_id, BNXT_ULP_INTF_TYPE_INVALID);
191 port_data->port_vport = bnxt_get_vport(port_id);
192 port_data->port_valid = true;
199 * Api to get the ulp ifindex for a given device port.
201 * ulp_ctxt [in] Ptr to ulp context
202 * port_id [in].device port id
203 * ifindex [out] ulp ifindex
205 * Returns 0 on success or negative number on failure.
208 ulp_port_db_dev_port_to_ulp_index(struct bnxt_ulp_context *ulp_ctxt,
212 struct bnxt_ulp_port_db *port_db;
215 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
216 if (!port_db || port_id >= RTE_MAX_ETHPORTS) {
217 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
220 if (!port_db->dev_port_list[port_id])
223 *ifindex = port_db->dev_port_list[port_id];
228 * Api to get the function id for a given ulp ifindex.
230 * ulp_ctxt [in] Ptr to ulp context
231 * ifindex [in] ulp ifindex
232 * func_id [out] the function id of the given ifindex.
234 * Returns 0 on success or negative number on failure.
237 ulp_port_db_function_id_get(struct bnxt_ulp_context *ulp_ctxt,
242 struct bnxt_ulp_port_db *port_db;
244 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
245 if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
246 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
250 if (fid_type == BNXT_ULP_DRV_FUNC_FID)
251 *func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
253 *func_id = port_db->ulp_intf_list[ifindex].vf_func_id;
259 * Api to get the svif for a given ulp ifindex.
261 * ulp_ctxt [in] Ptr to ulp context
262 * ifindex [in] ulp ifindex
263 * svif_type [in] the svif type of the given ifindex.
264 * svif [out] the svif of the given ifindex.
266 * Returns 0 on success or negative number on failure.
269 ulp_port_db_svif_get(struct bnxt_ulp_context *ulp_ctxt,
274 struct bnxt_ulp_port_db *port_db;
275 uint16_t phy_port_id, func_id;
277 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
278 if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
279 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
283 if (svif_type == BNXT_ULP_DRV_FUNC_SVIF) {
284 func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
285 *svif = port_db->ulp_func_id_tbl[func_id].func_svif;
286 } else if (svif_type == BNXT_ULP_VF_FUNC_SVIF) {
287 func_id = port_db->ulp_intf_list[ifindex].vf_func_id;
288 *svif = port_db->ulp_func_id_tbl[func_id].func_svif;
290 func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
291 phy_port_id = port_db->ulp_func_id_tbl[func_id].phy_port_id;
292 *svif = port_db->phy_port_list[phy_port_id].port_svif;
299 * Api to get the spif for a given ulp ifindex.
301 * ulp_ctxt [in] Ptr to ulp context
302 * ifindex [in] ulp ifindex
303 * spif_type [in] the spif type of the given ifindex.
304 * spif [out] the spif of the given ifindex.
306 * Returns 0 on success or negative number on failure.
309 ulp_port_db_spif_get(struct bnxt_ulp_context *ulp_ctxt,
314 struct bnxt_ulp_port_db *port_db;
315 uint16_t phy_port_id, func_id;
317 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
318 if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
319 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
323 if (spif_type == BNXT_ULP_DRV_FUNC_SPIF) {
324 func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
325 *spif = port_db->ulp_func_id_tbl[func_id].func_spif;
326 } else if (spif_type == BNXT_ULP_VF_FUNC_SPIF) {
327 func_id = port_db->ulp_intf_list[ifindex].vf_func_id;
328 *spif = port_db->ulp_func_id_tbl[func_id].func_spif;
330 func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
331 phy_port_id = port_db->ulp_func_id_tbl[func_id].phy_port_id;
332 *spif = port_db->phy_port_list[phy_port_id].port_spif;
339 * Api to get the parif for a given ulp ifindex.
341 * ulp_ctxt [in] Ptr to ulp context
342 * ifindex [in] ulp ifindex
343 * parif_type [in] the parif type of the given ifindex.
344 * parif [out] the parif of the given ifindex.
346 * Returns 0 on success or negative number on failure.
349 ulp_port_db_parif_get(struct bnxt_ulp_context *ulp_ctxt,
354 struct bnxt_ulp_port_db *port_db;
355 uint16_t phy_port_id, func_id;
357 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
358 if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
359 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
362 if (parif_type == BNXT_ULP_DRV_FUNC_PARIF) {
363 func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
364 *parif = port_db->ulp_func_id_tbl[func_id].func_parif;
365 } else if (parif_type == BNXT_ULP_VF_FUNC_PARIF) {
366 func_id = port_db->ulp_intf_list[ifindex].vf_func_id;
367 *parif = port_db->ulp_func_id_tbl[func_id].func_parif;
369 func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
370 phy_port_id = port_db->ulp_func_id_tbl[func_id].phy_port_id;
371 *parif = port_db->phy_port_list[phy_port_id].port_parif;
378 * Api to get the vnic id for a given ulp ifindex.
380 * ulp_ctxt [in] Ptr to ulp context
381 * ifindex [in] ulp ifindex
382 * vnic [out] the vnic of the given ifindex.
384 * Returns 0 on success or negative number on failure.
387 ulp_port_db_default_vnic_get(struct bnxt_ulp_context *ulp_ctxt,
392 struct bnxt_ulp_port_db *port_db;
395 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
396 if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
397 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
401 if (vnic_type == BNXT_ULP_DRV_FUNC_VNIC) {
402 func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
403 *vnic = port_db->ulp_func_id_tbl[func_id].func_vnic;
405 func_id = port_db->ulp_intf_list[ifindex].vf_func_id;
406 *vnic = port_db->ulp_func_id_tbl[func_id].func_vnic;
413 * Api to get the vport id for a given ulp ifindex.
415 * ulp_ctxt [in] Ptr to ulp context
416 * ifindex [in] ulp ifindex
417 * vport [out] the port of the given ifindex.
419 * Returns 0 on success or negative number on failure.
422 ulp_port_db_vport_get(struct bnxt_ulp_context *ulp_ctxt,
423 uint32_t ifindex, uint16_t *vport)
425 struct bnxt_ulp_port_db *port_db;
426 uint16_t phy_port_id, func_id;
428 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
429 if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
430 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
434 func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
435 phy_port_id = port_db->ulp_func_id_tbl[func_id].phy_port_id;
436 *vport = port_db->phy_port_list[phy_port_id].port_vport;
441 * Api to get the vport for a given physical port.
443 * ulp_ctxt [in] Ptr to ulp context
444 * phy_port [in] physical port index
445 * out_port [out] the port of the given physical index
447 * Returns 0 on success or negative number on failure.
450 ulp_port_db_phy_port_vport_get(struct bnxt_ulp_context *ulp_ctxt,
454 struct bnxt_ulp_port_db *port_db;
456 port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
457 if (!port_db || phy_port >= port_db->phy_port_cnt) {
458 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
461 *out_port = port_db->phy_port_list[phy_port].port_vport;