1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2019-2021 Broadcom
7 #include <rte_common.h>
13 #include "tf_common.h"
17 #include "tf_ext_flow_handle.h"
24 static void *em_db[TF_DIR_MAX];
26 #define TF_EM_DB_EM_REC 0
29 * Init flag, set on bind and cleared on unbind
37 static struct stack em_pool[TF_DIR_MAX];
40 * Create EM Tbl pool of memory indexes.
45 * number of entries to write
50 * 0 - Success, entry allocated - no search support
51 * -ENOMEM -EINVAL -EOPNOTSUPP
52 * - Failure, entry not allocated, out of resources
55 tf_create_em_pool(enum tf_dir dir,
59 struct tfp_calloc_parms parms;
62 struct stack *pool = &em_pool[dir];
64 /* Assumes that num_entries has been checked before we get here */
65 parms.nitems = num_entries / TF_SESSION_EM_ENTRY_SIZE;
66 parms.size = sizeof(uint32_t);
69 rc = tfp_calloc(&parms);
73 "%s, EM pool allocation failure %s\n",
81 rc = stack_init(num_entries / TF_SESSION_EM_ENTRY_SIZE,
82 (uint32_t *)parms.mem_va,
87 "%s, EM pool stack init failure %s\n",
93 /* Fill pool with indexes
95 j = start + num_entries - TF_SESSION_EM_ENTRY_SIZE;
97 for (i = 0; i < (num_entries / TF_SESSION_EM_ENTRY_SIZE); i++) {
98 rc = stack_push(pool, j);
101 "%s, EM pool stack push failure %s\n",
107 j -= TF_SESSION_EM_ENTRY_SIZE;
110 if (!stack_is_full(pool)) {
113 "%s, EM pool stack failure %s\n",
121 tfp_free((void *)parms.mem_va);
126 * Create EM Tbl pool of memory indexes.
134 tf_free_em_pool(enum tf_dir dir)
136 struct stack *pool = &em_pool[dir];
139 ptr = stack_items(pool);
146 * Insert EM internal entry API
152 tf_em_insert_int_entry(struct tf *tfp,
153 struct tf_insert_em_entry_parms *parms)
157 uint16_t rptr_index = 0;
158 uint8_t rptr_entry = 0;
159 uint8_t num_of_entries = 0;
160 struct stack *pool = &em_pool[parms->dir];
163 rc = stack_pop(pool, &index);
167 "%s, EM entry index allocation failed\n",
168 tf_dir_2_str(parms->dir));
173 rc = tf_msg_insert_em_internal_entry(tfp,
179 /* Free the allocated index before returning */
180 stack_push(pool, index);
186 "%s, Internal entry @ Index:%d rptr_index:0x%x rptr_entry:0x%x num_of_entries:%d\n",
187 tf_dir_2_str(parms->dir),
194 ((rptr_index << TF_EM_INTERNAL_INDEX_SHIFT) |
196 0); /* N/A for internal table */
198 TF_SET_FLOW_ID(parms->flow_id,
200 TF_GFID_TABLE_INTERNAL,
203 TF_SET_FIELDS_IN_FLOW_HANDLE(parms->flow_handle,
204 (uint32_t)num_of_entries,
214 /** Delete EM internal entry API
221 tf_em_delete_int_entry(struct tf *tfp,
222 struct tf_delete_em_entry_parms *parms)
225 struct stack *pool = &em_pool[parms->dir];
227 rc = tf_msg_delete_em_entry(tfp, parms);
229 /* Return resource to pool */
231 stack_push(pool, parms->index);
237 tf_em_int_bind(struct tf *tfp,
238 struct tf_em_cfg_parms *parms)
242 struct tf_rm_create_db_parms db_cfg = { 0 };
243 uint8_t db_exists = 0;
244 struct tf_rm_get_alloc_info_parms iparms;
245 struct tf_rm_alloc_info info;
247 TF_CHECK_PARMS2(tfp, parms);
251 "EM Int DB already initialized\n");
255 db_cfg.type = TF_DEVICE_MODULE_TYPE_EM;
256 db_cfg.num_elements = parms->num_elements;
257 db_cfg.cfg = parms->cfg;
259 for (i = 0; i < TF_DIR_MAX; i++) {
261 db_cfg.alloc_cnt = parms->resources->em_cnt[i].cnt;
263 /* Check if we got any request to support EEM, if so
264 * we build an EM Int DB holding Table Scopes.
266 if (db_cfg.alloc_cnt[TF_EM_TBL_TYPE_EM_RECORD] == 0)
269 if (db_cfg.alloc_cnt[TF_EM_TBL_TYPE_EM_RECORD] %
270 TF_SESSION_EM_ENTRY_SIZE != 0) {
273 "%s, EM Allocation must be in blocks of %d, failure %s\n",
275 TF_SESSION_EM_ENTRY_SIZE,
281 db_cfg.rm_db = &em_db[i];
282 rc = tf_rm_create_db(tfp, &db_cfg);
285 "%s: EM Int DB creation failed\n",
296 for (i = 0; i < TF_DIR_MAX; i++) {
297 iparms.rm_db = em_db[i];
298 iparms.db_index = TF_EM_DB_EM_REC;
301 rc = tf_rm_get_info(&iparms);
304 "%s: EM DB get info failed\n",
309 rc = tf_create_em_pool(i,
310 iparms.info->entry.stride,
311 iparms.info->entry.start);
312 /* Logging handled in tf_create_em_pool */
322 tf_em_int_unbind(struct tf *tfp)
326 struct tf_rm_free_db_parms fparms = { 0 };
328 TF_CHECK_PARMS1(tfp);
330 /* Bail if nothing has been initialized */
333 "No EM Int DBs created\n");
337 for (i = 0; i < TF_DIR_MAX; i++)
340 for (i = 0; i < TF_DIR_MAX; i++) {
342 fparms.rm_db = em_db[i];
343 if (em_db[i] != NULL) {
344 rc = tf_rm_free_db(tfp, &fparms);