xref: /dpdk/drivers/net/bnxt/tf_ulp/ulp_gen_tbl.c (revision a2417601)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2014-2021 Broadcom
3  * All rights reserved.
4  */
5 
6 #include <rte_log.h>
7 #include <rte_malloc.h>
8 #include "tf_core.h"
9 #include "tfp.h"
10 #include "ulp_mapper.h"
11 #include "ulp_flow_db.h"
12 
13 /* Retrieve the generic table  initialization parameters for the tbl_idx */
14 static struct bnxt_ulp_generic_tbl_params*
15 ulp_mapper_gen_tbl_params_get(uint32_t tbl_idx)
16 {
17 	if (tbl_idx >= BNXT_ULP_GEN_TBL_MAX_SZ)
18 		return NULL;
19 
20 	return &ulp_generic_tbl_params[tbl_idx];
21 }
22 
23 /*
24  * Initialize the generic table list
25  *
26  * mapper_data [in] Pointer to the mapper data and the generic table is
27  * part of it
28  *
29  * returns 0 on success
30  */
31 int32_t
32 ulp_mapper_generic_tbl_list_init(struct bnxt_ulp_mapper_data *mapper_data)
33 {
34 	struct bnxt_ulp_generic_tbl_params *tbl;
35 	struct ulp_mapper_gen_tbl_list *entry;
36 	uint32_t idx, size;
37 
38 	/* Allocate the generic tables. */
39 	for (idx = 0; idx < BNXT_ULP_GEN_TBL_MAX_SZ; idx++) {
40 		tbl = ulp_mapper_gen_tbl_params_get(idx);
41 		if (!tbl) {
42 			BNXT_TF_DBG(ERR, "Failed to get gen table parms %d\n",
43 				    idx);
44 			return -EINVAL;
45 		}
46 		entry = &mapper_data->gen_tbl_list[idx];
47 		if (tbl->result_num_entries != 0) {
48 			/* add 4 bytes for reference count */
49 			entry->mem_data_size = (tbl->result_num_entries + 1) *
50 				(tbl->result_num_bytes + sizeof(uint32_t));
51 
52 			/* allocate the big chunk of memory */
53 			entry->mem_data = rte_zmalloc("ulp mapper gen tbl",
54 						      entry->mem_data_size, 0);
55 			if (!entry->mem_data) {
56 				BNXT_TF_DBG(ERR,
57 					    "Failed to allocate gen table %d\n",
58 					    idx);
59 				return -ENOMEM;
60 			}
61 			/* Populate the generic table container */
62 			entry->container.num_elem = tbl->result_num_entries;
63 			entry->container.byte_data_size = tbl->result_num_bytes;
64 			entry->container.ref_count =
65 				(uint32_t *)entry->mem_data;
66 			size = sizeof(uint32_t) * (tbl->result_num_entries + 1);
67 			entry->container.byte_data = &entry->mem_data[size];
68 			entry->container.byte_order = tbl->result_byte_order;
69 		}
70 	}
71 	/* success */
72 	return 0;
73 }
74 
75 /*
76  * Free the generic table list
77  *
78  * mapper_data [in] Pointer to the mapper data and the generic table is
79  * part of it
80  *
81  * returns 0 on success
82  */
83 int32_t
84 ulp_mapper_generic_tbl_list_deinit(struct bnxt_ulp_mapper_data *mapper_data)
85 {
86 	struct ulp_mapper_gen_tbl_list *tbl_list;
87 	uint32_t idx;
88 
89 	/* iterate the generic table. */
90 	for (idx = 0; idx < BNXT_ULP_GEN_TBL_MAX_SZ; idx++) {
91 		tbl_list = &mapper_data->gen_tbl_list[idx];
92 		if (tbl_list->mem_data) {
93 			rte_free(tbl_list->mem_data);
94 			tbl_list->mem_data = NULL;
95 		}
96 	}
97 	/* success */
98 	return 0;
99 }
100 
101 /*
102  * Get the generic table list entry
103  *
104  * ulp_ctxt [in] - Ptr to ulp_context
105  * tbl_idx [in] -  Table index to the generic table list
106  * key [in] - Key index to the table
107  * entry [out] - output will include the entry if found
108  *
109  * returns 0 on success.
110  */
111 int32_t
112 ulp_mapper_gen_tbl_entry_get(struct bnxt_ulp_context *ulp,
113 			     uint32_t tbl_idx,
114 			     uint32_t key,
115 			     struct ulp_mapper_gen_tbl_entry *entry)
116 {
117 	struct bnxt_ulp_mapper_data *mapper_data;
118 	struct ulp_mapper_gen_tbl_list *tbl_list;
119 
120 	mapper_data = bnxt_ulp_cntxt_ptr2_mapper_data_get(ulp);
121 	if (!mapper_data || tbl_idx >= BNXT_ULP_GEN_TBL_MAX_SZ ||
122 	    !entry) {
123 		BNXT_TF_DBG(ERR, "invalid arguments %x:%x\n", tbl_idx, key);
124 		return -EINVAL;
125 	}
126 	/* populate the output and return the values */
127 	tbl_list = &mapper_data->gen_tbl_list[tbl_idx];
128 	if (key > tbl_list->container.num_elem) {
129 		BNXT_TF_DBG(ERR, "invalid key %x:%x\n", key,
130 			    tbl_list->container.num_elem);
131 		return -EINVAL;
132 	}
133 	entry->ref_count = &tbl_list->container.ref_count[key];
134 	entry->byte_data_size = tbl_list->container.byte_data_size;
135 	entry->byte_data = &tbl_list->container.byte_data[key *
136 		entry->byte_data_size];
137 	entry->byte_order = tbl_list->container.byte_order;
138 	return 0;
139 }
140 
141 /*
142  * utility function to calculate the table idx
143  *
144  * res_sub_type [in] - Resource sub type
145  * dir [in] - Direction
146  *
147  * returns None
148  */
149 int32_t
150 ulp_mapper_gen_tbl_idx_calculate(uint32_t res_sub_type, uint32_t dir)
151 {
152 	int32_t tbl_idx;
153 
154 	/* Validate for direction */
155 	if (dir >= TF_DIR_MAX) {
156 		BNXT_TF_DBG(ERR, "invalid argument %x\n", dir);
157 		return -EINVAL;
158 	}
159 	tbl_idx = (res_sub_type << 1) | (dir & 0x1);
160 	if (tbl_idx >= BNXT_ULP_GEN_TBL_MAX_SZ) {
161 		BNXT_TF_DBG(ERR, "invalid table index %x\n", tbl_idx);
162 		return -EINVAL;
163 	}
164 	return tbl_idx;
165 }
166 
167 /*
168  * Set the data in the generic table entry, Data is in Big endian format
169  *
170  * entry [in] - generic table entry
171  * len [in] - The length of the data in bits to be set
172  * data [in] - pointer to the data to be used for setting the value.
173  * data_size [in] - length of the data pointer in bytes.
174  *
175  * returns 0 on success
176  */
177 int32_t
178 ulp_mapper_gen_tbl_entry_data_set(struct ulp_mapper_gen_tbl_entry *entry,
179 				  uint32_t len, uint8_t *data,
180 				  uint32_t data_size)
181 {
182 	/* validate the null arguments */
183 	if (!entry || !data) {
184 		BNXT_TF_DBG(ERR, "invalid argument\n");
185 		return -EINVAL;
186 	}
187 
188 	/* check the size of the buffer for validation */
189 	if (len > ULP_BYTE_2_BITS(entry->byte_data_size) ||
190 	    data_size < ULP_BITS_2_BYTE(len)) {
191 		BNXT_TF_DBG(ERR, "invalid offset or length %x:%x\n",
192 			    len, entry->byte_data_size);
193 		return -EINVAL;
194 	}
195 	memcpy(entry->byte_data, data, ULP_BITS_2_BYTE(len));
196 	return 0;
197 }
198 
199 /*
200  * Get the data in the generic table entry, Data is in Big endian format
201  *
202  * entry [in] - generic table entry
203  * offset [in] - The offset in bits where the data has to get
204  * len [in] - The length of the data in bits to be get
205  * data [out] - pointer to the data to be used for setting the value.
206  * data_size [in] - The size of data in bytes
207  *
208  * returns 0 on success
209  */
210 int32_t
211 ulp_mapper_gen_tbl_entry_data_get(struct ulp_mapper_gen_tbl_entry *entry,
212 				  uint32_t offset, uint32_t len, uint8_t *data,
213 				  uint32_t data_size)
214 {
215 	/* validate the null arguments */
216 	if (!entry || !data) {
217 		BNXT_TF_DBG(ERR, "invalid argument\n");
218 		return -EINVAL;
219 	}
220 
221 	/* check the size of the buffer for validation */
222 	if ((offset + len) > ULP_BYTE_2_BITS(entry->byte_data_size) ||
223 	    len > ULP_BYTE_2_BITS(data_size)) {
224 		BNXT_TF_DBG(ERR, "invalid offset or length %x:%x:%x\n",
225 			    offset, len, entry->byte_data_size);
226 		return -EINVAL;
227 	}
228 	if (entry->byte_order == BNXT_ULP_BYTE_ORDER_LE)
229 		ulp_bs_pull_lsb(entry->byte_data, data, data_size, offset, len);
230 	else
231 		ulp_bs_pull_msb(entry->byte_data, data, offset, len);
232 
233 	return 0;
234 }
235 
236 /*
237  * Free the generic table list entry
238  *
239  * ulp_ctx [in] - Pointer to the ulp context
240  * res [in] - Pointer to flow db resource entry
241  *
242  * returns 0 on success
243  */
244 int32_t
245 ulp_mapper_gen_tbl_res_free(struct bnxt_ulp_context *ulp_ctx,
246 			    struct ulp_flow_db_res_params *res)
247 {
248 	struct ulp_mapper_gen_tbl_entry entry;
249 	int32_t tbl_idx;
250 	uint32_t fid = 0;
251 
252 	/* Extract the resource sub type and direction */
253 	tbl_idx = ulp_mapper_gen_tbl_idx_calculate(res->resource_sub_type,
254 						   res->direction);
255 	if (tbl_idx < 0) {
256 		BNXT_TF_DBG(ERR, "invalid argument %x:%x\n",
257 			    res->resource_sub_type, res->direction);
258 		return -EINVAL;
259 	}
260 
261 	/* Get the generic table entry*/
262 	if (ulp_mapper_gen_tbl_entry_get(ulp_ctx, tbl_idx, res->resource_hndl,
263 					 &entry)) {
264 		BNXT_TF_DBG(ERR, "Gen tbl entry get failed %x:%" PRIX64 "\n",
265 			    tbl_idx, res->resource_hndl);
266 		return -EINVAL;
267 	}
268 
269 	/* Decrement the reference count */
270 	if (!ULP_GEN_TBL_REF_CNT(&entry)) {
271 		BNXT_TF_DBG(ERR, "generic table corrupt %x:%" PRIX64 "\n",
272 			    tbl_idx, res->resource_hndl);
273 		return -EINVAL;
274 	}
275 	ULP_GEN_TBL_REF_CNT_DEC(&entry);
276 
277 	/* retain the details since there are other users */
278 	if (ULP_GEN_TBL_REF_CNT(&entry))
279 		return 0;
280 
281 	/* Delete the generic table entry. First extract the fid */
282 	if (ulp_mapper_gen_tbl_entry_data_get(&entry, ULP_GEN_TBL_FID_OFFSET,
283 					      ULP_GEN_TBL_FID_SIZE_BITS,
284 					      (uint8_t *)&fid,
285 					      sizeof(fid))) {
286 		BNXT_TF_DBG(ERR, "Unable to get fid %x:%" PRIX64 "\n",
287 			    tbl_idx, res->resource_hndl);
288 		return -EINVAL;
289 	}
290 	fid = tfp_be_to_cpu_32(fid);
291 
292 	/* Destroy the flow associated with the shared flow id */
293 	if (ulp_mapper_flow_destroy(ulp_ctx, BNXT_ULP_FDB_TYPE_RID,
294 				    fid))
295 		BNXT_TF_DBG(ERR, "Error in deleting shared flow id %x\n", fid);
296 
297 	/* clear the byte data of the generic table entry */
298 	memset(entry.byte_data, 0, entry.byte_data_size);
299 
300 	return 0;
301 }
302