net/bnxt: remove unused macro
[dpdk.git] / drivers / net / bnxt / tf_core / tf_em_internal.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019-2020 Broadcom
3  * All rights reserved.
4  */
5
6 #include <string.h>
7 #include <rte_common.h>
8 #include <rte_errno.h>
9 #include <rte_log.h>
10
11 #include "tf_core.h"
12 #include "tf_util.h"
13 #include "tf_common.h"
14 #include "tf_em.h"
15 #include "tf_msg.h"
16 #include "tfp.h"
17 #include "tf_ext_flow_handle.h"
18
19 #include "bnxt.h"
20
21 /**
22  * EM DBs.
23  */
24 static void *em_db[TF_DIR_MAX];
25
26 #define TF_EM_DB_EM_REC 0
27
28 /**
29  * Init flag, set on bind and cleared on unbind
30  */
31 static uint8_t init;
32
33
34 /**
35  * EM Pool
36  */
37 static struct stack em_pool[TF_DIR_MAX];
38
39 /**
40  * Create EM Tbl pool of memory indexes.
41  *
42  * [in] dir
43  *   direction
44  * [in] num_entries
45  *   number of entries to write
46  * [in] start
47  *   starting offset
48  *
49  * Return:
50  *  0       - Success, entry allocated - no search support
51  *  -ENOMEM -EINVAL -EOPNOTSUPP
52  *          - Failure, entry not allocated, out of resources
53  */
54 static int
55 tf_create_em_pool(enum tf_dir dir,
56                   uint32_t num_entries,
57                   uint32_t start)
58 {
59         struct tfp_calloc_parms parms;
60         uint32_t i, j;
61         int rc = 0;
62         struct stack *pool = &em_pool[dir];
63
64         /* Assumes that num_entries has been checked before we get here */
65         parms.nitems = num_entries / TF_SESSION_EM_ENTRY_SIZE;
66         parms.size = sizeof(uint32_t);
67         parms.alignment = 0;
68
69         rc = tfp_calloc(&parms);
70
71         if (rc) {
72                 TFP_DRV_LOG(ERR,
73                             "%s, EM pool allocation failure %s\n",
74                             tf_dir_2_str(dir),
75                             strerror(-rc));
76                 return rc;
77         }
78
79         /* Create empty stack
80          */
81         rc = stack_init(num_entries / TF_SESSION_EM_ENTRY_SIZE,
82                         (uint32_t *)parms.mem_va,
83                         pool);
84
85         if (rc) {
86                 TFP_DRV_LOG(ERR,
87                             "%s, EM pool stack init failure %s\n",
88                             tf_dir_2_str(dir),
89                             strerror(-rc));
90                 goto cleanup;
91         }
92
93         /* Fill pool with indexes
94          */
95         j = start + num_entries - TF_SESSION_EM_ENTRY_SIZE;
96
97         for (i = 0; i < (num_entries / TF_SESSION_EM_ENTRY_SIZE); i++) {
98                 rc = stack_push(pool, j);
99                 if (rc) {
100                         TFP_DRV_LOG(ERR,
101                                     "%s, EM pool stack push failure %s\n",
102                                     tf_dir_2_str(dir),
103                                     strerror(-rc));
104                         goto cleanup;
105                 }
106
107                 j -= TF_SESSION_EM_ENTRY_SIZE;
108         }
109
110         if (!stack_is_full(pool)) {
111                 rc = -EINVAL;
112                 TFP_DRV_LOG(ERR,
113                             "%s, EM pool stack failure %s\n",
114                             tf_dir_2_str(dir),
115                             strerror(-rc));
116                 goto cleanup;
117         }
118
119         return 0;
120 cleanup:
121         tfp_free((void *)parms.mem_va);
122         return rc;
123 }
124
125 /**
126  * Create EM Tbl pool of memory indexes.
127  *
128  * [in] dir
129  *   direction
130  *
131  * Return:
132  */
133 static void
134 tf_free_em_pool(enum tf_dir dir)
135 {
136         struct stack *pool = &em_pool[dir];
137         uint32_t *ptr;
138
139         ptr = stack_items(pool);
140
141         if (ptr != NULL)
142                 tfp_free(ptr);
143 }
144
145 /**
146  * Insert EM internal entry API
147  *
148  *  returns:
149  *     0 - Success
150  */
151 int
152 tf_em_insert_int_entry(struct tf *tfp,
153                        struct tf_insert_em_entry_parms *parms)
154 {
155         int rc;
156         uint32_t gfid;
157         uint16_t rptr_index = 0;
158         uint8_t rptr_entry = 0;
159         uint8_t num_of_entries = 0;
160         struct stack *pool = &em_pool[parms->dir];
161         uint32_t index;
162
163         rc = stack_pop(pool, &index);
164
165         if (rc) {
166                 PMD_DRV_LOG(ERR,
167                             "%s, EM entry index allocation failed\n",
168                             tf_dir_2_str(parms->dir));
169                 return rc;
170         }
171
172         rptr_index = index;
173         rc = tf_msg_insert_em_internal_entry(tfp,
174                                              parms,
175                                              &rptr_index,
176                                              &rptr_entry,
177                                              &num_of_entries);
178         if (rc)
179                 return -1;
180
181         PMD_DRV_LOG
182                   (DEBUG,
183                    "%s, Internal entry @ Index:%d rptr_index:0x%x rptr_entry:0x%x num_of_entries:%d\n",
184                    tf_dir_2_str(parms->dir),
185                    index,
186                    rptr_index,
187                    rptr_entry,
188                    num_of_entries);
189
190         TF_SET_GFID(gfid,
191                     ((rptr_index << TF_EM_INTERNAL_INDEX_SHIFT) |
192                      rptr_entry),
193                     0); /* N/A for internal table */
194
195         TF_SET_FLOW_ID(parms->flow_id,
196                        gfid,
197                        TF_GFID_TABLE_INTERNAL,
198                        parms->dir);
199
200         TF_SET_FIELDS_IN_FLOW_HANDLE(parms->flow_handle,
201                                      (uint32_t)num_of_entries,
202                                      0,
203                                      0,
204                                      rptr_index,
205                                      rptr_entry,
206                                      0);
207         return 0;
208 }
209
210
211 /** Delete EM internal entry API
212  *
213  * returns:
214  * 0
215  * -EINVAL
216  */
217 int
218 tf_em_delete_int_entry(struct tf *tfp,
219                        struct tf_delete_em_entry_parms *parms)
220 {
221         int rc = 0;
222         struct stack *pool = &em_pool[parms->dir];
223
224         rc = tf_msg_delete_em_entry(tfp, parms);
225
226         /* Return resource to pool */
227         if (rc == 0)
228                 stack_push(pool, parms->index);
229
230         return rc;
231 }
232
233 int
234 tf_em_int_bind(struct tf *tfp,
235                struct tf_em_cfg_parms *parms)
236 {
237         int rc;
238         int i;
239         struct tf_rm_create_db_parms db_cfg = { 0 };
240         uint8_t db_exists = 0;
241         struct tf_rm_get_alloc_info_parms iparms;
242         struct tf_rm_alloc_info info;
243
244         TF_CHECK_PARMS2(tfp, parms);
245
246         if (init) {
247                 TFP_DRV_LOG(ERR,
248                             "EM Int DB already initialized\n");
249                 return -EINVAL;
250         }
251
252         db_cfg.type = TF_DEVICE_MODULE_TYPE_EM;
253         db_cfg.num_elements = parms->num_elements;
254         db_cfg.cfg = parms->cfg;
255
256         for (i = 0; i < TF_DIR_MAX; i++) {
257                 db_cfg.dir = i;
258                 db_cfg.alloc_cnt = parms->resources->em_cnt[i].cnt;
259
260                 /* Check if we got any request to support EEM, if so
261                  * we build an EM Int DB holding Table Scopes.
262                  */
263                 if (db_cfg.alloc_cnt[TF_EM_TBL_TYPE_EM_RECORD] == 0)
264                         continue;
265
266                 if (db_cfg.alloc_cnt[TF_EM_TBL_TYPE_EM_RECORD] %
267                     TF_SESSION_EM_ENTRY_SIZE != 0) {
268                         rc = -ENOMEM;
269                         TFP_DRV_LOG(ERR,
270                                     "%s, EM Allocation must be in blocks of %d, failure %s\n",
271                                     tf_dir_2_str(i),
272                                     TF_SESSION_EM_ENTRY_SIZE,
273                                     strerror(-rc));
274
275                         return rc;
276                 }
277
278                 db_cfg.rm_db = &em_db[i];
279                 rc = tf_rm_create_db(tfp, &db_cfg);
280                 if (rc) {
281                         TFP_DRV_LOG(ERR,
282                                     "%s: EM Int DB creation failed\n",
283                                     tf_dir_2_str(i));
284
285                         return rc;
286                 }
287                 db_exists = 1;
288         }
289
290         if (db_exists)
291                 init = 1;
292
293         for (i = 0; i < TF_DIR_MAX; i++) {
294                 iparms.rm_db = em_db[i];
295                 iparms.db_index = TF_EM_DB_EM_REC;
296                 iparms.info = &info;
297
298                 rc = tf_rm_get_info(&iparms);
299                 if (rc) {
300                         TFP_DRV_LOG(ERR,
301                                     "%s: EM DB get info failed\n",
302                                     tf_dir_2_str(i));
303                         return rc;
304                 }
305
306                 rc = tf_create_em_pool(i,
307                                        iparms.info->entry.stride,
308                                        iparms.info->entry.start);
309                 /* Logging handled in tf_create_em_pool */
310                 if (rc)
311                         return rc;
312         }
313
314
315         return 0;
316 }
317
318 int
319 tf_em_int_unbind(struct tf *tfp)
320 {
321         int rc;
322         int i;
323         struct tf_rm_free_db_parms fparms = { 0 };
324
325         TF_CHECK_PARMS1(tfp);
326
327         /* Bail if nothing has been initialized */
328         if (!init) {
329                 TFP_DRV_LOG(INFO,
330                             "No EM Int DBs created\n");
331                 return 0;
332         }
333
334         for (i = 0; i < TF_DIR_MAX; i++)
335                 tf_free_em_pool(i);
336
337         for (i = 0; i < TF_DIR_MAX; i++) {
338                 fparms.dir = i;
339                 fparms.rm_db = em_db[i];
340                 if (em_db[i] != NULL) {
341                         rc = tf_rm_free_db(tfp, &fparms);
342                         if (rc)
343                                 return rc;
344                 }
345
346                 em_db[i] = NULL;
347         }
348
349         init = 0;
350
351         return 0;
352 }