9e71c04bf24d6cb15953c0e39d041bcfd048edab
[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 #include "tf_rm.h"
12
13 struct tf;
14
15 /* Forward declarations */
16 static int tf_dev_unbind_p4(struct tf *tfp);
17 static int tf_dev_unbind_p58(struct tf *tfp);
18
19 /**
20  * Resource Reservation Check function
21  *
22  * [in] count
23  *   Number of module subtypes
24  *
25  * [in] cfg
26  *   Pointer to rm element config
27  *
28  * [in] reservations
29  *   Pointer to resource reservation array
30  *
31  * Returns
32  *   - (n) number of tables in module that have non-zero reservation count.
33  */
34 static int
35 tf_dev_reservation_check(uint16_t count,
36                          struct tf_rm_element_cfg *cfg,
37                          uint16_t *reservations)
38 {
39         uint16_t cnt = 0;
40         uint16_t *rm_num;
41         int i, j;
42
43         for (i = 0; i < TF_DIR_MAX; i++) {
44                 rm_num = (uint16_t *)reservations + i * count;
45                 for (j = 0; j < count; j++) {
46                         if ((cfg[j].cfg_type == TF_RM_ELEM_CFG_HCAPI ||
47                              cfg[j].cfg_type == TF_RM_ELEM_CFG_HCAPI_BA) &&
48                              rm_num[j] > 0)
49                                 cnt++;
50                 }
51         }
52
53         return cnt;
54 }
55
56 /**
57  * Device specific bind function, WH+
58  *
59  * [in] tfp
60  *   Pointer to TF handle
61  *
62  * [in] shadow_copy
63  *   Flag controlling shadow copy DB creation
64  *
65  * [in] resources
66  *   Pointer to resource allocation information
67  *
68  * [out] dev_handle
69  *   Device handle
70  *
71  * Returns
72  *   - (0) if successful.
73  *   - (-EINVAL) on parameter or internal failure.
74  */
75 static int
76 tf_dev_bind_p4(struct tf *tfp,
77                bool shadow_copy,
78                struct tf_session_resources *resources,
79                struct tf_dev_info *dev_handle)
80 {
81         int rc;
82         int frc;
83         int rsv_cnt;
84         bool no_rsv_flag = true;
85         struct tf_ident_cfg_parms ident_cfg;
86         struct tf_tbl_cfg_parms tbl_cfg;
87         struct tf_tcam_cfg_parms tcam_cfg;
88         struct tf_em_cfg_parms em_cfg;
89         struct tf_if_tbl_cfg_parms if_tbl_cfg;
90         struct tf_global_cfg_cfg_parms global_cfg;
91
92         /* Initial function initialization */
93         dev_handle->ops = &tf_dev_ops_p4_init;
94
95         /* Initialize the modules */
96
97         rsv_cnt = tf_dev_reservation_check(TF_IDENT_TYPE_MAX,
98                                            tf_ident_p4,
99                                            (uint16_t *)resources->ident_cnt);
100         if (rsv_cnt) {
101                 ident_cfg.num_elements = TF_IDENT_TYPE_MAX;
102                 ident_cfg.cfg = tf_ident_p4;
103                 ident_cfg.shadow_copy = shadow_copy;
104                 ident_cfg.resources = resources;
105                 rc = tf_ident_bind(tfp, &ident_cfg);
106                 if (rc) {
107                         TFP_DRV_LOG(ERR,
108                                     "Identifier initialization failure\n");
109                         goto fail;
110                 }
111
112                 no_rsv_flag = false;
113         }
114
115         rsv_cnt = tf_dev_reservation_check(TF_TBL_TYPE_MAX,
116                                            tf_tbl_p4,
117                                            (uint16_t *)resources->tbl_cnt);
118         if (rsv_cnt) {
119                 tbl_cfg.num_elements = TF_TBL_TYPE_MAX;
120                 tbl_cfg.cfg = tf_tbl_p4;
121                 tbl_cfg.shadow_copy = shadow_copy;
122                 tbl_cfg.resources = resources;
123                 rc = tf_tbl_bind(tfp, &tbl_cfg);
124                 if (rc) {
125                         TFP_DRV_LOG(ERR,
126                                     "Table initialization failure\n");
127                         goto fail;
128                 }
129
130                 no_rsv_flag = false;
131         }
132
133         rsv_cnt = tf_dev_reservation_check(TF_TCAM_TBL_TYPE_MAX,
134                                            tf_tcam_p4,
135                                            (uint16_t *)resources->tcam_cnt);
136         if (rsv_cnt) {
137                 tcam_cfg.num_elements = TF_TCAM_TBL_TYPE_MAX;
138                 tcam_cfg.cfg = tf_tcam_p4;
139                 tcam_cfg.shadow_copy = shadow_copy;
140                 tcam_cfg.resources = resources;
141                 rc = tf_tcam_bind(tfp, &tcam_cfg);
142                 if (rc) {
143                         TFP_DRV_LOG(ERR,
144                                     "TCAM initialization failure\n");
145                         goto fail;
146                 }
147                 no_rsv_flag = false;
148         }
149
150         /*
151          * EEM
152          */
153
154         em_cfg.cfg = tf_em_ext_p4;
155         rsv_cnt = tf_dev_reservation_check(TF_EM_TBL_TYPE_MAX,
156                                            em_cfg.cfg,
157                                            (uint16_t *)resources->em_cnt);
158         if (rsv_cnt) {
159                 em_cfg.num_elements = TF_EM_TBL_TYPE_MAX;
160                 em_cfg.resources = resources;
161                 em_cfg.mem_type = TF_EEM_MEM_TYPE_HOST;
162                 rc = tf_em_ext_common_bind(tfp, &em_cfg);
163                 if (rc) {
164                         TFP_DRV_LOG(ERR,
165                                     "EEM initialization failure\n");
166                         goto fail;
167                 }
168                 no_rsv_flag = false;
169         }
170
171         /*
172          * EM
173          */
174         rsv_cnt = tf_dev_reservation_check(TF_EM_TBL_TYPE_MAX,
175                                            tf_em_int_p4,
176                                            (uint16_t *)resources->em_cnt);
177         if (rsv_cnt) {
178                 em_cfg.num_elements = TF_EM_TBL_TYPE_MAX;
179                 em_cfg.cfg = tf_em_int_p4;
180                 em_cfg.resources = resources;
181                 em_cfg.mem_type = 0; /* Not used by EM */
182
183                 rc = tf_em_int_bind(tfp, &em_cfg);
184                 if (rc) {
185                         TFP_DRV_LOG(ERR,
186                                     "EM initialization failure\n");
187                         goto fail;
188                 }
189                 no_rsv_flag = false;
190         }
191
192         /*
193          * There is no rm reserved for any tables
194          *
195          */
196         if (no_rsv_flag) {
197                 TFP_DRV_LOG(ERR,
198                             "No rm reserved for any tables\n");
199                 return -ENOMEM;
200         }
201
202         /*
203          * IF_TBL
204          */
205         if_tbl_cfg.num_elements = TF_IF_TBL_TYPE_MAX;
206         if_tbl_cfg.cfg = tf_if_tbl_p4;
207         if_tbl_cfg.shadow_copy = shadow_copy;
208         rc = tf_if_tbl_bind(tfp, &if_tbl_cfg);
209         if (rc) {
210                 TFP_DRV_LOG(ERR,
211                             "IF Table initialization failure\n");
212                 goto fail;
213         }
214
215         /*
216          * GLOBAL_CFG
217          */
218         global_cfg.num_elements = TF_GLOBAL_CFG_TYPE_MAX;
219         global_cfg.cfg = tf_global_cfg_p4;
220         rc = tf_global_cfg_bind(tfp, &global_cfg);
221         if (rc) {
222                 TFP_DRV_LOG(ERR,
223                             "Global Cfg initialization failure\n");
224                 goto fail;
225         }
226
227         /* Final function initialization */
228         dev_handle->ops = &tf_dev_ops_p4;
229
230         return 0;
231
232  fail:
233         /* Cleanup of already created modules */
234         frc = tf_dev_unbind_p4(tfp);
235         if (frc)
236                 return frc;
237
238         return rc;
239 }
240
241 /**
242  * Device specific unbind function, WH+
243  *
244  * [in] tfp
245  *   Pointer to TF handle
246  *
247  * Returns
248  *   - (0) if successful.
249  *   - (-EINVAL) on failure.
250  */
251 static int
252 tf_dev_unbind_p4(struct tf *tfp)
253 {
254         int rc = 0;
255         bool fail = false;
256
257         /* Unbind all the support modules. As this is only done on
258          * close we only report errors as everything has to be cleaned
259          * up regardless.
260          *
261          * In case of residuals TCAMs are cleaned up first as to
262          * invalidate the pipeline in a clean manner.
263          */
264         rc = tf_tcam_unbind(tfp);
265         if (rc) {
266                 TFP_DRV_LOG(ERR,
267                             "Device unbind failed, TCAM\n");
268                 fail = true;
269         }
270
271         rc = tf_ident_unbind(tfp);
272         if (rc) {
273                 TFP_DRV_LOG(ERR,
274                             "Device unbind failed, Identifier\n");
275                 fail = true;
276         }
277
278         rc = tf_tbl_unbind(tfp);
279         if (rc) {
280                 TFP_DRV_LOG(ERR,
281                             "Device unbind failed, Table Type\n");
282                 fail = true;
283         }
284
285         rc = tf_em_ext_common_unbind(tfp);
286         if (rc) {
287                 TFP_DRV_LOG(ERR,
288                             "Device unbind failed, EEM\n");
289                 fail = true;
290         }
291
292         rc = tf_em_int_unbind(tfp);
293         if (rc) {
294                 TFP_DRV_LOG(ERR,
295                             "Device unbind failed, EM\n");
296                 fail = true;
297         }
298
299         rc = tf_if_tbl_unbind(tfp);
300         if (rc) {
301                 TFP_DRV_LOG(ERR,
302                             "Device unbind failed, IF Table Type\n");
303                 fail = true;
304         }
305
306         rc = tf_global_cfg_unbind(tfp);
307         if (rc) {
308                 TFP_DRV_LOG(ERR,
309                             "Device unbind failed, Global Cfg Type\n");
310                 fail = true;
311         }
312
313         if (fail)
314                 return -1;
315
316         return rc;
317 }
318
319 /**
320  * Device specific bind function, THOR
321  *
322  * [in] tfp
323  *   Pointer to TF handle
324  *
325  * [in] shadow_copy
326  *   Flag controlling shadow copy DB creation
327  *
328  * [in] resources
329  *   Pointer to resource allocation information
330  *
331  * [out] dev_handle
332  *   Device handle
333  *
334  * Returns
335  *   - (0) if successful.
336  *   - (-EINVAL) on parameter or internal failure.
337  */
338 static int
339 tf_dev_bind_p58(struct tf *tfp,
340                 bool shadow_copy,
341                 struct tf_session_resources *resources,
342                 struct tf_dev_info *dev_handle)
343 {
344         int rc;
345         int frc;
346         int rsv_cnt;
347         bool no_rsv_flag = true;
348         struct tf_ident_cfg_parms ident_cfg;
349         struct tf_tbl_cfg_parms tbl_cfg;
350         struct tf_tcam_cfg_parms tcam_cfg;
351         struct tf_em_cfg_parms em_cfg;
352         struct tf_if_tbl_cfg_parms if_tbl_cfg;
353         struct tf_global_cfg_cfg_parms global_cfg;
354
355         /* Initial function initialization */
356         dev_handle->ops = &tf_dev_ops_p58_init;
357
358         rsv_cnt = tf_dev_reservation_check(TF_IDENT_TYPE_MAX,
359                                            tf_ident_p58,
360                                            (uint16_t *)resources->ident_cnt);
361         if (rsv_cnt) {
362                 ident_cfg.num_elements = TF_IDENT_TYPE_MAX;
363                 ident_cfg.cfg = tf_ident_p58;
364                 ident_cfg.shadow_copy = shadow_copy;
365                 ident_cfg.resources = resources;
366                 rc = tf_ident_bind(tfp, &ident_cfg);
367                 if (rc) {
368                         TFP_DRV_LOG(ERR,
369                                     "Identifier initialization failure\n");
370                         goto fail;
371                 }
372                 no_rsv_flag = false;
373         }
374
375         rsv_cnt = tf_dev_reservation_check(TF_TBL_TYPE_MAX,
376                                            tf_tbl_p58,
377                                            (uint16_t *)resources->tbl_cnt);
378         if (rsv_cnt) {
379                 tbl_cfg.num_elements = TF_TBL_TYPE_MAX;
380                 tbl_cfg.cfg = tf_tbl_p58;
381                 tbl_cfg.shadow_copy = shadow_copy;
382                 tbl_cfg.resources = resources;
383                 rc = tf_tbl_bind(tfp, &tbl_cfg);
384                 if (rc) {
385                         TFP_DRV_LOG(ERR,
386                                     "Table initialization failure\n");
387                         goto fail;
388                 }
389                 no_rsv_flag = false;
390         }
391
392         rsv_cnt = tf_dev_reservation_check(TF_TCAM_TBL_TYPE_MAX,
393                                            tf_tcam_p58,
394                                            (uint16_t *)resources->tcam_cnt);
395         if (rsv_cnt) {
396                 tcam_cfg.num_elements = TF_TCAM_TBL_TYPE_MAX;
397                 tcam_cfg.cfg = tf_tcam_p58;
398                 tcam_cfg.shadow_copy = shadow_copy;
399                 tcam_cfg.resources = resources;
400                 rc = tf_tcam_bind(tfp, &tcam_cfg);
401                 if (rc) {
402                         TFP_DRV_LOG(ERR,
403                                     "TCAM initialization failure\n");
404                         goto fail;
405                 }
406                 no_rsv_flag = false;
407         }
408
409         /*
410          * EM
411          */
412         rsv_cnt = tf_dev_reservation_check(TF_EM_TBL_TYPE_MAX,
413                                            tf_em_int_p58,
414                                            (uint16_t *)resources->em_cnt);
415         if (rsv_cnt) {
416                 em_cfg.num_elements = TF_EM_TBL_TYPE_MAX;
417                 em_cfg.cfg = tf_em_int_p58;
418                 em_cfg.resources = resources;
419                 em_cfg.mem_type = 0; /* Not used by EM */
420
421                 rc = tf_em_int_bind(tfp, &em_cfg);
422                 if (rc) {
423                         TFP_DRV_LOG(ERR,
424                                     "EM initialization failure\n");
425                         goto fail;
426                 }
427                 no_rsv_flag = false;
428         }
429
430         /*
431          * There is no rm reserved for any tables
432          *
433          */
434         if (no_rsv_flag) {
435                 TFP_DRV_LOG(ERR,
436                             "No rm reserved for any tables\n");
437                 return -ENOMEM;
438         }
439
440         /*
441          * IF_TBL
442          */
443         if_tbl_cfg.num_elements = TF_IF_TBL_TYPE_MAX;
444         if_tbl_cfg.cfg = tf_if_tbl_p58;
445         if_tbl_cfg.shadow_copy = shadow_copy;
446         rc = tf_if_tbl_bind(tfp, &if_tbl_cfg);
447         if (rc) {
448                 TFP_DRV_LOG(ERR,
449                             "IF Table initialization failure\n");
450                 goto fail;
451         }
452
453         /*
454          * GLOBAL_CFG
455          */
456         global_cfg.num_elements = TF_GLOBAL_CFG_TYPE_MAX;
457         global_cfg.cfg = tf_global_cfg_p58;
458         rc = tf_global_cfg_bind(tfp, &global_cfg);
459         if (rc) {
460                 TFP_DRV_LOG(ERR,
461                             "Global Cfg initialization failure\n");
462                 goto fail;
463         }
464
465         /* Final function initialization */
466         dev_handle->ops = &tf_dev_ops_p58;
467
468         return 0;
469
470  fail:
471         /* Cleanup of already created modules */
472         frc = tf_dev_unbind_p58(tfp);
473         if (frc)
474                 return frc;
475
476         return rc;
477 }
478
479 /**
480  * Device specific unbind function, THOR
481  *
482  * [in] tfp
483  *   Pointer to TF handle
484  *
485  * Returns
486  *   - (0) if successful.
487  *   - (-EINVAL) on failure.
488  */
489 static int
490 tf_dev_unbind_p58(struct tf *tfp)
491 {
492         int rc = 0;
493         bool fail = false;
494
495         /* Unbind all the support modules. As this is only done on
496          * close we only report errors as everything has to be cleaned
497          * up regardless.
498          *
499          * In case of residuals TCAMs are cleaned up first as to
500          * invalidate the pipeline in a clean manner.
501          */
502         rc = tf_tcam_unbind(tfp);
503         if (rc) {
504                 TFP_DRV_LOG(ERR,
505                             "Device unbind failed, TCAM\n");
506                 fail = true;
507         }
508
509         rc = tf_ident_unbind(tfp);
510         if (rc) {
511                 TFP_DRV_LOG(ERR,
512                             "Device unbind failed, Identifier\n");
513                 fail = true;
514         }
515
516         rc = tf_tbl_unbind(tfp);
517         if (rc) {
518                 TFP_DRV_LOG(ERR,
519                             "Device unbind failed, Table Type\n");
520                 fail = true;
521         }
522
523         rc = tf_em_int_unbind(tfp);
524         if (rc) {
525                 TFP_DRV_LOG(ERR,
526                             "Device unbind failed, EM\n");
527                 fail = true;
528         }
529
530         rc = tf_if_tbl_unbind(tfp);
531         if (rc) {
532                 TFP_DRV_LOG(ERR,
533                             "Device unbind failed, IF Table Type\n");
534                 fail = true;
535         }
536
537         rc = tf_global_cfg_unbind(tfp);
538         if (rc) {
539                 TFP_DRV_LOG(ERR,
540                             "Device unbind failed, Global Cfg Type\n");
541                 fail = true;
542         }
543
544         if (fail)
545                 return -1;
546
547         return rc;
548 }
549
550 int
551 tf_dev_bind(struct tf *tfp __rte_unused,
552             enum tf_device_type type,
553             bool shadow_copy,
554             struct tf_session_resources *resources,
555             struct tf_dev_info *dev_handle)
556 {
557         switch (type) {
558         case TF_DEVICE_TYPE_WH:
559         case TF_DEVICE_TYPE_SR:
560                 dev_handle->type = type;
561                 return tf_dev_bind_p4(tfp,
562                                       shadow_copy,
563                                       resources,
564                                       dev_handle);
565         case TF_DEVICE_TYPE_THOR:
566                 dev_handle->type = type;
567                 return tf_dev_bind_p58(tfp,
568                                        shadow_copy,
569                                        resources,
570                                        dev_handle);
571         default:
572                 TFP_DRV_LOG(ERR,
573                             "No such device\n");
574                 return -ENODEV;
575         }
576 }
577
578 int
579 tf_dev_bind_ops(enum tf_device_type type,
580                 struct tf_dev_info *dev_handle)
581 {
582         switch (type) {
583         case TF_DEVICE_TYPE_WH:
584         case TF_DEVICE_TYPE_SR:
585                 dev_handle->ops = &tf_dev_ops_p4_init;
586                 break;
587         case TF_DEVICE_TYPE_THOR:
588                 dev_handle->ops = &tf_dev_ops_p58_init;
589                 break;
590         default:
591                 TFP_DRV_LOG(ERR,
592                             "No such device\n");
593                 return -ENODEV;
594         }
595
596         return 0;
597 }
598
599 int
600 tf_dev_unbind(struct tf *tfp,
601               struct tf_dev_info *dev_handle)
602 {
603         switch (dev_handle->type) {
604         case TF_DEVICE_TYPE_WH:
605         case TF_DEVICE_TYPE_SR:
606                 return tf_dev_unbind_p4(tfp);
607         case TF_DEVICE_TYPE_THOR:
608                 return tf_dev_unbind_p58(tfp);
609         default:
610                 TFP_DRV_LOG(ERR,
611                             "No such device\n");
612                 return -ENODEV;
613         }
614 }