net/sfc: introduce common driver library
[dpdk.git] / drivers / common / sfc_efx / base / efx_proxy.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2019-2020 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
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
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
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
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
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
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
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
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
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 */