1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2019-2023 Broadcom
3 * All rights reserved.
4 */
5
6 #include <rte_common.h>
7
8 #include "tf_identifier.h"
9 #include "tf_common.h"
10 #include "tf_rm.h"
11 #include "tf_util.h"
12 #include "tfp.h"
13 #include "tf_session.h"
14
15 struct tf;
16
17 int
tf_ident_bind(struct tf * tfp,struct tf_ident_cfg_parms * parms)18 tf_ident_bind(struct tf *tfp,
19 struct tf_ident_cfg_parms *parms)
20 {
21 int rc;
22 int db_rc[TF_DIR_MAX] = { 0 };
23 int i;
24 struct tf_rm_create_db_parms db_cfg = { 0 };
25 struct ident_rm_db *ident_db;
26 struct tfp_calloc_parms cparms;
27 struct tf_session *tfs;
28
29 TF_CHECK_PARMS2(tfp, parms);
30
31 /* Retrieve the session information */
32 rc = tf_session_get_session_internal(tfp, &tfs);
33 if (rc)
34 return rc;
35
36 memset(&db_cfg, 0, sizeof(db_cfg));
37 cparms.nitems = 1;
38 cparms.size = sizeof(struct ident_rm_db);
39 cparms.alignment = 0;
40 if (tfp_calloc(&cparms) != 0) {
41 TFP_DRV_LOG(ERR, "ident_rm_db alloc error %s\n",
42 strerror(ENOMEM));
43 return -ENOMEM;
44 }
45
46 ident_db = cparms.mem_va;
47 for (i = 0; i < TF_DIR_MAX; i++)
48 ident_db->ident_db[i] = NULL;
49 tf_session_set_db(tfp, TF_MODULE_TYPE_IDENTIFIER, ident_db);
50
51 db_cfg.module = TF_MODULE_TYPE_IDENTIFIER;
52 db_cfg.num_elements = parms->num_elements;
53 db_cfg.cfg = parms->cfg;
54
55 for (i = 0; i < TF_DIR_MAX; i++) {
56 db_cfg.rm_db = (void *)&ident_db->ident_db[i];
57 db_cfg.dir = i;
58 db_cfg.alloc_cnt = parms->resources->ident_cnt[i].cnt;
59 if (tf_session_is_shared_session(tfs) &&
60 (!tf_session_is_shared_session_creator(tfs)))
61 db_rc[i] = tf_rm_create_db_no_reservation(tfp, &db_cfg);
62 else
63 db_rc[i] = tf_rm_create_db(tfp, &db_cfg);
64 }
65
66 /* No db created */
67 if (db_rc[TF_DIR_RX] && db_rc[TF_DIR_TX]) {
68 TFP_DRV_LOG(ERR, "No Identifier DB created\n");
69 return db_rc[TF_DIR_RX];
70 }
71
72 TFP_DRV_LOG(INFO,
73 "Identifier - initialized\n");
74
75 return 0;
76 }
77
78 int
tf_ident_unbind(struct tf * tfp)79 tf_ident_unbind(struct tf *tfp)
80 {
81 int rc = 0;
82 int i;
83 struct tf_rm_free_db_parms fparms = { 0 };
84 struct ident_rm_db *ident_db;
85 void *ident_db_ptr = NULL;
86
87 TF_CHECK_PARMS1(tfp);
88
89 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
90 if (rc)
91 return 0;
92
93 ident_db = (struct ident_rm_db *)ident_db_ptr;
94
95 for (i = 0; i < TF_DIR_MAX; i++) {
96 if (ident_db->ident_db[i] == NULL)
97 continue;
98 fparms.rm_db = ident_db->ident_db[i];
99 fparms.dir = i;
100 rc = tf_rm_free_db(tfp, &fparms);
101 if (rc) {
102 TFP_DRV_LOG(ERR,
103 "rm free failed on unbind\n");
104 }
105 ident_db->ident_db[i] = NULL;
106 }
107 return 0;
108 }
109
110 int
tf_ident_alloc(struct tf * tfp __rte_unused,struct tf_ident_alloc_parms * parms)111 tf_ident_alloc(struct tf *tfp __rte_unused,
112 struct tf_ident_alloc_parms *parms)
113 {
114 int rc;
115 uint32_t id;
116 uint32_t base_id;
117 struct tf_rm_allocate_parms aparms = { 0 };
118 struct ident_rm_db *ident_db;
119 void *ident_db_ptr = NULL;
120
121 TF_CHECK_PARMS2(tfp, parms);
122
123 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
124 if (rc) {
125 TFP_DRV_LOG(ERR,
126 "Failed to get ident_db from session, rc:%s\n",
127 strerror(-rc));
128 return rc;
129 }
130 ident_db = (struct ident_rm_db *)ident_db_ptr;
131
132 aparms.rm_db = ident_db->ident_db[parms->dir];
133 aparms.subtype = parms->type;
134 aparms.index = &id;
135 aparms.base_index = &base_id;
136 rc = tf_rm_allocate(&aparms);
137 if (rc) {
138 TFP_DRV_LOG(ERR,
139 "%s: Failed allocate, type:%d\n",
140 tf_dir_2_str(parms->dir),
141 parms->type);
142 return rc;
143 }
144
145 *parms->id = id;
146 return 0;
147 }
148
149 int
tf_ident_free(struct tf * tfp __rte_unused,struct tf_ident_free_parms * parms)150 tf_ident_free(struct tf *tfp __rte_unused,
151 struct tf_ident_free_parms *parms)
152 {
153 int rc;
154 struct tf_rm_is_allocated_parms aparms = { 0 };
155 struct tf_rm_free_parms fparms = { 0 };
156 int allocated = 0;
157 uint32_t base_id;
158 struct ident_rm_db *ident_db;
159 void *ident_db_ptr = NULL;
160
161 TF_CHECK_PARMS2(tfp, parms);
162
163 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
164 if (rc) {
165 TFP_DRV_LOG(ERR,
166 "Failed to get ident_db from session, rc:%s\n",
167 strerror(-rc));
168 return rc;
169 }
170 ident_db = (struct ident_rm_db *)ident_db_ptr;
171
172 /* Check if element is in use */
173 aparms.rm_db = ident_db->ident_db[parms->dir];
174 aparms.subtype = parms->type;
175 aparms.index = parms->id;
176 aparms.base_index = &base_id;
177 aparms.allocated = &allocated;
178 rc = tf_rm_is_allocated(&aparms);
179 if (rc)
180 return rc;
181
182 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
183 TFP_DRV_LOG(ERR,
184 "%s: Entry already free, type:%d, index:%d\n",
185 tf_dir_2_str(parms->dir),
186 parms->type,
187 parms->id);
188 return -EINVAL;
189 }
190
191 /* Free requested element */
192 fparms.rm_db = ident_db->ident_db[parms->dir];
193 fparms.subtype = parms->type;
194 fparms.index = parms->id;
195 rc = tf_rm_free(&fparms);
196 if (rc) {
197 TFP_DRV_LOG(ERR,
198 "%s: Free failed, type:%d, index:%d\n",
199 tf_dir_2_str(parms->dir),
200 parms->type,
201 parms->id);
202 return rc;
203 }
204
205 return 0;
206 }
207
208 int
tf_ident_search(struct tf * tfp __rte_unused,struct tf_ident_search_parms * parms)209 tf_ident_search(struct tf *tfp __rte_unused,
210 struct tf_ident_search_parms *parms)
211 {
212 int rc;
213 struct tf_rm_is_allocated_parms aparms = { 0 };
214 int allocated = 0;
215 uint32_t base_id;
216 struct ident_rm_db *ident_db;
217 void *ident_db_ptr = NULL;
218
219 TF_CHECK_PARMS2(tfp, parms);
220
221 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
222 if (rc) {
223 TFP_DRV_LOG(ERR,
224 "Failed to get ident_db from session, rc:%s\n",
225 strerror(-rc));
226 return rc;
227 }
228 ident_db = (struct ident_rm_db *)ident_db_ptr;
229
230 /* Check if element is in use */
231 aparms.rm_db = ident_db->ident_db[parms->dir];
232 aparms.subtype = parms->type;
233 aparms.index = parms->search_id;
234 aparms.base_index = &base_id;
235 aparms.allocated = &allocated;
236 rc = tf_rm_is_allocated(&aparms);
237 if (rc)
238 return rc;
239
240 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
241 TFP_DRV_LOG(ERR,
242 "%s: Entry not allocated, type:%d, index:%d\n",
243 tf_dir_2_str(parms->dir),
244 parms->type,
245 parms->search_id);
246 return -EINVAL;
247 }
248 return 0;
249 }
250
251 int
tf_ident_get_resc_info(struct tf * tfp,struct tf_identifier_resource_info * ident)252 tf_ident_get_resc_info(struct tf *tfp,
253 struct tf_identifier_resource_info *ident)
254 {
255 int rc;
256 int d;
257 struct tf_resource_info *dinfo;
258 struct tf_rm_get_alloc_info_parms ainfo;
259 void *ident_db_ptr = NULL;
260 struct ident_rm_db *ident_db;
261
262 TF_CHECK_PARMS2(tfp, ident);
263
264 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
265 if (rc == -ENOMEM)
266 return 0; /* db doesn't exist */
267 else if (rc)
268 return rc; /* error getting db */
269
270 ident_db = (struct ident_rm_db *)ident_db_ptr;
271
272 /* check if reserved resource for WC is multiple of num_slices */
273 for (d = 0; d < TF_DIR_MAX; d++) {
274 ainfo.rm_db = ident_db->ident_db[d];
275
276 if (!ainfo.rm_db)
277 continue;
278
279 dinfo = ident[d].info;
280
281 ainfo.info = (struct tf_rm_alloc_info *)dinfo;
282 ainfo.subtype = 0;
283 rc = tf_rm_get_all_info(&ainfo, TF_IDENT_TYPE_MAX);
284 if (rc)
285 return rc;
286 }
287
288 return 0;
289 }
290