net/bnxt: modify table processing
[dpdk.git] / drivers / net / bnxt / tf_ulp / ulp_gen_tbl.c
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_byte_size + 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_byte_size;
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  * offset [in] - The offset in bits where the data has to be set
172  * len [in] - The length of the data in bits to be set
173  * data [in] - pointer to the data to be used for setting the value.
174  * data_size [in] - length of the data pointer in bytes.
175  *
176  * returns 0 on success
177  */
178 int32_t
179 ulp_mapper_gen_tbl_entry_data_set(struct ulp_mapper_gen_tbl_entry *entry,
180                                   uint32_t offset, uint32_t len, uint8_t *data,
181                                   uint32_t data_size)
182 {
183         /* validate the null arguments */
184         if (!entry || !data) {
185                 BNXT_TF_DBG(ERR, "invalid argument\n");
186                 return -EINVAL;
187         }
188
189         /* check the size of the buffer for validation */
190         if ((offset + len) > ULP_BYTE_2_BITS(entry->byte_data_size) ||
191             data_size < ULP_BITS_2_BYTE(len)) {
192                 BNXT_TF_DBG(ERR, "invalid offset or length %x:%x:%x\n",
193                             offset, len, entry->byte_data_size);
194                 return -EINVAL;
195         }
196
197         /* adjust the data pointer */
198         data = data + (data_size - ULP_BITS_2_BYTE(len));
199
200         /* Push the data into the byte data array */
201         if (entry->byte_order == BNXT_ULP_BYTE_ORDER_LE) {
202                 if (ulp_bs_push_lsb(entry->byte_data, offset, len, data) !=
203                     len) {
204                         BNXT_TF_DBG(ERR, "write failed offset = %x, len =%x\n",
205                                     offset, len);
206                         return -EIO;
207                 }
208         } else {
209                 if (ulp_bs_push_msb(entry->byte_data, offset, len, data) !=
210                     len) {
211                         BNXT_TF_DBG(ERR, "write failed offset = %x, len =%x\n",
212                                     offset, len);
213                         return -EIO;
214                 }
215         }
216         return 0;
217 }
218
219 /*
220  * Get the data in the generic table entry, Data is in Big endian format
221  *
222  * entry [in] - generic table entry
223  * offset [in] - The offset in bits where the data has to get
224  * len [in] - The length of the data in bits to be get
225  * data [out] - pointer to the data to be used for setting the value.
226  * data_size [in] - The size of data in bytes
227  *
228  * returns 0 on success
229  */
230 int32_t
231 ulp_mapper_gen_tbl_entry_data_get(struct ulp_mapper_gen_tbl_entry *entry,
232                                   uint32_t offset, uint32_t len, uint8_t *data,
233                                   uint32_t data_size)
234 {
235         /* validate the null arguments */
236         if (!entry || !data) {
237                 BNXT_TF_DBG(ERR, "invalid argument\n");
238                 return -EINVAL;
239         }
240
241         /* check the size of the buffer for validation */
242         if ((offset + len) > ULP_BYTE_2_BITS(entry->byte_data_size) ||
243             len > ULP_BYTE_2_BITS(data_size)) {
244                 BNXT_TF_DBG(ERR, "invalid offset or length %x:%x:%x\n",
245                             offset, len, entry->byte_data_size);
246                 return -EINVAL;
247         }
248         if (entry->byte_order == BNXT_ULP_BYTE_ORDER_LE)
249                 ulp_bs_pull_lsb(entry->byte_data, data, data_size, offset, len);
250         else
251                 ulp_bs_pull_msb(entry->byte_data, data, offset, len);
252
253         return 0;
254 }
255
256 /*
257  * Free the generic table list entry
258  *
259  * ulp_ctx [in] - Pointer to the ulp context
260  * res [in] - Pointer to flow db resource entry
261  *
262  * returns 0 on success
263  */
264 int32_t
265 ulp_mapper_gen_tbl_res_free(struct bnxt_ulp_context *ulp_ctx,
266                             struct ulp_flow_db_res_params *res)
267 {
268         struct ulp_mapper_gen_tbl_entry entry;
269         int32_t tbl_idx;
270         uint32_t fid;
271
272         /* Extract the resource sub type and direction */
273         tbl_idx = ulp_mapper_gen_tbl_idx_calculate(res->resource_sub_type,
274                                                    res->direction);
275         if (tbl_idx < 0) {
276                 BNXT_TF_DBG(ERR, "invalid argument %x:%x\n",
277                             res->resource_sub_type, res->direction);
278                 return -EINVAL;
279         }
280
281         /* Get the generic table entry*/
282         if (ulp_mapper_gen_tbl_entry_get(ulp_ctx, tbl_idx, res->resource_hndl,
283                                          &entry)) {
284                 BNXT_TF_DBG(ERR, "Gen tbl entry get failed %x:%" PRIX64 "\n",
285                             tbl_idx, res->resource_hndl);
286                 return -EINVAL;
287         }
288
289         /* Decrement the reference count */
290         if (!ULP_GEN_TBL_REF_CNT(&entry)) {
291                 BNXT_TF_DBG(ERR, "generic table corrupt %x:%" PRIX64 "\n",
292                             tbl_idx, res->resource_hndl);
293                 return -EINVAL;
294         }
295         ULP_GEN_TBL_REF_CNT_DEC(&entry);
296
297         /* retain the details since there are other users */
298         if (ULP_GEN_TBL_REF_CNT(&entry))
299                 return 0;
300
301         /* Delete the generic table entry. First extract the fid */
302         if (ulp_mapper_gen_tbl_entry_data_get(&entry, ULP_GEN_TBL_FID_OFFSET,
303                                               ULP_GEN_TBL_FID_SIZE_BITS,
304                                               (uint8_t *)&fid,
305                                               sizeof(fid))) {
306                 BNXT_TF_DBG(ERR, "Unable to get fid %x:%" PRIX64 "\n",
307                             tbl_idx, res->resource_hndl);
308                 return -EINVAL;
309         }
310         fid = tfp_be_to_cpu_32(fid);
311
312         /* Destroy the flow associated with the shared flow id */
313         if (ulp_mapper_flow_destroy(ulp_ctx, BNXT_ULP_FDB_TYPE_REGULAR,
314                                     fid))
315                 BNXT_TF_DBG(ERR, "Error in deleting shared flow id %x\n", fid);
316
317         /* clear the byte data of the generic table entry */
318         memset(entry.byte_data, 0, entry.byte_data_size);
319
320         return 0;
321 }