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