net/bnxt: support multiple device
[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_new.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 already initialized\n");
53                 return -EINVAL;
54         }
55
56         db_cfg.num_elements = parms->num_elements;
57
58         for (i = 0; i < TF_DIR_MAX; i++) {
59                 db_cfg.dir = i;
60                 db_cfg.num_elements = parms->num_elements;
61                 db_cfg.cfg = parms->cfg;
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 done silent as to
90          * allow for creation cleanup.
91          */
92         if (!init)
93                 return -EINVAL;
94
95         for (i = 0; i < TF_DIR_MAX; i++) {
96                 fparms.dir = i;
97                 fparms.rm_db = tcam_db[i];
98                 rc = tf_rm_free_db(tfp, &fparms);
99                 if (rc)
100                         return rc;
101
102                 tcam_db[i] = NULL;
103         }
104
105         init = 0;
106
107         return 0;
108 }
109
110 int
111 tf_tcam_alloc(struct tf *tfp,
112               struct tf_tcam_alloc_parms *parms)
113 {
114         int rc;
115         struct tf_session *tfs;
116         struct tf_dev_info *dev;
117         struct tf_rm_allocate_parms aparms = { 0 };
118         uint16_t num_slice_per_row = 1;
119
120         TF_CHECK_PARMS2(tfp, parms);
121
122         if (!init) {
123                 TFP_DRV_LOG(ERR,
124                             "%s: No TCAM DBs created\n",
125                             tf_dir_2_str(parms->dir));
126                 return -EINVAL;
127         }
128
129         /* Retrieve the session information */
130         rc = tf_session_get_session(tfp, &tfs);
131         if (rc)
132                 return rc;
133
134         /* Retrieve the device information */
135         rc = tf_session_get_device(tfs, &dev);
136         if (rc)
137                 return rc;
138
139         if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
140                 rc = -EOPNOTSUPP;
141                 TFP_DRV_LOG(ERR,
142                             "%s: Operation not supported, rc:%s\n",
143                             tf_dir_2_str(parms->dir),
144                             strerror(-rc));
145                 return rc;
146         }
147
148         /* Need to retrieve row size etc */
149         rc = dev->ops->tf_dev_get_tcam_slice_info(tfp,
150                                                   parms->type,
151                                                   parms->key_size,
152                                                   &num_slice_per_row);
153         if (rc)
154                 return rc;
155
156         /* Allocate requested element */
157         aparms.rm_db = tcam_db[parms->dir];
158         aparms.db_index = parms->type;
159         aparms.index = (uint32_t *)&parms->idx;
160         rc = tf_rm_allocate(&aparms);
161         if (rc) {
162                 TFP_DRV_LOG(ERR,
163                             "%s: Failed tcam, type:%d\n",
164                             tf_dir_2_str(parms->dir),
165                             parms->type);
166                 return rc;
167         }
168
169         parms->idx *= num_slice_per_row;
170
171         return 0;
172 }
173
174 int
175 tf_tcam_free(struct tf *tfp __rte_unused,
176              struct tf_tcam_free_parms *parms __rte_unused)
177 {
178         int rc;
179         struct tf_session *tfs;
180         struct tf_dev_info *dev;
181         struct tf_rm_is_allocated_parms aparms = { 0 };
182         struct tf_rm_free_parms fparms = { 0 };
183         uint16_t num_slice_per_row = 1;
184         int allocated = 0;
185
186         TF_CHECK_PARMS2(tfp, parms);
187
188         if (!init) {
189                 TFP_DRV_LOG(ERR,
190                             "%s: No TCAM DBs created\n",
191                             tf_dir_2_str(parms->dir));
192                 return -EINVAL;
193         }
194
195         /* Retrieve the session information */
196         rc = tf_session_get_session(tfp, &tfs);
197         if (rc)
198                 return rc;
199
200         /* Retrieve the device information */
201         rc = tf_session_get_device(tfs, &dev);
202         if (rc)
203                 return rc;
204
205         if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
206                 rc = -EOPNOTSUPP;
207                 TFP_DRV_LOG(ERR,
208                             "%s: Operation not supported, rc:%s\n",
209                             tf_dir_2_str(parms->dir),
210                             strerror(-rc));
211                 return rc;
212         }
213
214         /* Need to retrieve row size etc */
215         rc = dev->ops->tf_dev_get_tcam_slice_info(tfp,
216                                                   parms->type,
217                                                   0,
218                                                   &num_slice_per_row);
219         if (rc)
220                 return rc;
221
222         /* Check if element is in use */
223         aparms.rm_db = tcam_db[parms->dir];
224         aparms.db_index = parms->type;
225         aparms.index = parms->idx / num_slice_per_row;
226         aparms.allocated = &allocated;
227         rc = tf_rm_is_allocated(&aparms);
228         if (rc)
229                 return rc;
230
231         if (!allocated) {
232                 TFP_DRV_LOG(ERR,
233                             "%s: Entry already free, type:%d, index:%d\n",
234                             tf_dir_2_str(parms->dir),
235                             parms->type,
236                             parms->idx);
237                 return rc;
238         }
239
240         /* Free requested element */
241         fparms.rm_db = tcam_db[parms->dir];
242         fparms.db_index = parms->type;
243         fparms.index = parms->idx / num_slice_per_row;
244         rc = tf_rm_free(&fparms);
245         if (rc) {
246                 TFP_DRV_LOG(ERR,
247                             "%s: Free failed, type:%d, index:%d\n",
248                             tf_dir_2_str(parms->dir),
249                             parms->type,
250                             parms->idx);
251                 return rc;
252         }
253
254         rc = tf_msg_tcam_entry_free(tfp, parms);
255         if (rc) {
256                 /* Log error */
257                 TFP_DRV_LOG(ERR, "%s: %s: Entry %d free failed with err %s",
258                             tf_dir_2_str(parms->dir),
259                             tf_tcam_tbl_2_str(parms->type),
260                             parms->idx,
261                             strerror(-rc));
262         }
263
264         return 0;
265 }
266
267 int
268 tf_tcam_alloc_search(struct tf *tfp __rte_unused,
269                      struct tf_tcam_alloc_search_parms *parms __rte_unused)
270 {
271         return 0;
272 }
273
274 int
275 tf_tcam_set(struct tf *tfp __rte_unused,
276             struct tf_tcam_set_parms *parms __rte_unused)
277 {
278         int rc;
279         struct tf_session *tfs;
280         struct tf_dev_info *dev;
281         struct tf_rm_is_allocated_parms aparms = { 0 };
282         uint16_t num_slice_per_row = 1;
283         int allocated = 0;
284
285         TF_CHECK_PARMS2(tfp, parms);
286
287         if (!init) {
288                 TFP_DRV_LOG(ERR,
289                             "%s: No TCAM DBs created\n",
290                             tf_dir_2_str(parms->dir));
291                 return -EINVAL;
292         }
293
294         /* Retrieve the session information */
295         rc = tf_session_get_session(tfp, &tfs);
296         if (rc)
297                 return rc;
298
299         /* Retrieve the device information */
300         rc = tf_session_get_device(tfs, &dev);
301         if (rc)
302                 return rc;
303
304         if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
305                 rc = -EOPNOTSUPP;
306                 TFP_DRV_LOG(ERR,
307                             "%s: Operation not supported, rc:%s\n",
308                             tf_dir_2_str(parms->dir),
309                             strerror(-rc));
310                 return rc;
311         }
312
313         /* Need to retrieve row size etc */
314         rc = dev->ops->tf_dev_get_tcam_slice_info(tfp,
315                                                   parms->type,
316                                                   parms->key_size,
317                                                   &num_slice_per_row);
318         if (rc)
319                 return rc;
320
321         /* Check if element is in use */
322         aparms.rm_db = tcam_db[parms->dir];
323         aparms.db_index = parms->type;
324         aparms.index = parms->idx / num_slice_per_row;
325         aparms.allocated = &allocated;
326         rc = tf_rm_is_allocated(&aparms);
327         if (rc)
328                 return rc;
329
330         if (!allocated) {
331                 TFP_DRV_LOG(ERR,
332                             "%s: Entry is not allocated, type:%d, index:%d\n",
333                             tf_dir_2_str(parms->dir),
334                             parms->type,
335                             parms->idx);
336                 return rc;
337         }
338
339         rc = tf_msg_tcam_entry_set(tfp, parms);
340         if (rc) {
341                 /* Log error */
342                 TFP_DRV_LOG(ERR, "%s: %s: Entry %d free failed with err %s",
343                             tf_dir_2_str(parms->dir),
344                             tf_tcam_tbl_2_str(parms->type),
345                             parms->idx,
346                             strerror(-rc));
347         }
348
349         return 0;
350 }
351
352 int
353 tf_tcam_get(struct tf *tfp __rte_unused,
354             struct tf_tcam_get_parms *parms __rte_unused)
355 {
356         return 0;
357 }