xref: /dpdk/drivers/net/bnxt/tf_core/tf_identifier.c (revision 97435d7906d7706e39e5c3dfefa5e09d7de7f733)
18187694bSMichael Wildt /* SPDX-License-Identifier: BSD-3-Clause
2e6e8f03eSRandy Schacher  * Copyright(c) 2019-2023 Broadcom
38187694bSMichael Wildt  * All rights reserved.
48187694bSMichael Wildt  */
58187694bSMichael Wildt 
68187694bSMichael Wildt #include <rte_common.h>
78187694bSMichael Wildt 
88187694bSMichael Wildt #include "tf_identifier.h"
9a46bbb57SMichael Wildt #include "tf_common.h"
10ced3cdedSMichael Wildt #include "tf_rm.h"
11a46bbb57SMichael Wildt #include "tf_util.h"
12a46bbb57SMichael Wildt #include "tfp.h"
1338dc96f9SJay Ding #include "tf_session.h"
148187694bSMichael Wildt 
158187694bSMichael Wildt struct tf;
168187694bSMichael Wildt 
178187694bSMichael Wildt int
tf_ident_bind(struct tf * tfp,struct tf_ident_cfg_parms * parms)18a46bbb57SMichael Wildt tf_ident_bind(struct tf *tfp,
19a46bbb57SMichael Wildt 	      struct tf_ident_cfg_parms *parms)
208187694bSMichael Wildt {
21a46bbb57SMichael Wildt 	int rc;
221a3f3817SJay Ding 	int db_rc[TF_DIR_MAX] = { 0 };
23a46bbb57SMichael Wildt 	int i;
24a46bbb57SMichael Wildt 	struct tf_rm_create_db_parms db_cfg = { 0 };
2538dc96f9SJay Ding 	struct ident_rm_db *ident_db;
2638dc96f9SJay Ding 	struct tfp_calloc_parms cparms;
27873661aaSJay Ding 	struct tf_session *tfs;
28a46bbb57SMichael Wildt 
29a46bbb57SMichael Wildt 	TF_CHECK_PARMS2(tfp, parms);
30a46bbb57SMichael Wildt 
31873661aaSJay Ding 	/* Retrieve the session information */
32873661aaSJay Ding 	rc = tf_session_get_session_internal(tfp, &tfs);
33873661aaSJay Ding 	if (rc)
34873661aaSJay Ding 		return rc;
35a46bbb57SMichael Wildt 
3638dc96f9SJay Ding 	memset(&db_cfg, 0, sizeof(db_cfg));
3738dc96f9SJay Ding 	cparms.nitems = 1;
3838dc96f9SJay Ding 	cparms.size = sizeof(struct ident_rm_db);
3938dc96f9SJay Ding 	cparms.alignment = 0;
4038dc96f9SJay Ding 	if (tfp_calloc(&cparms) != 0) {
4138dc96f9SJay Ding 		TFP_DRV_LOG(ERR, "ident_rm_db alloc error %s\n",
4238dc96f9SJay Ding 			    strerror(ENOMEM));
4338dc96f9SJay Ding 		return -ENOMEM;
4438dc96f9SJay Ding 	}
4538dc96f9SJay Ding 
4638dc96f9SJay Ding 	ident_db = cparms.mem_va;
4738dc96f9SJay Ding 	for (i = 0; i < TF_DIR_MAX; i++)
4838dc96f9SJay Ding 		ident_db->ident_db[i] = NULL;
4938dc96f9SJay Ding 	tf_session_set_db(tfp, TF_MODULE_TYPE_IDENTIFIER, ident_db);
5038dc96f9SJay Ding 
5170529991SFarah Smith 	db_cfg.module = TF_MODULE_TYPE_IDENTIFIER;
52a46bbb57SMichael Wildt 	db_cfg.num_elements = parms->num_elements;
53eee264adSMichael Wildt 	db_cfg.cfg = parms->cfg;
54a46bbb57SMichael Wildt 
55a46bbb57SMichael Wildt 	for (i = 0; i < TF_DIR_MAX; i++) {
5638dc96f9SJay Ding 		db_cfg.rm_db = (void *)&ident_db->ident_db[i];
57a46bbb57SMichael Wildt 		db_cfg.dir = i;
5848d3dff2SMichael Wildt 		db_cfg.alloc_cnt = parms->resources->ident_cnt[i].cnt;
59873661aaSJay Ding 		if (tf_session_is_shared_session(tfs) &&
60873661aaSJay Ding 			(!tf_session_is_shared_session_creator(tfs)))
611a3f3817SJay Ding 			db_rc[i] = tf_rm_create_db_no_reservation(tfp, &db_cfg);
62873661aaSJay Ding 		else
631a3f3817SJay Ding 			db_rc[i] = tf_rm_create_db(tfp, &db_cfg);
64a46bbb57SMichael Wildt 	}
65a46bbb57SMichael Wildt 
661a3f3817SJay Ding 	/* No db created */
671678535bSFarah Smith 	if (db_rc[TF_DIR_RX] && db_rc[TF_DIR_TX]) {
681678535bSFarah Smith 		TFP_DRV_LOG(ERR, "No Identifier DB created\n");
691a3f3817SJay Ding 		return db_rc[TF_DIR_RX];
701678535bSFarah Smith 	}
711a3f3817SJay Ding 
72d0d22f1fSRandy Schacher 	TFP_DRV_LOG(INFO,
73d0d22f1fSRandy Schacher 		    "Identifier - initialized\n");
7448d3dff2SMichael Wildt 
758187694bSMichael Wildt 	return 0;
768187694bSMichael Wildt }
778187694bSMichael Wildt 
788187694bSMichael Wildt int
tf_ident_unbind(struct tf * tfp)79ced3cdedSMichael Wildt tf_ident_unbind(struct tf *tfp)
808187694bSMichael Wildt {
81f3502f5cSJay Ding 	int rc = 0;
82a46bbb57SMichael Wildt 	int i;
83a46bbb57SMichael Wildt 	struct tf_rm_free_db_parms fparms = { 0 };
8438dc96f9SJay Ding 	struct ident_rm_db *ident_db;
8538dc96f9SJay Ding 	void *ident_db_ptr = NULL;
86a46bbb57SMichael Wildt 
87a46bbb57SMichael Wildt 	TF_CHECK_PARMS1(tfp);
88a46bbb57SMichael Wildt 
8938dc96f9SJay Ding 	rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
901678535bSFarah Smith 	if (rc)
91b97763fcSJay Ding 		return 0;
92*97435d79SRandy Schacher 
9338dc96f9SJay Ding 	ident_db = (struct ident_rm_db *)ident_db_ptr;
9438dc96f9SJay Ding 
95a46bbb57SMichael Wildt 	for (i = 0; i < TF_DIR_MAX; i++) {
96b97763fcSJay Ding 		if (ident_db->ident_db[i] == NULL)
97b97763fcSJay Ding 			continue;
9838dc96f9SJay Ding 		fparms.rm_db = ident_db->ident_db[i];
99a46bbb57SMichael Wildt 		fparms.dir = i;
100a46bbb57SMichael Wildt 		rc = tf_rm_free_db(tfp, &fparms);
101eee264adSMichael Wildt 		if (rc) {
102eee264adSMichael Wildt 			TFP_DRV_LOG(ERR,
103eee264adSMichael Wildt 				    "rm free failed on unbind\n");
104eee264adSMichael Wildt 		}
10538dc96f9SJay Ding 		ident_db->ident_db[i] = NULL;
106a46bbb57SMichael Wildt 	}
1078187694bSMichael Wildt 	return 0;
1088187694bSMichael Wildt }
1098187694bSMichael Wildt 
1108187694bSMichael Wildt int
tf_ident_alloc(struct tf * tfp __rte_unused,struct tf_ident_alloc_parms * parms)1118187694bSMichael Wildt tf_ident_alloc(struct tf *tfp __rte_unused,
112a46bbb57SMichael Wildt 	       struct tf_ident_alloc_parms *parms)
1138187694bSMichael Wildt {
114a46bbb57SMichael Wildt 	int rc;
11548d3dff2SMichael Wildt 	uint32_t id;
1168ee821cfSJay Ding 	uint32_t base_id;
117a46bbb57SMichael Wildt 	struct tf_rm_allocate_parms aparms = { 0 };
11838dc96f9SJay Ding 	struct ident_rm_db *ident_db;
11938dc96f9SJay Ding 	void *ident_db_ptr = NULL;
120a46bbb57SMichael Wildt 
121a46bbb57SMichael Wildt 	TF_CHECK_PARMS2(tfp, parms);
122a46bbb57SMichael Wildt 
12338dc96f9SJay Ding 	rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
12438dc96f9SJay Ding 	if (rc) {
12538dc96f9SJay Ding 		TFP_DRV_LOG(ERR,
12638dc96f9SJay Ding 			    "Failed to get ident_db from session, rc:%s\n",
12738dc96f9SJay Ding 			    strerror(-rc));
12838dc96f9SJay Ding 		return rc;
12938dc96f9SJay Ding 	}
13038dc96f9SJay Ding 	ident_db = (struct ident_rm_db *)ident_db_ptr;
13138dc96f9SJay Ding 
13238dc96f9SJay Ding 	aparms.rm_db = ident_db->ident_db[parms->dir];
13370529991SFarah Smith 	aparms.subtype = parms->type;
13448d3dff2SMichael Wildt 	aparms.index = &id;
1358ee821cfSJay Ding 	aparms.base_index = &base_id;
136a46bbb57SMichael Wildt 	rc = tf_rm_allocate(&aparms);
137a46bbb57SMichael Wildt 	if (rc) {
138a46bbb57SMichael Wildt 		TFP_DRV_LOG(ERR,
139a46bbb57SMichael Wildt 			    "%s: Failed allocate, type:%d\n",
140a46bbb57SMichael Wildt 			    tf_dir_2_str(parms->dir),
14148d3dff2SMichael Wildt 			    parms->type);
142a46bbb57SMichael Wildt 		return rc;
143a46bbb57SMichael Wildt 	}
144a46bbb57SMichael Wildt 
14548d3dff2SMichael Wildt 	*parms->id = id;
1468187694bSMichael Wildt 	return 0;
1478187694bSMichael Wildt }
1488187694bSMichael Wildt 
1498187694bSMichael Wildt int
tf_ident_free(struct tf * tfp __rte_unused,struct tf_ident_free_parms * parms)1508187694bSMichael Wildt tf_ident_free(struct tf *tfp __rte_unused,
151a46bbb57SMichael Wildt 	      struct tf_ident_free_parms *parms)
1528187694bSMichael Wildt {
153a46bbb57SMichael Wildt 	int rc;
154a46bbb57SMichael Wildt 	struct tf_rm_is_allocated_parms aparms = { 0 };
155a46bbb57SMichael Wildt 	struct tf_rm_free_parms fparms = { 0 };
156a46bbb57SMichael Wildt 	int allocated = 0;
1578ee821cfSJay Ding 	uint32_t base_id;
15838dc96f9SJay Ding 	struct ident_rm_db *ident_db;
15938dc96f9SJay Ding 	void *ident_db_ptr = NULL;
160a46bbb57SMichael Wildt 
161a46bbb57SMichael Wildt 	TF_CHECK_PARMS2(tfp, parms);
162a46bbb57SMichael Wildt 
16338dc96f9SJay Ding 	rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
16438dc96f9SJay Ding 	if (rc) {
16538dc96f9SJay Ding 		TFP_DRV_LOG(ERR,
16638dc96f9SJay Ding 			    "Failed to get ident_db from session, rc:%s\n",
16738dc96f9SJay Ding 			    strerror(-rc));
16838dc96f9SJay Ding 		return rc;
16938dc96f9SJay Ding 	}
17038dc96f9SJay Ding 	ident_db = (struct ident_rm_db *)ident_db_ptr;
17138dc96f9SJay Ding 
172a46bbb57SMichael Wildt 	/* Check if element is in use */
17338dc96f9SJay Ding 	aparms.rm_db = ident_db->ident_db[parms->dir];
17470529991SFarah Smith 	aparms.subtype = parms->type;
175a46bbb57SMichael Wildt 	aparms.index = parms->id;
1768ee821cfSJay Ding 	aparms.base_index = &base_id;
177a46bbb57SMichael Wildt 	aparms.allocated = &allocated;
178a46bbb57SMichael Wildt 	rc = tf_rm_is_allocated(&aparms);
179a46bbb57SMichael Wildt 	if (rc)
180a46bbb57SMichael Wildt 		return rc;
181a46bbb57SMichael Wildt 
182f000d3dcSJay Ding 	if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
183a46bbb57SMichael Wildt 		TFP_DRV_LOG(ERR,
184a46bbb57SMichael Wildt 			    "%s: Entry already free, type:%d, index:%d\n",
185a46bbb57SMichael Wildt 			    tf_dir_2_str(parms->dir),
18648d3dff2SMichael Wildt 			    parms->type,
187a46bbb57SMichael Wildt 			    parms->id);
188f000d3dcSJay Ding 		return -EINVAL;
189a46bbb57SMichael Wildt 	}
190a46bbb57SMichael Wildt 
191a46bbb57SMichael Wildt 	/* Free requested element */
19238dc96f9SJay Ding 	fparms.rm_db = ident_db->ident_db[parms->dir];
19370529991SFarah Smith 	fparms.subtype = parms->type;
194a46bbb57SMichael Wildt 	fparms.index = parms->id;
195a46bbb57SMichael Wildt 	rc = tf_rm_free(&fparms);
196a46bbb57SMichael Wildt 	if (rc) {
197a46bbb57SMichael Wildt 		TFP_DRV_LOG(ERR,
198a46bbb57SMichael Wildt 			    "%s: Free failed, type:%d, index:%d\n",
199a46bbb57SMichael Wildt 			    tf_dir_2_str(parms->dir),
20048d3dff2SMichael Wildt 			    parms->type,
201a46bbb57SMichael Wildt 			    parms->id);
202a46bbb57SMichael Wildt 		return rc;
203a46bbb57SMichael Wildt 	}
204a46bbb57SMichael Wildt 
2058187694bSMichael Wildt 	return 0;
2068187694bSMichael Wildt }
2078ee821cfSJay Ding 
2088ee821cfSJay Ding int
tf_ident_search(struct tf * tfp __rte_unused,struct tf_ident_search_parms * parms)2098ee821cfSJay Ding tf_ident_search(struct tf *tfp __rte_unused,
2108ee821cfSJay Ding 		struct tf_ident_search_parms *parms)
2118ee821cfSJay Ding {
2128ee821cfSJay Ding 	int rc;
2138ee821cfSJay Ding 	struct tf_rm_is_allocated_parms aparms = { 0 };
2148ee821cfSJay Ding 	int allocated = 0;
2158ee821cfSJay Ding 	uint32_t base_id;
21638dc96f9SJay Ding 	struct ident_rm_db *ident_db;
21738dc96f9SJay Ding 	void *ident_db_ptr = NULL;
2188ee821cfSJay Ding 
2198ee821cfSJay Ding 	TF_CHECK_PARMS2(tfp, parms);
2208ee821cfSJay Ding 
22138dc96f9SJay Ding 	rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
22238dc96f9SJay Ding 	if (rc) {
22338dc96f9SJay Ding 		TFP_DRV_LOG(ERR,
22438dc96f9SJay Ding 			    "Failed to get ident_db from session, rc:%s\n",
22538dc96f9SJay Ding 			    strerror(-rc));
22638dc96f9SJay Ding 		return rc;
22738dc96f9SJay Ding 	}
22838dc96f9SJay Ding 	ident_db = (struct ident_rm_db *)ident_db_ptr;
22938dc96f9SJay Ding 
2308ee821cfSJay Ding 	/* Check if element is in use */
23138dc96f9SJay Ding 	aparms.rm_db = ident_db->ident_db[parms->dir];
23270529991SFarah Smith 	aparms.subtype = parms->type;
2338ee821cfSJay Ding 	aparms.index = parms->search_id;
2348ee821cfSJay Ding 	aparms.base_index = &base_id;
2358ee821cfSJay Ding 	aparms.allocated = &allocated;
2368ee821cfSJay Ding 	rc = tf_rm_is_allocated(&aparms);
2378ee821cfSJay Ding 	if (rc)
2388ee821cfSJay Ding 		return rc;
2398ee821cfSJay Ding 
2408ee821cfSJay Ding 	if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
2418ee821cfSJay Ding 		TFP_DRV_LOG(ERR,
2428ee821cfSJay Ding 			    "%s: Entry not allocated, type:%d, index:%d\n",
2438ee821cfSJay Ding 			    tf_dir_2_str(parms->dir),
2448ee821cfSJay Ding 			    parms->type,
2458ee821cfSJay Ding 			    parms->search_id);
2468ee821cfSJay Ding 		return -EINVAL;
2478ee821cfSJay Ding 	}
2488ee821cfSJay Ding 	return 0;
2498ee821cfSJay Ding }
250873661aaSJay Ding 
251873661aaSJay Ding int
tf_ident_get_resc_info(struct tf * tfp,struct tf_identifier_resource_info * ident)252873661aaSJay Ding tf_ident_get_resc_info(struct tf *tfp,
253873661aaSJay Ding 		       struct tf_identifier_resource_info *ident)
254873661aaSJay Ding {
255873661aaSJay Ding 	int rc;
256873661aaSJay Ding 	int d;
257873661aaSJay Ding 	struct tf_resource_info *dinfo;
258873661aaSJay Ding 	struct tf_rm_get_alloc_info_parms ainfo;
259873661aaSJay Ding 	void *ident_db_ptr = NULL;
260873661aaSJay Ding 	struct ident_rm_db *ident_db;
261873661aaSJay Ding 
262873661aaSJay Ding 	TF_CHECK_PARMS2(tfp, ident);
263873661aaSJay Ding 
264873661aaSJay Ding 	rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
265b08e34cdSJay Ding 	if (rc == -ENOMEM)
266b08e34cdSJay Ding 		return 0; /* db doesn't exist */
267b08e34cdSJay Ding 	else if (rc)
268b08e34cdSJay Ding 		return rc; /* error getting db */
269b08e34cdSJay Ding 
270873661aaSJay Ding 	ident_db = (struct ident_rm_db *)ident_db_ptr;
271873661aaSJay Ding 
272873661aaSJay Ding 	/* check if reserved resource for WC is multiple of num_slices */
273873661aaSJay Ding 	for (d = 0; d < TF_DIR_MAX; d++) {
274873661aaSJay Ding 		ainfo.rm_db = ident_db->ident_db[d];
275b08e34cdSJay Ding 
276b08e34cdSJay Ding 		if (!ainfo.rm_db)
277b08e34cdSJay Ding 			continue;
278b08e34cdSJay Ding 
279873661aaSJay Ding 		dinfo = ident[d].info;
280873661aaSJay Ding 
281873661aaSJay Ding 		ainfo.info = (struct tf_rm_alloc_info *)dinfo;
282873661aaSJay Ding 		ainfo.subtype = 0;
283873661aaSJay Ding 		rc = tf_rm_get_all_info(&ainfo, TF_IDENT_TYPE_MAX);
284873661aaSJay Ding 		if (rc)
285873661aaSJay Ding 			return rc;
286873661aaSJay Ding 	}
287873661aaSJay Ding 
288873661aaSJay Ding 	return 0;
289873661aaSJay Ding }
290