net/bnxt: modify port DB dev interface
[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         struct bnxt_ulp_port_db *port_db;
110         struct bnxt *bp = eth_dev->data->dev_private;
111         uint32_t port_id = eth_dev->data->port_id;
112         uint32_t ifindex;
113         struct ulp_interface_info *intf;
114         int32_t rc;
115         struct bnxt_vnic_info *vnic;
116
117         port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
118         if (!port_db) {
119                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
120                 return -EINVAL;
121         }
122
123         rc = ulp_port_db_dev_port_to_ulp_index(ulp_ctxt, port_id, &ifindex);
124         if (rc == -ENOENT) {
125                 /* port not found, allocate one */
126                 ifindex = ulp_port_db_allocate_ifindex(port_db);
127                 if (!ifindex)
128                         return -ENOMEM;
129                 port_db->dev_port_list[port_id] = ifindex;
130         } else if (rc == -EINVAL) {
131                 return -EINVAL;
132         }
133
134         /* update the interface details */
135         intf = &port_db->ulp_intf_list[ifindex];
136         if (BNXT_PF(bp) || BNXT_VF(bp)) {
137                 if (BNXT_PF(bp)) {
138                         intf->type = BNXT_ULP_INTF_TYPE_PF;
139                         intf->port_svif = bp->port_svif;
140                 } else {
141                         intf->type = BNXT_ULP_INTF_TYPE_VF;
142                 }
143                 intf->func_id = bp->fw_fid;
144                 intf->func_svif = bp->func_svif;
145                 vnic = BNXT_GET_DEFAULT_VNIC(bp);
146                 if (vnic)
147                         intf->default_vnic = vnic->fw_vnic_id;
148                 intf->bp = bp;
149                 memcpy(intf->mac_addr, bp->mac_addr, sizeof(intf->mac_addr));
150         } else {
151                 BNXT_TF_DBG(ERR, "Invalid interface type\n");
152         }
153
154         return 0;
155 }
156
157 /*
158  * Api to get the ulp ifindex for a given device port.
159  *
160  * ulp_ctxt [in] Ptr to ulp context
161  * port_id [in].device port id
162  * ifindex [out] ulp ifindex
163  *
164  * Returns 0 on success or negative number on failure.
165  */
166 int32_t
167 ulp_port_db_dev_port_to_ulp_index(struct bnxt_ulp_context *ulp_ctxt,
168                                   uint32_t port_id,
169                                   uint32_t *ifindex)
170 {
171         struct bnxt_ulp_port_db *port_db;
172
173         *ifindex = 0;
174         port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
175         if (!port_db || port_id >= RTE_MAX_ETHPORTS) {
176                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
177                 return -EINVAL;
178         }
179         if (!port_db->dev_port_list[port_id])
180                 return -ENOENT;
181
182         *ifindex = port_db->dev_port_list[port_id];
183         return 0;
184 }
185
186 /*
187  * Api to get the function id for a given ulp ifindex.
188  *
189  * ulp_ctxt [in] Ptr to ulp context
190  * ifindex [in] ulp ifindex
191  * func_id [out] the function id of the given ifindex.
192  *
193  * Returns 0 on success or negative number on failure.
194  */
195 int32_t
196 ulp_port_db_function_id_get(struct bnxt_ulp_context *ulp_ctxt,
197                             uint32_t ifindex,
198                             uint16_t *func_id)
199 {
200         struct bnxt_ulp_port_db *port_db;
201
202         port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
203         if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
204                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
205                 return -EINVAL;
206         }
207         *func_id =  port_db->ulp_intf_list[ifindex].func_id;
208         return 0;
209 }
210
211 /*
212  * Api to get the svid for a given ulp ifindex.
213  *
214  * ulp_ctxt [in] Ptr to ulp context
215  * ifindex [in] ulp ifindex
216  * dir [in] the direction for the flow.
217  * svif [out] the svif of the given ifindex.
218  *
219  * Returns 0 on success or negative number on failure.
220  */
221 int32_t
222 ulp_port_db_svif_get(struct bnxt_ulp_context *ulp_ctxt,
223                      uint32_t ifindex,
224                      uint32_t dir,
225                      uint16_t *svif)
226 {
227         struct bnxt_ulp_port_db *port_db;
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                 *svif = port_db->ulp_intf_list[ifindex].port_svif;
238         return 0;
239 }
240
241 /*
242  * Api to get the vnic id for a given ulp ifindex.
243  *
244  * ulp_ctxt [in] Ptr to ulp context
245  * ifindex [in] ulp ifindex
246  * vnic [out] the vnic of the given ifindex.
247  *
248  * Returns 0 on success or negative number on failure.
249  */
250 int32_t
251 ulp_port_db_default_vnic_get(struct bnxt_ulp_context *ulp_ctxt,
252                              uint32_t ifindex,
253                              uint16_t *vnic)
254 {
255         struct bnxt_ulp_port_db *port_db;
256
257         port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
258         if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
259                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
260                 return -EINVAL;
261         }
262         *vnic = port_db->ulp_intf_list[ifindex].default_vnic;
263         return 0;
264 }