1 /* SPDX-License-Identifier: BSD-3-Clause
2 *
3 * Copyright(c) 2019-2021 Xilinx, Inc.
4 * Copyright(c) 2018-2019 Solarflare Communications Inc.
5 */
6
7 #include "efx.h"
8 #include "efx_impl.h"
9
10 #if EFSYS_OPT_MCDI_PROXY_AUTH_SERVER
11
12 #if EFSYS_OPT_SIENA
13 static const efx_proxy_ops_t __efx_proxy_dummy_ops = {
14 NULL, /* epo_init */
15 NULL, /* epo_fini */
16 NULL, /* epo_mc_config */
17 NULL, /* epo_disable */
18 NULL, /* epo_privilege_modify */
19 NULL, /* epo_set_privilege_mask */
20 NULL, /* epo_complete_request */
21 NULL, /* epo_exec_cmd */
22 NULL, /* epo_get_privilege_mask */
23 };
24 #endif /* EFSYS_OPT_SIENA */
25
26 #if EFX_OPTS_EF10()
27 static const efx_proxy_ops_t __efx_proxy_ef10_ops = {
28 ef10_proxy_auth_init, /* epo_init */
29 ef10_proxy_auth_fini, /* epo_fini */
30 ef10_proxy_auth_mc_config, /* epo_mc_config */
31 ef10_proxy_auth_disable, /* epo_disable */
32 ef10_proxy_auth_privilege_modify, /* epo_privilege_modify */
33 ef10_proxy_auth_set_privilege_mask, /* epo_set_privilege_mask */
34 ef10_proxy_auth_complete_request, /* epo_complete_request */
35 ef10_proxy_auth_exec_cmd, /* epo_exec_cmd */
36 ef10_proxy_auth_get_privilege_mask, /* epo_get_privilege_mask */
37 };
38 #endif /* EFX_OPTS_EF10() */
39
40 __checkReturn efx_rc_t
efx_proxy_auth_init(__in efx_nic_t * enp)41 efx_proxy_auth_init(
42 __in efx_nic_t *enp)
43 {
44 const efx_proxy_ops_t *epop;
45 efx_rc_t rc;
46
47 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
48 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
49 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_PROXY));
50
51 switch (enp->en_family) {
52 #if EFSYS_OPT_SIENA
53 case EFX_FAMILY_SIENA:
54 epop = &__efx_proxy_dummy_ops;
55 break;
56 #endif /* EFSYS_OPT_SIENA */
57
58 #if EFSYS_OPT_HUNTINGTON
59 case EFX_FAMILY_HUNTINGTON:
60 epop = &__efx_proxy_ef10_ops;
61 break;
62 #endif /* EFSYS_OPT_HUNTINGTON */
63
64 #if EFSYS_OPT_MEDFORD
65 case EFX_FAMILY_MEDFORD:
66 epop = &__efx_proxy_ef10_ops;
67 break;
68 #endif /* EFSYS_OPT_MEDFORD */
69
70 #if EFSYS_OPT_MEDFORD2
71 case EFX_FAMILY_MEDFORD2:
72 epop = &__efx_proxy_ef10_ops;
73 break;
74 #endif /* EFSYS_OPT_MEDFORD2 */
75
76 default:
77 EFSYS_ASSERT(0);
78 rc = ENOTSUP;
79 goto fail1;
80 }
81
82 if (epop->epo_init == NULL) {
83 rc = ENOTSUP;
84 goto fail2;
85 }
86
87 if ((rc = epop->epo_init(enp)) != 0)
88 goto fail3;
89
90 enp->en_epop = epop;
91 enp->en_mod_flags |= EFX_MOD_PROXY;
92 return (0);
93
94 fail3:
95 EFSYS_PROBE(fail3);
96 fail2:
97 EFSYS_PROBE(fail2);
98 fail1:
99 EFSYS_PROBE1(fail1, efx_rc_t, rc);
100
101 return (rc);
102 }
103
104 void
efx_proxy_auth_fini(__in efx_nic_t * enp)105 efx_proxy_auth_fini(
106 __in efx_nic_t *enp)
107 {
108 const efx_proxy_ops_t *epop = enp->en_epop;
109
110 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
111 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
112 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROXY);
113
114 if ((epop != NULL) && (epop->epo_fini != NULL))
115 epop->epo_fini(enp);
116
117 enp->en_epop = NULL;
118 enp->en_mod_flags &= ~EFX_MOD_PROXY;
119 }
120
121 __checkReturn efx_rc_t
efx_proxy_auth_configure(__in efx_nic_t * enp,__in efx_proxy_auth_config_t * configp)122 efx_proxy_auth_configure(
123 __in efx_nic_t *enp,
124 __in efx_proxy_auth_config_t *configp)
125 {
126 const efx_proxy_ops_t *epop = enp->en_epop;
127 efx_rc_t rc;
128
129 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROXY);
130
131 if ((configp == NULL) ||
132 (configp->request_bufferp == NULL) ||
133 (configp->response_bufferp == NULL) ||
134 (configp->status_bufferp == NULL) ||
135 (configp->op_listp == NULL) ||
136 (configp->block_cnt == 0)) {
137 rc = EINVAL;
138 goto fail1;
139 }
140
141 if ((epop->epo_mc_config == NULL) ||
142 (epop->epo_privilege_modify == NULL)) {
143 rc = ENOTSUP;
144 goto fail2;
145 }
146
147 rc = epop->epo_mc_config(enp, configp->request_bufferp,
148 configp->response_bufferp, configp->status_bufferp,
149 configp->block_cnt, configp->op_listp,
150 configp->op_count);
151 if (rc != 0)
152 goto fail3;
153
154 rc = epop->epo_privilege_modify(enp, MC_CMD_PRIVILEGE_MODIFY_IN_ALL,
155 0, 0, 0, configp->handled_privileges);
156 if (rc != 0)
157 goto fail4;
158
159 return (0);
160
161 fail4:
162 EFSYS_PROBE(fail4);
163 fail3:
164 EFSYS_PROBE(fail3);
165 fail2:
166 EFSYS_PROBE(fail2);
167 fail1:
168 EFSYS_PROBE1(fail1, efx_rc_t, rc);
169 return (rc);
170 }
171
172 __checkReturn efx_rc_t
efx_proxy_auth_destroy(__in efx_nic_t * enp,__in uint32_t handled_privileges)173 efx_proxy_auth_destroy(
174 __in efx_nic_t *enp,
175 __in uint32_t handled_privileges)
176 {
177 const efx_proxy_ops_t *epop = enp->en_epop;
178 efx_rc_t rc;
179
180 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROXY);
181
182 if ((epop->epo_disable == NULL) ||
183 (epop->epo_privilege_modify == NULL)) {
184 rc = ENOTSUP;
185 goto fail1;
186 }
187
188 rc = epop->epo_privilege_modify(enp, MC_CMD_PRIVILEGE_MODIFY_IN_ALL,
189 0, 0, handled_privileges, 0);
190 if (rc != 0)
191 goto fail2;
192
193 rc = epop->epo_disable(enp);
194 if (rc != 0)
195 goto fail3;
196
197 return (0);
198
199 fail3:
200 EFSYS_PROBE(fail3);
201 fail2:
202 EFSYS_PROBE(fail2);
203 fail1:
204 EFSYS_PROBE1(fail1, efx_rc_t, rc);
205 return (rc);
206 }
207
208 __checkReturn efx_rc_t
efx_proxy_auth_complete_request(__in efx_nic_t * enp,__in uint32_t fn_index,__in uint32_t proxy_result,__in uint32_t handle)209 efx_proxy_auth_complete_request(
210 __in efx_nic_t *enp,
211 __in uint32_t fn_index,
212 __in uint32_t proxy_result,
213 __in uint32_t handle)
214 {
215 const efx_proxy_ops_t *epop = enp->en_epop;
216 efx_rc_t rc;
217
218 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROXY);
219
220 if (epop->epo_complete_request == NULL) {
221 rc = ENOTSUP;
222 goto fail1;
223 }
224
225 rc = epop->epo_complete_request(enp, fn_index, proxy_result, handle);
226 if (rc != 0)
227 goto fail2;
228
229 return (0);
230 fail2:
231 EFSYS_PROBE(fail2);
232 fail1:
233 EFSYS_PROBE1(fail1, efx_rc_t, rc);
234 return (rc);
235 }
236
237 __checkReturn efx_rc_t
efx_proxy_auth_exec_cmd(__in efx_nic_t * enp,__inout efx_proxy_cmd_params_t * paramsp)238 efx_proxy_auth_exec_cmd(
239 __in efx_nic_t *enp,
240 __inout efx_proxy_cmd_params_t *paramsp)
241 {
242 const efx_proxy_ops_t *epop = enp->en_epop;
243 efx_rc_t rc;
244
245 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROXY);
246
247 if (paramsp == NULL) {
248 rc = EINVAL;
249 goto fail1;
250 }
251
252 if (epop->epo_exec_cmd == NULL) {
253 rc = ENOTSUP;
254 goto fail2;
255 }
256
257 rc = epop->epo_exec_cmd(enp, paramsp);
258 if (rc != 0)
259 goto fail3;
260
261 return (0);
262 fail3:
263 EFSYS_PROBE(fail3);
264 fail2:
265 EFSYS_PROBE(fail2);
266 fail1:
267 EFSYS_PROBE1(fail1, efx_rc_t, rc);
268 return (rc);
269 }
270
271 __checkReturn efx_rc_t
efx_proxy_auth_set_privilege_mask(__in efx_nic_t * enp,__in uint32_t vf_index,__in uint32_t mask,__in uint32_t value)272 efx_proxy_auth_set_privilege_mask(
273 __in efx_nic_t *enp,
274 __in uint32_t vf_index,
275 __in uint32_t mask,
276 __in uint32_t value)
277 {
278 const efx_proxy_ops_t *epop = enp->en_epop;
279 efx_rc_t rc;
280
281 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROXY);
282
283 if (epop->epo_set_privilege_mask == NULL) {
284 rc = ENOTSUP;
285 goto fail1;
286 }
287
288 rc = epop->epo_set_privilege_mask(enp, vf_index, mask, value);
289 if (rc != 0)
290 goto fail2;
291
292 return (0);
293
294 fail2:
295 EFSYS_PROBE(fail2);
296 fail1:
297 EFSYS_PROBE1(fail1, efx_rc_t, rc);
298 return (rc);
299 }
300
301 __checkReturn efx_rc_t
efx_proxy_auth_privilege_mask_get(__in efx_nic_t * enp,__in uint32_t pf_index,__in uint32_t vf_index,__out uint32_t * maskp)302 efx_proxy_auth_privilege_mask_get(
303 __in efx_nic_t *enp,
304 __in uint32_t pf_index,
305 __in uint32_t vf_index,
306 __out uint32_t *maskp)
307 {
308 const efx_proxy_ops_t *epop = enp->en_epop;
309 efx_rc_t rc;
310
311 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROXY);
312
313 if (epop->epo_get_privilege_mask == NULL) {
314 rc = ENOTSUP;
315 goto fail1;
316 }
317
318 rc = epop->epo_get_privilege_mask(enp, pf_index, vf_index, maskp);
319 if (rc != 0)
320 goto fail2;
321
322 return (0);
323
324 fail2:
325 EFSYS_PROBE(fail2);
326 fail1:
327 EFSYS_PROBE1(fail1, efx_rc_t, rc);
328 return (rc);
329 }
330
331 __checkReturn efx_rc_t
efx_proxy_auth_privilege_modify(__in efx_nic_t * enp,__in uint32_t pf_index,__in uint32_t vf_index,__in uint32_t add_privileges_mask,__in uint32_t remove_privileges_mask)332 efx_proxy_auth_privilege_modify(
333 __in efx_nic_t *enp,
334 __in uint32_t pf_index,
335 __in uint32_t vf_index,
336 __in uint32_t add_privileges_mask,
337 __in uint32_t remove_privileges_mask)
338 {
339 const efx_proxy_ops_t *epop = enp->en_epop;
340 efx_rc_t rc;
341
342 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROXY);
343
344 if (epop->epo_privilege_modify == NULL) {
345 rc = ENOTSUP;
346 goto fail1;
347 }
348
349 rc = epop->epo_privilege_modify(enp, MC_CMD_PRIVILEGE_MODIFY_IN_ONE,
350 pf_index, vf_index, add_privileges_mask,
351 remove_privileges_mask);
352 if (rc != 0)
353 goto fail2;
354
355 return (0);
356
357 fail2:
358 EFSYS_PROBE(fail2);
359 fail1:
360 EFSYS_PROBE1(fail1, efx_rc_t, rc);
361 return (rc);
362 }
363
364 #endif /* EFSYS_OPT_MCDI_PROXY_AUTH_SERVER */
365