1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2019-2020 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,
183 "%s, Internal entry @ Index:%d rptr_index:0x%x rptr_entry:0x%x num_of_entries:%d\n",
184 tf_dir_2_str(parms->dir),
191 ((rptr_index << TF_EM_INTERNAL_INDEX_SHIFT) |
193 0); /* N/A for internal table */
195 TF_SET_FLOW_ID(parms->flow_id,
197 TF_GFID_TABLE_INTERNAL,
200 TF_SET_FIELDS_IN_FLOW_HANDLE(parms->flow_handle,
201 (uint32_t)num_of_entries,
211 /** Delete EM internal entry API
218 tf_em_delete_int_entry(struct tf *tfp,
219 struct tf_delete_em_entry_parms *parms)
222 struct stack *pool = &em_pool[parms->dir];
224 rc = tf_msg_delete_em_entry(tfp, parms);
226 /* Return resource to pool */
228 stack_push(pool, parms->index);
234 tf_em_int_bind(struct tf *tfp,
235 struct tf_em_cfg_parms *parms)
239 struct tf_rm_create_db_parms db_cfg = { 0 };
240 uint8_t db_exists = 0;
241 struct tf_rm_get_alloc_info_parms iparms;
242 struct tf_rm_alloc_info info;
244 TF_CHECK_PARMS2(tfp, parms);
248 "EM Int DB already initialized\n");
252 db_cfg.type = TF_DEVICE_MODULE_TYPE_EM;
253 db_cfg.num_elements = parms->num_elements;
254 db_cfg.cfg = parms->cfg;
256 for (i = 0; i < TF_DIR_MAX; i++) {
258 db_cfg.alloc_cnt = parms->resources->em_cnt[i].cnt;
260 /* Check if we got any request to support EEM, if so
261 * we build an EM Int DB holding Table Scopes.
263 if (db_cfg.alloc_cnt[TF_EM_TBL_TYPE_EM_RECORD] == 0)
266 if (db_cfg.alloc_cnt[TF_EM_TBL_TYPE_EM_RECORD] %
267 TF_SESSION_EM_ENTRY_SIZE != 0) {
270 "%s, EM Allocation must be in blocks of %d, failure %s\n",
272 TF_SESSION_EM_ENTRY_SIZE,
278 db_cfg.rm_db = &em_db[i];
279 rc = tf_rm_create_db(tfp, &db_cfg);
282 "%s: EM Int DB creation failed\n",
293 for (i = 0; i < TF_DIR_MAX; i++) {
294 iparms.rm_db = em_db[i];
295 iparms.db_index = TF_EM_DB_EM_REC;
298 rc = tf_rm_get_info(&iparms);
301 "%s: EM DB get info failed\n",
306 rc = tf_create_em_pool(i,
307 iparms.info->entry.stride,
308 iparms.info->entry.start);
309 /* Logging handled in tf_create_em_pool */
319 tf_em_int_unbind(struct tf *tfp)
323 struct tf_rm_free_db_parms fparms = { 0 };
325 TF_CHECK_PARMS1(tfp);
327 /* Bail if nothing has been initialized */
330 "No EM Int DBs created\n");
334 for (i = 0; i < TF_DIR_MAX; i++)
337 for (i = 0; i < TF_DIR_MAX; i++) {
339 fparms.rm_db = em_db[i];
340 if (em_db[i] != NULL) {
341 rc = tf_rm_free_db(tfp, &fparms);