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