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