14dda72dbSVijay Srivastava /* SPDX-License-Identifier: BSD-3-Clause
24dda72dbSVijay Srivastava *
34dda72dbSVijay Srivastava * Copyright(c) 2020-2021 Xilinx, Inc.
44dda72dbSVijay Srivastava */
54dda72dbSVijay Srivastava
64dda72dbSVijay Srivastava #include "efx.h"
74dda72dbSVijay Srivastava #include "efx_impl.h"
84dda72dbSVijay Srivastava
94dda72dbSVijay Srivastava #if EFSYS_OPT_RIVERHEAD && EFSYS_OPT_VIRTIO
104dda72dbSVijay Srivastava
114dda72dbSVijay Srivastava /*
124dda72dbSVijay Srivastava * Get function-local index of the associated VI from the
134dda72dbSVijay Srivastava * virtqueue number queue 0 is reserved for MCDI
144dda72dbSVijay Srivastava */
154dda72dbSVijay Srivastava #define EFX_VIRTIO_GET_VI_INDEX(vq_num) (((vq_num) / 2) + 1)
164dda72dbSVijay Srivastava
174dda72dbSVijay Srivastava __checkReturn efx_rc_t
rhead_virtio_qstart(__in efx_virtio_vq_t * evvp,__in efx_virtio_vq_cfg_t * evvcp,__in_opt efx_virtio_vq_dyncfg_t * evvdp)184dda72dbSVijay Srivastava rhead_virtio_qstart(
194dda72dbSVijay Srivastava __in efx_virtio_vq_t *evvp,
204dda72dbSVijay Srivastava __in efx_virtio_vq_cfg_t *evvcp,
214dda72dbSVijay Srivastava __in_opt efx_virtio_vq_dyncfg_t *evvdp)
224dda72dbSVijay Srivastava
234dda72dbSVijay Srivastava {
244dda72dbSVijay Srivastava efx_nic_t *enp = evvp->evv_enp;
254dda72dbSVijay Srivastava efx_mcdi_req_t req;
264dda72dbSVijay Srivastava uint32_t vi_index;
274dda72dbSVijay Srivastava EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VIRTIO_INIT_QUEUE_REQ_LEN,
284dda72dbSVijay Srivastava MC_CMD_VIRTIO_INIT_QUEUE_RESP_LEN);
294dda72dbSVijay Srivastava efx_rc_t rc;
304dda72dbSVijay Srivastava
314dda72dbSVijay Srivastava EFX_STATIC_ASSERT(EFX_VIRTIO_VQ_TYPE_NET_RXQ ==
324dda72dbSVijay Srivastava MC_CMD_VIRTIO_INIT_QUEUE_REQ_NET_RXQ);
334dda72dbSVijay Srivastava EFX_STATIC_ASSERT(EFX_VIRTIO_VQ_TYPE_NET_TXQ ==
344dda72dbSVijay Srivastava MC_CMD_VIRTIO_INIT_QUEUE_REQ_NET_TXQ);
354dda72dbSVijay Srivastava EFX_STATIC_ASSERT(EFX_VIRTIO_VQ_TYPE_BLOCK ==
364dda72dbSVijay Srivastava MC_CMD_VIRTIO_INIT_QUEUE_REQ_BLOCK);
374dda72dbSVijay Srivastava
384dda72dbSVijay Srivastava if (evvcp->evvc_type >= EFX_VIRTIO_VQ_NTYPES) {
394dda72dbSVijay Srivastava rc = EINVAL;
404dda72dbSVijay Srivastava goto fail1;
414dda72dbSVijay Srivastava }
424dda72dbSVijay Srivastava
434dda72dbSVijay Srivastava /* virtqueue size must be power of 2 */
444dda72dbSVijay Srivastava if ((!ISP2(evvcp->evvc_vq_size)) ||
454dda72dbSVijay Srivastava (evvcp->evvc_vq_size > EFX_VIRTIO_MAX_VQ_SIZE)) {
464dda72dbSVijay Srivastava rc = EINVAL;
474dda72dbSVijay Srivastava goto fail2;
484dda72dbSVijay Srivastava }
494dda72dbSVijay Srivastava
504dda72dbSVijay Srivastava req.emr_cmd = MC_CMD_VIRTIO_INIT_QUEUE;
514dda72dbSVijay Srivastava req.emr_in_buf = payload;
524dda72dbSVijay Srivastava req.emr_in_length = MC_CMD_VIRTIO_INIT_QUEUE_REQ_LEN;
534dda72dbSVijay Srivastava req.emr_out_buf = payload;
544dda72dbSVijay Srivastava req.emr_out_length = MC_CMD_VIRTIO_INIT_QUEUE_RESP_LEN;
554dda72dbSVijay Srivastava
564dda72dbSVijay Srivastava MCDI_IN_SET_BYTE(req, VIRTIO_INIT_QUEUE_REQ_QUEUE_TYPE,
574dda72dbSVijay Srivastava evvcp->evvc_type);
584dda72dbSVijay Srivastava MCDI_IN_SET_WORD(req, VIRTIO_INIT_QUEUE_REQ_TARGET_VF,
594dda72dbSVijay Srivastava evvcp->evvc_target_vf);
604dda72dbSVijay Srivastava
614dda72dbSVijay Srivastava vi_index = EFX_VIRTIO_GET_VI_INDEX(evvcp->evvc_vq_num);
624dda72dbSVijay Srivastava MCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_INSTANCE, vi_index);
634dda72dbSVijay Srivastava
644dda72dbSVijay Srivastava MCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_SIZE,
654dda72dbSVijay Srivastava evvcp->evvc_vq_size);
664dda72dbSVijay Srivastava
674dda72dbSVijay Srivastava MCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_DESC_TBL_ADDR_LO,
684dda72dbSVijay Srivastava evvcp->evvc_desc_tbl_addr & 0xFFFFFFFF);
694dda72dbSVijay Srivastava MCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_DESC_TBL_ADDR_HI,
704dda72dbSVijay Srivastava evvcp->evvc_desc_tbl_addr >> 32);
714dda72dbSVijay Srivastava
724dda72dbSVijay Srivastava MCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_AVAIL_RING_ADDR_LO,
734dda72dbSVijay Srivastava evvcp->evvc_avail_ring_addr & 0xFFFFFFFF);
744dda72dbSVijay Srivastava MCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_AVAIL_RING_ADDR_HI,
754dda72dbSVijay Srivastava evvcp->evvc_avail_ring_addr >> 32);
764dda72dbSVijay Srivastava
774dda72dbSVijay Srivastava MCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_USED_RING_ADDR_LO,
784dda72dbSVijay Srivastava evvcp->evvc_used_ring_addr & 0xFFFFFFFF);
794dda72dbSVijay Srivastava MCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_USED_RING_ADDR_HI,
804dda72dbSVijay Srivastava evvcp->evvc_used_ring_addr >> 32);
814dda72dbSVijay Srivastava
824dda72dbSVijay Srivastava if (evvcp->evvc_use_pasid) {
834dda72dbSVijay Srivastava MCDI_IN_POPULATE_DWORD_1(req, VIRTIO_INIT_QUEUE_REQ_FLAGS,
844dda72dbSVijay Srivastava VIRTIO_INIT_QUEUE_REQ_USE_PASID, 1);
854dda72dbSVijay Srivastava MCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_PASID,
864dda72dbSVijay Srivastava evvcp->evvc_pas_id);
874dda72dbSVijay Srivastava }
884dda72dbSVijay Srivastava
894dda72dbSVijay Srivastava MCDI_IN_SET_WORD(req, VIRTIO_INIT_QUEUE_REQ_MSIX_VECTOR,
904dda72dbSVijay Srivastava evvcp->evvc_msix_vector);
914dda72dbSVijay Srivastava
924dda72dbSVijay Srivastava MCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_FEATURES_LO,
934dda72dbSVijay Srivastava evvcp->evcc_features & 0xFFFFFFFF);
944dda72dbSVijay Srivastava MCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_FEATURES_HI,
954dda72dbSVijay Srivastava evvcp->evcc_features >> 32);
964dda72dbSVijay Srivastava
974dda72dbSVijay Srivastava if (evvdp != NULL) {
98*05308e34SAbhimanyu Saini MCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_INITIAL_AVAIL_IDX,
99*05308e34SAbhimanyu Saini evvdp->evvd_vq_avail_idx);
100*05308e34SAbhimanyu Saini MCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_INITIAL_USED_IDX,
101*05308e34SAbhimanyu Saini evvdp->evvd_vq_used_idx);
1024dda72dbSVijay Srivastava }
1034dda72dbSVijay Srivastava
1044dda72dbSVijay Srivastava MCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_MPORT_SELECTOR,
1054dda72dbSVijay Srivastava MAE_MPORT_SELECTOR_ASSIGNED);
1064dda72dbSVijay Srivastava
1074dda72dbSVijay Srivastava efx_mcdi_execute(enp, &req);
1084dda72dbSVijay Srivastava
1094dda72dbSVijay Srivastava if (req.emr_rc != 0) {
1104dda72dbSVijay Srivastava rc = req.emr_rc;
11193211a52SAbhimanyu Saini goto fail3;
1124dda72dbSVijay Srivastava }
1134dda72dbSVijay Srivastava
1144dda72dbSVijay Srivastava evvp->evv_vi_index = vi_index;
1154dda72dbSVijay Srivastava
1164dda72dbSVijay Srivastava return (0);
1174dda72dbSVijay Srivastava
1184dda72dbSVijay Srivastava fail3:
1194dda72dbSVijay Srivastava EFSYS_PROBE(fail3);
1204dda72dbSVijay Srivastava fail2:
1214dda72dbSVijay Srivastava EFSYS_PROBE(fail2);
1224dda72dbSVijay Srivastava fail1:
1234dda72dbSVijay Srivastava EFSYS_PROBE1(fail1, efx_rc_t, rc);
1244dda72dbSVijay Srivastava
1254dda72dbSVijay Srivastava return (rc);
1264dda72dbSVijay Srivastava }
1274dda72dbSVijay Srivastava
1284dda72dbSVijay Srivastava __checkReturn efx_rc_t
rhead_virtio_qstop(__in efx_virtio_vq_t * evvp,__out_opt efx_virtio_vq_dyncfg_t * evvdp)1294dda72dbSVijay Srivastava rhead_virtio_qstop(
1304dda72dbSVijay Srivastava __in efx_virtio_vq_t *evvp,
1314dda72dbSVijay Srivastava __out_opt efx_virtio_vq_dyncfg_t *evvdp)
1324dda72dbSVijay Srivastava {
1334dda72dbSVijay Srivastava efx_mcdi_req_t req;
1344dda72dbSVijay Srivastava efx_nic_t *enp = evvp->evv_enp;
1354dda72dbSVijay Srivastava EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VIRTIO_FINI_QUEUE_REQ_LEN,
1364dda72dbSVijay Srivastava MC_CMD_VIRTIO_FINI_QUEUE_RESP_LEN);
1374dda72dbSVijay Srivastava efx_rc_t rc;
1384dda72dbSVijay Srivastava
1394dda72dbSVijay Srivastava req.emr_cmd = MC_CMD_VIRTIO_FINI_QUEUE;
1404dda72dbSVijay Srivastava req.emr_in_buf = payload;
1414dda72dbSVijay Srivastava req.emr_in_length = MC_CMD_VIRTIO_FINI_QUEUE_REQ_LEN;
1424dda72dbSVijay Srivastava req.emr_out_buf = payload;
1434dda72dbSVijay Srivastava req.emr_out_length = MC_CMD_VIRTIO_FINI_QUEUE_RESP_LEN;
1444dda72dbSVijay Srivastava
1454dda72dbSVijay Srivastava MCDI_IN_SET_BYTE(req, VIRTIO_FINI_QUEUE_REQ_QUEUE_TYPE, evvp->evv_type);
1464dda72dbSVijay Srivastava MCDI_IN_SET_WORD(req, VIRTIO_INIT_QUEUE_REQ_TARGET_VF,
1474dda72dbSVijay Srivastava evvp->evv_target_vf);
1484dda72dbSVijay Srivastava MCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_INSTANCE,
1494dda72dbSVijay Srivastava evvp->evv_vi_index);
1504dda72dbSVijay Srivastava
1514dda72dbSVijay Srivastava efx_mcdi_execute(enp, &req);
1524dda72dbSVijay Srivastava
1534dda72dbSVijay Srivastava if (req.emr_rc != 0) {
1544dda72dbSVijay Srivastava rc = req.emr_rc;
1554dda72dbSVijay Srivastava goto fail1;
1564dda72dbSVijay Srivastava }
1574dda72dbSVijay Srivastava
1584dda72dbSVijay Srivastava if (req.emr_out_length_used < MC_CMD_VIRTIO_FINI_QUEUE_RESP_LEN) {
1594dda72dbSVijay Srivastava rc = EMSGSIZE;
1604dda72dbSVijay Srivastava goto fail2;
1614dda72dbSVijay Srivastava }
1624dda72dbSVijay Srivastava
1634dda72dbSVijay Srivastava if (evvdp != NULL) {
164*05308e34SAbhimanyu Saini evvdp->evvd_vq_avail_idx =
165*05308e34SAbhimanyu Saini MCDI_OUT_DWORD(req, VIRTIO_FINI_QUEUE_RESP_FINAL_AVAIL_IDX);
166*05308e34SAbhimanyu Saini evvdp->evvd_vq_used_idx =
167*05308e34SAbhimanyu Saini MCDI_OUT_DWORD(req, VIRTIO_FINI_QUEUE_RESP_FINAL_USED_IDX);
1684dda72dbSVijay Srivastava }
1694dda72dbSVijay Srivastava
1704dda72dbSVijay Srivastava return (0);
1714dda72dbSVijay Srivastava
1724dda72dbSVijay Srivastava fail2:
1734dda72dbSVijay Srivastava EFSYS_PROBE(fail2);
1744dda72dbSVijay Srivastava fail1:
1754dda72dbSVijay Srivastava EFSYS_PROBE1(fail1, efx_rc_t, rc);
1764dda72dbSVijay Srivastava
1774dda72dbSVijay Srivastava return (rc);
1784dda72dbSVijay Srivastava }
1794dda72dbSVijay Srivastava
180ec03ce69SVijay Srivastava __checkReturn efx_rc_t
rhead_virtio_get_doorbell_offset(__in efx_virtio_vq_t * evvp,__out uint32_t * offsetp)181ec03ce69SVijay Srivastava rhead_virtio_get_doorbell_offset(
182ec03ce69SVijay Srivastava __in efx_virtio_vq_t *evvp,
183ec03ce69SVijay Srivastava __out uint32_t *offsetp)
184ec03ce69SVijay Srivastava {
185ec03ce69SVijay Srivastava efx_nic_t *enp = evvp->evv_enp;
186ec03ce69SVijay Srivastava efx_mcdi_req_t req;
187ec03ce69SVijay Srivastava uint32_t type;
188ec03ce69SVijay Srivastava EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VIRTIO_GET_DOORBELL_OFFSET_REQ_LEN,
189ec03ce69SVijay Srivastava MC_CMD_VIRTIO_GET_NET_DOORBELL_OFFSET_RESP_LEN);
190ec03ce69SVijay Srivastava efx_rc_t rc;
191ec03ce69SVijay Srivastava
192ec03ce69SVijay Srivastava req.emr_cmd = MC_CMD_VIRTIO_GET_DOORBELL_OFFSET;
193ec03ce69SVijay Srivastava req.emr_in_buf = payload;
194ec03ce69SVijay Srivastava req.emr_in_length = MC_CMD_VIRTIO_GET_DOORBELL_OFFSET_REQ_LEN;
195ec03ce69SVijay Srivastava req.emr_out_buf = payload;
196ec03ce69SVijay Srivastava req.emr_out_length = MC_CMD_VIRTIO_GET_NET_DOORBELL_OFFSET_RESP_LEN;
197ec03ce69SVijay Srivastava
198ec03ce69SVijay Srivastava switch (evvp->evv_type) {
199ec03ce69SVijay Srivastava case EFX_VIRTIO_VQ_TYPE_NET_RXQ:
200ec03ce69SVijay Srivastava case EFX_VIRTIO_VQ_TYPE_NET_TXQ:
201ec03ce69SVijay Srivastava type = MC_CMD_VIRTIO_GET_FEATURES_IN_NET;
202ec03ce69SVijay Srivastava break;
203ec03ce69SVijay Srivastava case EFX_VIRTIO_VQ_TYPE_BLOCK:
204ec03ce69SVijay Srivastava type = MC_CMD_VIRTIO_GET_FEATURES_IN_BLOCK;
205ec03ce69SVijay Srivastava break;
206ec03ce69SVijay Srivastava default:
207ec03ce69SVijay Srivastava rc = EINVAL;
208ec03ce69SVijay Srivastava goto fail1;
209ec03ce69SVijay Srivastava }
210ec03ce69SVijay Srivastava
211ec03ce69SVijay Srivastava MCDI_IN_SET_BYTE(req, VIRTIO_GET_DOORBELL_OFFSET_REQ_DEVICE_ID,
212ec03ce69SVijay Srivastava type);
213ec03ce69SVijay Srivastava MCDI_IN_SET_WORD(req, VIRTIO_GET_DOORBELL_OFFSET_REQ_TARGET_VF,
214ec03ce69SVijay Srivastava evvp->evv_target_vf);
215ec03ce69SVijay Srivastava MCDI_IN_SET_DWORD(req, VIRTIO_GET_DOORBELL_OFFSET_REQ_INSTANCE,
216ec03ce69SVijay Srivastava evvp->evv_vi_index);
217ec03ce69SVijay Srivastava
218ec03ce69SVijay Srivastava efx_mcdi_execute(enp, &req);
219ec03ce69SVijay Srivastava
220ec03ce69SVijay Srivastava if (req.emr_rc != 0) {
221ec03ce69SVijay Srivastava rc = req.emr_rc;
222ec03ce69SVijay Srivastava goto fail2;
223ec03ce69SVijay Srivastava }
224ec03ce69SVijay Srivastava
225ec03ce69SVijay Srivastava switch (type) {
226ec03ce69SVijay Srivastava case MC_CMD_VIRTIO_GET_FEATURES_IN_NET:
227ec03ce69SVijay Srivastava if (req.emr_out_length_used <
228ec03ce69SVijay Srivastava MC_CMD_VIRTIO_GET_NET_DOORBELL_OFFSET_RESP_LEN) {
229ec03ce69SVijay Srivastava rc = EMSGSIZE;
230ec03ce69SVijay Srivastava goto fail3;
231ec03ce69SVijay Srivastava }
232ec03ce69SVijay Srivastava
233ec03ce69SVijay Srivastava if (evvp->evv_type == EFX_VIRTIO_VQ_TYPE_NET_RXQ) {
234ec03ce69SVijay Srivastava *offsetp = MCDI_OUT_DWORD(req,
235ec03ce69SVijay Srivastava VIRTIO_GET_NET_DOORBELL_OFFSET_RESP_RX_DBL_OFFSET);
236ec03ce69SVijay Srivastava } else if (evvp->evv_type == EFX_VIRTIO_VQ_TYPE_NET_TXQ) {
237ec03ce69SVijay Srivastava *offsetp = MCDI_OUT_DWORD(req,
238ec03ce69SVijay Srivastava VIRTIO_GET_NET_DOORBELL_OFFSET_RESP_TX_DBL_OFFSET);
239ec03ce69SVijay Srivastava }
240ec03ce69SVijay Srivastava break;
241ec03ce69SVijay Srivastava case MC_CMD_VIRTIO_GET_FEATURES_IN_BLOCK:
242ec03ce69SVijay Srivastava if (req.emr_out_length_used <
243ec03ce69SVijay Srivastava MC_CMD_VIRTIO_GET_BLOCK_DOORBELL_OFFSET_RESP_LEN) {
244ec03ce69SVijay Srivastava rc = EMSGSIZE;
245ec03ce69SVijay Srivastava goto fail4;
246ec03ce69SVijay Srivastava }
247ec03ce69SVijay Srivastava
248ec03ce69SVijay Srivastava *offsetp = MCDI_OUT_DWORD(req,
249ec03ce69SVijay Srivastava VIRTIO_GET_BLOCK_DOORBELL_OFFSET_RESP_DBL_OFFSET);
250ec03ce69SVijay Srivastava break;
251ec03ce69SVijay Srivastava default:
252ec03ce69SVijay Srivastava EFSYS_ASSERT(0);
253ec03ce69SVijay Srivastava rc = EINVAL;
254ec03ce69SVijay Srivastava goto fail5;
255ec03ce69SVijay Srivastava }
256ec03ce69SVijay Srivastava
257ec03ce69SVijay Srivastava return (0);
258ec03ce69SVijay Srivastava
259ec03ce69SVijay Srivastava fail5:
260ec03ce69SVijay Srivastava EFSYS_PROBE(fail5);
261ec03ce69SVijay Srivastava fail4:
262ec03ce69SVijay Srivastava EFSYS_PROBE(fail4);
263ec03ce69SVijay Srivastava fail3:
264ec03ce69SVijay Srivastava EFSYS_PROBE(fail3);
265ec03ce69SVijay Srivastava fail2:
266ec03ce69SVijay Srivastava EFSYS_PROBE(fail2);
267ec03ce69SVijay Srivastava fail1:
268ec03ce69SVijay Srivastava EFSYS_PROBE1(fail1, efx_rc_t, rc);
269ec03ce69SVijay Srivastava
270ec03ce69SVijay Srivastava return (rc);
271ec03ce69SVijay Srivastava }
272ec03ce69SVijay Srivastava
27346d2b38bSVijay Kumar Srivastava __checkReturn efx_rc_t
rhead_virtio_get_features(__in efx_nic_t * enp,__in efx_virtio_device_type_t type,__out uint64_t * featuresp)27446d2b38bSVijay Kumar Srivastava rhead_virtio_get_features(
27546d2b38bSVijay Kumar Srivastava __in efx_nic_t *enp,
27646d2b38bSVijay Kumar Srivastava __in efx_virtio_device_type_t type,
27746d2b38bSVijay Kumar Srivastava __out uint64_t *featuresp)
27846d2b38bSVijay Kumar Srivastava {
27946d2b38bSVijay Kumar Srivastava efx_mcdi_req_t req;
28046d2b38bSVijay Kumar Srivastava uint32_t features_lo;
28146d2b38bSVijay Kumar Srivastava uint32_t features_hi;
28246d2b38bSVijay Kumar Srivastava EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VIRTIO_GET_FEATURES_IN_LEN,
28346d2b38bSVijay Kumar Srivastava MC_CMD_VIRTIO_GET_FEATURES_OUT_LEN);
28446d2b38bSVijay Kumar Srivastava efx_rc_t rc;
28546d2b38bSVijay Kumar Srivastava
28646d2b38bSVijay Kumar Srivastava EFX_STATIC_ASSERT(EFX_VIRTIO_DEVICE_TYPE_NET ==
28746d2b38bSVijay Kumar Srivastava MC_CMD_VIRTIO_GET_FEATURES_IN_NET);
28846d2b38bSVijay Kumar Srivastava EFX_STATIC_ASSERT(EFX_VIRTIO_DEVICE_TYPE_BLOCK ==
28946d2b38bSVijay Kumar Srivastava MC_CMD_VIRTIO_GET_FEATURES_IN_BLOCK);
29046d2b38bSVijay Kumar Srivastava
29146d2b38bSVijay Kumar Srivastava req.emr_cmd = MC_CMD_VIRTIO_GET_FEATURES;
29246d2b38bSVijay Kumar Srivastava req.emr_in_buf = payload;
29346d2b38bSVijay Kumar Srivastava req.emr_in_length = MC_CMD_VIRTIO_GET_FEATURES_IN_LEN;
29446d2b38bSVijay Kumar Srivastava req.emr_out_buf = payload;
29546d2b38bSVijay Kumar Srivastava req.emr_out_length = MC_CMD_VIRTIO_GET_FEATURES_OUT_LEN;
29646d2b38bSVijay Kumar Srivastava
29746d2b38bSVijay Kumar Srivastava MCDI_IN_SET_DWORD(req, VIRTIO_GET_FEATURES_IN_DEVICE_ID, type);
29846d2b38bSVijay Kumar Srivastava
29946d2b38bSVijay Kumar Srivastava efx_mcdi_execute(enp, &req);
30046d2b38bSVijay Kumar Srivastava
30146d2b38bSVijay Kumar Srivastava if (req.emr_rc != 0) {
30246d2b38bSVijay Kumar Srivastava rc = req.emr_rc;
30346d2b38bSVijay Kumar Srivastava goto fail1;
30446d2b38bSVijay Kumar Srivastava }
30546d2b38bSVijay Kumar Srivastava
30646d2b38bSVijay Kumar Srivastava if (req.emr_out_length_used < MC_CMD_VIRTIO_GET_FEATURES_OUT_LEN) {
30746d2b38bSVijay Kumar Srivastava rc = EMSGSIZE;
30846d2b38bSVijay Kumar Srivastava goto fail2;
30946d2b38bSVijay Kumar Srivastava }
31046d2b38bSVijay Kumar Srivastava
31146d2b38bSVijay Kumar Srivastava features_lo = MCDI_OUT_DWORD(req, VIRTIO_GET_FEATURES_OUT_FEATURES_LO);
31246d2b38bSVijay Kumar Srivastava features_hi = MCDI_OUT_DWORD(req, VIRTIO_GET_FEATURES_OUT_FEATURES_HI);
31346d2b38bSVijay Kumar Srivastava *featuresp = ((uint64_t)features_hi << 32) | features_lo;
31446d2b38bSVijay Kumar Srivastava
31546d2b38bSVijay Kumar Srivastava return (0);
31646d2b38bSVijay Kumar Srivastava
31746d2b38bSVijay Kumar Srivastava fail2:
31846d2b38bSVijay Kumar Srivastava EFSYS_PROBE(fail2);
31946d2b38bSVijay Kumar Srivastava fail1:
32046d2b38bSVijay Kumar Srivastava EFSYS_PROBE1(fail1, efx_rc_t, rc);
32146d2b38bSVijay Kumar Srivastava
32246d2b38bSVijay Kumar Srivastava return (rc);
32346d2b38bSVijay Kumar Srivastava }
32446d2b38bSVijay Kumar Srivastava
325b8a896abSVijay Kumar Srivastava __checkReturn efx_rc_t
rhead_virtio_verify_features(__in efx_nic_t * enp,__in efx_virtio_device_type_t type,__in uint64_t features)326b8a896abSVijay Kumar Srivastava rhead_virtio_verify_features(
327b8a896abSVijay Kumar Srivastava __in efx_nic_t *enp,
328b8a896abSVijay Kumar Srivastava __in efx_virtio_device_type_t type,
329b8a896abSVijay Kumar Srivastava __in uint64_t features)
330b8a896abSVijay Kumar Srivastava {
331b8a896abSVijay Kumar Srivastava efx_mcdi_req_t req;
332b8a896abSVijay Kumar Srivastava EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VIRTIO_TEST_FEATURES_IN_LEN,
333b8a896abSVijay Kumar Srivastava MC_CMD_VIRTIO_TEST_FEATURES_OUT_LEN);
334b8a896abSVijay Kumar Srivastava efx_rc_t rc;
335b8a896abSVijay Kumar Srivastava
336b8a896abSVijay Kumar Srivastava EFX_STATIC_ASSERT(EFX_VIRTIO_DEVICE_TYPE_NET ==
337b8a896abSVijay Kumar Srivastava MC_CMD_VIRTIO_GET_FEATURES_IN_NET);
338b8a896abSVijay Kumar Srivastava EFX_STATIC_ASSERT(EFX_VIRTIO_DEVICE_TYPE_BLOCK ==
339b8a896abSVijay Kumar Srivastava MC_CMD_VIRTIO_GET_FEATURES_IN_BLOCK);
340b8a896abSVijay Kumar Srivastava
341b8a896abSVijay Kumar Srivastava req.emr_cmd = MC_CMD_VIRTIO_TEST_FEATURES;
342b8a896abSVijay Kumar Srivastava req.emr_in_buf = payload;
343b8a896abSVijay Kumar Srivastava req.emr_in_length = MC_CMD_VIRTIO_TEST_FEATURES_IN_LEN;
344b8a896abSVijay Kumar Srivastava req.emr_out_buf = payload;
345b8a896abSVijay Kumar Srivastava req.emr_out_length = MC_CMD_VIRTIO_TEST_FEATURES_OUT_LEN;
346b8a896abSVijay Kumar Srivastava
347b8a896abSVijay Kumar Srivastava MCDI_IN_SET_DWORD(req, VIRTIO_TEST_FEATURES_IN_DEVICE_ID, type);
348b8a896abSVijay Kumar Srivastava
349b8a896abSVijay Kumar Srivastava MCDI_IN_SET_DWORD(req, VIRTIO_TEST_FEATURES_IN_FEATURES_LO,
350b8a896abSVijay Kumar Srivastava features & 0xFFFFFFFF);
351b8a896abSVijay Kumar Srivastava MCDI_IN_SET_DWORD(req, VIRTIO_TEST_FEATURES_IN_FEATURES_HI,
352b8a896abSVijay Kumar Srivastava ((features >> 32) & 0xFFFFFFFF));
353b8a896abSVijay Kumar Srivastava
354b8a896abSVijay Kumar Srivastava efx_mcdi_execute(enp, &req);
355b8a896abSVijay Kumar Srivastava
356b8a896abSVijay Kumar Srivastava if (req.emr_rc != 0) {
357b8a896abSVijay Kumar Srivastava rc = req.emr_rc;
358b8a896abSVijay Kumar Srivastava goto fail1;
359b8a896abSVijay Kumar Srivastava }
360b8a896abSVijay Kumar Srivastava
361b8a896abSVijay Kumar Srivastava return (0);
362b8a896abSVijay Kumar Srivastava
363b8a896abSVijay Kumar Srivastava fail1:
364b8a896abSVijay Kumar Srivastava EFSYS_PROBE1(fail1, efx_rc_t, rc);
365b8a896abSVijay Kumar Srivastava
366b8a896abSVijay Kumar Srivastava return (rc);
367b8a896abSVijay Kumar Srivastava }
368b8a896abSVijay Kumar Srivastava
3694dda72dbSVijay Srivastava #endif /* EFSYS_OPT_RIVERHEAD && EFSYS_OPT_VIRTIO */
370