net/bnxt: update table get to use new design
[dpdk.git] / drivers / net / bnxt / tf_core / tf_tcam.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019-2020 Broadcom
3  * All rights reserved.
4  */
5
6 #include <string.h>
7 #include <rte_common.h>
8
9 #include "tf_tcam.h"
10 #include "tf_common.h"
11 #include "tf_util.h"
12 #include "tf_rm.h"
13 #include "tf_device.h"
14 #include "tfp.h"
15 #include "tf_session.h"
16 #include "tf_msg.h"
17
18 struct tf;
19
20 /**
21  * TCAM DBs.
22  */
23 static void *tcam_db[TF_DIR_MAX];
24
25 /**
26  * TCAM Shadow DBs
27  */
28 /* static void *shadow_tcam_db[TF_DIR_MAX]; */
29
30 /**
31  * Init flag, set on bind and cleared on unbind
32  */
33 static uint8_t init;
34
35 /**
36  * Shadow init flag, set on bind and cleared on unbind
37  */
38 /* static uint8_t shadow_init; */
39
40 int
41 tf_tcam_bind(struct tf *tfp,
42              struct tf_tcam_cfg_parms *parms)
43 {
44         int rc;
45         int i;
46         struct tf_rm_create_db_parms db_cfg = { 0 };
47
48         TF_CHECK_PARMS2(tfp, parms);
49
50         if (init) {
51                 TFP_DRV_LOG(ERR,
52                             "TCAM DB already initialized\n");
53                 return -EINVAL;
54         }
55
56         db_cfg.type = TF_DEVICE_MODULE_TYPE_TCAM;
57         db_cfg.num_elements = parms->num_elements;
58         db_cfg.cfg = parms->cfg;
59
60         for (i = 0; i < TF_DIR_MAX; i++) {
61                 db_cfg.dir = i;
62                 db_cfg.alloc_cnt = parms->resources->tcam_cnt[i].cnt;
63                 db_cfg.rm_db = &tcam_db[i];
64                 rc = tf_rm_create_db(tfp, &db_cfg);
65                 if (rc) {
66                         TFP_DRV_LOG(ERR,
67                                     "%s: TCAM DB creation failed\n",
68                                     tf_dir_2_str(i));
69                         return rc;
70                 }
71         }
72
73         init = 1;
74
75         printf("TCAM - initialized\n");
76
77         return 0;
78 }
79
80 int
81 tf_tcam_unbind(struct tf *tfp)
82 {
83         int rc;
84         int i;
85         struct tf_rm_free_db_parms fparms = { 0 };
86
87         TF_CHECK_PARMS1(tfp);
88
89         /* Bail if nothing has been initialized */
90         if (!init) {
91                 TFP_DRV_LOG(INFO,
92                             "No TCAM DBs created\n");
93                 return 0;
94         }
95
96         for (i = 0; i < TF_DIR_MAX; i++) {
97                 fparms.dir = i;
98                 fparms.rm_db = tcam_db[i];
99                 rc = tf_rm_free_db(tfp, &fparms);
100                 if (rc)
101                         return rc;
102
103                 tcam_db[i] = NULL;
104         }
105
106         init = 0;
107
108         return 0;
109 }
110
111 int
112 tf_tcam_alloc(struct tf *tfp,
113               struct tf_tcam_alloc_parms *parms)
114 {
115         int rc;
116         struct tf_session *tfs;
117         struct tf_dev_info *dev;
118         struct tf_rm_allocate_parms aparms = { 0 };
119         uint16_t num_slice_per_row = 1;
120
121         TF_CHECK_PARMS2(tfp, parms);
122
123         if (!init) {
124                 TFP_DRV_LOG(ERR,
125                             "%s: No TCAM DBs created\n",
126                             tf_dir_2_str(parms->dir));
127                 return -EINVAL;
128         }
129
130         /* Retrieve the session information */
131         rc = tf_session_get_session(tfp, &tfs);
132         if (rc)
133                 return rc;
134
135         /* Retrieve the device information */
136         rc = tf_session_get_device(tfs, &dev);
137         if (rc)
138                 return rc;
139
140         if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
141                 rc = -EOPNOTSUPP;
142                 TFP_DRV_LOG(ERR,
143                             "%s: Operation not supported, rc:%s\n",
144                             tf_dir_2_str(parms->dir),
145                             strerror(-rc));
146                 return rc;
147         }
148
149         /* Need to retrieve row size etc */
150         rc = dev->ops->tf_dev_get_tcam_slice_info(tfp,
151                                                   parms->type,
152                                                   parms->key_size,
153                                                   &num_slice_per_row);
154         if (rc)
155                 return rc;
156
157         /* Allocate requested element */
158         aparms.rm_db = tcam_db[parms->dir];
159         aparms.db_index = parms->type;
160         aparms.priority = parms->priority;
161         aparms.index = (uint32_t *)&parms->idx;
162         rc = tf_rm_allocate(&aparms);
163         if (rc) {
164                 TFP_DRV_LOG(ERR,
165                             "%s: Failed tcam, type:%d\n",
166                             tf_dir_2_str(parms->dir),
167                             parms->type);
168                 return rc;
169         }
170
171         parms->idx *= num_slice_per_row;
172
173         return 0;
174 }
175
176 int
177 tf_tcam_free(struct tf *tfp,
178              struct tf_tcam_free_parms *parms)
179 {
180         int rc;
181         struct tf_session *tfs;
182         struct tf_dev_info *dev;
183         struct tf_rm_is_allocated_parms aparms = { 0 };
184         struct tf_rm_free_parms fparms = { 0 };
185         struct tf_rm_get_hcapi_parms hparms = { 0 };
186         uint16_t num_slice_per_row = 1;
187         int allocated = 0;
188
189         TF_CHECK_PARMS2(tfp, parms);
190
191         if (!init) {
192                 TFP_DRV_LOG(ERR,
193                             "%s: No TCAM DBs created\n",
194                             tf_dir_2_str(parms->dir));
195                 return -EINVAL;
196         }
197
198         /* Retrieve the session information */
199         rc = tf_session_get_session(tfp, &tfs);
200         if (rc)
201                 return rc;
202
203         /* Retrieve the device information */
204         rc = tf_session_get_device(tfs, &dev);
205         if (rc)
206                 return rc;
207
208         if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
209                 rc = -EOPNOTSUPP;
210                 TFP_DRV_LOG(ERR,
211                             "%s: Operation not supported, rc:%s\n",
212                             tf_dir_2_str(parms->dir),
213                             strerror(-rc));
214                 return rc;
215         }
216
217         /* Need to retrieve row size etc */
218         rc = dev->ops->tf_dev_get_tcam_slice_info(tfp,
219                                                   parms->type,
220                                                   0,
221                                                   &num_slice_per_row);
222         if (rc)
223                 return rc;
224
225         /* Check if element is in use */
226         aparms.rm_db = tcam_db[parms->dir];
227         aparms.db_index = parms->type;
228         aparms.index = parms->idx / num_slice_per_row;
229         aparms.allocated = &allocated;
230         rc = tf_rm_is_allocated(&aparms);
231         if (rc)
232                 return rc;
233
234         if (!allocated) {
235                 TFP_DRV_LOG(ERR,
236                             "%s: Entry already free, type:%d, index:%d\n",
237                             tf_dir_2_str(parms->dir),
238                             parms->type,
239                             parms->idx);
240                 return rc;
241         }
242
243         /* Free requested element */
244         fparms.rm_db = tcam_db[parms->dir];
245         fparms.db_index = parms->type;
246         fparms.index = parms->idx / num_slice_per_row;
247         rc = tf_rm_free(&fparms);
248         if (rc) {
249                 TFP_DRV_LOG(ERR,
250                             "%s: Free failed, type:%d, index:%d\n",
251                             tf_dir_2_str(parms->dir),
252                             parms->type,
253                             parms->idx);
254                 return rc;
255         }
256
257         /* Convert TF type to HCAPI RM type */
258         hparms.rm_db = tcam_db[parms->dir];
259         hparms.db_index = parms->type;
260         hparms.hcapi_type = &parms->hcapi_type;
261
262         rc = tf_rm_get_hcapi_type(&hparms);
263         if (rc)
264                 return rc;
265
266         rc = tf_msg_tcam_entry_free(tfp, parms);
267         if (rc) {
268                 /* Log error */
269                 TFP_DRV_LOG(ERR, "%s: %s: Entry %d free failed with err %s",
270                             tf_dir_2_str(parms->dir),
271                             tf_tcam_tbl_2_str(parms->type),
272                             parms->idx,
273                             strerror(-rc));
274         }
275
276         return 0;
277 }
278
279 int
280 tf_tcam_alloc_search(struct tf *tfp __rte_unused,
281                      struct tf_tcam_alloc_search_parms *parms __rte_unused)
282 {
283         return 0;
284 }
285
286 int
287 tf_tcam_set(struct tf *tfp __rte_unused,
288             struct tf_tcam_set_parms *parms __rte_unused)
289 {
290         int rc;
291         struct tf_session *tfs;
292         struct tf_dev_info *dev;
293         struct tf_rm_is_allocated_parms aparms = { 0 };
294         struct tf_rm_get_hcapi_parms hparms = { 0 };
295         uint16_t num_slice_per_row = 1;
296         int allocated = 0;
297
298         TF_CHECK_PARMS2(tfp, parms);
299
300         if (!init) {
301                 TFP_DRV_LOG(ERR,
302                             "%s: No TCAM DBs created\n",
303                             tf_dir_2_str(parms->dir));
304                 return -EINVAL;
305         }
306
307         /* Retrieve the session information */
308         rc = tf_session_get_session(tfp, &tfs);
309         if (rc)
310                 return rc;
311
312         /* Retrieve the device information */
313         rc = tf_session_get_device(tfs, &dev);
314         if (rc)
315                 return rc;
316
317         if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
318                 rc = -EOPNOTSUPP;
319                 TFP_DRV_LOG(ERR,
320                             "%s: Operation not supported, rc:%s\n",
321                             tf_dir_2_str(parms->dir),
322                             strerror(-rc));
323                 return rc;
324         }
325
326         /* Need to retrieve row size etc */
327         rc = dev->ops->tf_dev_get_tcam_slice_info(tfp,
328                                                   parms->type,
329                                                   parms->key_size,
330                                                   &num_slice_per_row);
331         if (rc)
332                 return rc;
333
334         /* Check if element is in use */
335         aparms.rm_db = tcam_db[parms->dir];
336         aparms.db_index = parms->type;
337         aparms.index = parms->idx / num_slice_per_row;
338         aparms.allocated = &allocated;
339         rc = tf_rm_is_allocated(&aparms);
340         if (rc)
341                 return rc;
342
343         if (!allocated) {
344                 TFP_DRV_LOG(ERR,
345                             "%s: Entry is not allocated, type:%d, index:%d\n",
346                             tf_dir_2_str(parms->dir),
347                             parms->type,
348                             parms->idx);
349                 return rc;
350         }
351
352         /* Convert TF type to HCAPI RM type */
353         hparms.rm_db = tcam_db[parms->dir];
354         hparms.db_index = parms->type;
355         hparms.hcapi_type = &parms->hcapi_type;
356
357         rc = tf_rm_get_hcapi_type(&hparms);
358         if (rc)
359                 return rc;
360
361         rc = tf_msg_tcam_entry_set(tfp, parms);
362         if (rc) {
363                 /* Log error */
364                 TFP_DRV_LOG(ERR, "%s: %s: Entry %d free failed with err %s",
365                             tf_dir_2_str(parms->dir),
366                             tf_tcam_tbl_2_str(parms->type),
367                             parms->idx,
368                             strerror(-rc));
369         }
370
371         return 0;
372 }
373
374 int
375 tf_tcam_get(struct tf *tfp __rte_unused,
376             struct tf_tcam_get_parms *parms __rte_unused)
377 {
378         return 0;
379 }