xref: /dpdk/drivers/net/bnxt/tf_ulp/ulp_alloc_tbl.c (revision d4b36fc5f0dc59b256441c82e5a9395054026496)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2014-2023 Broadcom
3  * All rights reserved.
4  */
5 
6 #include <rte_log.h>
7 #include <rte_malloc.h>
8 #include "tf_core.h"
9 #include "ulp_mapper.h"
10 #include "ulp_alloc_tbl.h"
11 #include "bnxt_ulp_utils.h"
12 
13 #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG
14 #include "ulp_template_debug_proto.h"
15 #include "ulp_tf_debug.h"
16 #endif
17 
18 /* Retrieve the allocator table  initialization parameters for the tbl_idx */
19 static const struct bnxt_ulp_allocator_tbl_params*
20 ulp_allocator_tbl_params_get(struct bnxt_ulp_context *ulp_ctx, uint32_t tbl_idx)
21 {
22 	struct bnxt_ulp_device_params *dparms;
23 	const struct bnxt_ulp_allocator_tbl_params *alloc_tbl;
24 	uint32_t dev_id;
25 
26 	if (tbl_idx >= BNXT_ULP_ALLOCATOR_TBL_MAX_SZ) {
27 		BNXT_DRV_DBG(ERR, "Allocator table out of bounds %d\n",
28 			     tbl_idx);
29 		return NULL;
30 	}
31 
32 	if (bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id))
33 		return NULL;
34 
35 	dparms = bnxt_ulp_device_params_get(dev_id);
36 	if (!dparms) {
37 		BNXT_DRV_DBG(ERR, "Failed to get device parms\n");
38 		return NULL;
39 	}
40 
41 	alloc_tbl = &dparms->allocator_tbl_params[tbl_idx];
42 	return alloc_tbl;
43 }
44 
45 /*
46  * Initialize the allocator table list
47  *
48  * mapper_data [in] Pointer to the mapper data and the allocator table is
49  * part of it
50  *
51  * returns 0 on success
52  */
53 int32_t
54 ulp_allocator_tbl_list_init(struct bnxt_ulp_context *ulp_ctx,
55 			    struct bnxt_ulp_mapper_data *mapper_data)
56 {
57 	const struct bnxt_ulp_allocator_tbl_params *tbl;
58 	struct ulp_allocator_tbl_entry *entry;
59 	uint32_t idx, pool_size;
60 
61 	/* Allocate the generic tables. */
62 	for (idx = 0; idx < BNXT_ULP_ALLOCATOR_TBL_MAX_SZ; idx++) {
63 		tbl = ulp_allocator_tbl_params_get(ulp_ctx, idx);
64 		if (!tbl) {
65 			BNXT_DRV_DBG(ERR, "Failed to get alloc table parm %d\n",
66 				     idx);
67 			return -EINVAL;
68 		}
69 		entry = &mapper_data->alloc_tbl[idx];
70 
71 		/* Allocate memory for result data and key data */
72 		if (tbl->num_entries != 0) {
73 			/* assign the name */
74 			entry->alloc_tbl_name = tbl->name;
75 			entry->num_entries = tbl->num_entries;
76 			pool_size = BITALLOC_SIZEOF(tbl->num_entries);
77 			/* allocate the big chunk of memory */
78 			entry->ulp_bitalloc = rte_zmalloc("ulp allocator",
79 							  pool_size, 0);
80 			if (!entry->ulp_bitalloc) {
81 				BNXT_DRV_DBG(ERR,
82 					     "%s:Fail to alloc bit alloc %d\n",
83 					     tbl->name, idx);
84 				return -ENOMEM;
85 			}
86 			if (ba_init(entry->ulp_bitalloc, entry->num_entries,
87 				    true)) {
88 				BNXT_DRV_DBG(ERR, "%s:Unable to alloc ba %d\n",
89 					     tbl->name, idx);
90 				return -ENOMEM;
91 			}
92 		} else {
93 			BNXT_DRV_DBG(DEBUG, "%s:Unused alloc tbl entry is %d\n",
94 				     tbl->name, idx);
95 			continue;
96 		}
97 	}
98 	return 0;
99 }
100 
101 /*
102  * Free the allocator table list
103  *
104  * mapper_data [in] Pointer to the mapper data and the generic table is
105  * part of it
106  *
107  * returns 0 on success
108  */
109 int32_t
110 ulp_allocator_tbl_list_deinit(struct bnxt_ulp_mapper_data *mapper_data)
111 {
112 	struct ulp_allocator_tbl_entry *entry;
113 	uint32_t idx;
114 
115 	/* iterate the generic table. */
116 	for (idx = 0; idx < BNXT_ULP_ALLOCATOR_TBL_MAX_SZ; idx++) {
117 		entry = &mapper_data->alloc_tbl[idx];
118 		if (entry->ulp_bitalloc) {
119 			rte_free(entry->ulp_bitalloc);
120 			entry->ulp_bitalloc = NULL;
121 		}
122 	}
123 	/* success */
124 	return 0;
125 }
126 
127 /*
128  * utility function to calculate the table idx
129  *
130  * res_sub_type [in] - Resource sub type
131  * dir [in] - Direction
132  *
133  * returns None
134  */
135 static int32_t
136 ulp_allocator_tbl_idx_calculate(uint32_t res_sub_type, uint32_t dir)
137 {
138 	int32_t tbl_idx;
139 
140 	/* Validate for direction */
141 	if (dir >= TF_DIR_MAX) {
142 		BNXT_DRV_DBG(ERR, "invalid argument %x\n", dir);
143 		return -EINVAL;
144 	}
145 	tbl_idx = (res_sub_type << 1) | (dir & 0x1);
146 	if (tbl_idx >= BNXT_ULP_ALLOCATOR_TBL_MAX_SZ) {
147 		BNXT_DRV_DBG(ERR, "invalid table index %x\n", tbl_idx);
148 		return -EINVAL;
149 	}
150 	return tbl_idx;
151 }
152 
153 /*
154  * allocate a index from allocator
155  *
156  * mapper_data [in] Pointer to the mapper data and the allocator table is
157  * part of it
158  *
159  * returns index on success or negative number on failure
160  */
161 int32_t
162 ulp_allocator_tbl_list_alloc(struct bnxt_ulp_mapper_data *mapper_data,
163 			     uint32_t res_sub_type, uint32_t dir,
164 			     int32_t *alloc_id)
165 {
166 	struct ulp_allocator_tbl_entry *entry;
167 	int32_t idx;
168 
169 	idx = ulp_allocator_tbl_idx_calculate(res_sub_type, dir);
170 	if (idx < 0)
171 		return -EINVAL;
172 
173 	entry = &mapper_data->alloc_tbl[idx];
174 	if (!entry->ulp_bitalloc || !entry->num_entries) {
175 		BNXT_DRV_DBG(ERR, "invalid table index %x\n", idx);
176 		return -EINVAL;
177 	}
178 	*alloc_id = ba_alloc(entry->ulp_bitalloc);
179 
180 	if (*alloc_id < 0) {
181 		BNXT_DRV_DBG(ERR, "unable to alloc index %x\n", idx);
182 		return -ENOMEM;
183 	}
184 	/* Not using zero index */
185 	*alloc_id += 1;
186 	return 0;
187 }
188 
189 /*
190  * free a index in allocator
191  *
192  * mapper_data [in] Pointer to the mapper data and the allocator table is
193  * part of it
194  *
195  * returns error
196  */
197 int32_t
198 ulp_allocator_tbl_list_free(struct bnxt_ulp_mapper_data *mapper_data,
199 			    uint32_t res_sub_type, uint32_t dir,
200 			    int32_t index)
201 {
202 	struct ulp_allocator_tbl_entry *entry;
203 	int32_t rc;
204 	int32_t idx;
205 
206 	idx = ulp_allocator_tbl_idx_calculate(res_sub_type, dir);
207 	if (idx < 0)
208 		return -EINVAL;
209 
210 	entry = &mapper_data->alloc_tbl[idx];
211 	if (!entry->ulp_bitalloc || !entry->num_entries) {
212 		BNXT_DRV_DBG(ERR, "invalid table index %x\n", idx);
213 		return -EINVAL;
214 	}
215 	/* not using zero index */
216 	index -= 1;
217 	if (index < 0 || index > entry->num_entries) {
218 		BNXT_DRV_DBG(ERR, "invalid alloc index %x\n", index);
219 		return -EINVAL;
220 	}
221 	rc = ba_free(entry->ulp_bitalloc, index);
222 	if (rc < 0) {
223 		BNXT_DRV_DBG(ERR, "%s:unable to free index %x\n",
224 			     entry->alloc_tbl_name, index);
225 		return -EINVAL;
226 	}
227 	return 0;
228 }
229