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