net/bnxt: add mailbox selection via device operation
[dpdk.git] / drivers / net / bnxt / tf_core / tf_device.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019-2021 Broadcom
3  * All rights reserved.
4  */
5
6 #include "tf_device.h"
7 #include "tf_device_p4.h"
8 #include "tf_device_p58.h"
9 #include "tfp.h"
10 #include "tf_em.h"
11
12 struct tf;
13
14 /* Forward declarations */
15 static int tf_dev_unbind_p4(struct tf *tfp);
16 static int tf_dev_unbind_p58(struct tf *tfp);
17
18 /**
19  * Device specific bind function, WH+
20  *
21  * [in] tfp
22  *   Pointer to TF handle
23  *
24  * [in] shadow_copy
25  *   Flag controlling shadow copy DB creation
26  *
27  * [in] resources
28  *   Pointer to resource allocation information
29  *
30  * [out] dev_handle
31  *   Device handle
32  *
33  * Returns
34  *   - (0) if successful.
35  *   - (-EINVAL) on parameter or internal failure.
36  */
37 static int
38 tf_dev_bind_p4(struct tf *tfp,
39                bool shadow_copy,
40                struct tf_session_resources *resources,
41                struct tf_dev_info *dev_handle)
42 {
43         int rc;
44         int frc;
45         struct tf_ident_cfg_parms ident_cfg;
46         struct tf_tbl_cfg_parms tbl_cfg;
47         struct tf_tcam_cfg_parms tcam_cfg;
48         struct tf_em_cfg_parms em_cfg;
49         struct tf_if_tbl_cfg_parms if_tbl_cfg;
50         struct tf_global_cfg_cfg_parms global_cfg;
51
52         /* Initial function initialization */
53         dev_handle->ops = &tf_dev_ops_p4_init;
54
55         /* Initialize the modules */
56
57         ident_cfg.num_elements = TF_IDENT_TYPE_MAX;
58         ident_cfg.cfg = tf_ident_p4;
59         ident_cfg.shadow_copy = shadow_copy;
60         ident_cfg.resources = resources;
61         rc = tf_ident_bind(tfp, &ident_cfg);
62         if (rc) {
63                 TFP_DRV_LOG(ERR,
64                             "Identifier initialization failure\n");
65                 goto fail;
66         }
67
68         tbl_cfg.num_elements = TF_TBL_TYPE_MAX;
69         tbl_cfg.cfg = tf_tbl_p4;
70         tbl_cfg.shadow_copy = shadow_copy;
71         tbl_cfg.resources = resources;
72         rc = tf_tbl_bind(tfp, &tbl_cfg);
73         if (rc) {
74                 TFP_DRV_LOG(ERR,
75                             "Table initialization failure\n");
76                 goto fail;
77         }
78
79         tcam_cfg.num_elements = TF_TCAM_TBL_TYPE_MAX;
80         tcam_cfg.cfg = tf_tcam_p4;
81         tcam_cfg.shadow_copy = shadow_copy;
82         tcam_cfg.resources = resources;
83         rc = tf_tcam_bind(tfp, &tcam_cfg);
84         if (rc) {
85                 TFP_DRV_LOG(ERR,
86                             "TCAM initialization failure\n");
87                 goto fail;
88         }
89
90         /*
91          * EEM
92          */
93         em_cfg.num_elements = TF_EM_TBL_TYPE_MAX;
94         if (dev_handle->type == TF_DEVICE_TYPE_WH)
95                 em_cfg.cfg = tf_em_ext_p4;
96         else
97                 em_cfg.cfg = tf_em_ext_p45;
98         em_cfg.resources = resources;
99         em_cfg.mem_type = TF_EEM_MEM_TYPE_HOST;
100         rc = tf_em_ext_common_bind(tfp, &em_cfg);
101         if (rc) {
102                 TFP_DRV_LOG(ERR,
103                             "EEM initialization failure\n");
104                 goto fail;
105         }
106
107         /*
108          * EM
109          */
110         em_cfg.num_elements = TF_EM_TBL_TYPE_MAX;
111         em_cfg.cfg = tf_em_int_p4;
112         em_cfg.resources = resources;
113         em_cfg.mem_type = 0; /* Not used by EM */
114
115         rc = tf_em_int_bind(tfp, &em_cfg);
116         if (rc) {
117                 TFP_DRV_LOG(ERR,
118                             "EM initialization failure\n");
119                 goto fail;
120         }
121
122         /*
123          * IF_TBL
124          */
125         if_tbl_cfg.num_elements = TF_IF_TBL_TYPE_MAX;
126         if_tbl_cfg.cfg = tf_if_tbl_p4;
127         if_tbl_cfg.shadow_copy = shadow_copy;
128         rc = tf_if_tbl_bind(tfp, &if_tbl_cfg);
129         if (rc) {
130                 TFP_DRV_LOG(ERR,
131                             "IF Table initialization failure\n");
132                 goto fail;
133         }
134
135         /*
136          * GLOBAL_CFG
137          */
138         global_cfg.num_elements = TF_GLOBAL_CFG_TYPE_MAX;
139         global_cfg.cfg = tf_global_cfg_p4;
140         rc = tf_global_cfg_bind(tfp, &global_cfg);
141         if (rc) {
142                 TFP_DRV_LOG(ERR,
143                             "Global Cfg initialization failure\n");
144                 goto fail;
145         }
146
147         /* Final function initialization */
148         dev_handle->ops = &tf_dev_ops_p4;
149
150         return 0;
151
152  fail:
153         /* Cleanup of already created modules */
154         frc = tf_dev_unbind_p4(tfp);
155         if (frc)
156                 return frc;
157
158         return rc;
159 }
160
161 /**
162  * Device specific unbind function, WH+
163  *
164  * [in] tfp
165  *   Pointer to TF handle
166  *
167  * Returns
168  *   - (0) if successful.
169  *   - (-EINVAL) on failure.
170  */
171 static int
172 tf_dev_unbind_p4(struct tf *tfp)
173 {
174         int rc = 0;
175         bool fail = false;
176
177         /* Unbind all the support modules. As this is only done on
178          * close we only report errors as everything has to be cleaned
179          * up regardless.
180          *
181          * In case of residuals TCAMs are cleaned up first as to
182          * invalidate the pipeline in a clean manner.
183          */
184         rc = tf_tcam_unbind(tfp);
185         if (rc) {
186                 TFP_DRV_LOG(ERR,
187                             "Device unbind failed, TCAM\n");
188                 fail = true;
189         }
190
191         rc = tf_ident_unbind(tfp);
192         if (rc) {
193                 TFP_DRV_LOG(ERR,
194                             "Device unbind failed, Identifier\n");
195                 fail = true;
196         }
197
198         rc = tf_tbl_unbind(tfp);
199         if (rc) {
200                 TFP_DRV_LOG(ERR,
201                             "Device unbind failed, Table Type\n");
202                 fail = true;
203         }
204
205         rc = tf_em_ext_common_unbind(tfp);
206         if (rc) {
207                 TFP_DRV_LOG(ERR,
208                             "Device unbind failed, EEM\n");
209                 fail = true;
210         }
211
212         rc = tf_em_int_unbind(tfp);
213         if (rc) {
214                 TFP_DRV_LOG(ERR,
215                             "Device unbind failed, EM\n");
216                 fail = true;
217         }
218
219         rc = tf_if_tbl_unbind(tfp);
220         if (rc) {
221                 TFP_DRV_LOG(ERR,
222                             "Device unbind failed, IF Table Type\n");
223                 fail = true;
224         }
225
226         rc = tf_global_cfg_unbind(tfp);
227         if (rc) {
228                 TFP_DRV_LOG(ERR,
229                             "Device unbind failed, Global Cfg Type\n");
230                 fail = true;
231         }
232
233         if (fail)
234                 return -1;
235
236         return rc;
237 }
238
239 /**
240  * Device specific bind function, THOR
241  *
242  * [in] tfp
243  *   Pointer to TF handle
244  *
245  * [in] shadow_copy
246  *   Flag controlling shadow copy DB creation
247  *
248  * [in] resources
249  *   Pointer to resource allocation information
250  *
251  * [out] dev_handle
252  *   Device handle
253  *
254  * Returns
255  *   - (0) if successful.
256  *   - (-EINVAL) on parameter or internal failure.
257  */
258 static int
259 tf_dev_bind_p58(struct tf *tfp,
260                 bool shadow_copy,
261                 struct tf_session_resources *resources,
262                 struct tf_dev_info *dev_handle)
263 {
264         int rc;
265         int frc;
266         struct tf_ident_cfg_parms ident_cfg;
267         struct tf_tbl_cfg_parms tbl_cfg;
268         struct tf_tcam_cfg_parms tcam_cfg;
269         struct tf_em_cfg_parms em_cfg;
270         struct tf_if_tbl_cfg_parms if_tbl_cfg;
271         struct tf_global_cfg_cfg_parms global_cfg;
272
273         /* Initial function initialization */
274         dev_handle->ops = &tf_dev_ops_p58_init;
275
276         /* Initialize the modules */
277
278         ident_cfg.num_elements = TF_IDENT_TYPE_MAX;
279         ident_cfg.cfg = tf_ident_p58;
280         ident_cfg.shadow_copy = shadow_copy;
281         ident_cfg.resources = resources;
282         rc = tf_ident_bind(tfp, &ident_cfg);
283         if (rc) {
284                 TFP_DRV_LOG(ERR,
285                             "Identifier initialization failure\n");
286                 goto fail;
287         }
288
289         tbl_cfg.num_elements = TF_TBL_TYPE_MAX;
290         tbl_cfg.cfg = tf_tbl_p58;
291         tbl_cfg.shadow_copy = shadow_copy;
292         tbl_cfg.resources = resources;
293         rc = tf_tbl_bind(tfp, &tbl_cfg);
294         if (rc) {
295                 TFP_DRV_LOG(ERR,
296                             "Table initialization failure\n");
297                 goto fail;
298         }
299
300         tcam_cfg.num_elements = TF_TCAM_TBL_TYPE_MAX;
301         tcam_cfg.cfg = tf_tcam_p58;
302         tcam_cfg.shadow_copy = shadow_copy;
303         tcam_cfg.resources = resources;
304         rc = tf_tcam_bind(tfp, &tcam_cfg);
305         if (rc) {
306                 TFP_DRV_LOG(ERR,
307                             "TCAM initialization failure\n");
308                 goto fail;
309         }
310
311         /*
312          * EM
313          */
314         em_cfg.num_elements = TF_EM_TBL_TYPE_MAX;
315         em_cfg.cfg = tf_em_int_p58;
316         em_cfg.resources = resources;
317         em_cfg.mem_type = 0; /* Not used by EM */
318
319         rc = tf_em_int_bind(tfp, &em_cfg);
320         if (rc) {
321                 TFP_DRV_LOG(ERR,
322                             "EM initialization failure\n");
323                 goto fail;
324         }
325
326         /*
327          * IF_TBL
328          */
329         if_tbl_cfg.num_elements = TF_IF_TBL_TYPE_MAX;
330         if_tbl_cfg.cfg = tf_if_tbl_p58;
331         if_tbl_cfg.shadow_copy = shadow_copy;
332         rc = tf_if_tbl_bind(tfp, &if_tbl_cfg);
333         if (rc) {
334                 TFP_DRV_LOG(ERR,
335                             "IF Table initialization failure\n");
336                 goto fail;
337         }
338
339         /*
340          * GLOBAL_CFG
341          */
342         global_cfg.num_elements = TF_GLOBAL_CFG_TYPE_MAX;
343         global_cfg.cfg = tf_global_cfg_p58;
344         rc = tf_global_cfg_bind(tfp, &global_cfg);
345         if (rc) {
346                 TFP_DRV_LOG(ERR,
347                             "Global Cfg initialization failure\n");
348                 goto fail;
349         }
350
351         /* Final function initialization */
352         dev_handle->ops = &tf_dev_ops_p58;
353
354         return 0;
355
356  fail:
357         /* Cleanup of already created modules */
358         frc = tf_dev_unbind_p58(tfp);
359         if (frc)
360                 return frc;
361
362         return rc;
363 }
364
365 /**
366  * Device specific unbind function, THOR
367  *
368  * [in] tfp
369  *   Pointer to TF handle
370  *
371  * Returns
372  *   - (0) if successful.
373  *   - (-EINVAL) on failure.
374  */
375 static int
376         tf_dev_unbind_p58(struct tf *tfp)
377 {
378         int rc = 0;
379         bool fail = false;
380
381         /* Unbind all the support modules. As this is only done on
382          * close we only report errors as everything has to be cleaned
383          * up regardless.
384          *
385          * In case of residuals TCAMs are cleaned up first as to
386          * invalidate the pipeline in a clean manner.
387          */
388         rc = tf_tcam_unbind(tfp);
389         if (rc) {
390                 TFP_DRV_LOG(ERR,
391                             "Device unbind failed, TCAM\n");
392                 fail = true;
393         }
394
395         rc = tf_ident_unbind(tfp);
396         if (rc) {
397                 TFP_DRV_LOG(ERR,
398                             "Device unbind failed, Identifier\n");
399                 fail = true;
400         }
401
402         rc = tf_tbl_unbind(tfp);
403         if (rc) {
404                 TFP_DRV_LOG(ERR,
405                             "Device unbind failed, Table Type\n");
406                 fail = true;
407         }
408
409         rc = tf_em_int_unbind(tfp);
410         if (rc) {
411                 TFP_DRV_LOG(ERR,
412                             "Device unbind failed, EM\n");
413                 fail = true;
414         }
415
416         rc = tf_if_tbl_unbind(tfp);
417         if (rc) {
418                 TFP_DRV_LOG(ERR,
419                             "Device unbind failed, IF Table Type\n");
420                 fail = true;
421         }
422
423         rc = tf_global_cfg_unbind(tfp);
424         if (rc) {
425                 TFP_DRV_LOG(ERR,
426                             "Device unbind failed, Global Cfg Type\n");
427                 fail = true;
428         }
429
430         if (fail)
431                 return -1;
432
433         return rc;
434 }
435
436 int
437 tf_dev_bind(struct tf *tfp __rte_unused,
438             enum tf_device_type type,
439             bool shadow_copy,
440             struct tf_session_resources *resources,
441             struct tf_dev_info *dev_handle)
442 {
443         switch (type) {
444         case TF_DEVICE_TYPE_WH:
445         case TF_DEVICE_TYPE_SR:
446                 dev_handle->type = type;
447                 return tf_dev_bind_p4(tfp,
448                                       shadow_copy,
449                                       resources,
450                                       dev_handle);
451         case TF_DEVICE_TYPE_THOR:
452                 dev_handle->type = type;
453                 return tf_dev_bind_p58(tfp,
454                                        shadow_copy,
455                                        resources,
456                                        dev_handle);
457         default:
458                 TFP_DRV_LOG(ERR,
459                             "No such device\n");
460                 return -ENODEV;
461         }
462 }
463
464 int
465 tf_dev_bind_ops(enum tf_device_type type,
466                 struct tf_dev_info *dev_handle)
467 {
468         switch (type) {
469         case TF_DEVICE_TYPE_WH:
470         case TF_DEVICE_TYPE_SR:
471                 dev_handle->ops = &tf_dev_ops_p4;
472                 break;
473         case TF_DEVICE_TYPE_THOR:
474                 dev_handle->ops = &tf_dev_ops_p58;
475                 break;
476         default:
477                 TFP_DRV_LOG(ERR,
478                             "No such device\n");
479                 return -ENODEV;
480         }
481
482         return 0;
483 }
484
485 int
486 tf_dev_unbind(struct tf *tfp,
487               struct tf_dev_info *dev_handle)
488 {
489         switch (dev_handle->type) {
490         case TF_DEVICE_TYPE_WH:
491         case TF_DEVICE_TYPE_SR:
492                 return tf_dev_unbind_p4(tfp);
493         case TF_DEVICE_TYPE_THOR:
494                 return tf_dev_unbind_p58(tfp);
495         default:
496                 TFP_DRV_LOG(ERR,
497                             "No such device\n");
498                 return -ENODEV;
499         }
500 }