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 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;
49 TF_CHECK_PARMS2(tfp, parms);
51 /* Retrieve the session information */
52 rc = tf_session_get_session_internal(tfp, &tfs);
56 memset(&db_cfg, 0, sizeof(db_cfg));
58 cparms.size = sizeof(struct tbl_rm_db);
60 if (tfp_calloc(&cparms) != 0) {
61 TFP_DRV_LOG(ERR, "tbl_rm_db alloc error %s\n",
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);
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;
76 for (d = 0; d < TF_DIR_MAX; 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);
84 rc = tf_rm_create_db(tfp, &db_cfg);
87 "%s: Table DB creation failed\n",
95 "Table Type - initialized\n");
101 tf_tbl_unbind(struct tf *tfp)
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);
110 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
113 "Tbl_db is not initialized, rc:%s\n",
117 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
119 for (i = 0; i < TF_DIR_MAX; i++) {
120 if (tbl_db->tbl_db[i] == NULL)
123 fparms.rm_db = tbl_db->tbl_db[i];
124 rc = tf_rm_free_db(tfp, &fparms);
128 tbl_db->tbl_db[i] = NULL;
137 tf_tbl_alloc(struct tf *tfp __rte_unused,
138 struct tf_tbl_alloc_parms *parms)
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;
149 TF_CHECK_PARMS2(tfp, parms);
151 /* Retrieve the session information */
152 rc = tf_session_get_session_internal(tfp, &tfs);
156 /* Retrieve the device information */
157 rc = tf_session_get_device(tfs, &dev);
161 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
164 "Failed to get em_ext_db from session, rc:%s\n",
168 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
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],
179 "%s: Failed to get table info:%d\n",
180 tf_dir_2_str(parms->dir),
186 /* Allocate requested element */
187 aparms.rm_db = tbl_db->tbl_db[parms->dir];
188 aparms.subtype = parms->type;
190 rc = tf_rm_allocate(&aparms);
193 "%s: Failed allocate, type:%d\n",
194 tf_dir_2_str(parms->dir),
199 TF_TBL_RM_TO_PTR(&idx, idx, base, shift);
206 tf_tbl_free(struct tf *tfp __rte_unused,
207 struct tf_tbl_free_parms *parms)
210 struct tf_rm_is_allocated_parms aparms = { 0 };
211 struct tf_rm_free_parms fparms = { 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;
219 TF_CHECK_PARMS2(tfp, parms);
221 /* Retrieve the session information */
222 rc = tf_session_get_session_internal(tfp, &tfs);
226 /* Retrieve the device information */
227 rc = tf_session_get_device(tfs, &dev);
231 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
234 "Failed to get em_ext_db from session, rc:%s\n",
238 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
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],
249 "%s: Failed to get table info:%d\n",
250 tf_dir_2_str(parms->dir),
256 /* Check if element is in use */
257 aparms.rm_db = tbl_db->tbl_db[parms->dir];
258 aparms.subtype = parms->type;
260 TF_TBL_PTR_TO_RM(&aparms.index, parms->idx, base, shift);
262 aparms.allocated = &allocated;
263 rc = tf_rm_is_allocated(&aparms);
267 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
269 "%s: Entry already free, type:%d, index:%d\n",
270 tf_dir_2_str(parms->dir),
275 /* Free requested element */
276 fparms.rm_db = tbl_db->tbl_db[parms->dir];
277 fparms.subtype = parms->type;
279 TF_TBL_PTR_TO_RM(&fparms.index, parms->idx, base, shift);
281 rc = tf_rm_free(&fparms);
284 "%s: Free failed, type:%d, index:%d\n",
285 tf_dir_2_str(parms->dir),
295 tf_tbl_alloc_search(struct tf *tfp,
296 struct tf_tbl_alloc_search_parms *parms)
299 TF_CHECK_PARMS2(tfp, parms);
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));
311 tf_tbl_set(struct tf *tfp,
312 struct tf_tbl_set_parms *parms)
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;
325 TF_CHECK_PARMS3(tfp, parms, parms->data);
327 /* Retrieve the session information */
328 rc = tf_session_get_session_internal(tfp, &tfs);
332 /* Retrieve the device information */
333 rc = tf_session_get_device(tfs, &dev);
337 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
340 "Failed to get em_ext_db from session, rc:%s\n",
344 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
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],
355 "%s: Failed to get table info:%d\n",
356 tf_dir_2_str(parms->dir),
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);
367 aparms.allocated = &allocated;
368 rc = tf_rm_is_allocated(&aparms);
372 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
374 "%s, Invalid or not allocated index, type:%d, idx:%d\n",
375 tf_dir_2_str(parms->dir),
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);
388 "%s, Failed type lookup, type:%d, rc:%s\n",
389 tf_dir_2_str(parms->dir),
395 rc = tf_msg_set_tbl_entry(tfp,
398 parms->data_sz_in_bytes,
403 "%s, Set failed, type:%d, rc:%s\n",
404 tf_dir_2_str(parms->dir),
414 tf_tbl_get(struct tf *tfp,
415 struct tf_tbl_get_parms *parms)
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;
428 TF_CHECK_PARMS3(tfp, parms, parms->data);
430 /* Retrieve the session information */
431 rc = tf_session_get_session_internal(tfp, &tfs);
435 /* Retrieve the device information */
436 rc = tf_session_get_device(tfs, &dev);
440 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
443 "Failed to get em_ext_db from session, rc:%s\n",
447 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
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],
458 "%s: Failed to get table info:%d\n",
459 tf_dir_2_str(parms->dir),
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);
470 aparms.allocated = &allocated;
471 rc = tf_rm_is_allocated(&aparms);
475 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
477 "%s, Invalid or not allocated index, type:%d, idx:%d\n",
478 tf_dir_2_str(parms->dir),
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);
491 "%s, Failed type lookup, type:%d, rc:%s\n",
492 tf_dir_2_str(parms->dir),
499 rc = tf_msg_get_tbl_entry(tfp,
502 parms->data_sz_in_bytes,
507 "%s, Get failed, type:%d, rc:%s\n",
508 tf_dir_2_str(parms->dir),
518 tf_tbl_bulk_get(struct tf *tfp,
519 struct tf_tbl_get_bulk_parms *parms)
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;
531 TF_CHECK_PARMS2(tfp, parms);
533 /* Retrieve the session information */
534 rc = tf_session_get_session_internal(tfp, &tfs);
538 /* Retrieve the device information */
539 rc = tf_session_get_device(tfs, &dev);
543 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
546 "Failed to get em_ext_db from session, rc:%s\n",
550 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
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],
561 "%s: Failed to get table info:%d\n",
562 tf_dir_2_str(parms->dir),
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;
572 TF_TBL_PTR_TO_RM(&cparms.starting_index, parms->starting_idx,
575 cparms.num_entries = parms->num_entries;
577 rc = tf_rm_check_indexes_in_range(&cparms);
580 "%s, Invalid or %d index starting from %d"
581 " not in range, type:%d",
582 tf_dir_2_str(parms->dir),
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);
595 "%s, Failed type lookup, type:%d, rc:%s\n",
596 tf_dir_2_str(parms->dir),
602 /* Get the entries */
603 rc = tf_msg_bulk_get_tbl_entry(tfp,
608 parms->entry_sz_in_bytes,
609 parms->physical_mem_addr);
612 "%s, Bulk get failed, type:%d, rc:%s\n",
613 tf_dir_2_str(parms->dir),
622 tf_tbl_get_resc_info(struct tf *tfp,
623 struct tf_tbl_resource_info *tbl)
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;
635 TF_CHECK_PARMS2(tfp, tbl);
637 /* Retrieve the session information */
638 rc = tf_session_get_session_internal(tfp, &tfs);
642 /* Retrieve the device information */
643 rc = tf_session_get_device(tfs, &dev);
647 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
650 "No resource allocated for table from session\n");
653 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
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];
661 ainfo.info = (struct tf_rm_alloc_info *)dinfo;
663 rc = tf_rm_get_all_info(&ainfo, TF_TBL_TYPE_MAX);
667 if (dev->ops->tf_dev_get_tbl_info) {
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,
678 "%s: Failed to get table info:%d\n",
684 TF_TBL_RM_TO_PTR(&dinfo[i].start,