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"
21 #define TF_EM_DB_EM_REC 0
24 * Init flag, set on bind and cleared on unbind
31 struct stack em_pool[TF_DIR_MAX];
34 * Create EM Tbl pool of memory indexes.
39 * number of entries to write
44 * 0 - Success, entry allocated - no search support
45 * -ENOMEM -EINVAL -EOPNOTSUPP
46 * - Failure, entry not allocated, out of resources
49 tf_create_em_pool(enum tf_dir dir,
53 struct tfp_calloc_parms parms;
56 struct stack *pool = &em_pool[dir];
58 /* Assumes that num_entries has been checked before we get here */
59 parms.nitems = num_entries / TF_SESSION_EM_ENTRY_SIZE;
60 parms.size = sizeof(uint32_t);
63 rc = tfp_calloc(&parms);
67 "%s, EM pool allocation failure %s\n",
75 rc = stack_init(num_entries / TF_SESSION_EM_ENTRY_SIZE,
76 (uint32_t *)parms.mem_va,
81 "%s, EM pool stack init failure %s\n",
87 /* Fill pool with indexes
89 j = start + num_entries - TF_SESSION_EM_ENTRY_SIZE;
91 for (i = 0; i < (num_entries / TF_SESSION_EM_ENTRY_SIZE); i++) {
92 rc = stack_push(pool, j);
95 "%s, EM pool stack push failure %s\n",
101 j -= TF_SESSION_EM_ENTRY_SIZE;
104 if (!stack_is_full(pool)) {
107 "%s, EM pool stack failure %s\n",
115 tfp_free((void *)parms.mem_va);
120 * Create EM Tbl pool of memory indexes.
128 tf_free_em_pool(enum tf_dir dir)
130 struct stack *pool = &em_pool[dir];
133 ptr = stack_items(pool);
140 * Insert EM internal entry API
146 tf_em_insert_int_entry(struct tf *tfp,
147 struct tf_insert_em_entry_parms *parms)
151 uint16_t rptr_index = 0;
152 uint8_t rptr_entry = 0;
153 uint8_t num_of_entries = 0;
154 struct stack *pool = &em_pool[parms->dir];
157 rc = stack_pop(pool, &index);
161 "%s, EM entry index allocation failed\n",
162 tf_dir_2_str(parms->dir));
167 rc = tf_msg_insert_em_internal_entry(tfp,
173 /* Free the allocated index before returning */
174 stack_push(pool, index);
180 "%s, Internal entry @ Index:%d rptr_index:0x%x rptr_entry:0x%x num_of_entries:%d\n",
181 tf_dir_2_str(parms->dir),
188 ((rptr_index << TF_EM_INTERNAL_INDEX_SHIFT) |
190 0); /* N/A for internal table */
192 TF_SET_FLOW_ID(parms->flow_id,
194 TF_GFID_TABLE_INTERNAL,
197 TF_SET_FIELDS_IN_FLOW_HANDLE(parms->flow_handle,
198 (uint32_t)num_of_entries,
200 TF_FLAGS_FLOW_HANDLE_INTERNAL,
208 /** Delete EM internal entry API
215 tf_em_delete_int_entry(struct tf *tfp,
216 struct tf_delete_em_entry_parms *parms)
219 struct stack *pool = &em_pool[parms->dir];
221 rc = tf_msg_delete_em_entry(tfp, parms);
223 /* Return resource to pool */
225 stack_push(pool, parms->index);
231 tf_em_int_bind(struct tf *tfp,
232 struct tf_em_cfg_parms *parms)
236 struct tf_rm_create_db_parms db_cfg = { 0 };
237 uint8_t db_exists = 0;
238 struct tf_rm_get_alloc_info_parms iparms;
239 struct tf_rm_alloc_info info;
240 struct em_rm_db *em_db;
241 struct tfp_calloc_parms cparms;
243 TF_CHECK_PARMS2(tfp, parms);
247 "EM Int DB already initialized\n");
251 memset(&db_cfg, 0, sizeof(db_cfg));
253 cparms.size = sizeof(struct em_rm_db);
254 cparms.alignment = 0;
255 if (tfp_calloc(&cparms) != 0) {
256 TFP_DRV_LOG(ERR, "em_rm_db alloc error %s\n",
261 em_db = cparms.mem_va;
262 for (i = 0; i < TF_DIR_MAX; i++)
263 em_db->em_db[i] = NULL;
264 tf_session_set_db(tfp, TF_MODULE_TYPE_EM, em_db);
266 db_cfg.module = TF_MODULE_TYPE_EM;
267 db_cfg.num_elements = parms->num_elements;
268 db_cfg.cfg = parms->cfg;
270 for (i = 0; i < TF_DIR_MAX; i++) {
272 db_cfg.alloc_cnt = parms->resources->em_cnt[i].cnt;
274 /* Check if we got any request to support EEM, if so
275 * we build an EM Int DB holding Table Scopes.
277 if (db_cfg.alloc_cnt[TF_EM_TBL_TYPE_EM_RECORD] == 0)
280 if (db_cfg.alloc_cnt[TF_EM_TBL_TYPE_EM_RECORD] %
281 TF_SESSION_EM_ENTRY_SIZE != 0) {
284 "%s, EM Allocation must be in blocks of %d, failure %s\n",
286 TF_SESSION_EM_ENTRY_SIZE,
292 db_cfg.rm_db = (void *)&em_db->em_db[i];
294 rc = tf_rm_create_db(tfp, &db_cfg);
297 "%s: EM Int DB creation failed\n",
308 for (i = 0; i < TF_DIR_MAX; i++) {
309 iparms.rm_db = em_db->em_db[i];
310 iparms.subtype = TF_EM_DB_EM_REC;
313 rc = tf_rm_get_info(&iparms);
316 "%s: EM DB get info failed\n",
321 rc = tf_create_em_pool(i,
322 iparms.info->entry.stride,
323 iparms.info->entry.start);
324 /* Logging handled in tf_create_em_pool */
334 tf_em_int_unbind(struct tf *tfp)
338 struct tf_rm_free_db_parms fparms = { 0 };
339 struct em_rm_db *em_db;
340 void *em_db_ptr = NULL;
342 TF_CHECK_PARMS1(tfp);
344 /* Bail if nothing has been initialized */
347 "No EM Int DBs created\n");
351 for (i = 0; i < TF_DIR_MAX; i++)
354 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_EM, &em_db_ptr);
357 "Failed to get em_ext_db from session, rc:%s\n",
361 em_db = (struct em_rm_db *)em_db_ptr;
363 for (i = 0; i < TF_DIR_MAX; i++) {
365 fparms.rm_db = em_db->em_db[i];
366 if (em_db->em_db[i] != NULL) {
367 rc = tf_rm_free_db(tfp, &fparms);
372 em_db->em_db[i] = NULL;