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