1 /* SPDX-License-Identifier: BSD-3-Clause
3 * Copyright(c) 2020-2021 Xilinx, Inc.
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 */
18 #endif /* EFSYS_OPT_RIVERHEAD */
20 __checkReturn efx_rc_t
24 const efx_virtio_ops_t *evop;
27 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
28 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
29 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_VIRTIO));
31 switch (enp->en_family) {
32 #if EFSYS_OPT_RIVERHEAD
33 case EFX_FAMILY_RIVERHEAD:
34 evop = &__efx_virtio_rhead_ops;
36 #endif /* EFSYS_OPT_RIVERHEAD */
45 enp->en_mod_flags |= EFX_MOD_VIRTIO;
50 EFSYS_PROBE1(fail1, efx_rc_t, rc);
53 enp->en_mod_flags &= ~EFX_MOD_VIRTIO;
62 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
63 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
64 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_VIRTIO);
67 enp->en_mod_flags &= ~EFX_MOD_VIRTIO;
70 __checkReturn efx_rc_t
73 __deref_out efx_virtio_vq_t **evvpp)
75 const efx_virtio_ops_t *evop = enp->en_evop;
76 efx_virtio_vq_t *evvp;
79 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
80 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_VIRTIO);
82 /* Allocate a virtqueue object */
83 EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_virtio_vq_t), evvp);
89 evvp->evv_magic = EFX_VQ_MAGIC;
91 evvp->evv_state = EFX_VIRTIO_VQ_STATE_INITIALIZED;
98 EFSYS_PROBE1(fail1, efx_rc_t, rc);
103 __checkReturn efx_rc_t
105 __in efx_virtio_vq_t *evvp,
106 __in efx_virtio_vq_cfg_t *evvcp,
107 __in_opt efx_virtio_vq_dyncfg_t *evvdp)
109 const efx_virtio_ops_t *evop;
112 if ((evvcp == NULL) || (evvp == NULL)) {
117 if (evvp->evv_state != EFX_VIRTIO_VQ_STATE_INITIALIZED) {
122 evop = evvp->evv_enp->en_evop;
128 if ((rc = evop->evo_virtio_qstart(evvp, evvcp, evvdp)) != 0)
131 evvp->evv_type = evvcp->evvc_type;
132 evvp->evv_target_vf = evvcp->evvc_target_vf;
133 evvp->evv_state = EFX_VIRTIO_VQ_STATE_STARTED;
144 EFSYS_PROBE1(fail1, efx_rc_t, rc);
149 __checkReturn efx_rc_t
151 __in efx_virtio_vq_t *evvp,
152 __out_opt efx_virtio_vq_dyncfg_t *evvdp)
155 const efx_virtio_ops_t *evop;
166 EFSYS_ASSERT3U(evvp->evv_magic, ==, EFX_VQ_MAGIC);
167 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
168 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_VIRTIO);
175 if (evvp->evv_state != EFX_VIRTIO_VQ_STATE_STARTED) {
180 if ((rc = evop->evo_virtio_qstop(evvp, evvdp)) != 0)
183 evvp->evv_state = EFX_VIRTIO_VQ_STATE_INITIALIZED;
194 EFSYS_PROBE1(fail1, efx_rc_t, rc);
201 __in efx_virtio_vq_t *evvp)
210 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
212 if (evvp->evv_state == EFX_VIRTIO_VQ_STATE_INITIALIZED) {
213 /* Free the virtqueue object */
214 EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_virtio_vq_t), evvp);
218 __checkReturn efx_rc_t
219 efx_virtio_get_doorbell_offset(
220 __in efx_virtio_vq_t *evvp,
221 __out uint32_t *offsetp)
224 const efx_virtio_ops_t *evop;
227 if ((evvp == NULL) || (offsetp == NULL)) {
235 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
236 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_VIRTIO);
243 if ((rc = evop->evo_get_doorbell_offset(evvp, offsetp)) != 0)
253 EFSYS_PROBE1(fail1, efx_rc_t, rc);
258 __checkReturn efx_rc_t
259 efx_virtio_get_features(
261 __in efx_virtio_device_type_t type,
262 __out uint64_t *featuresp)
264 const efx_virtio_ops_t *evop = enp->en_evop;
267 if (featuresp == NULL) {
272 if (type >= EFX_VIRTIO_DEVICE_NTYPES) {
277 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
278 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_VIRTIO);
285 if ((rc = evop->evo_get_features(enp, type, featuresp)) != 0)
297 EFSYS_PROBE1(fail1, efx_rc_t, rc);
302 #endif /* EFSYS_OPT_VIRTIO */