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