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