net/bnxt: configure PARIF for egress rules
[dpdk.git] / drivers / net / bnxt / tf_ulp / ulp_port_db.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2014-2020 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
12 static uint32_t
13 ulp_port_db_allocate_ifindex(struct bnxt_ulp_port_db *port_db)
14 {
15         uint32_t idx = 1;
16
17         while (idx < port_db->ulp_intf_list_size &&
18                port_db->ulp_intf_list[idx].type != BNXT_ULP_INTF_TYPE_INVALID)
19                 idx++;
20
21         if (idx >= port_db->ulp_intf_list_size) {
22                 BNXT_TF_DBG(ERR, "Port DB interface list is full\n");
23                 return 0;
24         }
25         return idx;
26 }
27
28 /*
29  * Initialize the port database. Memory is allocated in this
30  * call and assigned to the port database.
31  *
32  * ulp_ctxt [in] Ptr to ulp context
33  *
34  * Returns 0 on success or negative number on failure.
35  */
36 int32_t ulp_port_db_init(struct bnxt_ulp_context *ulp_ctxt, uint8_t port_cnt)
37 {
38         struct bnxt_ulp_port_db *port_db;
39
40         port_db = rte_zmalloc("bnxt_ulp_port_db",
41                               sizeof(struct bnxt_ulp_port_db), 0);
42         if (!port_db) {
43                 BNXT_TF_DBG(ERR,
44                             "Failed to allocate memory for port db\n");
45                 return -ENOMEM;
46         }
47
48         /* Attach the port database to the ulp context. */
49         bnxt_ulp_cntxt_ptr2_port_db_set(ulp_ctxt, port_db);
50
51         /* index 0 is not being used hence add 1 to size */
52         port_db->ulp_intf_list_size = BNXT_PORT_DB_MAX_INTF_LIST + 1;
53         /* Allocate the port tables */
54         port_db->ulp_intf_list = rte_zmalloc("bnxt_ulp_port_db_intf_list",
55                                              port_db->ulp_intf_list_size *
56                                              sizeof(struct ulp_interface_info),
57                                              0);
58         if (!port_db->ulp_intf_list) {
59                 BNXT_TF_DBG(ERR,
60                             "Failed to allocate mem for port interface list\n");
61                 goto error_free;
62         }
63
64         /* Allocate the phy port list */
65         port_db->phy_port_list = rte_zmalloc("bnxt_ulp_phy_port_list",
66                                              port_cnt *
67                                              sizeof(struct ulp_phy_port_info),
68                                              0);
69         if (!port_db->phy_port_list) {
70                 BNXT_TF_DBG(ERR,
71                             "Failed to allocate mem for phy port list\n");
72                 goto error_free;
73         }
74         port_db->phy_port_cnt = port_cnt;
75         return 0;
76
77 error_free:
78         ulp_port_db_deinit(ulp_ctxt);
79         return -ENOMEM;
80 }
81
82 /*
83  * Deinitialize the port database. Memory is deallocated in
84  * this call.
85  *
86  * ulp_ctxt [in] Ptr to ulp context
87  *
88  * Returns 0 on success.
89  */
90 int32_t ulp_port_db_deinit(struct bnxt_ulp_context *ulp_ctxt)
91 {
92         struct bnxt_ulp_port_db *port_db;
93
94         port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
95         if (!port_db) {
96                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
97                 return -EINVAL;
98         }
99
100         /* Detach the flow database from the ulp context. */
101         bnxt_ulp_cntxt_ptr2_port_db_set(ulp_ctxt, NULL);
102
103         /* Free up all the memory. */
104         rte_free(port_db->phy_port_list);
105         rte_free(port_db->ulp_intf_list);
106         rte_free(port_db);
107         return 0;
108 }
109
110 /*
111  * Update the port database.This api is called when the port
112  * details are available during the startup.
113  *
114  * ulp_ctxt [in] Ptr to ulp context
115  * bp [in]. ptr to the device function.
116  *
117  * Returns 0 on success or negative number on failure.
118  */
119 int32_t ulp_port_db_dev_port_intf_update(struct bnxt_ulp_context *ulp_ctxt,
120                                          struct rte_eth_dev *eth_dev)
121 {
122         uint32_t port_id = eth_dev->data->port_id;
123         struct ulp_phy_port_info *port_data;
124         struct bnxt_ulp_port_db *port_db;
125         struct ulp_interface_info *intf;
126         struct ulp_func_if_info *func;
127         uint32_t ifindex;
128         int32_t rc;
129
130         port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
131         if (!port_db) {
132                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
133                 return -EINVAL;
134         }
135
136         rc = ulp_port_db_dev_port_to_ulp_index(ulp_ctxt, port_id, &ifindex);
137         if (rc == -ENOENT) {
138                 /* port not found, allocate one */
139                 ifindex = ulp_port_db_allocate_ifindex(port_db);
140                 if (!ifindex)
141                         return -ENOMEM;
142                 port_db->dev_port_list[port_id] = ifindex;
143         } else if (rc == -EINVAL) {
144                 return -EINVAL;
145         }
146
147         /* update the interface details */
148         intf = &port_db->ulp_intf_list[ifindex];
149
150         intf->type = bnxt_get_interface_type(port_id);
151         intf->drv_func_id = bnxt_get_fw_func_id(port_id,
152                                                 BNXT_ULP_INTF_TYPE_INVALID);
153
154         func = &port_db->ulp_func_id_tbl[intf->drv_func_id];
155         if (!func->func_valid) {
156                 func->func_svif = bnxt_get_svif(port_id, true,
157                                                 BNXT_ULP_INTF_TYPE_INVALID);
158                 func->func_spif = bnxt_get_phy_port_id(port_id);
159                 func->func_parif =
160                         bnxt_get_parif(port_id, BNXT_ULP_INTF_TYPE_INVALID);
161                 func->func_vnic =
162                         bnxt_get_vnic_id(port_id, BNXT_ULP_INTF_TYPE_INVALID);
163                 func->phy_port_id = bnxt_get_phy_port_id(port_id);
164                 func->func_valid = true;
165                 func->ifindex = ifindex;
166         }
167
168         if (intf->type == BNXT_ULP_INTF_TYPE_VF_REP) {
169                 intf->vf_func_id =
170                         bnxt_get_fw_func_id(port_id, BNXT_ULP_INTF_TYPE_VF_REP);
171
172                 func = &port_db->ulp_func_id_tbl[intf->vf_func_id];
173                 func->func_svif =
174                         bnxt_get_svif(port_id, true, BNXT_ULP_INTF_TYPE_VF_REP);
175                 func->func_spif =
176                         bnxt_get_phy_port_id(port_id);
177                 func->func_parif =
178                         bnxt_get_parif(port_id, BNXT_ULP_INTF_TYPE_INVALID);
179                 func->func_vnic =
180                         bnxt_get_vnic_id(port_id, BNXT_ULP_INTF_TYPE_VF_REP);
181                 func->phy_port_id = bnxt_get_phy_port_id(port_id);
182                 func->ifindex = ifindex;
183         }
184
185         port_data = &port_db->phy_port_list[func->phy_port_id];
186         if (!port_data->port_valid) {
187                 port_data->port_svif =
188                         bnxt_get_svif(port_id, false,
189                                       BNXT_ULP_INTF_TYPE_INVALID);
190                 port_data->port_spif = bnxt_get_phy_port_id(port_id);
191                 port_data->port_parif =
192                         bnxt_get_parif(port_id, BNXT_ULP_INTF_TYPE_INVALID);
193                 port_data->port_vport = bnxt_get_vport(port_id);
194                 port_data->port_valid = true;
195         }
196
197         return 0;
198 }
199
200 /*
201  * Api to get the ulp ifindex for a given device port.
202  *
203  * ulp_ctxt [in] Ptr to ulp context
204  * port_id [in].device port id
205  * ifindex [out] ulp ifindex
206  *
207  * Returns 0 on success or negative number on failure.
208  */
209 int32_t
210 ulp_port_db_dev_port_to_ulp_index(struct bnxt_ulp_context *ulp_ctxt,
211                                   uint32_t port_id,
212                                   uint32_t *ifindex)
213 {
214         struct bnxt_ulp_port_db *port_db;
215
216         *ifindex = 0;
217         port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
218         if (!port_db || port_id >= RTE_MAX_ETHPORTS) {
219                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
220                 return -EINVAL;
221         }
222         if (!port_db->dev_port_list[port_id])
223                 return -ENOENT;
224
225         *ifindex = port_db->dev_port_list[port_id];
226         return 0;
227 }
228
229 /*
230  * Api to get the function id for a given ulp ifindex.
231  *
232  * ulp_ctxt [in] Ptr to ulp context
233  * ifindex [in] ulp ifindex
234  * func_id [out] the function id of the given ifindex.
235  *
236  * Returns 0 on success or negative number on failure.
237  */
238 int32_t
239 ulp_port_db_function_id_get(struct bnxt_ulp_context *ulp_ctxt,
240                             uint32_t ifindex,
241                             uint32_t fid_type,
242                             uint16_t *func_id)
243 {
244         struct bnxt_ulp_port_db *port_db;
245
246         port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
247         if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
248                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
249                 return -EINVAL;
250         }
251
252         if (fid_type == BNXT_ULP_DRV_FUNC_FID)
253                 *func_id =  port_db->ulp_intf_list[ifindex].drv_func_id;
254         else
255                 *func_id =  port_db->ulp_intf_list[ifindex].vf_func_id;
256
257         return 0;
258 }
259
260 /*
261  * Api to get the svif for a given ulp ifindex.
262  *
263  * ulp_ctxt [in] Ptr to ulp context
264  * ifindex [in] ulp ifindex
265  * svif_type [in] the svif type of the given ifindex.
266  * svif [out] the svif of the given ifindex.
267  *
268  * Returns 0 on success or negative number on failure.
269  */
270 int32_t
271 ulp_port_db_svif_get(struct bnxt_ulp_context *ulp_ctxt,
272                      uint32_t ifindex,
273                      uint32_t svif_type,
274                      uint16_t *svif)
275 {
276         struct bnxt_ulp_port_db *port_db;
277         uint16_t phy_port_id, func_id;
278
279         port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
280         if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
281                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
282                 return -EINVAL;
283         }
284
285         if (svif_type == BNXT_ULP_DRV_FUNC_SVIF) {
286                 func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
287                 *svif = port_db->ulp_func_id_tbl[func_id].func_svif;
288         } else if (svif_type == BNXT_ULP_VF_FUNC_SVIF) {
289                 func_id = port_db->ulp_intf_list[ifindex].vf_func_id;
290                 *svif = port_db->ulp_func_id_tbl[func_id].func_svif;
291         } else {
292                 func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
293                 phy_port_id = port_db->ulp_func_id_tbl[func_id].phy_port_id;
294                 *svif = port_db->phy_port_list[phy_port_id].port_svif;
295         }
296
297         return 0;
298 }
299
300 /*
301  * Api to get the spif for a given ulp ifindex.
302  *
303  * ulp_ctxt [in] Ptr to ulp context
304  * ifindex [in] ulp ifindex
305  * spif_type [in] the spif type of the given ifindex.
306  * spif [out] the spif of the given ifindex.
307  *
308  * Returns 0 on success or negative number on failure.
309  */
310 int32_t
311 ulp_port_db_spif_get(struct bnxt_ulp_context *ulp_ctxt,
312                      uint32_t ifindex,
313                      uint32_t spif_type,
314                      uint16_t *spif)
315 {
316         struct bnxt_ulp_port_db *port_db;
317         uint16_t phy_port_id, func_id;
318
319         port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
320         if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
321                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
322                 return -EINVAL;
323         }
324
325         if (spif_type == BNXT_ULP_DRV_FUNC_SPIF) {
326                 func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
327                 *spif = port_db->ulp_func_id_tbl[func_id].func_spif;
328         } else if (spif_type == BNXT_ULP_VF_FUNC_SPIF) {
329                 func_id = port_db->ulp_intf_list[ifindex].vf_func_id;
330                 *spif = port_db->ulp_func_id_tbl[func_id].func_spif;
331         } else {
332                 func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
333                 phy_port_id = port_db->ulp_func_id_tbl[func_id].phy_port_id;
334                 *spif = port_db->phy_port_list[phy_port_id].port_spif;
335         }
336
337         return 0;
338 }
339
340 /*
341  * Api to get the parif for a given ulp ifindex.
342  *
343  * ulp_ctxt [in] Ptr to ulp context
344  * ifindex [in] ulp ifindex
345  * parif_type [in] the parif type of the given ifindex.
346  * parif [out] the parif of the given ifindex.
347  *
348  * Returns 0 on success or negative number on failure.
349  */
350 int32_t
351 ulp_port_db_parif_get(struct bnxt_ulp_context *ulp_ctxt,
352                      uint32_t ifindex,
353                      uint32_t parif_type,
354                      uint16_t *parif)
355 {
356         struct bnxt_ulp_port_db *port_db;
357         uint16_t phy_port_id, func_id;
358
359         port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
360         if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
361                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
362                 return -EINVAL;
363         }
364         if (parif_type == BNXT_ULP_DRV_FUNC_PARIF) {
365                 func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
366                 *parif = port_db->ulp_func_id_tbl[func_id].func_parif;
367         } else if (parif_type == BNXT_ULP_VF_FUNC_PARIF) {
368                 func_id = port_db->ulp_intf_list[ifindex].vf_func_id;
369                 *parif = port_db->ulp_func_id_tbl[func_id].func_parif;
370         } else {
371                 func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
372                 phy_port_id = port_db->ulp_func_id_tbl[func_id].phy_port_id;
373                 *parif = port_db->phy_port_list[phy_port_id].port_parif;
374         }
375         /* Parif needs to be reset to a free partition */
376         *parif += BNXT_ULP_FREE_PARIF_BASE;
377
378         return 0;
379 }
380
381 /*
382  * Api to get the vnic id for a given ulp ifindex.
383  *
384  * ulp_ctxt [in] Ptr to ulp context
385  * ifindex [in] ulp ifindex
386  * vnic [out] the vnic of the given ifindex.
387  *
388  * Returns 0 on success or negative number on failure.
389  */
390 int32_t
391 ulp_port_db_default_vnic_get(struct bnxt_ulp_context *ulp_ctxt,
392                              uint32_t ifindex,
393                              uint32_t vnic_type,
394                              uint16_t *vnic)
395 {
396         struct bnxt_ulp_port_db *port_db;
397         uint16_t func_id;
398
399         port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
400         if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
401                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
402                 return -EINVAL;
403         }
404
405         if (vnic_type == BNXT_ULP_DRV_FUNC_VNIC) {
406                 func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
407                 *vnic = port_db->ulp_func_id_tbl[func_id].func_vnic;
408         } else {
409                 func_id = port_db->ulp_intf_list[ifindex].vf_func_id;
410                 *vnic = port_db->ulp_func_id_tbl[func_id].func_vnic;
411         }
412
413         return 0;
414 }
415
416 /*
417  * Api to get the vport id for a given ulp ifindex.
418  *
419  * ulp_ctxt [in] Ptr to ulp context
420  * ifindex [in] ulp ifindex
421  * vport [out] the port of the given ifindex.
422  *
423  * Returns 0 on success or negative number on failure.
424  */
425 int32_t
426 ulp_port_db_vport_get(struct bnxt_ulp_context *ulp_ctxt,
427                       uint32_t ifindex, uint16_t *vport)
428 {
429         struct bnxt_ulp_port_db *port_db;
430         uint16_t phy_port_id, func_id;
431
432         port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
433         if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
434                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
435                 return -EINVAL;
436         }
437
438         func_id = port_db->ulp_intf_list[ifindex].drv_func_id;
439         phy_port_id = port_db->ulp_func_id_tbl[func_id].phy_port_id;
440         *vport = port_db->phy_port_list[phy_port_id].port_vport;
441         return 0;
442 }
443
444 /*
445  * Api to get the vport for a given physical port.
446  *
447  * ulp_ctxt [in] Ptr to ulp context
448  * phy_port [in] physical port index
449  * out_port [out] the port of the given physical index
450  *
451  * Returns 0 on success or negative number on failure.
452  */
453 int32_t
454 ulp_port_db_phy_port_vport_get(struct bnxt_ulp_context *ulp_ctxt,
455                                uint32_t phy_port,
456                                uint16_t *out_port)
457 {
458         struct bnxt_ulp_port_db *port_db;
459
460         port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
461         if (!port_db || phy_port >= port_db->phy_port_cnt) {
462                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
463                 return -EINVAL;
464         }
465         *out_port = port_db->phy_port_list[phy_port].port_vport;
466         return 0;
467 }
468
469 /*
470  * Api to get the svif for a given physical port.
471  *
472  * ulp_ctxt [in] Ptr to ulp context
473  * phy_port [in] physical port index
474  * svif [out] the svif of the given physical index
475  *
476  * Returns 0 on success or negative number on failure.
477  */
478 int32_t
479 ulp_port_db_phy_port_svif_get(struct bnxt_ulp_context *ulp_ctxt,
480                               uint32_t phy_port,
481                               uint16_t *svif)
482 {
483         struct bnxt_ulp_port_db *port_db;
484
485         port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
486         if (!port_db || phy_port >= port_db->phy_port_cnt) {
487                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
488                 return -EINVAL;
489         }
490         *svif = port_db->phy_port_list[phy_port].port_svif;
491         return 0;
492 }
493
494 /*
495  * Api to get the port type for a given ulp ifindex.
496  *
497  * ulp_ctxt [in] Ptr to ulp context
498  * ifindex [in] ulp ifindex
499  *
500  * Returns port type.
501  */
502 enum bnxt_ulp_intf_type
503 ulp_port_db_port_type_get(struct bnxt_ulp_context *ulp_ctxt,
504                           uint32_t ifindex)
505 {
506         struct bnxt_ulp_port_db *port_db;
507
508         port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
509         if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
510                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
511                 return BNXT_ULP_INTF_TYPE_INVALID;
512         }
513         return port_db->ulp_intf_list[ifindex].type;
514 }
515
516 /*
517  * Api to get the ulp ifindex for a given function id.
518  *
519  * ulp_ctxt [in] Ptr to ulp context
520  * func_id [in].device func id
521  * ifindex [out] ulp ifindex
522  *
523  * Returns 0 on success or negative number on failure.
524  */
525 int32_t
526 ulp_port_db_dev_func_id_to_ulp_index(struct bnxt_ulp_context *ulp_ctxt,
527                                      uint32_t func_id, uint32_t *ifindex)
528 {
529         struct bnxt_ulp_port_db *port_db;
530
531         *ifindex = 0;
532         port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
533         if (!port_db || func_id >= BNXT_PORT_DB_MAX_FUNC) {
534                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
535                 return -EINVAL;
536         }
537         if (!port_db->ulp_func_id_tbl[func_id].func_valid)
538                 return -ENOENT;
539
540         *ifindex = port_db->ulp_func_id_tbl[func_id].ifindex;
541         return 0;
542 }