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)); \
32 static void *shadow_tbl_db[TF_DIR_MAX];
35 * Shadow init flag, set on bind and cleared on unbind
37 static uint8_t shadow_init;
40 tf_tbl_bind(struct tf *tfp,
41 struct tf_tbl_cfg_parms *parms)
44 int db_rc[TF_DIR_MAX] = { 0 };
45 struct tf_rm_create_db_parms db_cfg = { 0 };
46 struct tbl_rm_db *tbl_db;
47 struct tfp_calloc_parms cparms;
48 struct tf_session *tfs;
50 TF_CHECK_PARMS2(tfp, parms);
52 /* Retrieve the session information */
53 rc = tf_session_get_session_internal(tfp, &tfs);
57 memset(&db_cfg, 0, sizeof(db_cfg));
59 cparms.size = sizeof(struct tbl_rm_db);
61 if (tfp_calloc(&cparms) != 0) {
62 TFP_DRV_LOG(ERR, "tbl_rm_db alloc error %s\n",
67 tbl_db = cparms.mem_va;
68 for (i = 0; i < TF_DIR_MAX; i++)
69 tbl_db->tbl_db[i] = NULL;
70 tf_session_set_db(tfp, TF_MODULE_TYPE_TABLE, tbl_db);
72 db_cfg.num_elements = parms->num_elements;
73 db_cfg.module = TF_MODULE_TYPE_TABLE;
74 db_cfg.num_elements = parms->num_elements;
75 db_cfg.cfg = parms->cfg;
77 for (d = 0; d < TF_DIR_MAX; d++) {
79 db_cfg.alloc_cnt = parms->resources->tbl_cnt[d].cnt;
80 db_cfg.rm_db = (void *)&tbl_db->tbl_db[d];
81 if (tf_session_is_shared_session(tfs) &&
82 (!tf_session_is_shared_session_creator(tfs)))
83 db_rc[d] = tf_rm_create_db_no_reservation(tfp, &db_cfg);
85 db_rc[d] = tf_rm_create_db(tfp, &db_cfg);
89 if (db_rc[TF_DIR_RX] && db_rc[TF_DIR_TX]) {
91 "%s: No Table DB created\n",
93 return db_rc[TF_DIR_RX];
97 "Table Type - initialized\n");
103 tf_tbl_unbind(struct tf *tfp)
107 struct tf_rm_free_db_parms fparms = { 0 };
108 struct tbl_rm_db *tbl_db;
109 void *tbl_db_ptr = NULL;
110 TF_CHECK_PARMS1(tfp);
112 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
115 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
117 for (i = 0; i < TF_DIR_MAX; i++) {
118 if (tbl_db->tbl_db[i] == NULL)
121 fparms.rm_db = tbl_db->tbl_db[i];
122 rc = tf_rm_free_db(tfp, &fparms);
126 tbl_db->tbl_db[i] = NULL;
135 tf_tbl_alloc(struct tf *tfp __rte_unused,
136 struct tf_tbl_alloc_parms *parms)
140 struct tf_rm_allocate_parms aparms = { 0 };
141 struct tf_session *tfs;
142 struct tf_dev_info *dev;
143 uint16_t base = 0, shift = 0;
144 struct tbl_rm_db *tbl_db;
145 void *tbl_db_ptr = NULL;
147 TF_CHECK_PARMS2(tfp, parms);
149 /* Retrieve the session information */
150 rc = tf_session_get_session_internal(tfp, &tfs);
154 /* Retrieve the device information */
155 rc = tf_session_get_device(tfs, &dev);
159 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
162 "Failed to get em_ext_db from session, rc:%s\n",
166 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
168 /* Only get table info if required for the device */
169 if (dev->ops->tf_dev_get_tbl_info) {
170 rc = dev->ops->tf_dev_get_tbl_info(tfp,
171 tbl_db->tbl_db[parms->dir],
177 "%s: Failed to get table info:%d\n",
178 tf_dir_2_str(parms->dir),
184 /* Allocate requested element */
185 aparms.rm_db = tbl_db->tbl_db[parms->dir];
186 aparms.subtype = parms->type;
188 rc = tf_rm_allocate(&aparms);
191 "%s: Failed allocate, type:%d\n",
192 tf_dir_2_str(parms->dir),
197 TF_TBL_RM_TO_PTR(&idx, idx, base, shift);
204 tf_tbl_free(struct tf *tfp __rte_unused,
205 struct tf_tbl_free_parms *parms)
208 struct tf_rm_is_allocated_parms aparms = { 0 };
209 struct tf_rm_free_parms fparms = { 0 };
211 struct tf_session *tfs;
212 struct tf_dev_info *dev;
213 uint16_t base = 0, shift = 0;
214 struct tbl_rm_db *tbl_db;
215 void *tbl_db_ptr = NULL;
217 TF_CHECK_PARMS2(tfp, parms);
219 /* Retrieve the session information */
220 rc = tf_session_get_session_internal(tfp, &tfs);
224 /* Retrieve the device information */
225 rc = tf_session_get_device(tfs, &dev);
229 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
232 "Failed to get em_ext_db from session, rc:%s\n",
236 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
238 /* Only get table info if required for the device */
239 if (dev->ops->tf_dev_get_tbl_info) {
240 rc = dev->ops->tf_dev_get_tbl_info(tfp,
241 tbl_db->tbl_db[parms->dir],
247 "%s: Failed to get table info:%d\n",
248 tf_dir_2_str(parms->dir),
254 /* Check if element is in use */
255 aparms.rm_db = tbl_db->tbl_db[parms->dir];
256 aparms.subtype = parms->type;
258 TF_TBL_PTR_TO_RM(&aparms.index, parms->idx, base, shift);
260 aparms.allocated = &allocated;
261 rc = tf_rm_is_allocated(&aparms);
265 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
267 "%s: Entry already free, type:%d, index:%d\n",
268 tf_dir_2_str(parms->dir),
274 /* If this is counter table, clear the entry on free */
275 if (parms->type == TF_TBL_TYPE_ACT_STATS_64) {
276 uint8_t data[8] = { 0 };
277 uint16_t hcapi_type = 0;
278 struct tf_rm_get_hcapi_parms hparms = { 0 };
280 /* Get the hcapi type */
281 hparms.rm_db = tbl_db->tbl_db[parms->dir];
282 hparms.subtype = parms->type;
283 hparms.hcapi_type = &hcapi_type;
284 rc = tf_rm_get_hcapi_type(&hparms);
287 "%s, Failed type lookup, type:%d, rc:%s\n",
288 tf_dir_2_str(parms->dir),
295 rc = tf_msg_set_tbl_entry(tfp,
303 "%s, Set failed, type:%d, rc:%s\n",
304 tf_dir_2_str(parms->dir),
311 /* Free requested element */
312 fparms.rm_db = tbl_db->tbl_db[parms->dir];
313 fparms.subtype = parms->type;
315 TF_TBL_PTR_TO_RM(&fparms.index, parms->idx, base, shift);
317 rc = tf_rm_free(&fparms);
320 "%s: Free failed, type:%d, index:%d\n",
321 tf_dir_2_str(parms->dir),
331 tf_tbl_alloc_search(struct tf *tfp,
332 struct tf_tbl_alloc_search_parms *parms)
335 TF_CHECK_PARMS2(tfp, parms);
337 if (!shadow_init || !shadow_tbl_db[parms->dir]) {
338 TFP_DRV_LOG(ERR, "%s: Shadow TBL not initialized.\n",
339 tf_dir_2_str(parms->dir));
347 tf_tbl_set(struct tf *tfp,
348 struct tf_tbl_set_parms *parms)
353 struct tf_rm_is_allocated_parms aparms = { 0 };
354 struct tf_rm_get_hcapi_parms hparms = { 0 };
355 struct tf_session *tfs;
356 struct tf_dev_info *dev;
357 uint16_t base = 0, shift = 0;
358 struct tbl_rm_db *tbl_db;
359 void *tbl_db_ptr = NULL;
361 TF_CHECK_PARMS3(tfp, parms, parms->data);
363 /* Retrieve the session information */
364 rc = tf_session_get_session_internal(tfp, &tfs);
368 /* Retrieve the device information */
369 rc = tf_session_get_device(tfs, &dev);
373 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
376 "Failed to get em_ext_db from session, rc:%s\n",
380 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
382 /* Only get table info if required for the device */
383 if (dev->ops->tf_dev_get_tbl_info) {
384 rc = dev->ops->tf_dev_get_tbl_info(tfp,
385 tbl_db->tbl_db[parms->dir],
391 "%s: Failed to get table info:%d\n",
392 tf_dir_2_str(parms->dir),
398 /* Verify that the entry has been previously allocated */
399 aparms.rm_db = tbl_db->tbl_db[parms->dir];
400 aparms.subtype = parms->type;
401 TF_TBL_PTR_TO_RM(&aparms.index, parms->idx, base, shift);
403 aparms.allocated = &allocated;
404 rc = tf_rm_is_allocated(&aparms);
408 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
410 "%s, Invalid or not allocated index, type:%d, idx:%d\n",
411 tf_dir_2_str(parms->dir),
418 hparms.rm_db = tbl_db->tbl_db[parms->dir];
419 hparms.subtype = parms->type;
420 hparms.hcapi_type = &hcapi_type;
421 rc = tf_rm_get_hcapi_type(&hparms);
424 "%s, Failed type lookup, type:%d, rc:%s\n",
425 tf_dir_2_str(parms->dir),
431 rc = tf_msg_set_tbl_entry(tfp,
434 parms->data_sz_in_bytes,
439 "%s, Set failed, type:%d, rc:%s\n",
440 tf_dir_2_str(parms->dir),
450 tf_tbl_get(struct tf *tfp,
451 struct tf_tbl_get_parms *parms)
456 struct tf_rm_is_allocated_parms aparms = { 0 };
457 struct tf_rm_get_hcapi_parms hparms = { 0 };
458 struct tf_session *tfs;
459 struct tf_dev_info *dev;
460 uint16_t base = 0, shift = 0;
461 struct tbl_rm_db *tbl_db;
462 void *tbl_db_ptr = NULL;
464 TF_CHECK_PARMS3(tfp, parms, parms->data);
466 /* Retrieve the session information */
467 rc = tf_session_get_session_internal(tfp, &tfs);
471 /* Retrieve the device information */
472 rc = tf_session_get_device(tfs, &dev);
476 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
479 "Failed to get em_ext_db from session, rc:%s\n",
483 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
485 /* Only get table info if required for the device */
486 if (dev->ops->tf_dev_get_tbl_info) {
487 rc = dev->ops->tf_dev_get_tbl_info(tfp,
488 tbl_db->tbl_db[parms->dir],
494 "%s: Failed to get table info:%d\n",
495 tf_dir_2_str(parms->dir),
501 /* Verify that the entry has been previously allocated */
502 aparms.rm_db = tbl_db->tbl_db[parms->dir];
503 aparms.subtype = parms->type;
504 TF_TBL_PTR_TO_RM(&aparms.index, parms->idx, base, shift);
506 aparms.allocated = &allocated;
507 rc = tf_rm_is_allocated(&aparms);
511 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
513 "%s, Invalid or not allocated index, type:%d, idx:%d\n",
514 tf_dir_2_str(parms->dir),
521 hparms.rm_db = tbl_db->tbl_db[parms->dir];
522 hparms.subtype = parms->type;
523 hparms.hcapi_type = &hcapi_type;
524 rc = tf_rm_get_hcapi_type(&hparms);
527 "%s, Failed type lookup, type:%d, rc:%s\n",
528 tf_dir_2_str(parms->dir),
535 rc = tf_msg_get_tbl_entry(tfp,
538 parms->data_sz_in_bytes,
543 "%s, Get failed, type:%d, rc:%s\n",
544 tf_dir_2_str(parms->dir),
554 tf_tbl_bulk_get(struct tf *tfp,
555 struct tf_tbl_get_bulk_parms *parms)
559 struct tf_rm_get_hcapi_parms hparms = { 0 };
560 struct tf_rm_check_indexes_in_range_parms cparms = { 0 };
561 struct tf_session *tfs;
562 struct tf_dev_info *dev;
563 uint16_t base = 0, shift = 0;
564 struct tbl_rm_db *tbl_db;
565 void *tbl_db_ptr = NULL;
567 TF_CHECK_PARMS2(tfp, parms);
569 /* Retrieve the session information */
570 rc = tf_session_get_session_internal(tfp, &tfs);
574 /* Retrieve the device information */
575 rc = tf_session_get_device(tfs, &dev);
579 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
582 "Failed to get em_ext_db from session, rc:%s\n",
586 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
588 /* Only get table info if required for the device */
589 if (dev->ops->tf_dev_get_tbl_info) {
590 rc = dev->ops->tf_dev_get_tbl_info(tfp,
591 tbl_db->tbl_db[parms->dir],
597 "%s: Failed to get table info:%d\n",
598 tf_dir_2_str(parms->dir),
604 /* Verify that the entries are in the range of reserved resources. */
605 cparms.rm_db = tbl_db->tbl_db[parms->dir];
606 cparms.subtype = parms->type;
608 TF_TBL_PTR_TO_RM(&cparms.starting_index, parms->starting_idx,
611 cparms.num_entries = parms->num_entries;
613 rc = tf_rm_check_indexes_in_range(&cparms);
616 "%s, Invalid or %d index starting from %d"
617 " not in range, type:%d",
618 tf_dir_2_str(parms->dir),
625 hparms.rm_db = tbl_db->tbl_db[parms->dir];
626 hparms.subtype = parms->type;
627 hparms.hcapi_type = &hcapi_type;
628 rc = tf_rm_get_hcapi_type(&hparms);
631 "%s, Failed type lookup, type:%d, rc:%s\n",
632 tf_dir_2_str(parms->dir),
638 /* Get the entries */
639 rc = tf_msg_bulk_get_tbl_entry(tfp,
644 parms->entry_sz_in_bytes,
645 parms->physical_mem_addr);
648 "%s, Bulk get failed, type:%d, rc:%s\n",
649 tf_dir_2_str(parms->dir),
658 tf_tbl_get_resc_info(struct tf *tfp,
659 struct tf_tbl_resource_info *tbl)
663 struct tf_resource_info *dinfo;
664 struct tf_rm_get_alloc_info_parms ainfo;
665 void *tbl_db_ptr = NULL;
666 struct tbl_rm_db *tbl_db;
667 uint16_t base = 0, shift = 0;
668 struct tf_dev_info *dev;
669 struct tf_session *tfs;
671 TF_CHECK_PARMS2(tfp, tbl);
673 /* Retrieve the session information */
674 rc = tf_session_get_session_internal(tfp, &tfs);
678 /* Retrieve the device information */
679 rc = tf_session_get_device(tfs, &dev);
683 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
685 return 0; /* db doesn't exist */
687 return rc; /* error getting db */
689 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
691 /* check if reserved resource for WC is multiple of num_slices */
692 for (d = 0; d < TF_DIR_MAX; d++) {
693 ainfo.rm_db = tbl_db->tbl_db[d];
699 ainfo.info = (struct tf_rm_alloc_info *)dinfo;
701 rc = tf_rm_get_all_info(&ainfo, TF_TBL_TYPE_MAX);
705 if (dev->ops->tf_dev_get_tbl_info) {
707 for (i = 0; i < TF_TBL_TYPE_MAX; i++) {
708 /* Only get table info if required for the device */
709 rc = dev->ops->tf_dev_get_tbl_info(tfp,
716 "%s: Failed to get table info:%d\n",
722 TF_TBL_RM_TO_PTR(&dinfo[i].start,