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];
27 * Init flag, set on bind and cleared on unbind
32 * Create EM Tbl pool of memory indexes.
39 * number of entries to write
42 * 0 - Success, entry allocated - no search support
43 * -ENOMEM -EINVAL -EOPNOTSUPP
44 * - Failure, entry not allocated, out of resources
47 tf_create_em_pool(struct tf_session *session,
51 struct tfp_calloc_parms parms;
54 struct stack *pool = &session->em_pool[dir];
56 parms.nitems = num_entries;
57 parms.size = sizeof(uint32_t);
60 rc = tfp_calloc(&parms);
63 TFP_DRV_LOG(ERR, "EM pool allocation failure %s\n",
70 rc = stack_init(num_entries, (uint32_t *)parms.mem_va, pool);
73 TFP_DRV_LOG(ERR, "EM pool stack init failure %s\n",
78 /* Fill pool with indexes
82 for (i = 0; i < num_entries; i++) {
83 rc = stack_push(pool, j);
85 TFP_DRV_LOG(ERR, "EM pool stack push failure %s\n",
92 if (!stack_is_full(pool)) {
94 TFP_DRV_LOG(ERR, "EM pool stack failure %s\n",
101 tfp_free((void *)parms.mem_va);
106 * Create EM Tbl pool of memory indexes.
116 tf_free_em_pool(struct tf_session *session,
119 struct stack *pool = &session->em_pool[dir];
122 ptr = stack_items(pool);
129 * Insert EM internal entry API
135 tf_em_insert_int_entry(struct tf *tfp,
136 struct tf_insert_em_entry_parms *parms)
140 uint16_t rptr_index = 0;
141 uint8_t rptr_entry = 0;
142 uint8_t num_of_entries = 0;
143 struct tf_session *session =
144 (struct tf_session *)(tfp->session->core_data);
145 struct stack *pool = &session->em_pool[parms->dir];
148 rc = stack_pop(pool, &index);
153 "dir:%d, EM entry index allocation failed\n",
158 rptr_index = index * TF_SESSION_EM_ENTRY_SIZE;
159 rc = tf_msg_insert_em_internal_entry(tfp,
169 "Internal entry @ Index:%d rptr_index:0x%x rptr_entry:0x%x num_of_entries:%d\n",
170 index * TF_SESSION_EM_ENTRY_SIZE,
176 ((rptr_index << TF_EM_INTERNAL_INDEX_SHIFT) |
178 0); /* N/A for internal table */
180 TF_SET_FLOW_ID(parms->flow_id,
182 TF_GFID_TABLE_INTERNAL,
185 TF_SET_FIELDS_IN_FLOW_HANDLE(parms->flow_handle,
186 (uint32_t)num_of_entries,
196 /** Delete EM internal entry API
203 tf_em_delete_int_entry(struct tf *tfp,
204 struct tf_delete_em_entry_parms *parms)
207 struct tf_session *session =
208 (struct tf_session *)(tfp->session->core_data);
209 struct stack *pool = &session->em_pool[parms->dir];
211 rc = tf_msg_delete_em_entry(tfp, parms);
213 /* Return resource to pool */
215 stack_push(pool, parms->index / TF_SESSION_EM_ENTRY_SIZE);
221 tf_em_int_bind(struct tf *tfp,
222 struct tf_em_cfg_parms *parms)
226 struct tf_rm_create_db_parms db_cfg = { 0 };
227 struct tf_session *session;
229 TF_CHECK_PARMS2(tfp, parms);
233 "Identifier already initialized\n");
237 session = (struct tf_session *)tfp->session->core_data;
239 for (i = 0; i < TF_DIR_MAX; i++) {
240 tf_create_em_pool(session,
242 TF_SESSION_EM_POOL_SIZE);
246 * I'm not sure that this code is needed.
247 * leaving for now until resolved
249 if (parms->num_elements) {
250 db_cfg.type = TF_DEVICE_MODULE_TYPE_EM;
251 db_cfg.num_elements = parms->num_elements;
252 db_cfg.cfg = parms->cfg;
254 for (i = 0; i < TF_DIR_MAX; i++) {
256 db_cfg.alloc_cnt = parms->resources->em_cnt[i].cnt;
257 db_cfg.rm_db = &em_db[i];
258 rc = tf_rm_create_db(tfp, &db_cfg);
261 "%s: EM DB creation failed\n",
274 tf_em_int_unbind(struct tf *tfp)
278 struct tf_rm_free_db_parms fparms = { 0 };
279 struct tf_session *session;
281 TF_CHECK_PARMS1(tfp);
283 /* Bail if nothing has been initialized done silent as to
284 * allow for creation cleanup.
288 "No EM DBs created\n");
292 session = (struct tf_session *)tfp->session->core_data;
294 for (i = 0; i < TF_DIR_MAX; i++)
295 tf_free_em_pool(session, i);
297 for (i = 0; i < TF_DIR_MAX; i++) {
299 fparms.rm_db = em_db[i];
300 if (em_db[i] != NULL) {
301 rc = tf_rm_free_db(tfp, &fparms);