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 "Failed to get em_ext_db from session, rc:%s\n",
117 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
119 for (i = 0; i < TF_DIR_MAX; i++) {
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),
273 /* Free requested element */
274 fparms.rm_db = tbl_db->tbl_db[parms->dir];
275 fparms.subtype = parms->type;
277 TF_TBL_PTR_TO_RM(&fparms.index, parms->idx, base, shift);
279 rc = tf_rm_free(&fparms);
282 "%s: Free failed, type:%d, index:%d\n",
283 tf_dir_2_str(parms->dir),
293 tf_tbl_alloc_search(struct tf *tfp,
294 struct tf_tbl_alloc_search_parms *parms)
297 TF_CHECK_PARMS2(tfp, parms);
299 if (!shadow_init || !shadow_tbl_db[parms->dir]) {
300 TFP_DRV_LOG(ERR, "%s: Shadow TBL not initialized.\n",
301 tf_dir_2_str(parms->dir));
309 tf_tbl_set(struct tf *tfp,
310 struct tf_tbl_set_parms *parms)
315 struct tf_rm_is_allocated_parms aparms = { 0 };
316 struct tf_rm_get_hcapi_parms hparms = { 0 };
317 struct tf_session *tfs;
318 struct tf_dev_info *dev;
319 uint16_t base = 0, shift = 0;
320 struct tbl_rm_db *tbl_db;
321 void *tbl_db_ptr = NULL;
323 TF_CHECK_PARMS3(tfp, parms, parms->data);
325 /* Retrieve the session information */
326 rc = tf_session_get_session_internal(tfp, &tfs);
330 /* Retrieve the device information */
331 rc = tf_session_get_device(tfs, &dev);
335 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
338 "Failed to get em_ext_db from session, rc:%s\n",
342 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
344 /* Only get table info if required for the device */
345 if (dev->ops->tf_dev_get_tbl_info) {
346 rc = dev->ops->tf_dev_get_tbl_info(tfp,
347 tbl_db->tbl_db[parms->dir],
353 "%s: Failed to get table info:%d\n",
354 tf_dir_2_str(parms->dir),
360 /* Verify that the entry has been previously allocated */
361 aparms.rm_db = tbl_db->tbl_db[parms->dir];
362 aparms.subtype = parms->type;
363 TF_TBL_PTR_TO_RM(&aparms.index, parms->idx, base, shift);
365 aparms.allocated = &allocated;
366 rc = tf_rm_is_allocated(&aparms);
370 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
372 "%s, Invalid or not allocated index, type:%d, idx:%d\n",
373 tf_dir_2_str(parms->dir),
380 hparms.rm_db = tbl_db->tbl_db[parms->dir];
381 hparms.subtype = parms->type;
382 hparms.hcapi_type = &hcapi_type;
383 rc = tf_rm_get_hcapi_type(&hparms);
386 "%s, Failed type lookup, type:%d, rc:%s\n",
387 tf_dir_2_str(parms->dir),
393 rc = tf_msg_set_tbl_entry(tfp,
396 parms->data_sz_in_bytes,
401 "%s, Set failed, type:%d, rc:%s\n",
402 tf_dir_2_str(parms->dir),
412 tf_tbl_get(struct tf *tfp,
413 struct tf_tbl_get_parms *parms)
418 struct tf_rm_is_allocated_parms aparms = { 0 };
419 struct tf_rm_get_hcapi_parms hparms = { 0 };
420 struct tf_session *tfs;
421 struct tf_dev_info *dev;
422 uint16_t base = 0, shift = 0;
423 struct tbl_rm_db *tbl_db;
424 void *tbl_db_ptr = NULL;
426 TF_CHECK_PARMS3(tfp, parms, parms->data);
428 /* Retrieve the session information */
429 rc = tf_session_get_session_internal(tfp, &tfs);
433 /* Retrieve the device information */
434 rc = tf_session_get_device(tfs, &dev);
438 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
441 "Failed to get em_ext_db from session, rc:%s\n",
445 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
447 /* Only get table info if required for the device */
448 if (dev->ops->tf_dev_get_tbl_info) {
449 rc = dev->ops->tf_dev_get_tbl_info(tfp,
450 tbl_db->tbl_db[parms->dir],
456 "%s: Failed to get table info:%d\n",
457 tf_dir_2_str(parms->dir),
463 /* Verify that the entry has been previously allocated */
464 aparms.rm_db = tbl_db->tbl_db[parms->dir];
465 aparms.subtype = parms->type;
466 TF_TBL_PTR_TO_RM(&aparms.index, parms->idx, base, shift);
468 aparms.allocated = &allocated;
469 rc = tf_rm_is_allocated(&aparms);
473 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
475 "%s, Invalid or not allocated index, type:%d, idx:%d\n",
476 tf_dir_2_str(parms->dir),
483 hparms.rm_db = tbl_db->tbl_db[parms->dir];
484 hparms.subtype = parms->type;
485 hparms.hcapi_type = &hcapi_type;
486 rc = tf_rm_get_hcapi_type(&hparms);
489 "%s, Failed type lookup, type:%d, rc:%s\n",
490 tf_dir_2_str(parms->dir),
497 rc = tf_msg_get_tbl_entry(tfp,
500 parms->data_sz_in_bytes,
505 "%s, Get failed, type:%d, rc:%s\n",
506 tf_dir_2_str(parms->dir),
516 tf_tbl_bulk_get(struct tf *tfp,
517 struct tf_tbl_get_bulk_parms *parms)
521 struct tf_rm_get_hcapi_parms hparms = { 0 };
522 struct tf_rm_check_indexes_in_range_parms cparms = { 0 };
523 struct tf_session *tfs;
524 struct tf_dev_info *dev;
525 uint16_t base = 0, shift = 0;
526 struct tbl_rm_db *tbl_db;
527 void *tbl_db_ptr = NULL;
529 TF_CHECK_PARMS2(tfp, parms);
531 /* Retrieve the session information */
532 rc = tf_session_get_session_internal(tfp, &tfs);
536 /* Retrieve the device information */
537 rc = tf_session_get_device(tfs, &dev);
541 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
544 "Failed to get em_ext_db from session, rc:%s\n",
548 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
550 /* Only get table info if required for the device */
551 if (dev->ops->tf_dev_get_tbl_info) {
552 rc = dev->ops->tf_dev_get_tbl_info(tfp,
553 tbl_db->tbl_db[parms->dir],
559 "%s: Failed to get table info:%d\n",
560 tf_dir_2_str(parms->dir),
566 /* Verify that the entries are in the range of reserved resources. */
567 cparms.rm_db = tbl_db->tbl_db[parms->dir];
568 cparms.subtype = parms->type;
570 TF_TBL_PTR_TO_RM(&cparms.starting_index, parms->starting_idx,
573 cparms.num_entries = parms->num_entries;
575 rc = tf_rm_check_indexes_in_range(&cparms);
578 "%s, Invalid or %d index starting from %d"
579 " not in range, type:%d",
580 tf_dir_2_str(parms->dir),
587 hparms.rm_db = tbl_db->tbl_db[parms->dir];
588 hparms.subtype = parms->type;
589 hparms.hcapi_type = &hcapi_type;
590 rc = tf_rm_get_hcapi_type(&hparms);
593 "%s, Failed type lookup, type:%d, rc:%s\n",
594 tf_dir_2_str(parms->dir),
600 /* Get the entries */
601 rc = tf_msg_bulk_get_tbl_entry(tfp,
606 parms->entry_sz_in_bytes,
607 parms->physical_mem_addr);
610 "%s, Bulk get failed, type:%d, rc:%s\n",
611 tf_dir_2_str(parms->dir),
620 tf_tbl_get_resc_info(struct tf *tfp,
621 struct tf_tbl_resource_info *tbl)
625 struct tf_resource_info *dinfo;
626 struct tf_rm_get_alloc_info_parms ainfo;
627 void *tbl_db_ptr = NULL;
628 struct tbl_rm_db *tbl_db;
630 TF_CHECK_PARMS2(tfp, tbl);
632 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
635 "Failed to get em_ext_db from session, rc:%s\n",
639 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
641 /* check if reserved resource for WC is multiple of num_slices */
642 for (d = 0; d < TF_DIR_MAX; d++) {
643 ainfo.rm_db = tbl_db->tbl_db[d];
646 ainfo.info = (struct tf_rm_alloc_info *)dinfo;
648 rc = tf_rm_get_all_info(&ainfo, TF_TBL_TYPE_MAX);