1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2019-2021 Broadcom
6 /* Truflow Table APIs and supporting code */
8 #include <rte_common.h>
11 #include "tf_common.h"
16 #include "tf_session.h"
17 #include "tf_device.h"
19 #define TF_TBL_RM_TO_PTR(new_idx, idx, base, shift) { \
20 *(new_idx) = (((idx) + (base)) << (shift)); \
23 #define TF_TBL_PTR_TO_RM(new_idx, idx, base, shift) { \
24 *(new_idx) = (((idx) >> (shift)) - (base)); \
30 * Shadow init flag, set on bind and cleared on unbind
32 static uint8_t shadow_init;
35 tf_tbl_bind(struct tf *tfp,
36 struct tf_tbl_cfg_parms *parms)
39 int db_rc[TF_DIR_MAX] = { 0 };
40 struct tf_rm_create_db_parms db_cfg = { 0 };
41 struct tbl_rm_db *tbl_db;
42 struct tfp_calloc_parms cparms;
43 struct tf_session *tfs;
45 TF_CHECK_PARMS2(tfp, parms);
47 /* Retrieve the session information */
48 rc = tf_session_get_session_internal(tfp, &tfs);
52 memset(&db_cfg, 0, sizeof(db_cfg));
54 cparms.size = sizeof(struct tbl_rm_db);
56 if (tfp_calloc(&cparms) != 0) {
57 TFP_DRV_LOG(ERR, "tbl_rm_db alloc error %s\n",
62 tbl_db = cparms.mem_va;
63 for (i = 0; i < TF_DIR_MAX; i++)
64 tbl_db->tbl_db[i] = NULL;
65 tf_session_set_db(tfp, TF_MODULE_TYPE_TABLE, tbl_db);
67 db_cfg.num_elements = parms->num_elements;
68 db_cfg.module = TF_MODULE_TYPE_TABLE;
69 db_cfg.num_elements = parms->num_elements;
70 db_cfg.cfg = parms->cfg;
72 for (d = 0; d < TF_DIR_MAX; d++) {
74 db_cfg.alloc_cnt = parms->resources->tbl_cnt[d].cnt;
75 db_cfg.rm_db = (void *)&tbl_db->tbl_db[d];
76 if (tf_session_is_shared_session(tfs) &&
77 (!tf_session_is_shared_session_creator(tfs)))
78 db_rc[d] = tf_rm_create_db_no_reservation(tfp, &db_cfg);
80 db_rc[d] = tf_rm_create_db(tfp, &db_cfg);
84 if (db_rc[TF_DIR_RX] && db_rc[TF_DIR_TX]) {
86 "%s: No Table DB created\n",
88 return db_rc[TF_DIR_RX];
92 "Table Type - initialized\n");
98 tf_tbl_unbind(struct tf *tfp)
102 struct tf_rm_free_db_parms fparms = { 0 };
103 struct tbl_rm_db *tbl_db;
104 void *tbl_db_ptr = NULL;
105 TF_CHECK_PARMS1(tfp);
107 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
110 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
112 for (i = 0; i < TF_DIR_MAX; i++) {
113 if (tbl_db->tbl_db[i] == NULL)
116 fparms.rm_db = tbl_db->tbl_db[i];
117 rc = tf_rm_free_db(tfp, &fparms);
121 tbl_db->tbl_db[i] = NULL;
130 tf_tbl_alloc(struct tf *tfp __rte_unused,
131 struct tf_tbl_alloc_parms *parms)
135 struct tf_rm_allocate_parms aparms = { 0 };
136 struct tf_session *tfs;
137 struct tf_dev_info *dev;
138 uint16_t base = 0, shift = 0;
139 struct tbl_rm_db *tbl_db;
140 void *tbl_db_ptr = NULL;
142 TF_CHECK_PARMS2(tfp, parms);
144 /* Retrieve the session information */
145 rc = tf_session_get_session_internal(tfp, &tfs);
149 /* Retrieve the device information */
150 rc = tf_session_get_device(tfs, &dev);
154 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
157 "Failed to get em_ext_db from session, rc:%s\n",
161 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
163 /* Only get table info if required for the device */
164 if (dev->ops->tf_dev_get_tbl_info) {
165 rc = dev->ops->tf_dev_get_tbl_info(tfp,
166 tbl_db->tbl_db[parms->dir],
172 "%s: Failed to get table info:%d\n",
173 tf_dir_2_str(parms->dir),
179 /* Allocate requested element */
180 aparms.rm_db = tbl_db->tbl_db[parms->dir];
181 aparms.subtype = parms->type;
183 rc = tf_rm_allocate(&aparms);
186 "%s: Failed allocate, type:%d\n",
187 tf_dir_2_str(parms->dir),
192 TF_TBL_RM_TO_PTR(&idx, idx, base, shift);
199 tf_tbl_free(struct tf *tfp __rte_unused,
200 struct tf_tbl_free_parms *parms)
203 struct tf_rm_is_allocated_parms aparms = { 0 };
204 struct tf_rm_free_parms fparms = { 0 };
206 struct tf_session *tfs;
207 struct tf_dev_info *dev;
208 uint16_t base = 0, shift = 0;
209 struct tbl_rm_db *tbl_db;
210 void *tbl_db_ptr = NULL;
212 TF_CHECK_PARMS2(tfp, parms);
214 /* Retrieve the session information */
215 rc = tf_session_get_session_internal(tfp, &tfs);
219 /* Retrieve the device information */
220 rc = tf_session_get_device(tfs, &dev);
224 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
227 "Failed to get em_ext_db from session, rc:%s\n",
231 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
233 /* Only get table info if required for the device */
234 if (dev->ops->tf_dev_get_tbl_info) {
235 rc = dev->ops->tf_dev_get_tbl_info(tfp,
236 tbl_db->tbl_db[parms->dir],
242 "%s: Failed to get table info:%d\n",
243 tf_dir_2_str(parms->dir),
249 /* Check if element is in use */
250 aparms.rm_db = tbl_db->tbl_db[parms->dir];
251 aparms.subtype = parms->type;
253 TF_TBL_PTR_TO_RM(&aparms.index, parms->idx, base, shift);
255 aparms.allocated = &allocated;
256 rc = tf_rm_is_allocated(&aparms);
260 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
262 "%s: Entry already free, type:%d, index:%d\n",
263 tf_dir_2_str(parms->dir),
269 /* If this is counter table, clear the entry on free */
270 if (parms->type == TF_TBL_TYPE_ACT_STATS_64) {
271 uint8_t data[8] = { 0 };
272 uint16_t hcapi_type = 0;
273 struct tf_rm_get_hcapi_parms hparms = { 0 };
275 /* Get the hcapi type */
276 hparms.rm_db = tbl_db->tbl_db[parms->dir];
277 hparms.subtype = parms->type;
278 hparms.hcapi_type = &hcapi_type;
279 rc = tf_rm_get_hcapi_type(&hparms);
282 "%s, Failed type lookup, type:%d, rc:%s\n",
283 tf_dir_2_str(parms->dir),
290 rc = tf_msg_set_tbl_entry(tfp,
298 "%s, Set failed, type:%d, rc:%s\n",
299 tf_dir_2_str(parms->dir),
306 /* Free requested element */
307 fparms.rm_db = tbl_db->tbl_db[parms->dir];
308 fparms.subtype = parms->type;
310 TF_TBL_PTR_TO_RM(&fparms.index, parms->idx, base, shift);
312 rc = tf_rm_free(&fparms);
315 "%s: Free failed, type:%d, index:%d\n",
316 tf_dir_2_str(parms->dir),
326 tf_tbl_set(struct tf *tfp,
327 struct tf_tbl_set_parms *parms)
332 struct tf_rm_is_allocated_parms aparms = { 0 };
333 struct tf_rm_get_hcapi_parms hparms = { 0 };
334 struct tf_session *tfs;
335 struct tf_dev_info *dev;
336 uint16_t base = 0, shift = 0;
337 struct tbl_rm_db *tbl_db;
338 void *tbl_db_ptr = NULL;
340 TF_CHECK_PARMS3(tfp, parms, parms->data);
342 /* Retrieve the session information */
343 rc = tf_session_get_session_internal(tfp, &tfs);
347 /* Retrieve the device information */
348 rc = tf_session_get_device(tfs, &dev);
352 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
355 "Failed to get em_ext_db from session, rc:%s\n",
359 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
361 /* Only get table info if required for the device */
362 if (dev->ops->tf_dev_get_tbl_info) {
363 rc = dev->ops->tf_dev_get_tbl_info(tfp,
364 tbl_db->tbl_db[parms->dir],
370 "%s: Failed to get table info:%d\n",
371 tf_dir_2_str(parms->dir),
377 /* Verify that the entry has been previously allocated */
378 aparms.rm_db = tbl_db->tbl_db[parms->dir];
379 aparms.subtype = parms->type;
380 TF_TBL_PTR_TO_RM(&aparms.index, parms->idx, base, shift);
382 aparms.allocated = &allocated;
383 rc = tf_rm_is_allocated(&aparms);
387 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
389 "%s, Invalid or not allocated index, type:%d, idx:%d\n",
390 tf_dir_2_str(parms->dir),
397 hparms.rm_db = tbl_db->tbl_db[parms->dir];
398 hparms.subtype = parms->type;
399 hparms.hcapi_type = &hcapi_type;
400 rc = tf_rm_get_hcapi_type(&hparms);
403 "%s, Failed type lookup, type:%d, rc:%s\n",
404 tf_dir_2_str(parms->dir),
410 rc = tf_msg_set_tbl_entry(tfp,
413 parms->data_sz_in_bytes,
418 "%s, Set failed, type:%d, rc:%s\n",
419 tf_dir_2_str(parms->dir),
429 tf_tbl_get(struct tf *tfp,
430 struct tf_tbl_get_parms *parms)
435 struct tf_rm_is_allocated_parms aparms = { 0 };
436 struct tf_rm_get_hcapi_parms hparms = { 0 };
437 struct tf_session *tfs;
438 struct tf_dev_info *dev;
439 uint16_t base = 0, shift = 0;
440 struct tbl_rm_db *tbl_db;
441 void *tbl_db_ptr = NULL;
443 TF_CHECK_PARMS3(tfp, parms, parms->data);
445 /* Retrieve the session information */
446 rc = tf_session_get_session_internal(tfp, &tfs);
450 /* Retrieve the device information */
451 rc = tf_session_get_device(tfs, &dev);
455 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
458 "Failed to get em_ext_db from session, rc:%s\n",
462 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
464 /* Only get table info if required for the device */
465 if (dev->ops->tf_dev_get_tbl_info) {
466 rc = dev->ops->tf_dev_get_tbl_info(tfp,
467 tbl_db->tbl_db[parms->dir],
473 "%s: Failed to get table info:%d\n",
474 tf_dir_2_str(parms->dir),
480 /* Verify that the entry has been previously allocated */
481 aparms.rm_db = tbl_db->tbl_db[parms->dir];
482 aparms.subtype = parms->type;
483 TF_TBL_PTR_TO_RM(&aparms.index, parms->idx, base, shift);
485 aparms.allocated = &allocated;
486 rc = tf_rm_is_allocated(&aparms);
490 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
492 "%s, Invalid or not allocated index, type:%d, idx:%d\n",
493 tf_dir_2_str(parms->dir),
500 hparms.rm_db = tbl_db->tbl_db[parms->dir];
501 hparms.subtype = parms->type;
502 hparms.hcapi_type = &hcapi_type;
503 rc = tf_rm_get_hcapi_type(&hparms);
506 "%s, Failed type lookup, type:%d, rc:%s\n",
507 tf_dir_2_str(parms->dir),
514 rc = tf_msg_get_tbl_entry(tfp,
517 parms->data_sz_in_bytes,
522 "%s, Get failed, type:%d, rc:%s\n",
523 tf_dir_2_str(parms->dir),
533 tf_tbl_bulk_get(struct tf *tfp,
534 struct tf_tbl_get_bulk_parms *parms)
538 struct tf_rm_get_hcapi_parms hparms = { 0 };
539 struct tf_rm_check_indexes_in_range_parms cparms = { 0 };
540 struct tf_session *tfs;
541 struct tf_dev_info *dev;
542 uint16_t base = 0, shift = 0;
543 struct tbl_rm_db *tbl_db;
544 void *tbl_db_ptr = NULL;
546 TF_CHECK_PARMS2(tfp, parms);
548 /* Retrieve the session information */
549 rc = tf_session_get_session_internal(tfp, &tfs);
553 /* Retrieve the device information */
554 rc = tf_session_get_device(tfs, &dev);
558 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
561 "Failed to get em_ext_db from session, rc:%s\n",
565 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
567 /* Only get table info if required for the device */
568 if (dev->ops->tf_dev_get_tbl_info) {
569 rc = dev->ops->tf_dev_get_tbl_info(tfp,
570 tbl_db->tbl_db[parms->dir],
576 "%s: Failed to get table info:%d\n",
577 tf_dir_2_str(parms->dir),
583 /* Verify that the entries are in the range of reserved resources. */
584 cparms.rm_db = tbl_db->tbl_db[parms->dir];
585 cparms.subtype = parms->type;
587 TF_TBL_PTR_TO_RM(&cparms.starting_index, parms->starting_idx,
590 cparms.num_entries = parms->num_entries;
592 rc = tf_rm_check_indexes_in_range(&cparms);
595 "%s, Invalid or %d index starting from %d"
596 " not in range, type:%d",
597 tf_dir_2_str(parms->dir),
604 hparms.rm_db = tbl_db->tbl_db[parms->dir];
605 hparms.subtype = parms->type;
606 hparms.hcapi_type = &hcapi_type;
607 rc = tf_rm_get_hcapi_type(&hparms);
610 "%s, Failed type lookup, type:%d, rc:%s\n",
611 tf_dir_2_str(parms->dir),
617 /* Get the entries */
618 rc = tf_msg_bulk_get_tbl_entry(tfp,
623 parms->entry_sz_in_bytes,
624 parms->physical_mem_addr);
627 "%s, Bulk get failed, type:%d, rc:%s\n",
628 tf_dir_2_str(parms->dir),
637 tf_tbl_get_resc_info(struct tf *tfp,
638 struct tf_tbl_resource_info *tbl)
642 struct tf_resource_info *dinfo;
643 struct tf_rm_get_alloc_info_parms ainfo;
644 void *tbl_db_ptr = NULL;
645 struct tbl_rm_db *tbl_db;
646 uint16_t base = 0, shift = 0;
647 struct tf_dev_info *dev;
648 struct tf_session *tfs;
650 TF_CHECK_PARMS2(tfp, tbl);
652 /* Retrieve the session information */
653 rc = tf_session_get_session_internal(tfp, &tfs);
657 /* Retrieve the device information */
658 rc = tf_session_get_device(tfs, &dev);
662 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
664 return 0; /* db doesn't exist */
666 return rc; /* error getting db */
668 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
670 /* check if reserved resource for WC is multiple of num_slices */
671 for (d = 0; d < TF_DIR_MAX; d++) {
672 ainfo.rm_db = tbl_db->tbl_db[d];
678 ainfo.info = (struct tf_rm_alloc_info *)dinfo;
680 rc = tf_rm_get_all_info(&ainfo, TF_TBL_TYPE_MAX);
684 if (dev->ops->tf_dev_get_tbl_info) {
686 for (i = 0; i < TF_TBL_TYPE_MAX; i++) {
687 /* Only get table info if required for the device */
688 rc = dev->ops->tf_dev_get_tbl_info(tfp,
695 "%s: Failed to get table info:%d\n",
701 TF_TBL_RM_TO_PTR(&dinfo[i].start,