net/bnxt: implement IF tables set and get
[dpdk.git] / drivers / net / bnxt / tf_core / tf_device.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019-2020 Broadcom
3  * All rights reserved.
4  */
5
6 #include "tf_device.h"
7 #include "tf_device_p4.h"
8 #include "tfp.h"
9 #include "tf_em.h"
10
11 struct tf;
12
13 /* Forward declarations */
14 static int tf_dev_unbind_p4(struct tf *tfp);
15
16 /**
17  * Device specific bind function, WH+
18  *
19  * [in] tfp
20  *   Pointer to TF handle
21  *
22  * [in] shadow_copy
23  *   Flag controlling shadow copy DB creation
24  *
25  * [in] resources
26  *   Pointer to resource allocation information
27  *
28  * [out] dev_handle
29  *   Device handle
30  *
31  * Returns
32  *   - (0) if successful.
33  *   - (-EINVAL) on parameter or internal failure.
34  */
35 static int
36 tf_dev_bind_p4(struct tf *tfp,
37                bool shadow_copy,
38                struct tf_session_resources *resources,
39                struct tf_dev_info *dev_handle)
40 {
41         int rc;
42         int frc;
43         struct tf_ident_cfg_parms ident_cfg;
44         struct tf_tbl_cfg_parms tbl_cfg;
45         struct tf_tcam_cfg_parms tcam_cfg;
46         struct tf_em_cfg_parms em_cfg;
47         struct tf_if_tbl_cfg_parms if_tbl_cfg;
48
49         dev_handle->type = TF_DEVICE_TYPE_WH;
50         /* Initial function initialization */
51         dev_handle->ops = &tf_dev_ops_p4_init;
52
53         /* Initialize the modules */
54
55         ident_cfg.num_elements = TF_IDENT_TYPE_MAX;
56         ident_cfg.cfg = tf_ident_p4;
57         ident_cfg.shadow_copy = shadow_copy;
58         ident_cfg.resources = resources;
59         rc = tf_ident_bind(tfp, &ident_cfg);
60         if (rc) {
61                 TFP_DRV_LOG(ERR,
62                             "Identifier initialization failure\n");
63                 goto fail;
64         }
65
66         tbl_cfg.num_elements = TF_TBL_TYPE_MAX;
67         tbl_cfg.cfg = tf_tbl_p4;
68         tbl_cfg.shadow_copy = shadow_copy;
69         tbl_cfg.resources = resources;
70         rc = tf_tbl_bind(tfp, &tbl_cfg);
71         if (rc) {
72                 TFP_DRV_LOG(ERR,
73                             "Table initialization failure\n");
74                 goto fail;
75         }
76
77         tcam_cfg.num_elements = TF_TCAM_TBL_TYPE_MAX;
78         tcam_cfg.cfg = tf_tcam_p4;
79         tcam_cfg.shadow_copy = shadow_copy;
80         tcam_cfg.resources = resources;
81         rc = tf_tcam_bind(tfp, &tcam_cfg);
82         if (rc) {
83                 TFP_DRV_LOG(ERR,
84                             "TCAM initialization failure\n");
85                 goto fail;
86         }
87
88         /*
89          * EEM
90          */
91         em_cfg.num_elements = TF_EM_TBL_TYPE_MAX;
92         em_cfg.cfg = tf_em_ext_p4;
93         em_cfg.resources = resources;
94         em_cfg.mem_type = TF_EEM_MEM_TYPE_HOST;
95
96         rc = tf_em_ext_common_bind(tfp, &em_cfg);
97         if (rc) {
98                 TFP_DRV_LOG(ERR,
99                             "EEM initialization failure\n");
100                 goto fail;
101         }
102
103         /*
104          * EM
105          */
106         em_cfg.num_elements = TF_EM_TBL_TYPE_MAX;
107         em_cfg.cfg = tf_em_int_p4;
108         em_cfg.resources = resources;
109         em_cfg.mem_type = 0; /* Not used by EM */
110
111         rc = tf_em_int_bind(tfp, &em_cfg);
112         if (rc) {
113                 TFP_DRV_LOG(ERR,
114                             "EM initialization failure\n");
115                 goto fail;
116         }
117
118         /*
119          * IF_TBL
120          */
121         if_tbl_cfg.num_elements = TF_IF_TBL_TYPE_MAX;
122         if_tbl_cfg.cfg = tf_if_tbl_p4;
123         if_tbl_cfg.shadow_copy = shadow_copy;
124         rc = tf_if_tbl_bind(tfp, &if_tbl_cfg);
125         if (rc) {
126                 TFP_DRV_LOG(ERR,
127                             "IF Table initialization failure\n");
128                 goto fail;
129         }
130
131         /* Final function initialization */
132         dev_handle->ops = &tf_dev_ops_p4;
133
134         return 0;
135
136  fail:
137         /* Cleanup of already created modules */
138         frc = tf_dev_unbind_p4(tfp);
139         if (frc)
140                 return frc;
141
142         return rc;
143 }
144
145 /**
146  * Device specific unbind function, WH+
147  *
148  * [in] tfp
149  *   Pointer to TF handle
150  *
151  * Returns
152  *   - (0) if successful.
153  *   - (-EINVAL) on failure.
154  */
155 static int
156 tf_dev_unbind_p4(struct tf *tfp)
157 {
158         int rc = 0;
159         bool fail = false;
160
161         /* Unbind all the support modules. As this is only done on
162          * close we only report errors as everything has to be cleaned
163          * up regardless.
164          *
165          * In case of residuals TCAMs are cleaned up first as to
166          * invalidate the pipeline in a clean manner.
167          */
168         rc = tf_tcam_unbind(tfp);
169         if (rc) {
170                 TFP_DRV_LOG(ERR,
171                             "Device unbind failed, TCAM\n");
172                 fail = true;
173         }
174
175         rc = tf_ident_unbind(tfp);
176         if (rc) {
177                 TFP_DRV_LOG(ERR,
178                             "Device unbind failed, Identifier\n");
179                 fail = true;
180         }
181
182         rc = tf_tbl_unbind(tfp);
183         if (rc) {
184                 TFP_DRV_LOG(ERR,
185                             "Device unbind failed, Table Type\n");
186                 fail = true;
187         }
188
189         rc = tf_em_ext_common_unbind(tfp);
190         if (rc) {
191                 TFP_DRV_LOG(ERR,
192                             "Device unbind failed, EEM\n");
193                 fail = true;
194         }
195
196         rc = tf_em_int_unbind(tfp);
197         if (rc) {
198                 TFP_DRV_LOG(ERR,
199                             "Device unbind failed, EM\n");
200                 fail = true;
201         }
202
203         rc = tf_if_tbl_unbind(tfp);
204         if (rc) {
205                 TFP_DRV_LOG(ERR,
206                             "Device unbind failed, IF Table Type\n");
207                 fail = true;
208         }
209
210         if (fail)
211                 return -1;
212
213         return rc;
214 }
215
216 int
217 tf_dev_bind(struct tf *tfp __rte_unused,
218             enum tf_device_type type,
219             bool shadow_copy,
220             struct tf_session_resources *resources,
221             struct tf_dev_info *dev_handle)
222 {
223         switch (type) {
224         case TF_DEVICE_TYPE_WH:
225                 return tf_dev_bind_p4(tfp,
226                                       shadow_copy,
227                                       resources,
228                                       dev_handle);
229         default:
230                 TFP_DRV_LOG(ERR,
231                             "No such device\n");
232                 return -ENODEV;
233         }
234 }
235
236 int
237 tf_dev_unbind(struct tf *tfp,
238               struct tf_dev_info *dev_handle)
239 {
240         switch (dev_handle->type) {
241         case TF_DEVICE_TYPE_WH:
242                 return tf_dev_unbind_p4(tfp);
243         default:
244                 TFP_DRV_LOG(ERR,
245                             "No such device\n");
246                 return -ENODEV;
247         }
248 }