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