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
tf_dev_bind_p4(struct tf * tfp,bool shadow_copy,struct tf_session_resources * resources,struct tf_dev_info * dev_handle)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 struct tf_global_cfg_cfg_parms global_cfg;
49
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 if (dev_handle->type == TF_DEVICE_TYPE_WH)
93 em_cfg.cfg = tf_em_ext_p4;
94 else
95 em_cfg.cfg = tf_em_ext_p45;
96 em_cfg.resources = resources;
97 em_cfg.mem_type = TF_EEM_MEM_TYPE_HOST;
98 rc = tf_em_ext_common_bind(tfp, &em_cfg);
99 if (rc) {
100 TFP_DRV_LOG(ERR,
101 "EEM initialization failure\n");
102 goto fail;
103 }
104
105 /*
106 * EM
107 */
108 em_cfg.num_elements = TF_EM_TBL_TYPE_MAX;
109 em_cfg.cfg = tf_em_int_p4;
110 em_cfg.resources = resources;
111 em_cfg.mem_type = 0; /* Not used by EM */
112
113 rc = tf_em_int_bind(tfp, &em_cfg);
114 if (rc) {
115 TFP_DRV_LOG(ERR,
116 "EM initialization failure\n");
117 goto fail;
118 }
119
120 /*
121 * IF_TBL
122 */
123 if_tbl_cfg.num_elements = TF_IF_TBL_TYPE_MAX;
124 if_tbl_cfg.cfg = tf_if_tbl_p4;
125 if_tbl_cfg.shadow_copy = shadow_copy;
126 rc = tf_if_tbl_bind(tfp, &if_tbl_cfg);
127 if (rc) {
128 TFP_DRV_LOG(ERR,
129 "IF Table initialization failure\n");
130 goto fail;
131 }
132
133 /*
134 * GLOBAL_CFG
135 */
136 global_cfg.num_elements = TF_GLOBAL_CFG_TYPE_MAX;
137 global_cfg.cfg = tf_global_cfg_p4;
138 rc = tf_global_cfg_bind(tfp, &global_cfg);
139 if (rc) {
140 TFP_DRV_LOG(ERR,
141 "Global Cfg initialization failure\n");
142 goto fail;
143 }
144
145 /* Final function initialization */
146 dev_handle->ops = &tf_dev_ops_p4;
147
148 return 0;
149
150 fail:
151 /* Cleanup of already created modules */
152 frc = tf_dev_unbind_p4(tfp);
153 if (frc)
154 return frc;
155
156 return rc;
157 }
158
159 /**
160 * Device specific unbind function, WH+
161 *
162 * [in] tfp
163 * Pointer to TF handle
164 *
165 * Returns
166 * - (0) if successful.
167 * - (-EINVAL) on failure.
168 */
169 static int
tf_dev_unbind_p4(struct tf * tfp)170 tf_dev_unbind_p4(struct tf *tfp)
171 {
172 int rc = 0;
173 bool fail = false;
174
175 /* Unbind all the support modules. As this is only done on
176 * close we only report errors as everything has to be cleaned
177 * up regardless.
178 *
179 * In case of residuals TCAMs are cleaned up first as to
180 * invalidate the pipeline in a clean manner.
181 */
182 rc = tf_tcam_unbind(tfp);
183 if (rc) {
184 TFP_DRV_LOG(ERR,
185 "Device unbind failed, TCAM\n");
186 fail = true;
187 }
188
189 rc = tf_ident_unbind(tfp);
190 if (rc) {
191 TFP_DRV_LOG(ERR,
192 "Device unbind failed, Identifier\n");
193 fail = true;
194 }
195
196 rc = tf_tbl_unbind(tfp);
197 if (rc) {
198 TFP_DRV_LOG(ERR,
199 "Device unbind failed, Table Type\n");
200 fail = true;
201 }
202
203 rc = tf_em_ext_common_unbind(tfp);
204 if (rc) {
205 TFP_DRV_LOG(ERR,
206 "Device unbind failed, EEM\n");
207 fail = true;
208 }
209
210 rc = tf_em_int_unbind(tfp);
211 if (rc) {
212 TFP_DRV_LOG(ERR,
213 "Device unbind failed, EM\n");
214 fail = true;
215 }
216
217 rc = tf_if_tbl_unbind(tfp);
218 if (rc) {
219 TFP_DRV_LOG(ERR,
220 "Device unbind failed, IF Table Type\n");
221 fail = true;
222 }
223
224 rc = tf_global_cfg_unbind(tfp);
225 if (rc) {
226 TFP_DRV_LOG(ERR,
227 "Device unbind failed, Global Cfg Type\n");
228 fail = true;
229 }
230
231 if (fail)
232 return -1;
233
234 return rc;
235 }
236
237 int
tf_dev_bind(struct tf * tfp __rte_unused,enum tf_device_type type,bool shadow_copy,struct tf_session_resources * resources,struct tf_dev_info * dev_handle)238 tf_dev_bind(struct tf *tfp __rte_unused,
239 enum tf_device_type type,
240 bool shadow_copy,
241 struct tf_session_resources *resources,
242 struct tf_dev_info *dev_handle)
243 {
244 switch (type) {
245 case TF_DEVICE_TYPE_WH:
246 case TF_DEVICE_TYPE_SR:
247 dev_handle->type = type;
248 return tf_dev_bind_p4(tfp,
249 shadow_copy,
250 resources,
251 dev_handle);
252 default:
253 TFP_DRV_LOG(ERR,
254 "No such device\n");
255 return -ENODEV;
256 }
257 }
258
259 int
tf_dev_unbind(struct tf * tfp,struct tf_dev_info * dev_handle)260 tf_dev_unbind(struct tf *tfp,
261 struct tf_dev_info *dev_handle)
262 {
263 switch (dev_handle->type) {
264 case TF_DEVICE_TYPE_WH:
265 case TF_DEVICE_TYPE_SR:
266 return tf_dev_unbind_p4(tfp);
267 default:
268 TFP_DRV_LOG(ERR,
269 "No such device\n");
270 return -ENODEV;
271 }
272 }
273