xref: /dpdk/drivers/common/sfc_efx/base/efx_virtio.c (revision 4dda72dbdeab354699967ce496b9d23db6a65321)
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 */
217