net/bnxt: update RM to support HCAPI only
[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_tcam_resources *tcam_cnt;
47         struct tf_rm_create_db_parms db_cfg = { 0 };
48
49         TF_CHECK_PARMS2(tfp, parms);
50
51         if (init) {
52                 TFP_DRV_LOG(ERR,
53                             "TCAM DB already initialized\n");
54                 return -EINVAL;
55         }
56
57         tcam_cnt = parms->resources->tcam_cnt;
58         if ((tcam_cnt[TF_DIR_RX].cnt[TF_TCAM_TBL_TYPE_WC_TCAM] % 2) ||
59             (tcam_cnt[TF_DIR_TX].cnt[TF_TCAM_TBL_TYPE_WC_TCAM] % 2)) {
60                 TFP_DRV_LOG(ERR,
61                             "Number of WC TCAM entries cannot be odd num\n");
62                 return -EINVAL;
63         }
64
65         db_cfg.type = TF_DEVICE_MODULE_TYPE_TCAM;
66         db_cfg.num_elements = parms->num_elements;
67         db_cfg.cfg = parms->cfg;
68
69         for (i = 0; i < TF_DIR_MAX; i++) {
70                 db_cfg.dir = i;
71                 db_cfg.alloc_cnt = parms->resources->tcam_cnt[i].cnt;
72                 db_cfg.rm_db = &tcam_db[i];
73                 rc = tf_rm_create_db(tfp, &db_cfg);
74                 if (rc) {
75                         TFP_DRV_LOG(ERR,
76                                     "%s: TCAM DB creation failed\n",
77                                     tf_dir_2_str(i));
78                         return rc;
79                 }
80         }
81
82         init = 1;
83
84         printf("TCAM - initialized\n");
85
86         return 0;
87 }
88
89 int
90 tf_tcam_unbind(struct tf *tfp)
91 {
92         int rc;
93         int i;
94         struct tf_rm_free_db_parms fparms = { 0 };
95
96         TF_CHECK_PARMS1(tfp);
97
98         /* Bail if nothing has been initialized */
99         if (!init) {
100                 TFP_DRV_LOG(INFO,
101                             "No TCAM DBs created\n");
102                 return 0;
103         }
104
105         for (i = 0; i < TF_DIR_MAX; i++) {
106                 fparms.dir = i;
107                 fparms.rm_db = tcam_db[i];
108                 rc = tf_rm_free_db(tfp, &fparms);
109                 if (rc)
110                         return rc;
111
112                 tcam_db[i] = NULL;
113         }
114
115         init = 0;
116
117         return 0;
118 }
119
120 int
121 tf_tcam_alloc(struct tf *tfp,
122               struct tf_tcam_alloc_parms *parms)
123 {
124         int rc;
125         struct tf_session *tfs;
126         struct tf_dev_info *dev;
127         struct tf_rm_allocate_parms aparms = { 0 };
128         uint16_t num_slice_per_row = 1;
129
130         TF_CHECK_PARMS2(tfp, parms);
131
132         if (!init) {
133                 TFP_DRV_LOG(ERR,
134                             "%s: No TCAM DBs created\n",
135                             tf_dir_2_str(parms->dir));
136                 return -EINVAL;
137         }
138
139         /* Retrieve the session information */
140         rc = tf_session_get_session(tfp, &tfs);
141         if (rc)
142                 return rc;
143
144         /* Retrieve the device information */
145         rc = tf_session_get_device(tfs, &dev);
146         if (rc)
147                 return rc;
148
149         if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
150                 rc = -EOPNOTSUPP;
151                 TFP_DRV_LOG(ERR,
152                             "%s: Operation not supported, rc:%s\n",
153                             tf_dir_2_str(parms->dir),
154                             strerror(-rc));
155                 return rc;
156         }
157
158         /* Need to retrieve row size etc */
159         rc = dev->ops->tf_dev_get_tcam_slice_info(tfp,
160                                                   parms->type,
161                                                   parms->key_size,
162                                                   &num_slice_per_row);
163         if (rc)
164                 return rc;
165
166         /* Allocate requested element */
167         aparms.rm_db = tcam_db[parms->dir];
168         aparms.db_index = parms->type;
169         aparms.priority = parms->priority;
170         aparms.index = (uint32_t *)&parms->idx;
171         rc = tf_rm_allocate(&aparms);
172         if (rc) {
173                 TFP_DRV_LOG(ERR,
174                             "%s: Failed tcam, type:%d\n",
175                             tf_dir_2_str(parms->dir),
176                             parms->type);
177                 return rc;
178         }
179
180         if (parms->type == TF_TCAM_TBL_TYPE_WC_TCAM &&
181             (parms->idx % 2) != 0) {
182                 rc = tf_rm_allocate(&aparms);
183                 if (rc) {
184                         TFP_DRV_LOG(ERR,
185                                     "%s: Failed tcam, type:%d\n",
186                                     tf_dir_2_str(parms->dir),
187                                     parms->type);
188                         return rc;
189                 }
190         }
191
192         parms->idx *= num_slice_per_row;
193
194         return 0;
195 }
196
197 int
198 tf_tcam_free(struct tf *tfp,
199              struct tf_tcam_free_parms *parms)
200 {
201         int rc;
202         struct tf_session *tfs;
203         struct tf_dev_info *dev;
204         struct tf_rm_is_allocated_parms aparms = { 0 };
205         struct tf_rm_free_parms fparms = { 0 };
206         struct tf_rm_get_hcapi_parms hparms = { 0 };
207         uint16_t num_slice_per_row = 1;
208         int allocated = 0;
209
210         TF_CHECK_PARMS2(tfp, parms);
211
212         if (!init) {
213                 TFP_DRV_LOG(ERR,
214                             "%s: No TCAM DBs created\n",
215                             tf_dir_2_str(parms->dir));
216                 return -EINVAL;
217         }
218
219         /* Retrieve the session information */
220         rc = tf_session_get_session(tfp, &tfs);
221         if (rc)
222                 return rc;
223
224         /* Retrieve the device information */
225         rc = tf_session_get_device(tfs, &dev);
226         if (rc)
227                 return rc;
228
229         if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
230                 rc = -EOPNOTSUPP;
231                 TFP_DRV_LOG(ERR,
232                             "%s: Operation not supported, rc:%s\n",
233                             tf_dir_2_str(parms->dir),
234                             strerror(-rc));
235                 return rc;
236         }
237
238         /* Need to retrieve row size etc */
239         rc = dev->ops->tf_dev_get_tcam_slice_info(tfp,
240                                                   parms->type,
241                                                   0,
242                                                   &num_slice_per_row);
243         if (rc)
244                 return rc;
245
246         /* Check if element is in use */
247         aparms.rm_db = tcam_db[parms->dir];
248         aparms.db_index = parms->type;
249         aparms.index = parms->idx / num_slice_per_row;
250         aparms.allocated = &allocated;
251         rc = tf_rm_is_allocated(&aparms);
252         if (rc)
253                 return rc;
254
255         if (!allocated) {
256                 TFP_DRV_LOG(ERR,
257                             "%s: Entry already free, type:%d, index:%d\n",
258                             tf_dir_2_str(parms->dir),
259                             parms->type,
260                             parms->idx);
261                 return rc;
262         }
263
264         /* Free requested element */
265         fparms.rm_db = tcam_db[parms->dir];
266         fparms.db_index = parms->type;
267         fparms.index = parms->idx / num_slice_per_row;
268         rc = tf_rm_free(&fparms);
269         if (rc) {
270                 TFP_DRV_LOG(ERR,
271                             "%s: Free failed, type:%d, index:%d\n",
272                             tf_dir_2_str(parms->dir),
273                             parms->type,
274                             parms->idx);
275                 return rc;
276         }
277
278         /* Convert TF type to HCAPI RM type */
279         hparms.rm_db = tcam_db[parms->dir];
280         hparms.db_index = parms->type;
281         hparms.hcapi_type = &parms->hcapi_type;
282
283         rc = tf_rm_get_hcapi_type(&hparms);
284         if (rc)
285                 return rc;
286
287         rc = tf_msg_tcam_entry_free(tfp, parms);
288         if (rc) {
289                 /* Log error */
290                 TFP_DRV_LOG(ERR, "%s: %s: Entry %d free failed with err %s",
291                             tf_dir_2_str(parms->dir),
292                             tf_tcam_tbl_2_str(parms->type),
293                             parms->idx,
294                             strerror(-rc));
295         }
296
297         return 0;
298 }
299
300 int
301 tf_tcam_alloc_search(struct tf *tfp __rte_unused,
302                      struct tf_tcam_alloc_search_parms *parms __rte_unused)
303 {
304         return 0;
305 }
306
307 int
308 tf_tcam_set(struct tf *tfp __rte_unused,
309             struct tf_tcam_set_parms *parms __rte_unused)
310 {
311         int rc;
312         struct tf_session *tfs;
313         struct tf_dev_info *dev;
314         struct tf_rm_is_allocated_parms aparms = { 0 };
315         struct tf_rm_get_hcapi_parms hparms = { 0 };
316         uint16_t num_slice_per_row = 1;
317         int allocated = 0;
318
319         TF_CHECK_PARMS2(tfp, parms);
320
321         if (!init) {
322                 TFP_DRV_LOG(ERR,
323                             "%s: No TCAM DBs created\n",
324                             tf_dir_2_str(parms->dir));
325                 return -EINVAL;
326         }
327
328         /* Retrieve the session information */
329         rc = tf_session_get_session(tfp, &tfs);
330         if (rc)
331                 return rc;
332
333         /* Retrieve the device information */
334         rc = tf_session_get_device(tfs, &dev);
335         if (rc)
336                 return rc;
337
338         if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
339                 rc = -EOPNOTSUPP;
340                 TFP_DRV_LOG(ERR,
341                             "%s: Operation not supported, rc:%s\n",
342                             tf_dir_2_str(parms->dir),
343                             strerror(-rc));
344                 return rc;
345         }
346
347         /* Need to retrieve row size etc */
348         rc = dev->ops->tf_dev_get_tcam_slice_info(tfp,
349                                                   parms->type,
350                                                   parms->key_size,
351                                                   &num_slice_per_row);
352         if (rc)
353                 return rc;
354
355         /* Check if element is in use */
356         aparms.rm_db = tcam_db[parms->dir];
357         aparms.db_index = parms->type;
358         aparms.index = parms->idx / num_slice_per_row;
359         aparms.allocated = &allocated;
360         rc = tf_rm_is_allocated(&aparms);
361         if (rc)
362                 return rc;
363
364         if (!allocated) {
365                 TFP_DRV_LOG(ERR,
366                             "%s: Entry is not allocated, type:%d, index:%d\n",
367                             tf_dir_2_str(parms->dir),
368                             parms->type,
369                             parms->idx);
370                 return rc;
371         }
372
373         /* Convert TF type to HCAPI RM type */
374         hparms.rm_db = tcam_db[parms->dir];
375         hparms.db_index = parms->type;
376         hparms.hcapi_type = &parms->hcapi_type;
377
378         rc = tf_rm_get_hcapi_type(&hparms);
379         if (rc)
380                 return rc;
381
382         rc = tf_msg_tcam_entry_set(tfp, parms);
383         if (rc) {
384                 /* Log error */
385                 TFP_DRV_LOG(ERR, "%s: %s: Entry %d free failed with err %s",
386                             tf_dir_2_str(parms->dir),
387                             tf_tcam_tbl_2_str(parms->type),
388                             parms->idx,
389                             strerror(-rc));
390         }
391
392         return 0;
393 }
394
395 int
396 tf_tcam_get(struct tf *tfp __rte_unused,
397             struct tf_tcam_get_parms *parms __rte_unused)
398 {
399         return 0;
400 }