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