ebb975562dd1e13913773eacd173e13fd3f25424
[dpdk.git] / drivers / net / bnxt / tf_core / tf_identifier.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019-2021 Broadcom
3  * All rights reserved.
4  */
5
6 #include <rte_common.h>
7
8 #include "tf_identifier.h"
9 #include "tf_shadow_identifier.h"
10 #include "tf_common.h"
11 #include "tf_rm.h"
12 #include "tf_util.h"
13 #include "tfp.h"
14 #include "tf_session.h"
15
16 struct tf;
17
18 /**
19  * Identifier shadow DBs.
20  */
21 static void *ident_shadow_db[TF_DIR_MAX];
22
23 /**
24  * Shadow DB Init flag, set on bind and cleared on unbind
25  */
26 static uint8_t shadow_init;
27
28 int
29 tf_ident_bind(struct tf *tfp,
30               struct tf_ident_cfg_parms *parms)
31 {
32         int rc;
33         int i;
34         struct tf_rm_create_db_parms db_cfg = { 0 };
35         struct tf_shadow_ident_cfg_parms shadow_cfg = { 0 };
36         struct tf_shadow_ident_create_db_parms shadow_cdb = { 0 };
37         struct ident_rm_db *ident_db;
38         struct tfp_calloc_parms cparms;
39         struct tf_session *tfs;
40
41         TF_CHECK_PARMS2(tfp, parms);
42
43         /* Retrieve the session information */
44         rc = tf_session_get_session_internal(tfp, &tfs);
45         if (rc)
46                 return rc;
47
48         memset(&db_cfg, 0, sizeof(db_cfg));
49         cparms.nitems = 1;
50         cparms.size = sizeof(struct ident_rm_db);
51         cparms.alignment = 0;
52         if (tfp_calloc(&cparms) != 0) {
53                 TFP_DRV_LOG(ERR, "ident_rm_db alloc error %s\n",
54                             strerror(ENOMEM));
55                 return -ENOMEM;
56         }
57
58         ident_db = cparms.mem_va;
59         for (i = 0; i < TF_DIR_MAX; i++)
60                 ident_db->ident_db[i] = NULL;
61         tf_session_set_db(tfp, TF_MODULE_TYPE_IDENTIFIER, ident_db);
62
63         db_cfg.module = TF_MODULE_TYPE_IDENTIFIER;
64         db_cfg.num_elements = parms->num_elements;
65         db_cfg.cfg = parms->cfg;
66
67         for (i = 0; i < TF_DIR_MAX; i++) {
68                 db_cfg.rm_db = (void *)&ident_db->ident_db[i];
69                 db_cfg.dir = i;
70                 db_cfg.alloc_cnt = parms->resources->ident_cnt[i].cnt;
71                 if (tf_session_is_shared_session(tfs) &&
72                         (!tf_session_is_shared_session_creator(tfs)))
73                         rc = tf_rm_create_db_no_reservation(tfp, &db_cfg);
74                 else
75                         rc = tf_rm_create_db(tfp, &db_cfg);
76                 if (rc) {
77                         TFP_DRV_LOG(ERR,
78                                     "%s: Identifier DB creation failed\n",
79                                     tf_dir_2_str(i));
80
81                         return rc;
82                 }
83
84                 if (parms->shadow_copy) {
85                         shadow_cfg.alloc_cnt =
86                                 parms->resources->ident_cnt[i].cnt;
87                         shadow_cdb.num_elements = parms->num_elements;
88                         shadow_cdb.tf_shadow_ident_db = &ident_shadow_db[i];
89                         shadow_cdb.cfg = &shadow_cfg;
90                         rc = tf_shadow_ident_create_db(&shadow_cdb);
91                         if (rc) {
92                                 TFP_DRV_LOG(ERR,
93                                     "%s: Ident shadow DB creation failed\n",
94                                     tf_dir_2_str(i));
95
96                                 return rc;
97                         }
98                         shadow_init = 1;
99                 }
100         }
101
102         TFP_DRV_LOG(INFO,
103                     "Identifier - initialized\n");
104
105         return 0;
106 }
107
108 int
109 tf_ident_unbind(struct tf *tfp)
110 {
111         int rc = 0;
112         int i;
113         struct tf_rm_free_db_parms fparms = { 0 };
114         struct tf_shadow_ident_free_db_parms sparms = { 0 };
115         struct ident_rm_db *ident_db;
116         void *ident_db_ptr = NULL;
117
118         TF_CHECK_PARMS1(tfp);
119
120         rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
121         if (rc) {
122                 TFP_DRV_LOG(INFO,
123                             "Ident_db is not initialized, rc:%s\n",
124                             strerror(-rc));
125                 return 0;
126         }
127         ident_db = (struct ident_rm_db *)ident_db_ptr;
128
129         for (i = 0; i < TF_DIR_MAX; i++) {
130                 if (ident_db->ident_db[i] == NULL)
131                         continue;
132                 fparms.rm_db = ident_db->ident_db[i];
133                 fparms.dir = i;
134                 rc = tf_rm_free_db(tfp, &fparms);
135                 if (rc) {
136                         TFP_DRV_LOG(ERR,
137                                     "rm free failed on unbind\n");
138                 }
139                 if (shadow_init) {
140                         sparms.tf_shadow_ident_db = ident_shadow_db[i];
141                         rc = tf_shadow_ident_free_db(&sparms);
142                         if (rc) {
143                                 /* TODO: If there are failures on unbind we
144                                  * really just have to try until all DBs are
145                                  * attempted to be cleared.
146                                  */
147                         }
148                         ident_shadow_db[i] = NULL;
149                 }
150                 ident_db->ident_db[i] = NULL;
151         }
152
153         shadow_init = 0;
154
155         return 0;
156 }
157
158 int
159 tf_ident_alloc(struct tf *tfp __rte_unused,
160                struct tf_ident_alloc_parms *parms)
161 {
162         int rc;
163         uint32_t id;
164         uint32_t base_id;
165         struct tf_rm_allocate_parms aparms = { 0 };
166         struct tf_shadow_ident_insert_parms iparms = { 0 };
167         struct ident_rm_db *ident_db;
168         void *ident_db_ptr = NULL;
169
170         TF_CHECK_PARMS2(tfp, parms);
171
172         rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
173         if (rc) {
174                 TFP_DRV_LOG(ERR,
175                             "Failed to get ident_db from session, rc:%s\n",
176                             strerror(-rc));
177                 return rc;
178         }
179         ident_db = (struct ident_rm_db *)ident_db_ptr;
180
181         aparms.rm_db = ident_db->ident_db[parms->dir];
182         aparms.subtype = parms->type;
183         aparms.index = &id;
184         aparms.base_index = &base_id;
185         rc = tf_rm_allocate(&aparms);
186         if (rc) {
187                 TFP_DRV_LOG(ERR,
188                             "%s: Failed allocate, type:%d\n",
189                             tf_dir_2_str(parms->dir),
190                             parms->type);
191                 return rc;
192         }
193
194         if (shadow_init) {
195                 iparms.tf_shadow_ident_db = ident_shadow_db[parms->dir];
196                 iparms.type = parms->type;
197                 iparms.id = base_id;
198
199                 rc = tf_shadow_ident_insert(&iparms);
200                 if (rc) {
201                         TFP_DRV_LOG(ERR,
202                                     "%s: Failed insert shadow DB, type:%d\n",
203                                     tf_dir_2_str(parms->dir),
204                                     parms->type);
205                         return rc;
206                 }
207         }
208
209         *parms->id = id;
210
211         return 0;
212 }
213
214 int
215 tf_ident_free(struct tf *tfp __rte_unused,
216               struct tf_ident_free_parms *parms)
217 {
218         int rc;
219         struct tf_rm_is_allocated_parms aparms = { 0 };
220         struct tf_rm_free_parms fparms = { 0 };
221         struct tf_shadow_ident_remove_parms rparms = { 0 };
222         int allocated = 0;
223         uint32_t base_id;
224         struct ident_rm_db *ident_db;
225         void *ident_db_ptr = NULL;
226
227         TF_CHECK_PARMS2(tfp, parms);
228
229         rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
230         if (rc) {
231                 TFP_DRV_LOG(ERR,
232                             "Failed to get ident_db from session, rc:%s\n",
233                             strerror(-rc));
234                 return rc;
235         }
236         ident_db = (struct ident_rm_db *)ident_db_ptr;
237
238         /* Check if element is in use */
239         aparms.rm_db = ident_db->ident_db[parms->dir];
240         aparms.subtype = parms->type;
241         aparms.index = parms->id;
242         aparms.base_index = &base_id;
243         aparms.allocated = &allocated;
244         rc = tf_rm_is_allocated(&aparms);
245         if (rc)
246                 return rc;
247
248         if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
249                 TFP_DRV_LOG(ERR,
250                             "%s: Entry already free, type:%d, index:%d\n",
251                             tf_dir_2_str(parms->dir),
252                             parms->type,
253                             parms->id);
254                 return -EINVAL;
255         }
256
257         if (shadow_init) {
258                 rparms.tf_shadow_ident_db = ident_shadow_db[parms->dir];
259                 rparms.type = parms->type;
260                 rparms.id = base_id;
261                 rparms.ref_cnt = parms->ref_cnt;
262
263                 rc = tf_shadow_ident_remove(&rparms);
264                 if (rc) {
265                         TFP_DRV_LOG(ERR,
266                                     "%s: ref_cnt was 0 in shadow DB,"
267                                     " type:%d, index:%d\n",
268                                     tf_dir_2_str(parms->dir),
269                                     parms->type,
270                                     parms->id);
271                         return rc;
272                 }
273
274                 if (*rparms.ref_cnt > 0)
275                         return 0;
276         }
277
278         /* Free requested element */
279         fparms.rm_db = ident_db->ident_db[parms->dir];
280         fparms.subtype = parms->type;
281         fparms.index = parms->id;
282         rc = tf_rm_free(&fparms);
283         if (rc) {
284                 TFP_DRV_LOG(ERR,
285                             "%s: Free failed, type:%d, index:%d\n",
286                             tf_dir_2_str(parms->dir),
287                             parms->type,
288                             parms->id);
289                 return rc;
290         }
291
292         return 0;
293 }
294
295 int
296 tf_ident_search(struct tf *tfp __rte_unused,
297                 struct tf_ident_search_parms *parms)
298 {
299         int rc;
300         struct tf_rm_is_allocated_parms aparms = { 0 };
301         struct tf_shadow_ident_search_parms sparms = { 0 };
302         int allocated = 0;
303         uint32_t base_id;
304         struct ident_rm_db *ident_db;
305         void *ident_db_ptr = NULL;
306
307         TF_CHECK_PARMS2(tfp, parms);
308
309         if (!shadow_init) {
310                 TFP_DRV_LOG(ERR,
311                             "%s: Identifier Shadow copy is not enabled\n",
312                             tf_dir_2_str(parms->dir));
313                 return -EINVAL;
314         }
315
316         rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
317         if (rc) {
318                 TFP_DRV_LOG(ERR,
319                             "Failed to get ident_db from session, rc:%s\n",
320                             strerror(-rc));
321                 return rc;
322         }
323         ident_db = (struct ident_rm_db *)ident_db_ptr;
324
325         /* Check if element is in use */
326         aparms.rm_db = ident_db->ident_db[parms->dir];
327         aparms.subtype = parms->type;
328         aparms.index = parms->search_id;
329         aparms.base_index = &base_id;
330         aparms.allocated = &allocated;
331         rc = tf_rm_is_allocated(&aparms);
332         if (rc)
333                 return rc;
334
335         if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
336                 TFP_DRV_LOG(ERR,
337                             "%s: Entry not allocated, type:%d, index:%d\n",
338                             tf_dir_2_str(parms->dir),
339                             parms->type,
340                             parms->search_id);
341                 return -EINVAL;
342         }
343
344         sparms.tf_shadow_ident_db = ident_shadow_db[parms->dir];
345         sparms.type = parms->type;
346         sparms.search_id = base_id;
347         sparms.hit = parms->hit;
348         sparms.ref_cnt = parms->ref_cnt;
349
350         rc = tf_shadow_ident_search(&sparms);
351         if (rc) {
352                 TFP_DRV_LOG(ERR,
353                             "%s: Failed search shadow DB, type:%d\n",
354                             tf_dir_2_str(parms->dir),
355                             parms->type);
356                 return rc;
357         }
358
359         return 0;
360 }
361
362 int
363 tf_ident_get_resc_info(struct tf *tfp,
364                        struct tf_identifier_resource_info *ident)
365 {
366         int rc;
367         int d;
368         struct tf_resource_info *dinfo;
369         struct tf_rm_get_alloc_info_parms ainfo;
370         void *ident_db_ptr = NULL;
371         struct ident_rm_db *ident_db;
372
373         TF_CHECK_PARMS2(tfp, ident);
374
375         rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
376         if (rc) {
377                 TFP_DRV_LOG(INFO,
378                             "No resource allocated for ident from session\n");
379                 return 0;
380         }
381         ident_db = (struct ident_rm_db *)ident_db_ptr;
382
383         /* check if reserved resource for WC is multiple of num_slices */
384         for (d = 0; d < TF_DIR_MAX; d++) {
385                 ainfo.rm_db = ident_db->ident_db[d];
386                 dinfo = ident[d].info;
387
388                 ainfo.info = (struct tf_rm_alloc_info *)dinfo;
389                 ainfo.subtype = 0;
390                 rc = tf_rm_get_all_info(&ainfo, TF_IDENT_TYPE_MAX);
391                 if (rc)
392                         return rc;
393         }
394
395         return 0;
396 }