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"
20 #define TF_EM_DB_EM_REC 0
28 * Insert EM internal entry API
34 tf_em_insert_int_entry(struct tf *tfp,
35 struct tf_insert_em_entry_parms *parms)
39 uint16_t rptr_index = 0;
40 uint8_t rptr_entry = 0;
41 uint8_t num_of_entries = 0;
42 struct tf_session *tfs;
46 /* Retrieve the session information */
47 rc = tf_session_get_session(tfp, &tfs);
50 "%s: Failed to lookup session, rc:%s\n",
51 tf_dir_2_str(parms->dir),
56 pool = (struct dpool *)tfs->em_pool[parms->dir];
57 index = dpool_alloc(pool, TF_SESSION_EM_ENTRY_SIZE, 0);
58 if (index == DP_INVALID_INDEX) {
60 "%s, EM entry index allocation failed\n",
61 tf_dir_2_str(parms->dir));
67 rc = tf_msg_insert_em_internal_entry(tfp,
73 /* Free the allocated index before returning */
74 dpool_free(pool, index);
78 ((rptr_index << TF_EM_INTERNAL_INDEX_SHIFT) |
80 0); /* N/A for internal table */
82 TF_SET_FLOW_ID(parms->flow_id,
84 TF_GFID_TABLE_INTERNAL,
87 TF_SET_FIELDS_IN_FLOW_HANDLE(parms->flow_handle,
88 (uint32_t)num_of_entries,
90 TF_FLAGS_FLOW_HANDLE_INTERNAL,
98 /** Delete EM internal entry API
105 tf_em_delete_int_entry(struct tf *tfp,
106 struct tf_delete_em_entry_parms *parms)
109 struct tf_session *tfs;
111 /* Retrieve the session information */
112 rc = tf_session_get_session(tfp, &tfs);
115 "%s: Failed to lookup session, rc:%s\n",
116 tf_dir_2_str(parms->dir),
121 rc = tf_msg_delete_em_entry(tfp, parms);
123 /* Return resource to pool */
125 pool = (struct dpool *)tfs->em_pool[parms->dir];
126 dpool_free(pool, parms->index);
133 tf_em_move_callback(void *user_data,
138 struct tf *tfp = (struct tf *)user_data;
139 struct tf_move_em_entry_parms parms;
140 struct tf_dev_info *dev;
141 struct tf_session *tfs;
143 memset(&parms, 0, sizeof(parms));
145 parms.tbl_scope_id = 0;
146 parms.flow_handle = entry_data;
147 parms.new_index = new_index;
148 TF_GET_DIR_FROM_FLOW_ID(entry_data, parms.dir);
149 parms.mem = TF_MEM_INTERNAL;
151 /* Retrieve the session information */
152 rc = tf_session_get_session(tfp, &tfs);
155 "%s: Failed to lookup session, rc:%s\n",
156 tf_dir_2_str(parms.dir),
161 /* Retrieve the device information */
162 rc = tf_session_get_device(tfs, &dev);
165 "%s: Failed to lookup device, rc:%s\n",
166 tf_dir_2_str(parms.dir),
171 if (dev->ops->tf_dev_move_int_em_entry != NULL)
172 rc = dev->ops->tf_dev_move_int_em_entry(tfp, &parms);
180 tf_em_int_bind(struct tf *tfp,
181 struct tf_em_cfg_parms *parms)
184 int db_rc[TF_DIR_MAX] = { 0 };
186 struct tf_rm_create_db_parms db_cfg = { 0 };
187 struct tf_rm_get_alloc_info_parms iparms;
188 struct tf_rm_alloc_info info;
189 struct em_rm_db *em_db;
190 struct tfp_calloc_parms cparms;
191 struct tf_session *tfs;
193 TF_CHECK_PARMS2(tfp, parms);
195 /* Retrieve the session information */
196 rc = tf_session_get_session_internal(tfp, &tfs);
200 memset(&db_cfg, 0, sizeof(db_cfg));
202 cparms.size = sizeof(struct em_rm_db);
203 cparms.alignment = 0;
204 if (tfp_calloc(&cparms) != 0) {
205 TFP_DRV_LOG(ERR, "em_rm_db alloc error %s\n",
210 em_db = cparms.mem_va;
211 for (i = 0; i < TF_DIR_MAX; i++)
212 em_db->em_db[i] = NULL;
213 tf_session_set_db(tfp, TF_MODULE_TYPE_EM, em_db);
215 db_cfg.module = TF_MODULE_TYPE_EM;
216 db_cfg.num_elements = parms->num_elements;
217 db_cfg.cfg = parms->cfg;
219 for (i = 0; i < TF_DIR_MAX; i++) {
221 db_cfg.alloc_cnt = parms->resources->em_cnt[i].cnt;
223 /* Check if we got any request to support EEM, if so
224 * we build an EM Int DB holding Table Scopes.
226 if (db_cfg.alloc_cnt[TF_EM_TBL_TYPE_EM_RECORD] == 0)
229 if (db_cfg.alloc_cnt[TF_EM_TBL_TYPE_EM_RECORD] %
230 TF_SESSION_EM_ENTRY_SIZE != 0) {
233 "%s, EM Allocation must be in blocks of %d, failure %s\n",
235 TF_SESSION_EM_ENTRY_SIZE,
241 db_cfg.rm_db = (void *)&em_db->em_db[i];
242 if (tf_session_is_shared_session(tfs) &&
243 (!tf_session_is_shared_session_creator(tfs)))
244 db_rc[i] = tf_rm_create_db_no_reservation(tfp, &db_cfg);
246 db_rc[i] = tf_rm_create_db(tfp, &db_cfg);
250 if (db_rc[TF_DIR_RX] && db_rc[TF_DIR_TX]) {
251 TFP_DRV_LOG(ERR, "EM Int DB creation failed\n");
252 return db_rc[TF_DIR_RX];
256 if (!tf_session_is_shared_session(tfs)) {
257 for (i = 0; i < TF_DIR_MAX; i++) {
258 iparms.rm_db = em_db->em_db[i];
259 iparms.subtype = TF_EM_DB_EM_REC;
262 rc = tf_rm_get_info(&iparms);
265 "%s: EM DB get info failed\n",
271 * Allocate stack pool
274 cparms.size = sizeof(struct dpool);
275 cparms.alignment = 0;
277 rc = tfp_calloc(&cparms);
281 "%s, EM stack allocation failure %s\n",
287 tfs->em_pool[i] = (struct dpool *)cparms.mem_va;
289 rc = dpool_init(tfs->em_pool[i],
290 iparms.info->entry.start,
291 iparms.info->entry.stride,
294 tf_em_move_callback);
295 /* Logging handled in tf_create_em_pool */
302 "%s: EM pool init failed\n",
312 tf_em_int_unbind(struct tf *tfp)
316 struct tf_rm_free_db_parms fparms = { 0 };
317 struct em_rm_db *em_db;
318 void *em_db_ptr = NULL;
319 struct tf_session *tfs;
321 TF_CHECK_PARMS1(tfp);
323 /* Retrieve the session information */
324 rc = tf_session_get_session_internal(tfp, &tfs);
328 if (!tf_session_is_shared_session(tfs)) {
329 for (i = 0; i < TF_DIR_MAX; i++) {
330 if (tfs->em_pool[i] == NULL)
332 dpool_free_all(tfs->em_pool[i]);
336 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_EM, &em_db_ptr);
340 em_db = (struct em_rm_db *)em_db_ptr;
342 for (i = 0; i < TF_DIR_MAX; i++) {
343 if (em_db->em_db[i] == NULL)
346 fparms.rm_db = em_db->em_db[i];
347 rc = tf_rm_free_db(tfp, &fparms);
351 em_db->em_db[i] = NULL;
358 tf_em_get_resc_info(struct tf *tfp,
359 struct tf_em_resource_info *em)
363 struct tf_resource_info *dinfo;
364 struct tf_rm_get_alloc_info_parms ainfo;
365 void *em_db_ptr = NULL;
366 struct em_rm_db *em_db;
368 TF_CHECK_PARMS2(tfp, em);
370 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_EM, &em_db_ptr);
372 return 0; /* db does not exist */
374 return rc; /* db error */
376 em_db = (struct em_rm_db *)em_db_ptr;
378 /* check if reserved resource for EM is multiple of num_slices */
379 for (d = 0; d < TF_DIR_MAX; d++) {
380 ainfo.rm_db = em_db->em_db[d];
386 ainfo.info = (struct tf_rm_alloc_info *)dinfo;
388 rc = tf_rm_get_all_info(&ainfo, TF_EM_TBL_TYPE_MAX);
389 if (rc && rc != -ENOTSUP)