common/sfc_efx/base: add base virtio support for vDPA
[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 };
16 #endif /* EFSYS_OPT_RIVERHEAD */
17
18         __checkReturn   efx_rc_t
19 efx_virtio_init(
20         __in            efx_nic_t *enp)
21 {
22         const efx_virtio_ops_t *evop;
23         efx_rc_t rc;
24
25         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
26         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
27         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_VIRTIO));
28
29         switch (enp->en_family) {
30 #if EFSYS_OPT_RIVERHEAD
31         case EFX_FAMILY_RIVERHEAD:
32                 evop = &__efx_virtio_rhead_ops;
33                 break;
34 #endif /* EFSYS_OPT_RIVERHEAD */
35
36         default:
37                 EFSYS_ASSERT(0);
38                 rc = ENOTSUP;
39                 goto fail1;
40         }
41
42         enp->en_evop = evop;
43         enp->en_mod_flags |= EFX_MOD_VIRTIO;
44
45         return (0);
46
47 fail1:
48         EFSYS_PROBE1(fail1, efx_rc_t, rc);
49
50         enp->en_evop = NULL;
51         enp->en_mod_flags &= ~EFX_MOD_VIRTIO;
52
53         return (rc);
54 }
55
56         void
57 efx_virtio_fini(
58         __in            efx_nic_t *enp)
59 {
60         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
61         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
62         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_VIRTIO);
63
64         enp->en_evop = NULL;
65         enp->en_mod_flags &= ~EFX_MOD_VIRTIO;
66 }
67
68         __checkReturn   efx_rc_t
69 efx_virtio_qcreate(
70         __in            efx_nic_t *enp,
71         __deref_out     efx_virtio_vq_t **evvpp)
72 {
73         const efx_virtio_ops_t *evop = enp->en_evop;
74         efx_virtio_vq_t *evvp;
75         efx_rc_t rc;
76
77         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
78         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_VIRTIO);
79
80         /* Allocate a virtqueue object */
81         EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_virtio_vq_t), evvp);
82         if (evvp == NULL) {
83                 rc = ENOMEM;
84                 goto fail1;
85         }
86
87         evvp->evv_magic = EFX_VQ_MAGIC;
88         evvp->evv_enp = enp;
89         evvp->evv_state = EFX_VIRTIO_VQ_STATE_INITIALIZED;
90
91         *evvpp = evvp;
92
93         return (0);
94
95 fail1:
96         EFSYS_PROBE1(fail1, efx_rc_t, rc);
97
98         return (rc);
99 }
100
101         __checkReturn   efx_rc_t
102 efx_virtio_qstart(
103         __in            efx_virtio_vq_t *evvp,
104         __in            efx_virtio_vq_cfg_t *evvcp,
105         __in_opt        efx_virtio_vq_dyncfg_t *evvdp)
106 {
107         const efx_virtio_ops_t *evop;
108         efx_rc_t rc;
109
110         if ((evvcp == NULL) || (evvp == NULL)) {
111                 rc = EINVAL;
112                 goto fail1;
113         }
114
115         if (evvp->evv_state != EFX_VIRTIO_VQ_STATE_INITIALIZED) {
116                 rc = EINVAL;
117                 goto fail2;
118         }
119
120         evop = evvp->evv_enp->en_evop;
121         if (evop == NULL) {
122                 rc = ENOTSUP;
123                 goto fail3;
124         }
125
126         if ((rc = evop->evo_virtio_qstart(evvp, evvcp, evvdp)) != 0)
127                 goto fail4;
128
129         evvp->evv_type = evvcp->evvc_type;
130         evvp->evv_target_vf = evvcp->evvc_target_vf;
131         evvp->evv_state = EFX_VIRTIO_VQ_STATE_STARTED;
132
133         return (0);
134
135 fail4:
136         EFSYS_PROBE(fail4);
137 fail3:
138         EFSYS_PROBE(fail3);
139 fail2:
140         EFSYS_PROBE(fail2);
141 fail1:
142         EFSYS_PROBE1(fail1, efx_rc_t, rc);
143
144         return (rc);
145 }
146
147         __checkReturn   efx_rc_t
148 efx_virtio_qstop(
149         __in            efx_virtio_vq_t *evvp,
150         __out_opt       efx_virtio_vq_dyncfg_t *evvdp)
151 {
152         efx_nic_t *enp;
153         const efx_virtio_ops_t *evop;
154         efx_rc_t rc;
155
156         if (evvp == NULL) {
157                 rc = EINVAL;
158                 goto fail1;
159         }
160
161         enp = evvp->evv_enp;
162         evop = enp->en_evop;
163
164         EFSYS_ASSERT3U(evvp->evv_magic, ==, EFX_VQ_MAGIC);
165         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
166         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_VIRTIO);
167
168         if (evop == NULL) {
169                 rc = ENOTSUP;
170                 goto fail2;
171         }
172
173         if (evvp->evv_state != EFX_VIRTIO_VQ_STATE_STARTED) {
174                 rc = EINVAL;
175                 goto fail3;
176         }
177
178         if ((rc = evop->evo_virtio_qstop(evvp, evvdp)) != 0)
179                 goto fail4;
180
181         evvp->evv_state = EFX_VIRTIO_VQ_STATE_INITIALIZED;
182
183         return 0;
184
185 fail4:
186         EFSYS_PROBE(fail4);
187 fail3:
188         EFSYS_PROBE(fail3);
189 fail2:
190         EFSYS_PROBE(fail2);
191 fail1:
192         EFSYS_PROBE1(fail1, efx_rc_t, rc);
193
194         return (rc);
195 }
196
197         void
198 efx_virtio_qdestroy(
199         __in            efx_virtio_vq_t *evvp)
200 {
201         efx_nic_t *enp;
202
203         if (evvp == NULL)
204                 return;
205
206         enp = evvp->evv_enp;
207
208         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
209
210         if (evvp->evv_state == EFX_VIRTIO_VQ_STATE_INITIALIZED) {
211                 /* Free the virtqueue object */
212                 EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_virtio_vq_t), evvp);
213         }
214 }
215
216 #endif /* EFSYS_OPT_VIRTIO */