net/sfc/base: provide proxy APIs to client drivers
[dpdk.git] / drivers / net / sfc / base / efx_proxy.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright (c) 2018-2019 Solarflare Communications Inc.
4  * All rights reserved.
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 };
23 #endif /* EFSYS_OPT_SIENA */
24
25 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
26 static const efx_proxy_ops_t                    __efx_proxy_ef10_ops = {
27         ef10_proxy_auth_init,                   /* epo_init */
28         ef10_proxy_auth_fini,                   /* epo_fini */
29         ef10_proxy_auth_mc_config,              /* epo_mc_config */
30         ef10_proxy_auth_disable,                /* epo_disable */
31         ef10_proxy_auth_privilege_modify,       /* epo_privilege_modify */
32         ef10_proxy_auth_set_privilege_mask,     /* epo_set_privilege_mask */
33         ef10_proxy_auth_complete_request,       /* epo_complete_request */
34         ef10_proxy_auth_exec_cmd,               /* epo_exec_cmd */
35 };
36 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */
37
38         __checkReturn   efx_rc_t
39 efx_proxy_auth_init(
40         __in            efx_nic_t *enp)
41 {
42         const efx_proxy_ops_t *epop;
43         efx_rc_t rc;
44
45         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
46         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
47         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_PROXY));
48
49         switch (enp->en_family) {
50 #if EFSYS_OPT_SIENA
51         case EFX_FAMILY_SIENA:
52                 epop = &__efx_proxy_dummy_ops;
53                 break;
54 #endif /* EFSYS_OPT_SIENA */
55
56 #if EFSYS_OPT_HUNTINGTON
57         case EFX_FAMILY_HUNTINGTON:
58                 epop = &__efx_proxy_ef10_ops;
59                 break;
60 #endif /* EFSYS_OPT_HUNTINGTON */
61
62 #if EFSYS_OPT_MEDFORD
63         case EFX_FAMILY_MEDFORD:
64                 epop = &__efx_proxy_ef10_ops;
65                 break;
66 #endif /* EFSYS_OPT_MEDFORD */
67
68 #if EFSYS_OPT_MEDFORD2
69         case EFX_FAMILY_MEDFORD2:
70                 epop = &__efx_proxy_ef10_ops;
71                 break;
72 #endif /* EFSYS_OPT_MEDFORD2 */
73
74         default:
75                 EFSYS_ASSERT(0);
76                 rc = ENOTSUP;
77                 goto fail1;
78         }
79
80         if (epop->epo_init == NULL) {
81                 rc = ENOTSUP;
82                 goto fail2;
83         }
84
85         if ((rc = epop->epo_init(enp)) != 0)
86                 goto fail3;
87
88         enp->en_epop = epop;
89         enp->en_mod_flags |= EFX_MOD_PROXY;
90         return (0);
91
92 fail3:
93         EFSYS_PROBE(fail3);
94 fail2:
95         EFSYS_PROBE(fail2);
96 fail1:
97         EFSYS_PROBE1(fail1, efx_rc_t, rc);
98
99         return (rc);
100 }
101
102                         void
103 efx_proxy_auth_fini(
104         __in            efx_nic_t *enp)
105 {
106         const efx_proxy_ops_t *epop = enp->en_epop;
107
108         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
109         EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
110         EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROXY);
111
112         if ((epop != NULL) && (epop->epo_fini != NULL))
113                 epop->epo_fini(enp);
114
115         enp->en_epop = NULL;
116         enp->en_mod_flags &= ~EFX_MOD_PROXY;
117 }
118
119         __checkReturn   efx_rc_t
120 efx_proxy_auth_configure(
121         __in            efx_nic_t *enp,
122         __in            efx_proxy_auth_config_t *configp)
123 {
124         const efx_proxy_ops_t *epop = enp->en_epop;
125         efx_rc_t rc;
126
127         EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROXY);
128
129         if ((configp == NULL) ||
130             (configp->request_bufferp == NULL) ||
131             (configp->response_bufferp == NULL) ||
132             (configp->status_bufferp == NULL) ||
133             (configp->op_listp == NULL) ||
134             (configp->block_cnt == 0)) {
135                 rc = EINVAL;
136                 goto fail1;
137         }
138
139         if ((epop->epo_mc_config == NULL) ||
140             (epop->epo_privilege_modify == NULL)) {
141                 rc = ENOTSUP;
142                 goto fail2;
143         }
144
145         rc = epop->epo_mc_config(enp, configp->request_bufferp,
146                         configp->response_bufferp, configp->status_bufferp,
147                         configp->block_cnt, configp->op_listp,
148                         configp->op_count);
149         if (rc != 0)
150                 goto fail3;
151
152         rc = epop->epo_privilege_modify(enp, MC_CMD_PRIVILEGE_MODIFY_IN_ALL,
153                         0, 0, 0, configp->handled_privileges);
154         if (rc != 0)
155                 goto fail4;
156
157         return (0);
158
159 fail4:
160         EFSYS_PROBE(fail4);
161 fail3:
162         EFSYS_PROBE(fail3);
163 fail2:
164         EFSYS_PROBE(fail2);
165 fail1:
166         EFSYS_PROBE1(fail1, efx_rc_t, rc);
167         return (rc);
168 }
169
170         __checkReturn   efx_rc_t
171 efx_proxy_auth_destroy(
172         __in            efx_nic_t *enp,
173         __in            uint32_t handled_privileges)
174 {
175         const efx_proxy_ops_t *epop = enp->en_epop;
176         efx_rc_t rc;
177
178         EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROXY);
179
180         if ((epop->epo_disable == NULL) ||
181             (epop->epo_privilege_modify == NULL)) {
182                 rc = ENOTSUP;
183                 goto fail1;
184         }
185
186         rc = epop->epo_privilege_modify(enp, MC_CMD_PRIVILEGE_MODIFY_IN_ALL,
187                 0, 0, handled_privileges, 0);
188         if (rc != 0)
189                 goto fail2;
190
191         rc = epop->epo_disable(enp);
192         if (rc != 0)
193                 goto fail3;
194
195         return (0);
196
197 fail3:
198         EFSYS_PROBE(fail3);
199 fail2:
200         EFSYS_PROBE(fail2);
201 fail1:
202         EFSYS_PROBE1(fail1, efx_rc_t, rc);
203         return (rc);
204 }
205
206         __checkReturn   efx_rc_t
207 efx_proxy_auth_complete_request(
208         __in            efx_nic_t *enp,
209         __in            uint32_t fn_index,
210         __in            uint32_t proxy_result,
211         __in            uint32_t handle)
212 {
213         const efx_proxy_ops_t *epop = enp->en_epop;
214         efx_rc_t rc;
215
216         EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROXY);
217
218         if (epop->epo_complete_request == NULL) {
219                 rc = ENOTSUP;
220                 goto fail1;
221         }
222
223         rc = epop->epo_complete_request(enp, fn_index, proxy_result, handle);
224         if (rc != 0)
225                 goto fail2;
226
227         return (0);
228 fail2:
229         EFSYS_PROBE(fail2);
230 fail1:
231         EFSYS_PROBE1(fail1, efx_rc_t, rc);
232         return (rc);
233 }
234
235         __checkReturn   efx_rc_t
236 efx_proxy_auth_exec_cmd(
237         __in            efx_nic_t *enp,
238         __inout         efx_proxy_cmd_params_t *paramsp)
239 {
240         const efx_proxy_ops_t *epop = enp->en_epop;
241         efx_rc_t rc;
242
243         EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROXY);
244
245         if (paramsp == NULL) {
246                 rc = EINVAL;
247                 goto fail1;
248         }
249
250         if (epop->epo_exec_cmd == NULL) {
251                 rc = ENOTSUP;
252                 goto fail2;
253         }
254
255         rc = epop->epo_exec_cmd(enp, paramsp);
256         if (rc != 0)
257                 goto fail3;
258
259         return (0);
260 fail3:
261         EFSYS_PROBE(fail3);
262 fail2:
263         EFSYS_PROBE(fail2);
264 fail1:
265         EFSYS_PROBE1(fail1, efx_rc_t, rc);
266         return (rc);
267 }
268
269         __checkReturn   efx_rc_t
270 efx_proxy_auth_set_privilege_mask(
271         __in            efx_nic_t *enp,
272         __in            uint32_t vf_index,
273         __in            uint32_t mask,
274         __in            uint32_t value)
275 {
276         const efx_proxy_ops_t *epop = enp->en_epop;
277         efx_rc_t rc;
278
279         EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROXY);
280
281         if (epop->epo_set_privilege_mask == NULL) {
282                 rc = ENOTSUP;
283                 goto fail1;
284         }
285
286         rc = epop->epo_set_privilege_mask(enp, vf_index, mask, value);
287         if (rc != 0)
288                 goto fail2;
289
290         return (0);
291
292 fail2:
293         EFSYS_PROBE(fail2);
294 fail1:
295         EFSYS_PROBE1(fail1, efx_rc_t, rc);
296         return (rc);
297 }
298
299
300 #endif /* EFSYS_OPT_MCDI_PROXY_AUTH_SERVER */