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