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