common/sfc_efx/base: update EF100 registers definitions
[dpdk.git] / drivers / common / sfc_efx / base / efx_virtio.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2020-2021 Xilinx, Inc.
4  */
5
6 #include "efx.h"
7 #include "efx_impl.h"
8
9 #if EFSYS_OPT_VIRTIO
10
11 #if EFSYS_OPT_RIVERHEAD
12 static const efx_virtio_ops_t   __efx_virtio_rhead_ops = {
13         rhead_virtio_qstart,                    /* evo_virtio_qstart */
14         rhead_virtio_qstop,                     /* evo_virtio_qstop */
15         rhead_virtio_get_doorbell_offset,       /* evo_get_doorbell_offset */
16         rhead_virtio_get_features,              /* evo_get_features */
17         rhead_virtio_verify_features,           /* evo_verify_features */
18 };
19 #endif /* EFSYS_OPT_RIVERHEAD */
20
21         __checkReturn   efx_rc_t
22 efx_virtio_init(
23         __in            efx_nic_t *enp)
24 {
25         const efx_virtio_ops_t *evop;
26         efx_rc_t rc;
27
28         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
29         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
30         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_VIRTIO));
31
32         switch (enp->en_family) {
33 #if EFSYS_OPT_RIVERHEAD
34         case EFX_FAMILY_RIVERHEAD:
35                 evop = &__efx_virtio_rhead_ops;
36                 break;
37 #endif /* EFSYS_OPT_RIVERHEAD */
38
39         default:
40                 EFSYS_ASSERT(0);
41                 rc = ENOTSUP;
42                 goto fail1;
43         }
44
45         enp->en_evop = evop;
46         enp->en_mod_flags |= EFX_MOD_VIRTIO;
47
48         return (0);
49
50 fail1:
51         EFSYS_PROBE1(fail1, efx_rc_t, rc);
52
53         enp->en_evop = NULL;
54         enp->en_mod_flags &= ~EFX_MOD_VIRTIO;
55
56         return (rc);
57 }
58
59         void
60 efx_virtio_fini(
61         __in            efx_nic_t *enp)
62 {
63         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
64         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
65         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_VIRTIO);
66
67         enp->en_evop = NULL;
68         enp->en_mod_flags &= ~EFX_MOD_VIRTIO;
69 }
70
71         __checkReturn   efx_rc_t
72 efx_virtio_qcreate(
73         __in            efx_nic_t *enp,
74         __deref_out     efx_virtio_vq_t **evvpp)
75 {
76         const efx_virtio_ops_t *evop = enp->en_evop;
77         efx_virtio_vq_t *evvp;
78         efx_rc_t rc;
79
80         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
81         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_VIRTIO);
82
83         /* Allocate a virtqueue object */
84         EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_virtio_vq_t), evvp);
85         if (evvp == NULL) {
86                 rc = ENOMEM;
87                 goto fail1;
88         }
89
90         evvp->evv_magic = EFX_VQ_MAGIC;
91         evvp->evv_enp = enp;
92         evvp->evv_state = EFX_VIRTIO_VQ_STATE_INITIALIZED;
93
94         *evvpp = evvp;
95
96         return (0);
97
98 fail1:
99         EFSYS_PROBE1(fail1, efx_rc_t, rc);
100
101         return (rc);
102 }
103
104         __checkReturn   efx_rc_t
105 efx_virtio_qstart(
106         __in            efx_virtio_vq_t *evvp,
107         __in            efx_virtio_vq_cfg_t *evvcp,
108         __in_opt        efx_virtio_vq_dyncfg_t *evvdp)
109 {
110         const efx_virtio_ops_t *evop;
111         efx_rc_t rc;
112
113         if ((evvcp == NULL) || (evvp == NULL)) {
114                 rc = EINVAL;
115                 goto fail1;
116         }
117
118         if (evvp->evv_state != EFX_VIRTIO_VQ_STATE_INITIALIZED) {
119                 rc = EINVAL;
120                 goto fail2;
121         }
122
123         evop = evvp->evv_enp->en_evop;
124         if (evop == NULL) {
125                 rc = ENOTSUP;
126                 goto fail3;
127         }
128
129         if ((rc = evop->evo_virtio_qstart(evvp, evvcp, evvdp)) != 0)
130                 goto fail4;
131
132         evvp->evv_type = evvcp->evvc_type;
133         evvp->evv_target_vf = evvcp->evvc_target_vf;
134         evvp->evv_state = EFX_VIRTIO_VQ_STATE_STARTED;
135
136         return (0);
137
138 fail4:
139         EFSYS_PROBE(fail4);
140 fail3:
141         EFSYS_PROBE(fail3);
142 fail2:
143         EFSYS_PROBE(fail2);
144 fail1:
145         EFSYS_PROBE1(fail1, efx_rc_t, rc);
146
147         return (rc);
148 }
149
150         __checkReturn   efx_rc_t
151 efx_virtio_qstop(
152         __in            efx_virtio_vq_t *evvp,
153         __out_opt       efx_virtio_vq_dyncfg_t *evvdp)
154 {
155         efx_nic_t *enp;
156         const efx_virtio_ops_t *evop;
157         efx_rc_t rc;
158
159         if (evvp == NULL) {
160                 rc = EINVAL;
161                 goto fail1;
162         }
163
164         enp = evvp->evv_enp;
165         evop = enp->en_evop;
166
167         EFSYS_ASSERT3U(evvp->evv_magic, ==, EFX_VQ_MAGIC);
168         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
169         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_VIRTIO);
170
171         if (evop == NULL) {
172                 rc = ENOTSUP;
173                 goto fail2;
174         }
175
176         if (evvp->evv_state != EFX_VIRTIO_VQ_STATE_STARTED) {
177                 rc = EINVAL;
178                 goto fail3;
179         }
180
181         if ((rc = evop->evo_virtio_qstop(evvp, evvdp)) != 0)
182                 goto fail4;
183
184         evvp->evv_state = EFX_VIRTIO_VQ_STATE_INITIALIZED;
185
186         return 0;
187
188 fail4:
189         EFSYS_PROBE(fail4);
190 fail3:
191         EFSYS_PROBE(fail3);
192 fail2:
193         EFSYS_PROBE(fail2);
194 fail1:
195         EFSYS_PROBE1(fail1, efx_rc_t, rc);
196
197         return (rc);
198 }
199
200         void
201 efx_virtio_qdestroy(
202         __in            efx_virtio_vq_t *evvp)
203 {
204         efx_nic_t *enp;
205
206         if (evvp == NULL)
207                 return;
208
209         enp = evvp->evv_enp;
210
211         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
212
213         if (evvp->evv_state == EFX_VIRTIO_VQ_STATE_INITIALIZED) {
214                 /* Free the virtqueue object */
215                 EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_virtio_vq_t), evvp);
216         }
217 }
218
219         __checkReturn   efx_rc_t
220 efx_virtio_get_doorbell_offset(
221         __in            efx_virtio_vq_t *evvp,
222         __out           uint32_t *offsetp)
223 {
224         efx_nic_t *enp;
225         const efx_virtio_ops_t *evop;
226         efx_rc_t rc;
227
228         if ((evvp == NULL) || (offsetp == NULL)) {
229                 rc = EINVAL;
230                 goto fail1;
231         }
232
233         enp = evvp->evv_enp;
234         evop = enp->en_evop;
235
236         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
237         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_VIRTIO);
238
239         if (evop == NULL) {
240                 rc = ENOTSUP;
241                 goto fail2;
242         }
243
244         if ((rc = evop->evo_get_doorbell_offset(evvp, offsetp)) != 0)
245                 goto fail3;
246
247         return (0);
248
249 fail3:
250         EFSYS_PROBE(fail3);
251 fail2:
252         EFSYS_PROBE(fail2);
253 fail1:
254         EFSYS_PROBE1(fail1, efx_rc_t, rc);
255
256         return (rc);
257 }
258
259         __checkReturn   efx_rc_t
260 efx_virtio_get_features(
261         __in            efx_nic_t *enp,
262         __in            efx_virtio_device_type_t type,
263         __out           uint64_t *featuresp)
264 {
265         const efx_virtio_ops_t *evop = enp->en_evop;
266         efx_rc_t rc;
267
268         if (featuresp == NULL) {
269                 rc = EINVAL;
270                 goto fail1;
271         }
272
273         if (type >= EFX_VIRTIO_DEVICE_NTYPES) {
274                 rc = EINVAL;
275                 goto fail2;
276         }
277
278         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
279         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_VIRTIO);
280
281         if (evop == NULL) {
282                 rc = ENOTSUP;
283                 goto fail3;
284         }
285
286         if ((rc = evop->evo_get_features(enp, type, featuresp)) != 0)
287                 goto fail4;
288
289         return (0);
290
291 fail4:
292         EFSYS_PROBE(fail4);
293 fail3:
294         EFSYS_PROBE(fail3);
295 fail2:
296         EFSYS_PROBE(fail2);
297 fail1:
298         EFSYS_PROBE1(fail1, efx_rc_t, rc);
299
300         return (rc);
301 }
302
303         __checkReturn   efx_rc_t
304 efx_virtio_verify_features(
305         __in            efx_nic_t *enp,
306         __in            efx_virtio_device_type_t type,
307         __in            uint64_t features)
308 {
309         const efx_virtio_ops_t *evop = enp->en_evop;
310         efx_rc_t rc;
311
312         if (type >= EFX_VIRTIO_DEVICE_NTYPES) {
313                 rc = EINVAL;
314                 goto fail1;
315         }
316
317         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
318         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_VIRTIO);
319
320         if (evop == NULL) {
321                 rc = ENOTSUP;
322                 goto fail2;
323         }
324
325         if ((rc = evop->evo_verify_features(enp, type, features)) != 0)
326                 goto fail3;
327
328         return (0);
329
330 fail3:
331         EFSYS_PROBE(fail3);
332 fail2:
333         EFSYS_PROBE(fail2);
334 fail1:
335         EFSYS_PROBE1(fail1, efx_rc_t, rc);
336
337         return (rc);
338 }
339
340 #endif /* EFSYS_OPT_VIRTIO */