net/bnxt: change RM database type
[dpdk.git] / drivers / net / bnxt / tf_core / tf_tbl.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019-2021 Broadcom
3  * All rights reserved.
4  */
5
6 /* Truflow Table APIs and supporting code */
7
8 #include <rte_common.h>
9
10 #include "tf_tbl.h"
11 #include "tf_common.h"
12 #include "tf_rm.h"
13 #include "tf_util.h"
14 #include "tf_msg.h"
15 #include "tfp.h"
16 #include "tf_session.h"
17 #include "tf_device.h"
18
19 #define TF_TBL_RM_TO_PTR(new_idx, idx, base, shift) {           \
20                 *(new_idx) = (((idx) + (base)) << (shift));     \
21 }
22
23 #define TF_TBL_PTR_TO_RM(new_idx, idx, base, shift) {           \
24                 *(new_idx) = (((idx) >> (shift)) - (base));     \
25 }
26
27 struct tf;
28
29 /**
30  * Table Shadow DBs
31  */
32 static void *shadow_tbl_db[TF_DIR_MAX];
33
34 /**
35  * Init flag, set on bind and cleared on unbind
36  */
37 static uint8_t init;
38
39 /**
40  * Shadow init flag, set on bind and cleared on unbind
41  */
42 static uint8_t shadow_init;
43
44 int
45 tf_tbl_bind(struct tf *tfp,
46             struct tf_tbl_cfg_parms *parms)
47 {
48         int rc, d, i;
49         struct tf_rm_create_db_parms db_cfg = { 0 };
50         struct tbl_rm_db *tbl_db;
51         struct tfp_calloc_parms cparms;
52
53         TF_CHECK_PARMS2(tfp, parms);
54
55         if (init) {
56                 TFP_DRV_LOG(ERR,
57                             "Table DB already initialized\n");
58                 return -EINVAL;
59         }
60
61         memset(&db_cfg, 0, sizeof(db_cfg));
62         cparms.nitems = 1;
63         cparms.size = sizeof(struct tbl_rm_db);
64         cparms.alignment = 0;
65         if (tfp_calloc(&cparms) != 0) {
66                 TFP_DRV_LOG(ERR, "tbl_rm_db alloc error %s\n",
67                             strerror(ENOMEM));
68                 return -ENOMEM;
69         }
70
71         tbl_db = cparms.mem_va;
72         for (i = 0; i < TF_DIR_MAX; i++)
73                 tbl_db->tbl_db[i] = NULL;
74         tf_session_set_db(tfp, TF_MODULE_TYPE_TABLE, tbl_db);
75
76         db_cfg.num_elements = parms->num_elements;
77         db_cfg.module = TF_MODULE_TYPE_TABLE;
78         db_cfg.num_elements = parms->num_elements;
79         db_cfg.cfg = parms->cfg;
80
81         for (d = 0; d < TF_DIR_MAX; d++) {
82                 db_cfg.dir = d;
83                 db_cfg.alloc_cnt = parms->resources->tbl_cnt[d].cnt;
84                 db_cfg.rm_db = (void *)&tbl_db->tbl_db[d];
85
86                 rc = tf_rm_create_db(tfp, &db_cfg);
87                 if (rc) {
88                         TFP_DRV_LOG(ERR,
89                                     "%s: Table DB creation failed\n",
90                                     tf_dir_2_str(d));
91
92                         return rc;
93                 }
94         }
95         init = 1;
96
97         TFP_DRV_LOG(INFO,
98                     "Table Type - initialized\n");
99
100         return 0;
101 }
102
103 int
104 tf_tbl_unbind(struct tf *tfp)
105 {
106         int rc;
107         int i;
108         struct tf_rm_free_db_parms fparms = { 0 };
109         struct tbl_rm_db *tbl_db;
110         void *tbl_db_ptr = NULL;
111         TF_CHECK_PARMS1(tfp);
112
113         /* Bail if nothing has been initialized */
114         if (!init) {
115                 TFP_DRV_LOG(INFO,
116                             "No Table DBs created\n");
117                 return 0;
118         }
119
120         rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
121         if (rc) {
122                 TFP_DRV_LOG(ERR,
123                             "Failed to get em_ext_db from session, rc:%s\n",
124                             strerror(-rc));
125                 return rc;
126         }
127         tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
128
129         for (i = 0; i < TF_DIR_MAX; i++) {
130                 fparms.dir = i;
131                 fparms.rm_db = tbl_db->tbl_db[i];
132                 rc = tf_rm_free_db(tfp, &fparms);
133                 if (rc)
134                         return rc;
135
136                 tbl_db->tbl_db[i] = NULL;
137         }
138
139         init = 0;
140         shadow_init = 0;
141
142         return 0;
143 }
144
145 int
146 tf_tbl_alloc(struct tf *tfp __rte_unused,
147              struct tf_tbl_alloc_parms *parms)
148 {
149         int rc;
150         uint32_t idx;
151         struct tf_rm_allocate_parms aparms = { 0 };
152         struct tf_session *tfs;
153         struct tf_dev_info *dev;
154         uint16_t base = 0, shift = 0;
155         struct tbl_rm_db *tbl_db;
156         void *tbl_db_ptr = NULL;
157
158         TF_CHECK_PARMS2(tfp, parms);
159
160         if (!init) {
161                 TFP_DRV_LOG(ERR,
162                             "%s: No Table DBs created\n",
163                             tf_dir_2_str(parms->dir));
164                 return -EINVAL;
165         }
166
167         /* Retrieve the session information */
168         rc = tf_session_get_session_internal(tfp, &tfs);
169         if (rc)
170                 return rc;
171
172         /* Retrieve the device information */
173         rc = tf_session_get_device(tfs, &dev);
174         if (rc)
175                 return rc;
176
177         rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
178         if (rc) {
179                 TFP_DRV_LOG(ERR,
180                             "Failed to get em_ext_db from session, rc:%s\n",
181                             strerror(-rc));
182                 return rc;
183         }
184         tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
185
186         /* Only get table info if required for the device */
187         if (dev->ops->tf_dev_get_tbl_info) {
188                 rc = dev->ops->tf_dev_get_tbl_info(tfp,
189                                                    tbl_db->tbl_db[parms->dir],
190                                                    parms->type,
191                                                    &base,
192                                                    &shift);
193                 if (rc) {
194                         TFP_DRV_LOG(ERR,
195                                     "%s: Failed to get table info:%d\n",
196                                     tf_dir_2_str(parms->dir),
197                                     parms->type);
198                         return rc;
199                 }
200         }
201
202         /* Allocate requested element */
203         aparms.rm_db = tbl_db->tbl_db[parms->dir];
204         aparms.subtype = parms->type;
205         aparms.index = &idx;
206         rc = tf_rm_allocate(&aparms);
207         if (rc) {
208                 TFP_DRV_LOG(ERR,
209                             "%s: Failed allocate, type:%d\n",
210                             tf_dir_2_str(parms->dir),
211                             parms->type);
212                 return rc;
213         }
214
215         TF_TBL_RM_TO_PTR(&idx, idx, base, shift);
216         *parms->idx = idx;
217
218         return 0;
219 }
220
221 int
222 tf_tbl_free(struct tf *tfp __rte_unused,
223             struct tf_tbl_free_parms *parms)
224 {
225         int rc;
226         struct tf_rm_is_allocated_parms aparms = { 0 };
227         struct tf_rm_free_parms fparms = { 0 };
228         int allocated = 0;
229         struct tf_session *tfs;
230         struct tf_dev_info *dev;
231         uint16_t base = 0, shift = 0;
232         struct tbl_rm_db *tbl_db;
233         void *tbl_db_ptr = NULL;
234
235         TF_CHECK_PARMS2(tfp, parms);
236
237         if (!init) {
238                 TFP_DRV_LOG(ERR,
239                             "%s: No Table DBs created\n",
240                             tf_dir_2_str(parms->dir));
241                 return -EINVAL;
242         }
243         /* Retrieve the session information */
244         rc = tf_session_get_session_internal(tfp, &tfs);
245         if (rc)
246                 return rc;
247
248         /* Retrieve the device information */
249         rc = tf_session_get_device(tfs, &dev);
250         if (rc)
251                 return rc;
252
253         rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
254         if (rc) {
255                 TFP_DRV_LOG(ERR,
256                             "Failed to get em_ext_db from session, rc:%s\n",
257                             strerror(-rc));
258                 return rc;
259         }
260         tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
261
262         /* Only get table info if required for the device */
263         if (dev->ops->tf_dev_get_tbl_info) {
264                 rc = dev->ops->tf_dev_get_tbl_info(tfp,
265                                                    tbl_db->tbl_db[parms->dir],
266                                                    parms->type,
267                                                    &base,
268                                                    &shift);
269                 if (rc) {
270                         TFP_DRV_LOG(ERR,
271                                     "%s: Failed to get table info:%d\n",
272                                     tf_dir_2_str(parms->dir),
273                                     parms->type);
274                         return rc;
275                 }
276         }
277
278         /* Check if element is in use */
279         aparms.rm_db = tbl_db->tbl_db[parms->dir];
280         aparms.subtype = parms->type;
281
282         TF_TBL_PTR_TO_RM(&aparms.index, parms->idx, base, shift);
283
284         aparms.allocated = &allocated;
285         rc = tf_rm_is_allocated(&aparms);
286         if (rc)
287                 return rc;
288
289         if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
290                 TFP_DRV_LOG(ERR,
291                             "%s: Entry already free, type:%d, index:%d\n",
292                             tf_dir_2_str(parms->dir),
293                             parms->type,
294                             parms->idx);
295                 return -EINVAL;
296         }
297         /* Free requested element */
298         fparms.rm_db = tbl_db->tbl_db[parms->dir];
299         fparms.subtype = parms->type;
300
301         TF_TBL_PTR_TO_RM(&fparms.index, parms->idx, base, shift);
302
303         rc = tf_rm_free(&fparms);
304         if (rc) {
305                 TFP_DRV_LOG(ERR,
306                             "%s: Free failed, type:%d, index:%d\n",
307                             tf_dir_2_str(parms->dir),
308                             parms->type,
309                             parms->idx);
310                 return rc;
311         }
312
313         return 0;
314 }
315
316 int
317 tf_tbl_alloc_search(struct tf *tfp,
318                     struct tf_tbl_alloc_search_parms *parms)
319 {
320         int rc = 0;
321         TF_CHECK_PARMS2(tfp, parms);
322
323         if (!shadow_init || !shadow_tbl_db[parms->dir]) {
324                 TFP_DRV_LOG(ERR, "%s: Shadow TBL not initialized.\n",
325                             tf_dir_2_str(parms->dir));
326                 return -EINVAL;
327         }
328
329         return rc;
330 }
331
332 int
333 tf_tbl_set(struct tf *tfp,
334            struct tf_tbl_set_parms *parms)
335 {
336         int rc;
337         int allocated = 0;
338         uint16_t hcapi_type;
339         struct tf_rm_is_allocated_parms aparms = { 0 };
340         struct tf_rm_get_hcapi_parms hparms = { 0 };
341         struct tf_session *tfs;
342         struct tf_dev_info *dev;
343         uint16_t base = 0, shift = 0;
344         struct tbl_rm_db *tbl_db;
345         void *tbl_db_ptr = NULL;
346
347         TF_CHECK_PARMS3(tfp, parms, parms->data);
348
349         if (!init) {
350                 TFP_DRV_LOG(ERR,
351                             "%s: No Table DBs created\n",
352                             tf_dir_2_str(parms->dir));
353                 return -EINVAL;
354         }
355
356         /* Retrieve the session information */
357         rc = tf_session_get_session_internal(tfp, &tfs);
358         if (rc)
359                 return rc;
360
361         /* Retrieve the device information */
362         rc = tf_session_get_device(tfs, &dev);
363         if (rc)
364                 return rc;
365
366         rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
367         if (rc) {
368                 TFP_DRV_LOG(ERR,
369                             "Failed to get em_ext_db from session, rc:%s\n",
370                             strerror(-rc));
371                 return rc;
372         }
373         tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
374
375         /* Only get table info if required for the device */
376         if (dev->ops->tf_dev_get_tbl_info) {
377                 rc = dev->ops->tf_dev_get_tbl_info(tfp,
378                                                    tbl_db->tbl_db[parms->dir],
379                                                    parms->type,
380                                                    &base,
381                                                    &shift);
382                 if (rc) {
383                         TFP_DRV_LOG(ERR,
384                                     "%s: Failed to get table info:%d\n",
385                                     tf_dir_2_str(parms->dir),
386                                     parms->type);
387                         return rc;
388                 }
389         }
390
391         /* Verify that the entry has been previously allocated */
392         aparms.rm_db = tbl_db->tbl_db[parms->dir];
393         aparms.subtype = parms->type;
394         TF_TBL_PTR_TO_RM(&aparms.index, parms->idx, base, shift);
395
396         aparms.allocated = &allocated;
397         rc = tf_rm_is_allocated(&aparms);
398         if (rc)
399                 return rc;
400
401         if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
402                 TFP_DRV_LOG(ERR,
403                    "%s, Invalid or not allocated index, type:%d, idx:%d\n",
404                    tf_dir_2_str(parms->dir),
405                    parms->type,
406                    parms->idx);
407                 return -EINVAL;
408         }
409
410         /* Set the entry */
411         hparms.rm_db = tbl_db->tbl_db[parms->dir];
412         hparms.subtype = parms->type;
413         hparms.hcapi_type = &hcapi_type;
414         rc = tf_rm_get_hcapi_type(&hparms);
415         if (rc) {
416                 TFP_DRV_LOG(ERR,
417                             "%s, Failed type lookup, type:%d, rc:%s\n",
418                             tf_dir_2_str(parms->dir),
419                             parms->type,
420                             strerror(-rc));
421                 return rc;
422         }
423
424         rc = tf_msg_set_tbl_entry(tfp,
425                                   parms->dir,
426                                   hcapi_type,
427                                   parms->data_sz_in_bytes,
428                                   parms->data,
429                                   parms->idx);
430         if (rc) {
431                 TFP_DRV_LOG(ERR,
432                             "%s, Set failed, type:%d, rc:%s\n",
433                             tf_dir_2_str(parms->dir),
434                             parms->type,
435                             strerror(-rc));
436                 return rc;
437         }
438
439         return 0;
440 }
441
442 int
443 tf_tbl_get(struct tf *tfp,
444            struct tf_tbl_get_parms *parms)
445 {
446         int rc;
447         uint16_t hcapi_type;
448         int allocated = 0;
449         struct tf_rm_is_allocated_parms aparms = { 0 };
450         struct tf_rm_get_hcapi_parms hparms = { 0 };
451         struct tf_session *tfs;
452         struct tf_dev_info *dev;
453         uint16_t base = 0, shift = 0;
454         struct tbl_rm_db *tbl_db;
455         void *tbl_db_ptr = NULL;
456
457         TF_CHECK_PARMS3(tfp, parms, parms->data);
458
459         if (!init) {
460                 TFP_DRV_LOG(ERR,
461                             "%s: No Table DBs created\n",
462                             tf_dir_2_str(parms->dir));
463                 return -EINVAL;
464         }
465
466
467         /* Retrieve the session information */
468         rc = tf_session_get_session_internal(tfp, &tfs);
469         if (rc)
470                 return rc;
471
472         /* Retrieve the device information */
473         rc = tf_session_get_device(tfs, &dev);
474         if (rc)
475                 return rc;
476
477         rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
478         if (rc) {
479                 TFP_DRV_LOG(ERR,
480                             "Failed to get em_ext_db from session, rc:%s\n",
481                             strerror(-rc));
482                 return rc;
483         }
484         tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
485
486         /* Only get table info if required for the device */
487         if (dev->ops->tf_dev_get_tbl_info) {
488                 rc = dev->ops->tf_dev_get_tbl_info(tfp,
489                                                    tbl_db->tbl_db[parms->dir],
490                                                    parms->type,
491                                                    &base,
492                                                    &shift);
493                 if (rc) {
494                         TFP_DRV_LOG(ERR,
495                                     "%s: Failed to get table info:%d\n",
496                                     tf_dir_2_str(parms->dir),
497                                     parms->type);
498                         return rc;
499                 }
500         }
501
502         /* Verify that the entry has been previously allocated */
503         aparms.rm_db = tbl_db->tbl_db[parms->dir];
504         aparms.subtype = parms->type;
505         TF_TBL_PTR_TO_RM(&aparms.index, parms->idx, base, shift);
506
507         aparms.allocated = &allocated;
508         rc = tf_rm_is_allocated(&aparms);
509         if (rc)
510                 return rc;
511
512         if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
513                 TFP_DRV_LOG(ERR,
514                    "%s, Invalid or not allocated index, type:%d, idx:%d\n",
515                    tf_dir_2_str(parms->dir),
516                    parms->type,
517                    parms->idx);
518                 return -EINVAL;
519         }
520
521         /* Set the entry */
522         hparms.rm_db = tbl_db->tbl_db[parms->dir];
523         hparms.subtype = parms->type;
524         hparms.hcapi_type = &hcapi_type;
525         rc = tf_rm_get_hcapi_type(&hparms);
526         if (rc) {
527                 TFP_DRV_LOG(ERR,
528                             "%s, Failed type lookup, type:%d, rc:%s\n",
529                             tf_dir_2_str(parms->dir),
530                             parms->type,
531                             strerror(-rc));
532                 return rc;
533         }
534
535         /* Get the entry */
536         rc = tf_msg_get_tbl_entry(tfp,
537                                   parms->dir,
538                                   hcapi_type,
539                                   parms->data_sz_in_bytes,
540                                   parms->data,
541                                   parms->idx);
542         if (rc) {
543                 TFP_DRV_LOG(ERR,
544                             "%s, Get failed, type:%d, rc:%s\n",
545                             tf_dir_2_str(parms->dir),
546                             parms->type,
547                             strerror(-rc));
548                 return rc;
549         }
550
551         return 0;
552 }
553
554 int
555 tf_tbl_bulk_get(struct tf *tfp,
556                 struct tf_tbl_get_bulk_parms *parms)
557 {
558         int rc;
559         uint16_t hcapi_type;
560         struct tf_rm_get_hcapi_parms hparms = { 0 };
561         struct tf_rm_check_indexes_in_range_parms cparms = { 0 };
562         struct tf_session *tfs;
563         struct tf_dev_info *dev;
564         uint16_t base = 0, shift = 0;
565         struct tbl_rm_db *tbl_db;
566         void *tbl_db_ptr = NULL;
567
568         TF_CHECK_PARMS2(tfp, parms);
569
570         if (!init) {
571                 TFP_DRV_LOG(ERR,
572                             "%s: No Table DBs created\n",
573                             tf_dir_2_str(parms->dir));
574
575                 return -EINVAL;
576         }
577
578         /* Retrieve the session information */
579         rc = tf_session_get_session_internal(tfp, &tfs);
580         if (rc)
581                 return rc;
582
583         /* Retrieve the device information */
584         rc = tf_session_get_device(tfs, &dev);
585         if (rc)
586                 return rc;
587
588         rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
589         if (rc) {
590                 TFP_DRV_LOG(ERR,
591                             "Failed to get em_ext_db from session, rc:%s\n",
592                             strerror(-rc));
593                 return rc;
594         }
595         tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
596
597         /* Only get table info if required for the device */
598         if (dev->ops->tf_dev_get_tbl_info) {
599                 rc = dev->ops->tf_dev_get_tbl_info(tfp,
600                                                    tbl_db->tbl_db[parms->dir],
601                                                    parms->type,
602                                                    &base,
603                                                    &shift);
604                 if (rc) {
605                         TFP_DRV_LOG(ERR,
606                                     "%s: Failed to get table info:%d\n",
607                                     tf_dir_2_str(parms->dir),
608                                     parms->type);
609                         return rc;
610                 }
611         }
612
613         /* Verify that the entries are in the range of reserved resources. */
614         cparms.rm_db = tbl_db->tbl_db[parms->dir];
615         cparms.subtype = parms->type;
616
617         TF_TBL_PTR_TO_RM(&cparms.starting_index, parms->starting_idx,
618                          base, shift);
619
620         cparms.num_entries = parms->num_entries;
621
622         rc = tf_rm_check_indexes_in_range(&cparms);
623         if (rc) {
624                 TFP_DRV_LOG(ERR,
625                             "%s, Invalid or %d index starting from %d"
626                             " not in range, type:%d",
627                             tf_dir_2_str(parms->dir),
628                             parms->starting_idx,
629                             parms->num_entries,
630                             parms->type);
631                 return rc;
632         }
633
634         hparms.rm_db = tbl_db->tbl_db[parms->dir];
635         hparms.subtype = parms->type;
636         hparms.hcapi_type = &hcapi_type;
637         rc = tf_rm_get_hcapi_type(&hparms);
638         if (rc) {
639                 TFP_DRV_LOG(ERR,
640                             "%s, Failed type lookup, type:%d, rc:%s\n",
641                             tf_dir_2_str(parms->dir),
642                             parms->type,
643                             strerror(-rc));
644                 return rc;
645         }
646
647         /* Get the entries */
648         rc = tf_msg_bulk_get_tbl_entry(tfp,
649                                        parms->dir,
650                                        hcapi_type,
651                                        parms->starting_idx,
652                                        parms->num_entries,
653                                        parms->entry_sz_in_bytes,
654                                        parms->physical_mem_addr);
655         if (rc) {
656                 TFP_DRV_LOG(ERR,
657                             "%s, Bulk get failed, type:%d, rc:%s\n",
658                             tf_dir_2_str(parms->dir),
659                             parms->type,
660                             strerror(-rc));
661         }
662
663         return rc;
664 }