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),
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;
629 uint16_t base = 0, shift = 0;
630 struct tf_dev_info *dev;
631 struct tf_session *tfs;
633 TF_CHECK_PARMS2(tfp, tbl);
635 /* Retrieve the session information */
636 rc = tf_session_get_session_internal(tfp, &tfs);
640 /* Retrieve the device information */
641 rc = tf_session_get_device(tfs, &dev);
645 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
648 "No resource allocated for table from session\n");
651 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
653 /* check if reserved resource for WC is multiple of num_slices */
654 for (d = 0; d < TF_DIR_MAX; d++) {
655 ainfo.rm_db = tbl_db->tbl_db[d];
658 ainfo.info = (struct tf_rm_alloc_info *)dinfo;
660 rc = tf_rm_get_all_info(&ainfo, TF_TBL_TYPE_MAX);
664 if (dev->ops->tf_dev_get_tbl_info) {
666 for (i = 0; i < TF_TBL_TYPE_MAX; i++) {
667 /* Only get table info if required for the device */
668 rc = dev->ops->tf_dev_get_tbl_info(tfp,
675 "%s: Failed to get table info:%d\n",
681 TF_TBL_RM_TO_PTR(&dinfo[i].start,