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