net/ice: track DCF state of PF
[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 /* Forward declarations */
20 static int tf_dev_unbind_p4(struct tf *tfp);
21 static int tf_dev_unbind_p58(struct tf *tfp);
22
23 /**
24  * Resource Reservation Check function
25  *
26  * [in] count
27  *   Number of module subtypes
28  *
29  * [in] cfg
30  *   Pointer to rm element config
31  *
32  * [in] reservations
33  *   Pointer to resource reservation array
34  *
35  * Returns
36  *   - (n) number of tables in module that have non-zero reservation count.
37  */
38 static int
39 tf_dev_reservation_check(uint16_t count,
40                          struct tf_rm_element_cfg *cfg,
41                          uint16_t *reservations)
42 {
43         uint16_t cnt = 0;
44         uint16_t *rm_num;
45         int i, j;
46
47         for (i = 0; i < TF_DIR_MAX; i++) {
48                 rm_num = (uint16_t *)reservations + i * count;
49                 for (j = 0; j < count; j++) {
50                         if ((cfg[j].cfg_type == TF_RM_ELEM_CFG_HCAPI ||
51                              cfg[j].cfg_type == TF_RM_ELEM_CFG_HCAPI_BA ||
52                              cfg[j].cfg_type ==
53                                 TF_RM_ELEM_CFG_HCAPI_BA_PARENT ||
54                              cfg[j].cfg_type ==
55                                 TF_RM_ELEM_CFG_HCAPI_BA_CHILD) &&
56                              rm_num[j] > 0)
57                                 cnt++;
58                 }
59         }
60
61         return cnt;
62 }
63
64 /**
65  * Device specific bind function, WH+
66  *
67  * [in] tfp
68  *   Pointer to TF handle
69  *
70  * [in] shadow_copy
71  *   Flag controlling shadow copy DB creation
72  *
73  * [in] resources
74  *   Pointer to resource allocation information
75  *
76  * [out] dev_handle
77  *   Device handle
78  *
79  * Returns
80  *   - (0) if successful.
81  *   - (-EINVAL) on parameter or internal failure.
82  */
83 static int
84 tf_dev_bind_p4(struct tf *tfp,
85                bool shadow_copy,
86                struct tf_session_resources *resources,
87                struct tf_dev_info *dev_handle,
88                enum tf_wc_num_slice wc_num_slices)
89 {
90         int rc;
91         int frc;
92         int rsv_cnt;
93         bool no_rsv_flag = true;
94         struct tf_ident_cfg_parms ident_cfg;
95         struct tf_tbl_cfg_parms tbl_cfg;
96         struct tf_tcam_cfg_parms tcam_cfg;
97         struct tf_em_cfg_parms em_cfg;
98         struct tf_if_tbl_cfg_parms if_tbl_cfg;
99         struct tf_global_cfg_cfg_parms global_cfg;
100         struct tf_session *tfs;
101
102         /* Retrieve the session information */
103         rc = tf_session_get_session_internal(tfp, &tfs);
104         if (rc)
105                 return rc;
106
107         /* Initial function initialization */
108         dev_handle->ops = &tf_dev_ops_p4_init;
109
110         /* Initialize the modules */
111
112         rsv_cnt = tf_dev_reservation_check(TF_IDENT_TYPE_MAX,
113                                            tf_ident_p4,
114                                            (uint16_t *)resources->ident_cnt);
115         if (rsv_cnt) {
116                 ident_cfg.num_elements = TF_IDENT_TYPE_MAX;
117                 ident_cfg.cfg = tf_ident_p4;
118                 ident_cfg.shadow_copy = shadow_copy;
119                 ident_cfg.resources = resources;
120                 rc = tf_ident_bind(tfp, &ident_cfg);
121                 if (rc) {
122                         TFP_DRV_LOG(ERR,
123                                     "Identifier initialization failure\n");
124                         goto fail;
125                 }
126
127                 no_rsv_flag = false;
128         }
129
130         rsv_cnt = tf_dev_reservation_check(TF_TBL_TYPE_MAX,
131                                            tf_tbl_p4[TF_DIR_RX],
132                                            (uint16_t *)resources->tbl_cnt);
133         if (rsv_cnt) {
134                 tbl_cfg.num_elements = TF_TBL_TYPE_MAX;
135                 tbl_cfg.cfg = tf_tbl_p4[TF_DIR_RX];
136                 tbl_cfg.resources = resources;
137                 rc = tf_tbl_bind(tfp, &tbl_cfg);
138                 if (rc) {
139                         TFP_DRV_LOG(ERR,
140                                     "Table initialization failure\n");
141                         goto fail;
142                 }
143
144                 no_rsv_flag = false;
145         }
146
147         rsv_cnt = tf_dev_reservation_check(TF_TCAM_TBL_TYPE_MAX,
148                                            tf_tcam_p4,
149                                            (uint16_t *)resources->tcam_cnt);
150         if (rsv_cnt) {
151                 tcam_cfg.num_elements = TF_TCAM_TBL_TYPE_MAX;
152                 tcam_cfg.cfg = tf_tcam_p4;
153                 tcam_cfg.shadow_copy = shadow_copy;
154                 tcam_cfg.resources = resources;
155                 tcam_cfg.wc_num_slices = wc_num_slices;
156 #ifdef TF_TCAM_SHARED
157                 rc = tf_tcam_shared_bind(tfp, &tcam_cfg);
158 #else /* !TF_TCAM_SHARED */
159                 rc = tf_tcam_bind(tfp, &tcam_cfg);
160 #endif
161                 if (rc) {
162                         TFP_DRV_LOG(ERR,
163                                     "TCAM initialization failure\n");
164                         goto fail;
165                 }
166                 no_rsv_flag = false;
167         }
168
169         /*
170          * EEM
171          */
172
173         em_cfg.cfg = tf_em_ext_p4;
174         rsv_cnt = tf_dev_reservation_check(TF_EM_TBL_TYPE_MAX,
175                                            em_cfg.cfg,
176                                            (uint16_t *)resources->em_cnt);
177         if (rsv_cnt) {
178                 em_cfg.num_elements = TF_EM_TBL_TYPE_MAX;
179                 em_cfg.resources = resources;
180                 em_cfg.mem_type = TF_EEM_MEM_TYPE_HOST;
181                 rc = tf_em_ext_common_bind(tfp, &em_cfg);
182                 if (rc) {
183                         TFP_DRV_LOG(ERR,
184                                     "EEM initialization failure\n");
185                         goto fail;
186                 }
187                 no_rsv_flag = false;
188         }
189
190         /*
191          * EM
192          */
193         rsv_cnt = tf_dev_reservation_check(TF_EM_TBL_TYPE_MAX,
194                                            tf_em_int_p4,
195                                            (uint16_t *)resources->em_cnt);
196         if (rsv_cnt) {
197                 em_cfg.num_elements = TF_EM_TBL_TYPE_MAX;
198                 em_cfg.cfg = tf_em_int_p4;
199                 em_cfg.resources = resources;
200                 em_cfg.mem_type = 0; /* Not used by EM */
201
202                 rc = tf_em_int_bind(tfp, &em_cfg);
203                 if (rc) {
204                         TFP_DRV_LOG(ERR,
205                                     "EM initialization failure\n");
206                         goto fail;
207                 }
208                 no_rsv_flag = false;
209         }
210
211         /*
212          * There is no rm reserved for any tables
213          *
214          */
215         if (no_rsv_flag) {
216                 TFP_DRV_LOG(ERR,
217                             "No rm reserved for any tables\n");
218                 return -ENOMEM;
219         }
220
221         /*
222          * IF_TBL
223          */
224         if_tbl_cfg.num_elements = TF_IF_TBL_TYPE_MAX;
225         if_tbl_cfg.cfg = tf_if_tbl_p4;
226         if_tbl_cfg.shadow_copy = shadow_copy;
227         rc = tf_if_tbl_bind(tfp, &if_tbl_cfg);
228         if (rc) {
229                 TFP_DRV_LOG(ERR,
230                             "IF Table initialization failure\n");
231                 goto fail;
232         }
233
234         if (!tf_session_is_shared_session(tfs)) {
235                 /*
236                  * GLOBAL_CFG
237                  */
238                 global_cfg.num_elements = TF_GLOBAL_CFG_TYPE_MAX;
239                 global_cfg.cfg = tf_global_cfg_p4;
240                 rc = tf_global_cfg_bind(tfp, &global_cfg);
241                 if (rc) {
242                         TFP_DRV_LOG(ERR,
243                                     "Global Cfg initialization failure\n");
244                         goto fail;
245                 }
246         }
247         /* Final function initialization */
248         dev_handle->ops = &tf_dev_ops_p4;
249
250         return 0;
251
252  fail:
253         /* Cleanup of already created modules */
254         frc = tf_dev_unbind_p4(tfp);
255         if (frc)
256                 return frc;
257
258         return rc;
259 }
260
261 /**
262  * Device specific unbind function, WH+
263  *
264  * [in] tfp
265  *   Pointer to TF handle
266  *
267  * Returns
268  *   - (0) if successful.
269  *   - (-EINVAL) on failure.
270  */
271 static int
272 tf_dev_unbind_p4(struct tf *tfp)
273 {
274         int rc = 0;
275         bool fail = false;
276         struct tf_session *tfs;
277
278         /* Retrieve the session information */
279         rc = tf_session_get_session_internal(tfp, &tfs);
280         if (rc)
281                 return rc;
282
283         /* Unbind all the support modules. As this is only done on
284          * close we only report errors as everything has to be cleaned
285          * up regardless.
286          *
287          * In case of residuals TCAMs are cleaned up first as to
288          * invalidate the pipeline in a clean manner.
289          */
290 #ifdef TF_TCAM_SHARED
291         rc = tf_tcam_shared_unbind(tfp);
292 #else /* !TF_TCAM_SHARED */
293         rc = tf_tcam_unbind(tfp);
294 #endif /* TF_TCAM_SHARED */
295         if (rc) {
296                 TFP_DRV_LOG(INFO,
297                             "Device unbind failed, TCAM\n");
298                 fail = true;
299         }
300
301         rc = tf_ident_unbind(tfp);
302         if (rc) {
303                 TFP_DRV_LOG(INFO,
304                             "Device unbind failed, Identifier\n");
305                 fail = true;
306         }
307
308         rc = tf_tbl_unbind(tfp);
309         if (rc) {
310                 TFP_DRV_LOG(INFO,
311                             "Device unbind failed, Table Type\n");
312                 fail = true;
313         }
314
315         rc = tf_em_ext_common_unbind(tfp);
316         if (rc) {
317                 TFP_DRV_LOG(INFO,
318                             "Device unbind failed, EEM\n");
319                 fail = true;
320         }
321
322         rc = tf_em_int_unbind(tfp);
323         if (rc) {
324                 TFP_DRV_LOG(INFO,
325                             "Device unbind failed, EM\n");
326                 fail = true;
327         }
328
329         if (!tf_session_is_shared_session(tfs)) {
330                 rc = tf_if_tbl_unbind(tfp);
331                 if (rc) {
332                         TFP_DRV_LOG(INFO,
333                                     "Device unbind failed, IF Table Type\n");
334                         fail = true;
335                 }
336
337                 rc = tf_global_cfg_unbind(tfp);
338                 if (rc) {
339                         TFP_DRV_LOG(INFO,
340                                     "Device unbind failed, Global Cfg Type\n");
341                         fail = true;
342                 }
343         }
344
345         if (fail)
346                 return -1;
347
348         return rc;
349 }
350
351 /**
352  * Device specific bind function, THOR
353  *
354  * [in] tfp
355  *   Pointer to TF handle
356  *
357  * [in] shadow_copy
358  *   Flag controlling shadow copy DB creation
359  *
360  * [in] resources
361  *   Pointer to resource allocation information
362  *
363  * [out] dev_handle
364  *   Device handle
365  *
366  * Returns
367  *   - (0) if successful.
368  *   - (-EINVAL) on parameter or internal failure.
369  */
370 static int
371 tf_dev_bind_p58(struct tf *tfp,
372                 bool shadow_copy,
373                 struct tf_session_resources *resources,
374                 struct tf_dev_info *dev_handle,
375                 enum tf_wc_num_slice wc_num_slices)
376 {
377         int rc;
378         int frc;
379         int rsv_cnt;
380         bool no_rsv_flag = true;
381         struct tf_ident_cfg_parms ident_cfg;
382         struct tf_tbl_cfg_parms tbl_cfg;
383         struct tf_tcam_cfg_parms tcam_cfg;
384         struct tf_em_cfg_parms em_cfg;
385         struct tf_if_tbl_cfg_parms if_tbl_cfg;
386         struct tf_global_cfg_cfg_parms global_cfg;
387         struct tf_session *tfs;
388
389         /* Initial function initialization */
390         dev_handle->ops = &tf_dev_ops_p58_init;
391
392         /* Retrieve the session information */
393         rc = tf_session_get_session_internal(tfp, &tfs);
394         if (rc)
395                 return rc;
396
397         rsv_cnt = tf_dev_reservation_check(TF_IDENT_TYPE_MAX,
398                                            tf_ident_p58,
399                                            (uint16_t *)resources->ident_cnt);
400         if (rsv_cnt) {
401                 ident_cfg.num_elements = TF_IDENT_TYPE_MAX;
402                 ident_cfg.cfg = tf_ident_p58;
403                 ident_cfg.shadow_copy = shadow_copy;
404                 ident_cfg.resources = resources;
405                 rc = tf_ident_bind(tfp, &ident_cfg);
406                 if (rc) {
407                         TFP_DRV_LOG(ERR,
408                                     "Identifier initialization failure\n");
409                         goto fail;
410                 }
411                 no_rsv_flag = false;
412         }
413
414         rsv_cnt = tf_dev_reservation_check(TF_TBL_TYPE_MAX,
415                                            tf_tbl_p58[TF_DIR_RX],
416                                            (uint16_t *)resources->tbl_cnt);
417         rsv_cnt += tf_dev_reservation_check(TF_TBL_TYPE_MAX,
418                                            tf_tbl_p58[TF_DIR_TX],
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[TF_DIR_RX];
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 }