xref: /dpdk/drivers/net/bnxt/tf_core/tf_identifier.c (revision 97435d7906d7706e39e5c3dfefa5e09d7de7f733)
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