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