net/bnxt: update multi device design
[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)
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         return 0;
64
65 error_free:
66         ulp_port_db_deinit(ulp_ctxt);
67         return -ENOMEM;
68 }
69
70 /*
71  * Deinitialize the port database. Memory is deallocated in
72  * this call.
73  *
74  * ulp_ctxt [in] Ptr to ulp context
75  *
76  * Returns 0 on success.
77  */
78 int32_t ulp_port_db_deinit(struct bnxt_ulp_context *ulp_ctxt)
79 {
80         struct bnxt_ulp_port_db *port_db;
81
82         port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
83         if (!port_db) {
84                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
85                 return -EINVAL;
86         }
87
88         /* Detach the flow database from the ulp context. */
89         bnxt_ulp_cntxt_ptr2_port_db_set(ulp_ctxt, NULL);
90
91         /* Free up all the memory. */
92         rte_free(port_db->ulp_intf_list);
93         rte_free(port_db);
94         return 0;
95 }
96
97 /*
98  * Update the port database.This api is called when the port
99  * details are available during the startup.
100  *
101  * ulp_ctxt [in] Ptr to ulp context
102  * bp [in]. ptr to the device function.
103  *
104  * Returns 0 on success or negative number on failure.
105  */
106 int32_t ulp_port_db_dev_port_intf_update(struct bnxt_ulp_context *ulp_ctxt,
107                                          struct rte_eth_dev *eth_dev)
108 {
109         uint32_t port_id = eth_dev->data->port_id;
110         struct ulp_phy_port_info *port_data;
111         struct bnxt_ulp_port_db *port_db;
112         struct ulp_interface_info *intf;
113         uint32_t ifindex;
114         int32_t rc;
115
116         port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
117         if (!port_db) {
118                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
119                 return -EINVAL;
120         }
121
122         rc = ulp_port_db_dev_port_to_ulp_index(ulp_ctxt, port_id, &ifindex);
123         if (rc == -ENOENT) {
124                 /* port not found, allocate one */
125                 ifindex = ulp_port_db_allocate_ifindex(port_db);
126                 if (!ifindex)
127                         return -ENOMEM;
128                 port_db->dev_port_list[port_id] = ifindex;
129         } else if (rc == -EINVAL) {
130                 return -EINVAL;
131         }
132
133         /* update the interface details */
134         intf = &port_db->ulp_intf_list[ifindex];
135
136         intf->type = bnxt_get_interface_type(port_id);
137
138         intf->func_id = bnxt_get_fw_func_id(port_id);
139         intf->func_svif = bnxt_get_svif(port_id, 1);
140         intf->func_spif = bnxt_get_phy_port_id(port_id);
141         intf->func_parif = bnxt_get_parif(port_id);
142         intf->default_vnic = bnxt_get_vnic_id(port_id);
143         intf->phy_port_id = bnxt_get_phy_port_id(port_id);
144
145         if (intf->type == BNXT_ULP_INTF_TYPE_PF) {
146                 port_data = &port_db->phy_port_list[intf->phy_port_id];
147                 port_data->port_svif = bnxt_get_svif(port_id, 0);
148                 port_data->port_spif = bnxt_get_phy_port_id(port_id);
149                 port_data->port_parif = bnxt_get_parif(port_id);
150                 port_data->port_vport = bnxt_get_vport(port_id);
151         }
152
153         return 0;
154 }
155
156 /*
157  * Api to get the ulp ifindex for a given device port.
158  *
159  * ulp_ctxt [in] Ptr to ulp context
160  * port_id [in].device port id
161  * ifindex [out] ulp ifindex
162  *
163  * Returns 0 on success or negative number on failure.
164  */
165 int32_t
166 ulp_port_db_dev_port_to_ulp_index(struct bnxt_ulp_context *ulp_ctxt,
167                                   uint32_t port_id,
168                                   uint32_t *ifindex)
169 {
170         struct bnxt_ulp_port_db *port_db;
171
172         *ifindex = 0;
173         port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
174         if (!port_db || port_id >= RTE_MAX_ETHPORTS) {
175                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
176                 return -EINVAL;
177         }
178         if (!port_db->dev_port_list[port_id])
179                 return -ENOENT;
180
181         *ifindex = port_db->dev_port_list[port_id];
182         return 0;
183 }
184
185 /*
186  * Api to get the function id for a given ulp ifindex.
187  *
188  * ulp_ctxt [in] Ptr to ulp context
189  * ifindex [in] ulp ifindex
190  * func_id [out] the function id of the given ifindex.
191  *
192  * Returns 0 on success or negative number on failure.
193  */
194 int32_t
195 ulp_port_db_function_id_get(struct bnxt_ulp_context *ulp_ctxt,
196                             uint32_t ifindex,
197                             uint16_t *func_id)
198 {
199         struct bnxt_ulp_port_db *port_db;
200
201         port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
202         if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
203                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
204                 return -EINVAL;
205         }
206         *func_id =  port_db->ulp_intf_list[ifindex].func_id;
207         return 0;
208 }
209
210 /*
211  * Api to get the svif for a given ulp ifindex.
212  *
213  * ulp_ctxt [in] Ptr to ulp context
214  * ifindex [in] ulp ifindex
215  * dir [in] the direction for the flow.
216  * svif [out] the svif of the given ifindex.
217  *
218  * Returns 0 on success or negative number on failure.
219  */
220 int32_t
221 ulp_port_db_svif_get(struct bnxt_ulp_context *ulp_ctxt,
222                      uint32_t ifindex,
223                      uint32_t dir,
224                      uint16_t *svif)
225 {
226         struct bnxt_ulp_port_db *port_db;
227         uint16_t phy_port_id;
228
229         port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
230         if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
231                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
232                 return -EINVAL;
233         }
234         if (dir == ULP_DIR_EGRESS) {
235                 *svif = port_db->ulp_intf_list[ifindex].func_svif;
236         } else {
237                 phy_port_id = port_db->ulp_intf_list[ifindex].phy_port_id;
238                 *svif = port_db->phy_port_list[phy_port_id].port_svif;
239         }
240
241         return 0;
242 }
243
244 /*
245  * Api to get the spif for a given ulp ifindex.
246  *
247  * ulp_ctxt [in] Ptr to ulp context
248  * ifindex [in] ulp ifindex
249  * dir [in] the direction for the flow.
250  * spif [out] the spif of the given ifindex.
251  *
252  * Returns 0 on success or negative number on failure.
253  */
254 int32_t
255 ulp_port_db_spif_get(struct bnxt_ulp_context *ulp_ctxt,
256                      uint32_t ifindex,
257                      uint32_t dir,
258                      uint16_t *spif)
259 {
260         struct bnxt_ulp_port_db *port_db;
261         uint16_t phy_port_id;
262
263         port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
264         if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
265                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
266                 return -EINVAL;
267         }
268         if (dir == ULP_DIR_EGRESS) {
269                 *spif = port_db->ulp_intf_list[ifindex].func_spif;
270         } else {
271                 phy_port_id = port_db->ulp_intf_list[ifindex].phy_port_id;
272                 *spif = port_db->phy_port_list[phy_port_id].port_spif;
273         }
274
275         return 0;
276 }
277
278 /*
279  * Api to get the parif for a given ulp ifindex.
280  *
281  * ulp_ctxt [in] Ptr to ulp context
282  * ifindex [in] ulp ifindex
283  * dir [in] the direction for the flow.
284  * parif [out] the parif of the given ifindex.
285  *
286  * Returns 0 on success or negative number on failure.
287  */
288 int32_t
289 ulp_port_db_parif_get(struct bnxt_ulp_context *ulp_ctxt,
290                      uint32_t ifindex,
291                      uint32_t dir,
292                      uint16_t *parif)
293 {
294         struct bnxt_ulp_port_db *port_db;
295         uint16_t phy_port_id;
296
297         port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
298         if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
299                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
300                 return -EINVAL;
301         }
302         if (dir == ULP_DIR_EGRESS) {
303                 *parif = port_db->ulp_intf_list[ifindex].func_parif;
304         } else {
305                 phy_port_id = port_db->ulp_intf_list[ifindex].phy_port_id;
306                 *parif = port_db->phy_port_list[phy_port_id].port_parif;
307         }
308
309         return 0;
310 }
311
312 /*
313  * Api to get the vnic id for a given ulp ifindex.
314  *
315  * ulp_ctxt [in] Ptr to ulp context
316  * ifindex [in] ulp ifindex
317  * vnic [out] the vnic of the given ifindex.
318  *
319  * Returns 0 on success or negative number on failure.
320  */
321 int32_t
322 ulp_port_db_default_vnic_get(struct bnxt_ulp_context *ulp_ctxt,
323                              uint32_t ifindex,
324                              uint16_t *vnic)
325 {
326         struct bnxt_ulp_port_db *port_db;
327
328         port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
329         if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
330                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
331                 return -EINVAL;
332         }
333         *vnic = port_db->ulp_intf_list[ifindex].default_vnic;
334         return 0;
335 }
336
337 /*
338  * Api to get the vport id for a given ulp ifindex.
339  *
340  * ulp_ctxt [in] Ptr to ulp context
341  * ifindex [in] ulp ifindex
342  * vport [out] the port of the given ifindex.
343  *
344  * Returns 0 on success or negative number on failure.
345  */
346 int32_t
347 ulp_port_db_vport_get(struct bnxt_ulp_context *ulp_ctxt,
348                       uint32_t ifindex, uint16_t *vport)
349 {
350         struct bnxt_ulp_port_db *port_db;
351         uint16_t phy_port_id;
352
353         port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
354         if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
355                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
356                 return -EINVAL;
357         }
358         phy_port_id = port_db->ulp_intf_list[ifindex].phy_port_id;
359         *vport = port_db->phy_port_list[phy_port_id].port_vport;
360         return 0;
361 }