xref: /dpdk/drivers/net/bnxt/tf_ulp/ulp_port_db.c (revision d4b36fc5f0dc59b256441c82e5a9395054026496)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2014-2023 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_ulp_utils.h"
11 #include "bnxt_tf_pmd_shim.h"
12 #include "ulp_port_db.h"
13 #include "tfp.h"
14 
15 static uint32_t
16 ulp_port_db_allocate_ifindex(struct bnxt_ulp_port_db *port_db)
17 {
18 	uint32_t idx = 1;
19 
20 	while (idx < port_db->ulp_intf_list_size &&
21 	       port_db->ulp_intf_list[idx].type != BNXT_ULP_INTF_TYPE_INVALID)
22 		idx++;
23 
24 	if (idx >= port_db->ulp_intf_list_size) {
25 		BNXT_DRV_DBG(ERR, "Port DB interface list is full\n");
26 		return 0;
27 	}
28 	return idx;
29 }
30 
31 /*
32  * Initialize the port database. Memory is allocated in this
33  * call and assigned to the port database.
34  *
35  * ulp_ctxt [in] Ptr to ulp context
36  *
37  * Returns 0 on success or negative number on failure.
38  */
39 int32_t	ulp_port_db_init(struct bnxt_ulp_context *ulp_ctxt, uint8_t port_cnt)
40 {
41 	struct bnxt_ulp_port_db *port_db;
42 
43 	port_db = rte_zmalloc("bnxt_ulp_port_db",
44 			      sizeof(struct bnxt_ulp_port_db), 0);
45 	if (!port_db) {
46 		BNXT_DRV_DBG(ERR, "Failed to allocate memory for port db\n");
47 		return -ENOMEM;
48 	}
49 
50 	/* Attach the port database to the ulp context. */
51 	bnxt_ulp_cntxt_ptr2_port_db_set(ulp_ctxt, port_db);
52 
53 	/* 256 VFs + PFs etc. so making it 512*/
54 	port_db->ulp_intf_list_size = BNXT_PORT_DB_MAX_INTF_LIST * 2;
55 	/* Allocate the port tables */
56 	port_db->ulp_intf_list = rte_zmalloc("bnxt_ulp_port_db_intf_list",
57 					     port_db->ulp_intf_list_size *
58 					     sizeof(struct ulp_interface_info),
59 					     0);
60 	if (!port_db->ulp_intf_list) {
61 		BNXT_DRV_DBG(ERR,
62 			    "Failed to allocate mem for port interface list\n");
63 		goto error_free;
64 	}
65 
66 	/* Allocate the phy port list */
67 	port_db->phy_port_list = rte_zmalloc("bnxt_ulp_phy_port_list",
68 					     port_cnt *
69 					     sizeof(struct ulp_phy_port_info),
70 					     0);
71 	if (!port_db->phy_port_list) {
72 		BNXT_DRV_DBG(ERR,
73 			     "Failed to allocate mem for phy port list\n");
74 		goto error_free;
75 	}
76 	port_db->phy_port_cnt = port_cnt;
77 	return 0;
78 
79 error_free:
80 	ulp_port_db_deinit(ulp_ctxt);
81 	return -ENOMEM;
82 }
83 
84 /*
85  * Deinitialize the port database. Memory is deallocated in
86  * this call.
87  *
88  * ulp_ctxt [in] Ptr to ulp context
89  *
90  * Returns 0 on success.
91  */
92 int32_t	ulp_port_db_deinit(struct bnxt_ulp_context *ulp_ctxt)
93 {
94 	struct bnxt_ulp_port_db *port_db;
95 
96 	port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
97 	if (!port_db) {
98 		BNXT_DRV_DBG(ERR, "Invalid Arguments\n");
99 		return -EINVAL;
100 	}
101 
102 	/* Detach the flow database from the ulp context. */
103 	bnxt_ulp_cntxt_ptr2_port_db_set(ulp_ctxt, NULL);
104 
105 	/* Free up all the memory. */
106 	rte_free(port_db->phy_port_list);
107 	rte_free(port_db->ulp_intf_list);
108 	rte_free(port_db);
109 	return 0;
110 }
111 
112 /*
113  * Update the port database.This api is called when the port
114  * details are available during the startup.
115  *
116  * ulp_ctxt [in] Ptr to ulp context
117  * bp [in]. ptr to the device function.
118  *
119  * Returns 0 on success or negative number on failure.
120  */
121 int32_t	ulp_port_db_port_update(struct bnxt_ulp_context *ulp_ctxt,
122 				struct rte_eth_dev *eth_dev)
123 {
124 	uint32_t port_id = eth_dev->data->port_id;
125 	struct ulp_phy_port_info *port_data;
126 	struct bnxt_ulp_port_db *port_db;
127 	struct ulp_interface_info *intf;
128 	struct ulp_func_if_info *func;
129 	uint32_t ifindex;
130 	uint8_t tsid;
131 	int32_t rc;
132 
133 	port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
134 	if (!port_db) {
135 		BNXT_DRV_DBG(ERR, "Invalid Arguments\n");
136 		return -EINVAL;
137 	}
138 
139 	rc = ulp_port_db_dev_port_to_ulp_index(ulp_ctxt, port_id, &ifindex);
140 	if (rc == -ENOENT) {
141 		/* port not found, allocate one */
142 		ifindex = ulp_port_db_allocate_ifindex(port_db);
143 		if (!ifindex)
144 			return -ENOMEM;
145 		port_db->dev_port_list[port_id] = ifindex;
146 	} else if (rc == -EINVAL) {
147 		return -EINVAL;
148 	}
149 
150 	/* update the interface details */
151 	intf = &port_db->ulp_intf_list[ifindex];
152 
153 	intf->type = bnxt_pmd_get_interface_type(port_id);
154 	if (intf->type == BNXT_ULP_INTF_TYPE_PF)
155 		intf->type_is_pf = 1;
156 	else
157 		intf->type_is_pf = 0;
158 
159 	intf->drv_func_id = bnxt_pmd_get_fw_func_id(port_id,
160 						BNXT_ULP_INTF_TYPE_INVALID);
161 
162 	func = &port_db->ulp_func_id_tbl[intf->drv_func_id];
163 	if (!func->func_valid) {
164 		func->func_svif = bnxt_pmd_get_svif(port_id, true,
165 						BNXT_ULP_INTF_TYPE_INVALID);
166 		func->func_spif = bnxt_pmd_get_phy_port_id(port_id);
167 		func->func_parif =
168 			bnxt_pmd_get_parif(port_id, BNXT_ULP_INTF_TYPE_INVALID);
169 		func->func_vnic =
170 			bnxt_pmd_get_vnic_id(port_id, BNXT_ULP_INTF_TYPE_INVALID);
171 		func->phy_port_id = bnxt_pmd_get_phy_port_id(port_id);
172 		func->func_valid = true;
173 		func->ifindex = ifindex;
174 		/* Table scope is defined for all devices, ignore failures. */
175 		if (!bnxt_ulp_cntxt_tsid_get(ulp_ctxt, &tsid))
176 			func->table_scope = tsid;
177 	}
178 
179 	if (intf->type == BNXT_ULP_INTF_TYPE_VF_REP) {
180 		intf->vf_func_id =
181 			bnxt_pmd_get_fw_func_id(port_id, BNXT_ULP_INTF_TYPE_VF_REP);
182 
183 		func = &port_db->ulp_func_id_tbl[intf->vf_func_id];
184 		func->func_svif =
185 			bnxt_pmd_get_svif(port_id, true, BNXT_ULP_INTF_TYPE_VF_REP);
186 		func->func_spif =
187 			bnxt_pmd_get_phy_port_id(port_id);
188 		func->func_parif =
189 			bnxt_pmd_get_parif(port_id, BNXT_ULP_INTF_TYPE_INVALID);
190 		func->func_vnic =
191 			bnxt_pmd_get_vnic_id(port_id, BNXT_ULP_INTF_TYPE_VF_REP);
192 		func->phy_port_id = bnxt_pmd_get_phy_port_id(port_id);
193 		func->ifindex = ifindex;
194 		func->func_valid = true;
195 		func->vf_meta_data = tfp_cpu_to_be_16(BNXT_ULP_META_VF_FLAG |
196 						      intf->vf_func_id);
197 		if (!bnxt_ulp_cntxt_tsid_get(ulp_ctxt, &tsid))
198 			func->table_scope = tsid;
199 	}
200 
201 	/* When there is no match, the default action is to send the packet to
202 	 * the kernel. And to send it to the kernel, we need the PF's vnic id.
203 	 */
204 	func->func_parent_vnic = bnxt_pmd_get_parent_vnic_id(port_id, intf->type);
205 	func->func_parent_vnic = tfp_cpu_to_be_16(func->func_parent_vnic);
206 	bnxt_pmd_get_iface_mac(port_id, intf->type, func->func_mac,
207 			   func->func_parent_mac);
208 
209 	port_data = &port_db->phy_port_list[func->phy_port_id];
210 	if (!port_data->port_valid) {
211 		port_data->port_svif =
212 			bnxt_pmd_get_svif(port_id, false, BNXT_ULP_INTF_TYPE_INVALID);
213 		port_data->port_spif = bnxt_pmd_get_phy_port_id(port_id);
214 		port_data->port_parif =
215 			bnxt_pmd_get_parif(port_id, BNXT_ULP_INTF_TYPE_INVALID);
216 		port_data->port_vport = bnxt_pmd_get_vport(port_id);
217 		port_data->port_valid = true;
218 	}
219 	return 0;
220 }
221 
222 /*
223  * Api to get the ulp ifindex for a given device port.
224  *
225  * ulp_ctxt [in] Ptr to ulp context
226  * port_id [in].device port id
227  * ifindex [out] ulp ifindex
228  *
229  * Returns 0 on success or negative number on failure.
230  */
231 int32_t
232 ulp_port_db_dev_port_to_ulp_index(struct bnxt_ulp_context *ulp_ctxt,
233 				  uint32_t port_id,
234 				  uint32_t *ifindex)
235 {
236 	struct bnxt_ulp_port_db *port_db;
237 
238 	*ifindex = 0;
239 	port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
240 	if (!port_db || port_id >= RTE_MAX_ETHPORTS) {
241 		BNXT_DRV_DBG(ERR, "Invalid Arguments\n");
242 		return -EINVAL;
243 	}
244 	if (!port_db->dev_port_list[port_id])
245 		return -ENOENT;
246 
247 	*ifindex = port_db->dev_port_list[port_id];
248 	return 0;
249 }
250 
251 /*
252  * Api to get the function id for a given ulp ifindex.
253  *
254  * ulp_ctxt [in] Ptr to ulp context
255  * ifindex [in] ulp ifindex
256  * func_id [out] the function id of the given ifindex.
257  *
258  * Returns 0 on success or negative number on failure.
259  */
260 int32_t
261 ulp_port_db_function_id_get(struct bnxt_ulp_context *ulp_ctxt,
262 			    uint32_t ifindex,
263 			    uint32_t fid_type,
264 			    uint16_t *func_id)
265 {
266 	struct bnxt_ulp_port_db *port_db;
267 
268 	port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
269 	if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
270 		BNXT_DRV_DBG(ERR, "Invalid Arguments\n");
271 		return -EINVAL;
272 	}
273 
274 	if (fid_type == BNXT_ULP_DRV_FUNC_FID)
275 		*func_id =  port_db->ulp_intf_list[ifindex].drv_func_id;
276 	else
277 		*func_id =  port_db->ulp_intf_list[ifindex].vf_func_id;
278 
279 	return 0;
280 }
281 
282 /*
283  * Api to get the svif for a given ulp ifindex.
284  *
285  * ulp_ctxt [in] Ptr to ulp context
286  * ifindex [in] ulp ifindex
287  * svif_type [in] the svif type of the given ifindex.
288  * svif [out] the svif of the given ifindex.
289  *
290  * Returns 0 on success or negative number on failure.
291  */
292 int32_t
293 ulp_port_db_svif_get(struct bnxt_ulp_context *ulp_ctxt,
294 		     uint32_t ifindex,
295 		     uint32_t svif_type,
296 		     uint16_t *svif)
297 {
298 	struct bnxt_ulp_port_db *port_db;
299 	uint16_t phy_port_id, func_id;
300 
301 	port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
302 	if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
303 		BNXT_DRV_DBG(ERR, "Invalid Arguments\n");
304 		return -EINVAL;
305 	}
306 
307 	if (svif_type == BNXT_ULP_DRV_FUNC_SVIF) {
308 		func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
309 		*svif = port_db->ulp_func_id_tbl[func_id].func_svif;
310 	} else if (svif_type == BNXT_ULP_VF_FUNC_SVIF) {
311 		func_id = port_db->ulp_intf_list[ifindex].vf_func_id;
312 		*svif = port_db->ulp_func_id_tbl[func_id].func_svif;
313 	} else {
314 		func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
315 		phy_port_id = port_db->ulp_func_id_tbl[func_id].phy_port_id;
316 		*svif = port_db->phy_port_list[phy_port_id].port_svif;
317 	}
318 
319 	return 0;
320 }
321 
322 /*
323  * Api to get the spif for a given ulp ifindex.
324  *
325  * ulp_ctxt [in] Ptr to ulp context
326  * ifindex [in] ulp ifindex
327  * spif_type [in] the spif type of the given ifindex.
328  * spif [out] the spif of the given ifindex.
329  *
330  * Returns 0 on success or negative number on failure.
331  */
332 int32_t
333 ulp_port_db_spif_get(struct bnxt_ulp_context *ulp_ctxt,
334 		     uint32_t ifindex,
335 		     uint32_t spif_type,
336 		     uint16_t *spif)
337 {
338 	struct bnxt_ulp_port_db *port_db;
339 	uint16_t phy_port_id, func_id;
340 
341 	port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
342 	if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
343 		BNXT_DRV_DBG(ERR, "Invalid Arguments\n");
344 		return -EINVAL;
345 	}
346 
347 	if (spif_type == BNXT_ULP_DRV_FUNC_SPIF) {
348 		func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
349 		*spif = port_db->ulp_func_id_tbl[func_id].func_spif;
350 	} else if (spif_type == BNXT_ULP_VF_FUNC_SPIF) {
351 		func_id = port_db->ulp_intf_list[ifindex].vf_func_id;
352 		*spif = port_db->ulp_func_id_tbl[func_id].func_spif;
353 	} else {
354 		func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
355 		phy_port_id = port_db->ulp_func_id_tbl[func_id].phy_port_id;
356 		*spif = port_db->phy_port_list[phy_port_id].port_spif;
357 	}
358 
359 	return 0;
360 }
361 
362 /*
363  * Api to get the parif for a given ulp ifindex.
364  *
365  * ulp_ctxt [in] Ptr to ulp context
366  * ifindex [in] ulp ifindex
367  * parif_type [in] the parif type of the given ifindex.
368  * parif [out] the parif of the given ifindex.
369  *
370  * Returns 0 on success or negative number on failure.
371  */
372 int32_t
373 ulp_port_db_parif_get(struct bnxt_ulp_context *ulp_ctxt,
374 		     uint32_t ifindex,
375 		     uint32_t parif_type,
376 		     uint16_t *parif)
377 {
378 	struct bnxt_ulp_port_db *port_db;
379 	uint16_t phy_port_id, func_id;
380 
381 	port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
382 	if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
383 		BNXT_DRV_DBG(ERR, "Invalid Arguments\n");
384 		return -EINVAL;
385 	}
386 	if (parif_type == BNXT_ULP_DRV_FUNC_PARIF) {
387 		func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
388 		*parif = port_db->ulp_func_id_tbl[func_id].func_parif;
389 	} else if (parif_type == BNXT_ULP_VF_FUNC_PARIF) {
390 		func_id = port_db->ulp_intf_list[ifindex].vf_func_id;
391 		*parif = port_db->ulp_func_id_tbl[func_id].func_parif;
392 	} else {
393 		func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
394 		phy_port_id = port_db->ulp_func_id_tbl[func_id].phy_port_id;
395 		*parif = port_db->phy_port_list[phy_port_id].port_parif;
396 	}
397 	/* Parif needs to be reset to a free partition */
398 	*parif += BNXT_ULP_FREE_PARIF_BASE;
399 
400 	return 0;
401 }
402 
403 /*
404  * Api to get the vnic id for a given ulp ifindex.
405  *
406  * ulp_ctxt [in] Ptr to ulp context
407  * ifindex [in] ulp ifindex
408  * vnic [out] the vnic of the given ifindex.
409  *
410  * Returns 0 on success or negative number on failure.
411  */
412 int32_t
413 ulp_port_db_default_vnic_get(struct bnxt_ulp_context *ulp_ctxt,
414 			     uint32_t ifindex,
415 			     uint32_t vnic_type,
416 			     uint16_t *vnic)
417 {
418 	struct bnxt_ulp_port_db *port_db;
419 	uint16_t func_id;
420 
421 	port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
422 	if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
423 		BNXT_DRV_DBG(ERR, "Invalid Arguments\n");
424 		return -EINVAL;
425 	}
426 
427 	if (vnic_type == BNXT_ULP_DRV_FUNC_VNIC) {
428 		func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
429 		*vnic = port_db->ulp_func_id_tbl[func_id].func_vnic;
430 	} else {
431 		func_id = port_db->ulp_intf_list[ifindex].vf_func_id;
432 		*vnic = port_db->ulp_func_id_tbl[func_id].func_vnic;
433 	}
434 
435 	return 0;
436 }
437 
438 /*
439  * Api to get the vport id for a given ulp ifindex.
440  *
441  * ulp_ctxt [in] Ptr to ulp context
442  * ifindex [in] ulp ifindex
443  * vport [out] the port of the given ifindex.
444  *
445  * Returns 0 on success or negative number on failure.
446  */
447 int32_t
448 ulp_port_db_vport_get(struct bnxt_ulp_context *ulp_ctxt,
449 		      uint32_t ifindex, uint16_t *vport)
450 {
451 	struct bnxt_ulp_port_db *port_db;
452 	uint16_t phy_port_id, func_id;
453 
454 	port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
455 	if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
456 		BNXT_DRV_DBG(ERR, "Invalid Arguments\n");
457 		return -EINVAL;
458 	}
459 
460 	func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
461 	phy_port_id = port_db->ulp_func_id_tbl[func_id].phy_port_id;
462 	*vport = port_db->phy_port_list[phy_port_id].port_vport;
463 	return 0;
464 }
465 
466 /*
467  * Api to get the vport for a given physical port.
468  *
469  * ulp_ctxt [in] Ptr to ulp context
470  * phy_port [in] physical port index
471  * out_port [out] the port of the given physical index
472  *
473  * Returns 0 on success or negative number on failure.
474  */
475 int32_t
476 ulp_port_db_phy_port_vport_get(struct bnxt_ulp_context *ulp_ctxt,
477 			       uint32_t phy_port,
478 			       uint16_t *out_port)
479 {
480 	struct bnxt_ulp_port_db *port_db;
481 
482 	port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
483 	if (!port_db || phy_port >= port_db->phy_port_cnt) {
484 		BNXT_DRV_DBG(ERR, "Invalid Arguments\n");
485 		return -EINVAL;
486 	}
487 	*out_port = port_db->phy_port_list[phy_port].port_vport;
488 	return 0;
489 }
490 
491 /*
492  * Api to get the svif for a given physical port.
493  *
494  * ulp_ctxt [in] Ptr to ulp context
495  * phy_port [in] physical port index
496  * svif [out] the svif of the given physical index
497  *
498  * Returns 0 on success or negative number on failure.
499  */
500 int32_t
501 ulp_port_db_phy_port_svif_get(struct bnxt_ulp_context *ulp_ctxt,
502 			      uint32_t phy_port,
503 			      uint16_t *svif)
504 {
505 	struct bnxt_ulp_port_db *port_db;
506 
507 	port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
508 	if (!port_db || phy_port >= port_db->phy_port_cnt) {
509 		BNXT_DRV_DBG(ERR, "Invalid Arguments\n");
510 		return -EINVAL;
511 	}
512 	*svif = port_db->phy_port_list[phy_port].port_svif;
513 	return 0;
514 }
515 
516 /*
517  * Api to get the socket direct svif for a given device port.
518  *
519  * ulp_ctxt [in] Ptr to ulp context
520  * port_id [in] device port id
521  * svif [out] the socket direct svif of the given device index
522  *
523  * Returns 0 on success or negative number on failure.
524  */
525 int32_t
526 ulp_port_db_dev_port_socket_direct_svif_get(struct bnxt_ulp_context *ulp_ctxt,
527 					    uint32_t port_id,
528 					    uint16_t *svif)
529 {
530 	struct bnxt_ulp_port_db *port_db;
531 	uint32_t ifindex;
532 	uint16_t phy_port_id, func_id;
533 
534 	port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
535 
536 	if (!port_db || port_id >= RTE_MAX_ETHPORTS) {
537 		BNXT_DRV_DBG(ERR, "Invalid Arguments\n");
538 		return -EINVAL;
539 	}
540 	if (!port_db->dev_port_list[port_id])
541 		return -ENOENT;
542 
543 	/* Get physical port id */
544 	ifindex = port_db->dev_port_list[port_id];
545 	func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
546 	phy_port_id = port_db->ulp_func_id_tbl[func_id].phy_port_id;
547 
548 	/* Calculate physical port id for socket direct port */
549 	phy_port_id = phy_port_id ? 0 : 1;
550 	if (phy_port_id >= port_db->phy_port_cnt) {
551 		BNXT_DRV_DBG(ERR, "Invalid Arguments\n");
552 		return -EINVAL;
553 	}
554 
555 	*svif = port_db->phy_port_list[phy_port_id].port_svif;
556 	return 0;
557 }
558 
559 /*
560  * Api to get the port type for a given ulp ifindex.
561  *
562  * ulp_ctxt [in] Ptr to ulp context
563  * ifindex [in] ulp ifindex
564  *
565  * Returns port type.
566  */
567 enum bnxt_ulp_intf_type
568 ulp_port_db_port_type_get(struct bnxt_ulp_context *ulp_ctxt,
569 			  uint32_t ifindex)
570 {
571 	struct bnxt_ulp_port_db *port_db;
572 
573 	port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
574 	if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
575 		BNXT_DRV_DBG(ERR, "Invalid Arguments\n");
576 		return BNXT_ULP_INTF_TYPE_INVALID;
577 	}
578 	return port_db->ulp_intf_list[ifindex].type;
579 }
580 
581 /*
582  * Api to get the ulp ifindex for a given function id.
583  *
584  * ulp_ctxt [in] Ptr to ulp context
585  * func_id [in].device func id
586  * ifindex [out] ulp ifindex
587  *
588  * Returns 0 on success or negative number on failure.
589  */
590 int32_t
591 ulp_port_db_dev_func_id_to_ulp_index(struct bnxt_ulp_context *ulp_ctxt,
592 				     uint32_t func_id, uint32_t *ifindex)
593 {
594 	struct bnxt_ulp_port_db *port_db;
595 
596 	*ifindex = 0;
597 	port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
598 	if (!port_db || func_id >= BNXT_PORT_DB_MAX_FUNC) {
599 		BNXT_DRV_DBG(ERR, "Invalid Arguments\n");
600 		return -EINVAL;
601 	}
602 	if (!port_db->ulp_func_id_tbl[func_id].func_valid)
603 		return -ENOENT;
604 
605 	*ifindex = port_db->ulp_func_id_tbl[func_id].ifindex;
606 	return 0;
607 }
608 
609 /*
610  * Api to get the function id for a given port id.
611  *
612  * ulp_ctxt [in] Ptr to ulp context
613  * port_id [in] dpdk port id
614  * func_id [out] the function id of the given ifindex.
615  *
616  * Returns 0 on success or negative number on failure.
617  */
618 int32_t
619 ulp_port_db_port_func_id_get(struct bnxt_ulp_context *ulp_ctxt,
620 			     uint16_t port_id, uint16_t *func_id)
621 {
622 	struct bnxt_ulp_port_db *port_db;
623 	uint32_t ifindex;
624 
625 	port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
626 	if (!port_db || port_id >= RTE_MAX_ETHPORTS) {
627 		BNXT_DRV_DBG(ERR, "Invalid Arguments\n");
628 		return -EINVAL;
629 	}
630 	ifindex = port_db->dev_port_list[port_id];
631 	if (!ifindex)
632 		return -ENOENT;
633 
634 	switch (port_db->ulp_intf_list[ifindex].type) {
635 	case BNXT_ULP_INTF_TYPE_TRUSTED_VF:
636 	case BNXT_ULP_INTF_TYPE_PF:
637 		*func_id =  port_db->ulp_intf_list[ifindex].drv_func_id;
638 		break;
639 	case BNXT_ULP_INTF_TYPE_VF:
640 	case BNXT_ULP_INTF_TYPE_VF_REP:
641 		*func_id =  port_db->ulp_intf_list[ifindex].vf_func_id;
642 		break;
643 	default:
644 		*func_id = 0;
645 		break;
646 	}
647 	return 0;
648 }
649 
650 /* internal function to get the */
651 static struct ulp_func_if_info*
652 ulp_port_db_func_if_info_get(struct bnxt_ulp_context *ulp_ctxt,
653 			     uint32_t port_id)
654 {
655 	struct bnxt_ulp_port_db *port_db;
656 	uint16_t func_id;
657 
658 	port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
659 	if (ulp_port_db_port_func_id_get(ulp_ctxt, port_id, &func_id)) {
660 		BNXT_DRV_DBG(ERR, "Invalid port_id %x\n", port_id);
661 		return NULL;
662 	}
663 
664 	if (!port_db->ulp_func_id_tbl[func_id].func_valid) {
665 		BNXT_DRV_DBG(ERR, "Invalid func_id %x\n", func_id);
666 		return NULL;
667 	}
668 	return &port_db->ulp_func_id_tbl[func_id];
669 }
670 
671 /*
672  * Api to get the parent mac address for a given port id.
673  *
674  * ulp_ctxt [in] Ptr to ulp context
675  * port_id [in] device port id
676  * mac_addr [out] mac address
677  *
678  * Returns 0 on success or negative number on failure.
679  */
680 int32_t
681 ulp_port_db_parent_mac_addr_get(struct bnxt_ulp_context *ulp_ctxt,
682 				uint32_t port_id, uint8_t **mac_addr)
683 {
684 	struct ulp_func_if_info *info;
685 
686 	info = ulp_port_db_func_if_info_get(ulp_ctxt, port_id);
687 	if (info) {
688 		*mac_addr = info->func_parent_mac;
689 		return 0;
690 	}
691 	return -EINVAL;
692 }
693 
694 /*
695  * Api to get the mac address for a given port id.
696  *
697  * ulp_ctxt [in] Ptr to ulp context
698  * port_id [in] device port id
699  * mac_addr [out] mac address
700  *
701  * Returns 0 on success or negative number on failure.
702  */
703 int32_t
704 ulp_port_db_drv_mac_addr_get(struct bnxt_ulp_context *ulp_ctxt,
705 			     uint32_t port_id, uint8_t **mac_addr)
706 {
707 	struct ulp_func_if_info *info;
708 
709 	info = ulp_port_db_func_if_info_get(ulp_ctxt, port_id);
710 	if (info) {
711 		*mac_addr = info->func_mac;
712 		return 0;
713 	}
714 	return -EINVAL;
715 }
716 
717 /*
718  * Api to get the parent vnic for a given port id.
719  *
720  * ulp_ctxt [in] Ptr to ulp context
721  * port_id [in] device port id
722  * vnic [out] parent vnic
723  *
724  * Returns 0 on success or negative number on failure.
725  */
726 int32_t
727 ulp_port_db_parent_vnic_get(struct bnxt_ulp_context *ulp_ctxt,
728 			    uint32_t port_id, uint8_t **vnic)
729 {
730 	struct ulp_func_if_info *info;
731 
732 	info = ulp_port_db_func_if_info_get(ulp_ctxt, port_id);
733 	if (info) {
734 		*vnic = (uint8_t *)&info->func_parent_vnic;
735 		return 0;
736 	}
737 	return -EINVAL;
738 }
739 
740 /*
741  * Api to get the phy port for a given port id.
742  *
743  * ulp_ctxt [in] Ptr to ulp context
744  * port_id [in] device port id
745  * phy_port [out] phy_port of the dpdk port_id
746  *
747  * Returns 0 on success or negative number on failure.
748  */
749 int32_t
750 ulp_port_db_phy_port_get(struct bnxt_ulp_context *ulp_ctxt,
751 			 uint32_t port_id, uint16_t *phy_port)
752 {
753 	struct ulp_func_if_info *info;
754 
755 	info = ulp_port_db_func_if_info_get(ulp_ctxt, port_id);
756 	if (info) {
757 		*phy_port = info->phy_port_id;
758 		return 0;
759 	}
760 	return -EINVAL;
761 }
762 
763 /*
764  * Api to get the port type for a given port id.
765  *
766  * ulp_ctxt [in] Ptr to ulp context
767  * port_id [in] device port id
768  * type [out] type if pf or not
769  *
770  * Returns 0 on success or negative number on failure.
771  */
772 int32_t
773 ulp_port_db_port_is_pf_get(struct bnxt_ulp_context *ulp_ctxt,
774 			   uint32_t port_id, uint8_t **type)
775 {
776 	struct ulp_func_if_info *info;
777 	struct bnxt_ulp_port_db *port_db;
778 	uint16_t pid;
779 
780 	port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
781 	info = ulp_port_db_func_if_info_get(ulp_ctxt, port_id);
782 	if (info) {
783 		pid = info->ifindex;
784 		*type = &port_db->ulp_intf_list[pid].type_is_pf;
785 		return 0;
786 	}
787 	return -EINVAL;
788 }
789 
790 /*
791  * Api to get the meta data for a given port id.
792  *
793  * ulp_ctxt [in] Ptr to ulp context
794  * port_id [in] dpdk port id
795  * meta data [out] the meta data of the given port
796  *
797  * Returns 0 on success or negative number on failure.
798  */
799 int32_t
800 ulp_port_db_port_meta_data_get(struct bnxt_ulp_context *ulp_ctxt,
801 			       uint16_t port_id, uint8_t **meta_data)
802 {
803 	struct ulp_func_if_info *info;
804 
805 	info = ulp_port_db_func_if_info_get(ulp_ctxt, port_id);
806 	if (info) {
807 		*meta_data = (uint8_t *)&info->vf_meta_data;
808 		return 0;
809 	}
810 	return -EINVAL;
811 }
812 
813 /* Api to get the function id for a given port id
814  *
815  * ulp_ctxt [in] Ptr to ulp context
816  * port_id [in] dpdk port id
817  * fid_data [out] the function id of the given port
818  *
819  * Returns 0 on success or negative number on failure.
820  */
821 int32_t
822 ulp_port_db_port_vf_fid_get(struct bnxt_ulp_context *ulp_ctxt,
823 			    uint16_t port_id, uint8_t **fid_data)
824 {
825 	struct bnxt_ulp_port_db *port_db;
826 	uint32_t ifindex;
827 
828 	port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
829 	if (!port_db || port_id >= RTE_MAX_ETHPORTS) {
830 		BNXT_DRV_DBG(ERR, "Invalid Arguments\n");
831 		return -EINVAL;
832 	}
833 	ifindex = port_db->dev_port_list[port_id];
834 	if (!ifindex)
835 		return -ENOENT;
836 
837 	if (port_db->ulp_intf_list[ifindex].type != BNXT_ULP_INTF_TYPE_VF &&
838 	    port_db->ulp_intf_list[ifindex].type != BNXT_ULP_INTF_TYPE_VF_REP)
839 		return -EINVAL;
840 
841 	*fid_data = (uint8_t *)&port_db->ulp_intf_list[ifindex].vf_func_id;
842 	return 0;
843 }
844 
845 int32_t
846 ulp_port_db_port_table_scope_get(struct bnxt_ulp_context *ulp_ctxt,
847 				 uint16_t port_id, uint8_t **tsid)
848 {
849 	struct ulp_func_if_info *info;
850 
851 	info = ulp_port_db_func_if_info_get(ulp_ctxt, port_id);
852 	if (info) {
853 		*tsid = &info->table_scope;
854 		return 0;
855 	}
856 	return -EINVAL;
857 }
858 
859 /* Api to get the PF Mirror Id for a given port id
860  *
861  * ulp_ctxt [in] Ptr to ulp context
862  * port_id [in] dpdk port id
863  * mirror id [in] mirror id
864  *
865  * Returns 0 on success or negative number on failure.
866  */
867 int32_t
868 ulp_port_db_port_table_mirror_set(struct bnxt_ulp_context *ulp_ctxt,
869 				  uint16_t port_id, uint32_t mirror_id)
870 {
871 	struct ulp_phy_port_info *port_data;
872 	struct bnxt_ulp_port_db *port_db;
873 	struct ulp_interface_info *intf;
874 	struct ulp_func_if_info *func;
875 	uint32_t ifindex;
876 
877 	port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
878 	if (!port_db) {
879 		BNXT_DRV_DBG(ERR, "Invalid Arguments\n");
880 		return -EINVAL;
881 	}
882 
883 	if (ulp_port_db_dev_port_to_ulp_index(ulp_ctxt, port_id, &ifindex)) {
884 		BNXT_DRV_DBG(ERR, "Invalid port id %u\n", port_id);
885 		return -EINVAL;
886 	}
887 
888 	intf = &port_db->ulp_intf_list[ifindex];
889 	func = &port_db->ulp_func_id_tbl[intf->drv_func_id];
890 	if (!func->func_valid) {
891 		BNXT_DRV_DBG(ERR, "Invalid func for port id %u\n", port_id);
892 		return -EINVAL;
893 	}
894 
895 	port_data = &port_db->phy_port_list[func->phy_port_id];
896 	if (!port_data->port_valid) {
897 		BNXT_DRV_DBG(ERR, "Invalid phy port\n");
898 		return -EINVAL;
899 	}
900 
901 	port_data->port_mirror_id = mirror_id;
902 	return 0;
903 }
904