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);
88 "%s: No Table DB creation required\n",
95 if (db_rc[TF_DIR_RX] && db_rc[TF_DIR_TX])
96 return db_rc[TF_DIR_RX];
99 "Table Type - initialized\n");
105 tf_tbl_unbind(struct tf *tfp)
109 struct tf_rm_free_db_parms fparms = { 0 };
110 struct tbl_rm_db *tbl_db;
111 void *tbl_db_ptr = NULL;
112 TF_CHECK_PARMS1(tfp);
114 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
117 "Tbl_db is not initialized, rc:%s\n",
121 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
123 for (i = 0; i < TF_DIR_MAX; i++) {
124 if (tbl_db->tbl_db[i] == NULL)
127 fparms.rm_db = tbl_db->tbl_db[i];
128 rc = tf_rm_free_db(tfp, &fparms);
132 tbl_db->tbl_db[i] = NULL;
141 tf_tbl_alloc(struct tf *tfp __rte_unused,
142 struct tf_tbl_alloc_parms *parms)
146 struct tf_rm_allocate_parms aparms = { 0 };
147 struct tf_session *tfs;
148 struct tf_dev_info *dev;
149 uint16_t base = 0, shift = 0;
150 struct tbl_rm_db *tbl_db;
151 void *tbl_db_ptr = NULL;
153 TF_CHECK_PARMS2(tfp, parms);
155 /* Retrieve the session information */
156 rc = tf_session_get_session_internal(tfp, &tfs);
160 /* Retrieve the device information */
161 rc = tf_session_get_device(tfs, &dev);
165 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
168 "Failed to get em_ext_db from session, rc:%s\n",
172 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
174 /* Only get table info if required for the device */
175 if (dev->ops->tf_dev_get_tbl_info) {
176 rc = dev->ops->tf_dev_get_tbl_info(tfp,
177 tbl_db->tbl_db[parms->dir],
183 "%s: Failed to get table info:%d\n",
184 tf_dir_2_str(parms->dir),
190 /* Allocate requested element */
191 aparms.rm_db = tbl_db->tbl_db[parms->dir];
192 aparms.subtype = parms->type;
194 rc = tf_rm_allocate(&aparms);
197 "%s: Failed allocate, type:%d\n",
198 tf_dir_2_str(parms->dir),
203 TF_TBL_RM_TO_PTR(&idx, idx, base, shift);
210 tf_tbl_free(struct tf *tfp __rte_unused,
211 struct tf_tbl_free_parms *parms)
214 struct tf_rm_is_allocated_parms aparms = { 0 };
215 struct tf_rm_free_parms fparms = { 0 };
217 struct tf_session *tfs;
218 struct tf_dev_info *dev;
219 uint16_t base = 0, shift = 0;
220 struct tbl_rm_db *tbl_db;
221 void *tbl_db_ptr = NULL;
223 TF_CHECK_PARMS2(tfp, parms);
225 /* Retrieve the session information */
226 rc = tf_session_get_session_internal(tfp, &tfs);
230 /* Retrieve the device information */
231 rc = tf_session_get_device(tfs, &dev);
235 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
238 "Failed to get em_ext_db from session, rc:%s\n",
242 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
244 /* Only get table info if required for the device */
245 if (dev->ops->tf_dev_get_tbl_info) {
246 rc = dev->ops->tf_dev_get_tbl_info(tfp,
247 tbl_db->tbl_db[parms->dir],
253 "%s: Failed to get table info:%d\n",
254 tf_dir_2_str(parms->dir),
260 /* Check if element is in use */
261 aparms.rm_db = tbl_db->tbl_db[parms->dir];
262 aparms.subtype = parms->type;
264 TF_TBL_PTR_TO_RM(&aparms.index, parms->idx, base, shift);
266 aparms.allocated = &allocated;
267 rc = tf_rm_is_allocated(&aparms);
271 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
273 "%s: Entry already free, type:%d, index:%d\n",
274 tf_dir_2_str(parms->dir),
279 /* Free requested element */
280 fparms.rm_db = tbl_db->tbl_db[parms->dir];
281 fparms.subtype = parms->type;
283 TF_TBL_PTR_TO_RM(&fparms.index, parms->idx, base, shift);
285 rc = tf_rm_free(&fparms);
288 "%s: Free failed, type:%d, index:%d\n",
289 tf_dir_2_str(parms->dir),
299 tf_tbl_alloc_search(struct tf *tfp,
300 struct tf_tbl_alloc_search_parms *parms)
303 TF_CHECK_PARMS2(tfp, parms);
305 if (!shadow_init || !shadow_tbl_db[parms->dir]) {
306 TFP_DRV_LOG(ERR, "%s: Shadow TBL not initialized.\n",
307 tf_dir_2_str(parms->dir));
315 tf_tbl_set(struct tf *tfp,
316 struct tf_tbl_set_parms *parms)
321 struct tf_rm_is_allocated_parms aparms = { 0 };
322 struct tf_rm_get_hcapi_parms hparms = { 0 };
323 struct tf_session *tfs;
324 struct tf_dev_info *dev;
325 uint16_t base = 0, shift = 0;
326 struct tbl_rm_db *tbl_db;
327 void *tbl_db_ptr = NULL;
329 TF_CHECK_PARMS3(tfp, parms, parms->data);
331 /* Retrieve the session information */
332 rc = tf_session_get_session_internal(tfp, &tfs);
336 /* Retrieve the device information */
337 rc = tf_session_get_device(tfs, &dev);
341 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
344 "Failed to get em_ext_db from session, rc:%s\n",
348 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
350 /* Only get table info if required for the device */
351 if (dev->ops->tf_dev_get_tbl_info) {
352 rc = dev->ops->tf_dev_get_tbl_info(tfp,
353 tbl_db->tbl_db[parms->dir],
359 "%s: Failed to get table info:%d\n",
360 tf_dir_2_str(parms->dir),
366 /* Verify that the entry has been previously allocated */
367 aparms.rm_db = tbl_db->tbl_db[parms->dir];
368 aparms.subtype = parms->type;
369 TF_TBL_PTR_TO_RM(&aparms.index, parms->idx, base, shift);
371 aparms.allocated = &allocated;
372 rc = tf_rm_is_allocated(&aparms);
376 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
378 "%s, Invalid or not allocated index, type:%d, idx:%d\n",
379 tf_dir_2_str(parms->dir),
386 hparms.rm_db = tbl_db->tbl_db[parms->dir];
387 hparms.subtype = parms->type;
388 hparms.hcapi_type = &hcapi_type;
389 rc = tf_rm_get_hcapi_type(&hparms);
392 "%s, Failed type lookup, type:%d, rc:%s\n",
393 tf_dir_2_str(parms->dir),
399 rc = tf_msg_set_tbl_entry(tfp,
402 parms->data_sz_in_bytes,
407 "%s, Set failed, type:%d, rc:%s\n",
408 tf_dir_2_str(parms->dir),
418 tf_tbl_get(struct tf *tfp,
419 struct tf_tbl_get_parms *parms)
424 struct tf_rm_is_allocated_parms aparms = { 0 };
425 struct tf_rm_get_hcapi_parms hparms = { 0 };
426 struct tf_session *tfs;
427 struct tf_dev_info *dev;
428 uint16_t base = 0, shift = 0;
429 struct tbl_rm_db *tbl_db;
430 void *tbl_db_ptr = NULL;
432 TF_CHECK_PARMS3(tfp, parms, parms->data);
434 /* Retrieve the session information */
435 rc = tf_session_get_session_internal(tfp, &tfs);
439 /* Retrieve the device information */
440 rc = tf_session_get_device(tfs, &dev);
444 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
447 "Failed to get em_ext_db from session, rc:%s\n",
451 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
453 /* Only get table info if required for the device */
454 if (dev->ops->tf_dev_get_tbl_info) {
455 rc = dev->ops->tf_dev_get_tbl_info(tfp,
456 tbl_db->tbl_db[parms->dir],
462 "%s: Failed to get table info:%d\n",
463 tf_dir_2_str(parms->dir),
469 /* Verify that the entry has been previously allocated */
470 aparms.rm_db = tbl_db->tbl_db[parms->dir];
471 aparms.subtype = parms->type;
472 TF_TBL_PTR_TO_RM(&aparms.index, parms->idx, base, shift);
474 aparms.allocated = &allocated;
475 rc = tf_rm_is_allocated(&aparms);
479 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
481 "%s, Invalid or not allocated index, type:%d, idx:%d\n",
482 tf_dir_2_str(parms->dir),
489 hparms.rm_db = tbl_db->tbl_db[parms->dir];
490 hparms.subtype = parms->type;
491 hparms.hcapi_type = &hcapi_type;
492 rc = tf_rm_get_hcapi_type(&hparms);
495 "%s, Failed type lookup, type:%d, rc:%s\n",
496 tf_dir_2_str(parms->dir),
503 rc = tf_msg_get_tbl_entry(tfp,
506 parms->data_sz_in_bytes,
511 "%s, Get failed, type:%d, rc:%s\n",
512 tf_dir_2_str(parms->dir),
522 tf_tbl_bulk_get(struct tf *tfp,
523 struct tf_tbl_get_bulk_parms *parms)
527 struct tf_rm_get_hcapi_parms hparms = { 0 };
528 struct tf_rm_check_indexes_in_range_parms cparms = { 0 };
529 struct tf_session *tfs;
530 struct tf_dev_info *dev;
531 uint16_t base = 0, shift = 0;
532 struct tbl_rm_db *tbl_db;
533 void *tbl_db_ptr = NULL;
535 TF_CHECK_PARMS2(tfp, parms);
537 /* Retrieve the session information */
538 rc = tf_session_get_session_internal(tfp, &tfs);
542 /* Retrieve the device information */
543 rc = tf_session_get_device(tfs, &dev);
547 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
550 "Failed to get em_ext_db from session, rc:%s\n",
554 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
556 /* Only get table info if required for the device */
557 if (dev->ops->tf_dev_get_tbl_info) {
558 rc = dev->ops->tf_dev_get_tbl_info(tfp,
559 tbl_db->tbl_db[parms->dir],
565 "%s: Failed to get table info:%d\n",
566 tf_dir_2_str(parms->dir),
572 /* Verify that the entries are in the range of reserved resources. */
573 cparms.rm_db = tbl_db->tbl_db[parms->dir];
574 cparms.subtype = parms->type;
576 TF_TBL_PTR_TO_RM(&cparms.starting_index, parms->starting_idx,
579 cparms.num_entries = parms->num_entries;
581 rc = tf_rm_check_indexes_in_range(&cparms);
584 "%s, Invalid or %d index starting from %d"
585 " not in range, type:%d",
586 tf_dir_2_str(parms->dir),
593 hparms.rm_db = tbl_db->tbl_db[parms->dir];
594 hparms.subtype = parms->type;
595 hparms.hcapi_type = &hcapi_type;
596 rc = tf_rm_get_hcapi_type(&hparms);
599 "%s, Failed type lookup, type:%d, rc:%s\n",
600 tf_dir_2_str(parms->dir),
606 /* Get the entries */
607 rc = tf_msg_bulk_get_tbl_entry(tfp,
612 parms->entry_sz_in_bytes,
613 parms->physical_mem_addr);
616 "%s, Bulk get failed, type:%d, rc:%s\n",
617 tf_dir_2_str(parms->dir),
626 tf_tbl_get_resc_info(struct tf *tfp,
627 struct tf_tbl_resource_info *tbl)
631 struct tf_resource_info *dinfo;
632 struct tf_rm_get_alloc_info_parms ainfo;
633 void *tbl_db_ptr = NULL;
634 struct tbl_rm_db *tbl_db;
635 uint16_t base = 0, shift = 0;
636 struct tf_dev_info *dev;
637 struct tf_session *tfs;
639 TF_CHECK_PARMS2(tfp, tbl);
641 /* Retrieve the session information */
642 rc = tf_session_get_session_internal(tfp, &tfs);
646 /* Retrieve the device information */
647 rc = tf_session_get_device(tfs, &dev);
651 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
654 "No resource allocated for table from session\n");
657 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
659 /* check if reserved resource for WC is multiple of num_slices */
660 for (d = 0; d < TF_DIR_MAX; d++) {
661 ainfo.rm_db = tbl_db->tbl_db[d];
664 ainfo.info = (struct tf_rm_alloc_info *)dinfo;
666 rc = tf_rm_get_all_info(&ainfo, TF_TBL_TYPE_MAX);
670 if (dev->ops->tf_dev_get_tbl_info) {
672 for (i = 0; i < TF_TBL_TYPE_MAX; i++) {
673 /* Only get table info if required for the device */
674 rc = dev->ops->tf_dev_get_tbl_info(tfp,
681 "%s: Failed to get table info:%d\n",
687 TF_TBL_RM_TO_PTR(&dinfo[i].start,