Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2019-2023 Broadcom
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include <string.h>
7 : : #include <rte_common.h>
8 : : #include <rte_errno.h>
9 : : #include <rte_log.h>
10 : : #include "tf_core.h"
11 : : #include "tf_util.h"
12 : : #include "tf_common.h"
13 : : #include "tf_em.h"
14 : : #include "tf_msg.h"
15 : : #include "tfp.h"
16 : : #include "tf_ext_flow_handle.h"
17 : :
18 : : #include "bnxt.h"
19 : :
20 : : #define TF_EM_DB_EM_REC 0
21 : :
22 : : /**
23 : : * EM Pool
24 : : */
25 : : #include "dpool.h"
26 : :
27 : : /**
28 : : * Insert EM internal entry API
29 : : *
30 : : * returns:
31 : : * 0 - Success
32 : : */
33 : : int
34 : 0 : tf_em_insert_int_entry(struct tf *tfp,
35 : : struct tf_insert_em_entry_parms *parms)
36 : : {
37 : : int rc;
38 : : uint32_t gfid;
39 : 0 : uint16_t rptr_index = 0;
40 : 0 : uint8_t rptr_entry = 0;
41 : 0 : uint8_t num_of_entries = 0;
42 : : struct tf_session *tfs;
43 : : struct dpool *pool;
44 : : uint32_t index;
45 : :
46 : : /* Retrieve the session information */
47 : 0 : rc = tf_session_get_session(tfp, &tfs);
48 [ # # ]: 0 : if (rc) {
49 : 0 : TFP_DRV_LOG(ERR,
50 : : "%s: Failed to lookup session, rc:%s\n",
51 : : tf_dir_2_str(parms->dir),
52 : : strerror(-rc));
53 : 0 : return rc;
54 : : }
55 : :
56 : 0 : pool = (struct dpool *)tfs->em_pool[parms->dir];
57 : 0 : index = dpool_alloc(pool, TF_SESSION_EM_ENTRY_SIZE, 0);
58 [ # # ]: 0 : if (index == DP_INVALID_INDEX) {
59 : 0 : PMD_DRV_LOG(ERR,
60 : : "%s, EM entry index allocation failed\n",
61 : : tf_dir_2_str(parms->dir));
62 : 0 : return -1;
63 : : }
64 : :
65 : 0 : rptr_index = index;
66 : 0 : rc = tf_msg_insert_em_internal_entry(tfp,
67 : : parms,
68 : : &rptr_index,
69 : : &rptr_entry,
70 : : &num_of_entries);
71 [ # # ]: 0 : if (rc) {
72 : : /* Free the allocated index before returning */
73 : 0 : dpool_free(pool, index);
74 : 0 : return -1;
75 : : }
76 : :
77 : 0 : TF_SET_GFID(gfid,
78 : : ((rptr_index << TF_EM_INTERNAL_INDEX_SHIFT) |
79 : : rptr_entry),
80 : : 0); /* N/A for internal table */
81 : :
82 : 0 : TF_SET_FLOW_ID(parms->flow_id,
83 : : gfid,
84 : : TF_GFID_TABLE_INTERNAL,
85 : : parms->dir);
86 : :
87 : 0 : TF_SET_FIELDS_IN_FLOW_HANDLE(parms->flow_handle,
88 : : (uint32_t)num_of_entries,
89 : : 0,
90 : : TF_FLAGS_FLOW_HANDLE_INTERNAL,
91 : : rptr_index,
92 : : rptr_entry,
93 : : 0);
94 : 0 : return 0;
95 : : }
96 : :
97 : : /** Delete EM internal entry API
98 : : *
99 : : * returns:
100 : : * 0
101 : : * -EINVAL
102 : : */
103 : : int
104 : 0 : tf_em_delete_int_entry(struct tf *tfp,
105 : : struct tf_delete_em_entry_parms *parms)
106 : : {
107 : : int rc = 0;
108 : : struct tf_session *tfs;
109 : : struct dpool *pool;
110 : : /* Retrieve the session information */
111 : 0 : rc = tf_session_get_session(tfp, &tfs);
112 [ # # ]: 0 : if (rc) {
113 : 0 : TFP_DRV_LOG(ERR,
114 : : "%s: Failed to lookup session, rc:%s\n",
115 : : tf_dir_2_str(parms->dir),
116 : : strerror(-rc));
117 : 0 : return rc;
118 : : }
119 : :
120 : 0 : rc = tf_msg_delete_em_entry(tfp, parms);
121 : :
122 : : /* Return resource to pool */
123 [ # # ]: 0 : if (rc == 0) {
124 : 0 : pool = (struct dpool *)tfs->em_pool[parms->dir];
125 : 0 : dpool_free(pool, parms->index);
126 : : }
127 : :
128 : : return rc;
129 : : }
130 : :
131 : : static int
132 : 0 : tf_em_move_callback(void *user_data,
133 : : uint64_t entry_data,
134 : : uint32_t new_index)
135 : : {
136 : : int rc;
137 : : struct tf *tfp = (struct tf *)user_data;
138 : : struct tf_move_em_entry_parms parms;
139 : : struct tf_dev_info *dev;
140 : : struct tf_session *tfs;
141 : :
142 : : memset(&parms, 0, sizeof(parms));
143 : :
144 : : parms.tbl_scope_id = 0;
145 : 0 : parms.flow_handle = entry_data;
146 : 0 : parms.new_index = new_index;
147 : 0 : TF_GET_DIR_FROM_FLOW_ID(entry_data, parms.dir);
148 : : parms.mem = TF_MEM_INTERNAL;
149 : :
150 : : /* Retrieve the session information */
151 : 0 : rc = tf_session_get_session(tfp, &tfs);
152 [ # # ]: 0 : if (rc) {
153 : 0 : TFP_DRV_LOG(ERR,
154 : : "%s: Failed to lookup session, rc:%s\n",
155 : : tf_dir_2_str(parms.dir),
156 : : strerror(-rc));
157 : 0 : return rc;
158 : : }
159 : :
160 : : /* Retrieve the device information */
161 : 0 : rc = tf_session_get_device(tfs, &dev);
162 [ # # ]: 0 : if (rc) {
163 : 0 : TFP_DRV_LOG(ERR,
164 : : "%s: Failed to lookup device, rc:%s\n",
165 : : tf_dir_2_str(parms.dir),
166 : : strerror(-rc));
167 : 0 : return rc;
168 : : }
169 : :
170 [ # # ]: 0 : if (dev->ops->tf_dev_move_int_em_entry != NULL)
171 : 0 : rc = dev->ops->tf_dev_move_int_em_entry(tfp, &parms);
172 : : else
173 : : rc = -EOPNOTSUPP;
174 : :
175 : : return rc;
176 : : }
177 : :
178 : : int
179 : 0 : tf_em_int_bind(struct tf *tfp,
180 : : struct tf_em_cfg_parms *parms)
181 : : {
182 : : int rc;
183 : 0 : int db_rc[TF_DIR_MAX] = { 0 };
184 : : int i;
185 : 0 : struct tf_rm_create_db_parms db_cfg = { 0 };
186 : : struct tf_rm_get_alloc_info_parms iparms;
187 : : struct tf_rm_alloc_info info;
188 : : struct em_rm_db *em_db;
189 : : struct tfp_calloc_parms cparms;
190 : : struct tf_session *tfs;
191 : :
192 [ # # ]: 0 : TF_CHECK_PARMS2(tfp, parms);
193 : :
194 : : /* Retrieve the session information */
195 : 0 : rc = tf_session_get_session_internal(tfp, &tfs);
196 [ # # ]: 0 : if (rc)
197 : : return rc;
198 : :
199 : : memset(&db_cfg, 0, sizeof(db_cfg));
200 : 0 : cparms.nitems = 1;
201 : 0 : cparms.size = sizeof(struct em_rm_db);
202 : 0 : cparms.alignment = 0;
203 [ # # ]: 0 : if (tfp_calloc(&cparms) != 0) {
204 : 0 : TFP_DRV_LOG(ERR, "em_rm_db alloc error %s\n",
205 : : strerror(ENOMEM));
206 : 0 : return -ENOMEM;
207 : : }
208 : :
209 : 0 : em_db = cparms.mem_va;
210 [ # # ]: 0 : for (i = 0; i < TF_DIR_MAX; i++)
211 : 0 : em_db->em_db[i] = NULL;
212 : 0 : tf_session_set_db(tfp, TF_MODULE_TYPE_EM, em_db);
213 : :
214 : 0 : db_cfg.module = TF_MODULE_TYPE_EM;
215 : 0 : db_cfg.num_elements = parms->num_elements;
216 : 0 : db_cfg.cfg = parms->cfg;
217 : :
218 [ # # ]: 0 : for (i = 0; i < TF_DIR_MAX; i++) {
219 : 0 : db_cfg.dir = i;
220 : 0 : db_cfg.alloc_cnt = parms->resources->em_cnt[i].cnt;
221 : :
222 : : /* Check if we got any request to support EEM, if so
223 : : * we build an EM Int DB holding Table Scopes.
224 : : */
225 [ # # ]: 0 : if (db_cfg.alloc_cnt[TF_EM_TBL_TYPE_EM_RECORD] == 0)
226 : 0 : continue;
227 : :
228 : 0 : if (db_cfg.alloc_cnt[TF_EM_TBL_TYPE_EM_RECORD] %
229 [ # # ]: 0 : TF_SESSION_EM_ENTRY_SIZE != 0) {
230 : : rc = -ENOMEM;
231 : 0 : TFP_DRV_LOG(ERR,
232 : : "%s, EM Allocation must be in blocks of %d, failure %s\n",
233 : : tf_dir_2_str(i),
234 : : TF_SESSION_EM_ENTRY_SIZE,
235 : : strerror(-rc));
236 : :
237 : 0 : return rc;
238 : : }
239 : :
240 : 0 : db_cfg.rm_db = (void *)&em_db->em_db[i];
241 [ # # # # ]: 0 : if (tf_session_is_shared_session(tfs) &&
242 : : (!tf_session_is_shared_session_creator(tfs)))
243 : 0 : db_rc[i] = tf_rm_create_db_no_reservation(tfp, &db_cfg);
244 : : else
245 : 0 : db_rc[i] = tf_rm_create_db(tfp, &db_cfg);
246 : : }
247 : :
248 : : /* No db created */
249 [ # # # # ]: 0 : if (db_rc[TF_DIR_RX] && db_rc[TF_DIR_TX]) {
250 : 0 : TFP_DRV_LOG(ERR, "EM Int DB creation failed\n");
251 : 0 : return db_rc[TF_DIR_RX];
252 : : }
253 : :
254 [ # # ]: 0 : if (!tf_session_is_shared_session(tfs)) {
255 [ # # ]: 0 : for (i = 0; i < TF_DIR_MAX; i++) {
256 : 0 : iparms.rm_db = em_db->em_db[i];
257 : 0 : iparms.subtype = TF_EM_DB_EM_REC;
258 : 0 : iparms.info = &info;
259 : :
260 : 0 : rc = tf_rm_get_info(&iparms);
261 [ # # ]: 0 : if (rc) {
262 : 0 : TFP_DRV_LOG(ERR,
263 : : "%s: EM DB get info failed\n",
264 : : tf_dir_2_str(i));
265 : 0 : return rc;
266 : : }
267 : :
268 : : /*
269 : : * Allocate stack pool
270 : : */
271 : 0 : cparms.nitems = 1;
272 : 0 : cparms.size = sizeof(struct dpool);
273 : 0 : cparms.alignment = 0;
274 : :
275 : 0 : rc = tfp_calloc(&cparms);
276 : :
277 [ # # ]: 0 : if (rc) {
278 : 0 : TFP_DRV_LOG(ERR,
279 : : "%s, EM stack allocation failure %s\n",
280 : : tf_dir_2_str(i),
281 : : strerror(-rc));
282 : 0 : return rc;
283 : : }
284 : :
285 : 0 : tfs->em_pool[i] = (struct dpool *)cparms.mem_va;
286 : :
287 : 0 : rc = dpool_init(tfs->em_pool[i],
288 : 0 : iparms.info->entry.start,
289 : 0 : iparms.info->entry.stride,
290 : : 7,
291 : : (void *)tfp,
292 : : tf_em_move_callback);
293 : : /* Logging handled in tf_create_em_pool */
294 [ # # ]: 0 : if (rc)
295 : 0 : return rc;
296 : : }
297 : :
298 : : if (rc) {
299 : : TFP_DRV_LOG(ERR,
300 : : "%s: EM pool init failed\n",
301 : : tf_dir_2_str(i));
302 : : return rc;
303 : : }
304 : : }
305 : :
306 : : return 0;
307 : : }
308 : :
309 : : int
310 : 0 : tf_em_int_unbind(struct tf *tfp)
311 : : {
312 : : int rc;
313 : : int i;
314 : 0 : struct tf_rm_free_db_parms fparms = { 0 };
315 : : struct em_rm_db *em_db;
316 : 0 : void *em_db_ptr = NULL;
317 : : struct tf_session *tfs;
318 : :
319 [ # # ]: 0 : TF_CHECK_PARMS1(tfp);
320 : :
321 : : /* Retrieve the session information */
322 : 0 : rc = tf_session_get_session_internal(tfp, &tfs);
323 [ # # ]: 0 : if (rc)
324 : : return rc;
325 : :
326 [ # # ]: 0 : if (!tf_session_is_shared_session(tfs)) {
327 [ # # ]: 0 : for (i = 0; i < TF_DIR_MAX; i++) {
328 [ # # ]: 0 : if (tfs->em_pool[i] == NULL)
329 : 0 : continue;
330 : 0 : dpool_free_all(tfs->em_pool[i]);
331 : : }
332 : : }
333 : :
334 : 0 : rc = tf_session_get_db(tfp, TF_MODULE_TYPE_EM, &em_db_ptr);
335 [ # # ]: 0 : if (rc)
336 : : return 0;
337 : :
338 : 0 : em_db = (struct em_rm_db *)em_db_ptr;
339 [ # # ]: 0 : for (i = 0; i < TF_DIR_MAX; i++) {
340 [ # # ]: 0 : if (em_db->em_db[i] == NULL)
341 : 0 : continue;
342 : 0 : fparms.dir = i;
343 : 0 : fparms.rm_db = em_db->em_db[i];
344 : 0 : rc = tf_rm_free_db(tfp, &fparms);
345 [ # # ]: 0 : if (rc)
346 : 0 : return rc;
347 : :
348 : 0 : em_db->em_db[i] = NULL;
349 : : }
350 : :
351 : : return 0;
352 : : }
353 : :
354 : : int
355 : 0 : tf_em_get_resc_info(struct tf *tfp,
356 : : struct tf_em_resource_info *em)
357 : : {
358 : : int rc;
359 : : int d;
360 : : struct tf_resource_info *dinfo;
361 : : struct tf_rm_get_alloc_info_parms ainfo;
362 : 0 : void *em_db_ptr = NULL;
363 : : struct em_rm_db *em_db;
364 : :
365 [ # # ]: 0 : TF_CHECK_PARMS2(tfp, em);
366 : :
367 : 0 : rc = tf_session_get_db(tfp, TF_MODULE_TYPE_EM, &em_db_ptr);
368 [ # # ]: 0 : if (rc == -ENOMEM)
369 : : return 0; /* db does not exist */
370 [ # # ]: 0 : else if (rc)
371 : : return rc; /* db error */
372 : :
373 : 0 : em_db = (struct em_rm_db *)em_db_ptr;
374 : :
375 : : /* check if reserved resource for EM is multiple of num_slices */
376 [ # # ]: 0 : for (d = 0; d < TF_DIR_MAX; d++) {
377 : 0 : ainfo.rm_db = em_db->em_db[d];
378 : 0 : dinfo = em[d].info;
379 : :
380 [ # # ]: 0 : if (!ainfo.rm_db)
381 : 0 : continue;
382 : :
383 : 0 : ainfo.info = (struct tf_rm_alloc_info *)dinfo;
384 : 0 : ainfo.subtype = 0;
385 : 0 : rc = tf_rm_get_all_info(&ainfo, TF_EM_TBL_TYPE_MAX);
386 [ # # ]: 0 : if (rc && rc != -ENOTSUP)
387 : 0 : return rc;
388 : : }
389 : :
390 : : return 0;
391 : : }
|