get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/89176/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 89176,
    "url": "https://patches.dpdk.org/api/patches/89176/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20210316061544.861619-2-andrew.rybchenko@oktetlabs.ru/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20210316061544.861619-2-andrew.rybchenko@oktetlabs.ru>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210316061544.861619-2-andrew.rybchenko@oktetlabs.ru",
    "date": "2021-03-16T06:15:37",
    "name": "[v3,1/8] common/sfc_efx/base: add base virtio support for vDPA",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "410de8238b0603a8506959eef474484e838aa13b",
    "submitter": {
        "id": 2013,
        "url": "https://patches.dpdk.org/api/people/2013/?format=api",
        "name": "Andrew Rybchenko",
        "email": "Andrew.Rybchenko@oktetlabs.ru"
    },
    "delegate": {
        "id": 319,
        "url": "https://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20210316061544.861619-2-andrew.rybchenko@oktetlabs.ru/mbox/",
    "series": [
        {
            "id": 15680,
            "url": "https://patches.dpdk.org/api/series/15680/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=15680",
            "date": "2021-03-16T06:15:36",
            "name": "common/sfc_efx: prepare to introduce vDPA driver",
            "version": 3,
            "mbox": "https://patches.dpdk.org/series/15680/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/89176/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/89176/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id F2A0EA054F;\n\tTue, 16 Mar 2021 07:16:08 +0100 (CET)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 9E8F82427B8;\n\tTue, 16 Mar 2021 07:16:00 +0100 (CET)",
            "from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113])\n by mails.dpdk.org (Postfix) with ESMTP id 9D8252427A9\n for <dev@dpdk.org>; Tue, 16 Mar 2021 07:15:58 +0100 (CET)",
            "by shelob.oktetlabs.ru (Postfix, from userid 122)\n id 7363F7F5D8; Tue, 16 Mar 2021 09:15:58 +0300 (MSK)",
            "from aros.oktetlabs.ru (aros.oktetlabs.ru [192.168.38.17])\n by shelob.oktetlabs.ru (Postfix) with ESMTP id 51BCA7F527;\n Tue, 16 Mar 2021 09:15:50 +0300 (MSK)"
        ],
        "X-Spam-Checker-Version": "SpamAssassin 3.4.2 (2018-09-13) on shelob.oktetlabs.ru",
        "X-Spam-Level": "",
        "X-Spam-Status": "No, score=0.8 required=5.0 tests=ALL_TRUSTED,\n DKIM_ADSP_DISCARD,\n URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.2",
        "DKIM-Filter": "OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 51BCA7F527",
        "Authentication-Results": "shelob.oktetlabs.ru/51BCA7F527; dkim=none;\n dkim-atps=neutral",
        "From": "Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>",
        "To": "Ferruh Yigit <ferruh.yigit@intel.com>",
        "Cc": "dev@dpdk.org,\n\tVijay Srivastava <vijays@solarflare.com>",
        "Date": "Tue, 16 Mar 2021 09:15:37 +0300",
        "Message-Id": "<20210316061544.861619-2-andrew.rybchenko@oktetlabs.ru>",
        "X-Mailer": "git-send-email 2.30.1",
        "In-Reply-To": "<20210316061544.861619-1-andrew.rybchenko@oktetlabs.ru>",
        "References": "<20210311110325.3291203-1-andrew.rybchenko@oktetlabs.ru>\n <20210316061544.861619-1-andrew.rybchenko@oktetlabs.ru>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH v3 1/8] common/sfc_efx/base: add base virtio\n support for vDPA",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Vijay Srivastava <vijays@solarflare.com>\n\nIn the vDPA mode, only data path is offloaded in the hardware and\ncontrol path still goes through the hypervisor and it configures\nvirtqueues via vDPA driver so new virtqueue APIs are required.\n\nImplement virtio init/fini and virtqueue create/destroy APIs.\n\nSigned-off-by: Vijay Srivastava <vijays@solarflare.com>\nSigned-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>\n---\n drivers/common/sfc_efx/base/efx.h          | 109 +++++++++++\n drivers/common/sfc_efx/base/efx_check.h    |   6 +\n drivers/common/sfc_efx/base/efx_impl.h     |  36 ++++\n drivers/common/sfc_efx/base/efx_virtio.c   | 216 +++++++++++++++++++++\n drivers/common/sfc_efx/base/meson.build    |   2 +\n drivers/common/sfc_efx/base/rhead_impl.h   |  17 ++\n drivers/common/sfc_efx/base/rhead_virtio.c | 190 ++++++++++++++++++\n drivers/common/sfc_efx/efsys.h             |   2 +\n 8 files changed, 578 insertions(+)\n create mode 100644 drivers/common/sfc_efx/base/efx_virtio.c\n create mode 100644 drivers/common/sfc_efx/base/rhead_virtio.c",
    "diff": "diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h\nindex 2c820022b2..c2c73bd382 100644\n--- a/drivers/common/sfc_efx/base/efx.h\n+++ b/drivers/common/sfc_efx/base/efx.h\n@@ -4368,6 +4368,115 @@ efx_mae_action_rule_remove(\n \n #endif /* EFSYS_OPT_MAE */\n \n+#if EFSYS_OPT_VIRTIO\n+\n+/* A Virtio net device can have one or more pairs of Rx/Tx virtqueues\n+ * while virtio block device has a single virtqueue,\n+ * for further details refer section of 4.2.3 of SF-120734\n+ */\n+typedef enum efx_virtio_vq_type_e {\n+\tEFX_VIRTIO_VQ_TYPE_NET_RXQ,\n+\tEFX_VIRTIO_VQ_TYPE_NET_TXQ,\n+\tEFX_VIRTIO_VQ_TYPE_BLOCK,\n+\tEFX_VIRTIO_VQ_NTYPES\n+} efx_virtio_vq_type_t;\n+\n+typedef struct efx_virtio_vq_dyncfg_s {\n+\t/*\n+\t * If queue is being created to be migrated then this\n+\t * should be the FINAL_PIDX value returned by MC_CMD_VIRTIO_FINI_QUEUE\n+\t * of the queue being migrated from. Otherwise, it should be zero.\n+\t */\n+\tuint32_t\t\tevvd_vq_pidx;\n+\t/*\n+\t * If this queue is being created to be migrated then this\n+\t * should be the FINAL_CIDX value returned by MC_CMD_VIRTIO_FINI_QUEUE\n+\t * of the queue being migrated from. Otherwise, it should be zero.\n+\t */\n+\tuint32_t\t\tevvd_vq_cidx;\n+} efx_virtio_vq_dyncfg_t;\n+\n+/*\n+ * Virtqueue size must be a power of 2, maximum size is 32768\n+ * (see VIRTIO v1.1 section 2.6)\n+ */\n+#define EFX_VIRTIO_MAX_VQ_SIZE\t0x8000\n+\n+typedef struct efx_virtio_vq_cfg_s {\n+\tunsigned int\t\tevvc_vq_num;\n+\tefx_virtio_vq_type_t\tevvc_type;\n+\t/*\n+\t * vDPA as VF : It is target VF number if queue is being created on VF.\n+\t * vDPA as PF : If queue to be created on PF then it should be\n+\t * EFX_PCI_VF_INVALID.\n+\t */\n+\tuint16_t\t\tevvc_target_vf;\n+\t/*\n+\t * Maximum virtqueue size is EFX_VIRTIO_MAX_VQ_SIZE and\n+\t * virtqueue size 0 means the queue is unavailable.\n+\t */\n+\tuint32_t\t\tevvc_vq_size;\n+\tefsys_dma_addr_t        evvc_desc_tbl_addr;\n+\tefsys_dma_addr_t\tevvc_avail_ring_addr;\n+\tefsys_dma_addr_t\tevvc_used_ring_addr;\n+\t/* MSIX vector number for the virtqueue or 0xFFFF if MSIX is not used */\n+\tuint16_t                evvc_msix_vector;\n+\t/*\n+\t * evvc_pas_id contains a PCIe address space identifier if the queue\n+\t * uses PASID.\n+\t */\n+\tboolean_t               evvc_use_pasid;\n+\tuint32_t\t\tevvc_pas_id;\n+\t/* Negotiated virtio features to be applied to this virtqueue */\n+\tuint64_t\t\tevcc_features;\n+} efx_virtio_vq_cfg_t;\n+\n+typedef struct efx_virtio_vq_s\tefx_virtio_vq_t;\n+\n+LIBEFX_API\n+extern\t__checkReturn\tefx_rc_t\n+efx_virtio_init(\n+\t__in\t\tefx_nic_t *enp);\n+\n+LIBEFX_API\n+extern\t\t\tvoid\n+efx_virtio_fini(\n+\t__in\t\tefx_nic_t *enp);\n+\n+/*\n+ * When virtio net driver in the guest sets VIRTIO_CONFIG_STATUS_DRIVER_OK bit,\n+ * hypervisor starts configuring all the virtqueues in the device. When the\n+ * vhost_user has received VHOST_USER_SET_VRING_ENABLE for all the virtqueues,\n+ * then it invokes VDPA driver callback dev_conf. APIs qstart and qcreate would\n+ * be invoked from dev_conf callback to create the virtqueues, For further\n+ * details refer SF-122427.\n+ */\n+LIBEFX_API\n+extern\t__checkReturn\tefx_rc_t\n+efx_virtio_qcreate(\n+\t__in\t\tefx_nic_t *enp,\n+\t__deref_out\tefx_virtio_vq_t **evvpp);\n+\n+LIBEFX_API\n+extern\t__checkReturn\tefx_rc_t\n+efx_virtio_qstart(\n+\t__in\t\tefx_virtio_vq_t *evvp,\n+\t__in\t\tefx_virtio_vq_cfg_t *evvcp,\n+\t__in_opt\tefx_virtio_vq_dyncfg_t *evvdp);\n+\n+LIBEFX_API\n+extern\t__checkReturn\tefx_rc_t\n+efx_virtio_qstop(\n+\t__in\t\tefx_virtio_vq_t *evvp,\n+\t__out_opt\tefx_virtio_vq_dyncfg_t *evvdp);\n+\n+LIBEFX_API\n+extern\t\t\tvoid\n+efx_virtio_qdestroy(\n+\t__in\t\tefx_virtio_vq_t *evvp);\n+\n+#endif /* EFSYS_OPT_VIRTIO */\n+\n #ifdef\t__cplusplus\n }\n #endif\ndiff --git a/drivers/common/sfc_efx/base/efx_check.h b/drivers/common/sfc_efx/base/efx_check.h\nindex 9e288f272a..86a6d92fef 100644\n--- a/drivers/common/sfc_efx/base/efx_check.h\n+++ b/drivers/common/sfc_efx/base/efx_check.h\n@@ -407,4 +407,10 @@\n # endif\n #endif /* EFSYS_OPT_MAE */\n \n+#if EFSYS_OPT_VIRTIO\n+# if !EFSYS_OPT_RIVERHEAD\n+#  error \"VIRTIO requires RIVERHEAD\"\n+# endif\n+#endif /* EFSYS_OPT_VIRTIO */\n+\n #endif /* _SYS_EFX_CHECK_H */\ndiff --git a/drivers/common/sfc_efx/base/efx_impl.h b/drivers/common/sfc_efx/base/efx_impl.h\nindex a0628e6927..f27d9fa82c 100644\n--- a/drivers/common/sfc_efx/base/efx_impl.h\n+++ b/drivers/common/sfc_efx/base/efx_impl.h\n@@ -65,6 +65,7 @@ extern \"C\" {\n #define\tEFX_MOD_TUNNEL\t\t0x00004000\n #define\tEFX_MOD_EVB\t\t0x00008000\n #define\tEFX_MOD_PROXY\t\t0x00010000\n+#define\tEFX_MOD_VIRTIO\t\t0x00020000\n \n #define\tEFX_RESET_PHY\t\t0x00000001\n #define\tEFX_RESET_RXQ_ERR\t0x00000002\n@@ -308,6 +309,16 @@ typedef struct efx_tunnel_ops_s {\n } efx_tunnel_ops_t;\n #endif /* EFSYS_OPT_TUNNEL */\n \n+#if EFSYS_OPT_VIRTIO\n+typedef struct efx_virtio_ops_s {\n+\tefx_rc_t\t(*evo_virtio_qstart)(efx_virtio_vq_t *,\n+\t\t\t\tefx_virtio_vq_cfg_t *,\n+\t\t\t\tefx_virtio_vq_dyncfg_t *);\n+\tefx_rc_t\t(*evo_virtio_qstop)(efx_virtio_vq_t *,\n+\t\t\t\tefx_virtio_vq_dyncfg_t *);\n+} efx_virtio_ops_t;\n+#endif /* EFSYS_OPT_VIRTIO */\n+\n typedef struct efx_port_s {\n \tefx_mac_type_t\t\tep_mac_type;\n \tuint32_t\t\tep_phy_type;\n@@ -858,6 +869,9 @@ struct efx_nic_s {\n #if EFSYS_OPT_VPD\n \tconst efx_vpd_ops_t\t*en_evpdop;\n #endif\t/* EFSYS_OPT_VPD */\n+#if EFSYS_OPT_VIRTIO\n+\tconst efx_virtio_ops_t\t*en_evop;\n+#endif\t/* EFSYS_OPT_VPD */\n #if EFSYS_OPT_RX_SCALE\n \tefx_rx_hash_support_t\t\ten_hash_support;\n \tefx_rx_scale_context_type_t\ten_rss_context_type;\n@@ -1750,6 +1764,28 @@ struct efx_mae_actions_s {\n \n #endif /* EFSYS_OPT_MAE */\n \n+#if EFSYS_OPT_VIRTIO\n+\n+#define\tEFX_VQ_MAGIC\t0x026011950\n+\n+typedef enum efx_virtio_vq_state_e {\n+\tEFX_VIRTIO_VQ_STATE_UNKNOWN = 0,\n+\tEFX_VIRTIO_VQ_STATE_INITIALIZED,\n+\tEFX_VIRTIO_VQ_STATE_STARTED,\n+\tEFX_VIRTIO_VQ_NSTATES\n+} efx_virtio_vq_state_t;\n+\n+struct efx_virtio_vq_s {\n+\tuint32_t\t\tevv_magic;\n+\tefx_nic_t\t\t*evv_enp;\n+\tefx_virtio_vq_state_t\tevv_state;\n+\tuint32_t\t\tevv_vi_index;\n+\tefx_virtio_vq_type_t\tevv_type;\n+\tuint16_t\t\tevv_target_vf;\n+};\n+\n+#endif /* EFSYS_OPT_VIRTIO */\n+\n #ifdef\t__cplusplus\n }\n #endif\ndiff --git a/drivers/common/sfc_efx/base/efx_virtio.c b/drivers/common/sfc_efx/base/efx_virtio.c\nnew file mode 100644\nindex 0000000000..1b7b01556e\n--- /dev/null\n+++ b/drivers/common/sfc_efx/base/efx_virtio.c\n@@ -0,0 +1,216 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ *\n+ * Copyright(c) 2020 Xilinx, Inc.\n+ */\n+\n+#include \"efx.h\"\n+#include \"efx_impl.h\"\n+\n+#if EFSYS_OPT_VIRTIO\n+\n+#if EFSYS_OPT_RIVERHEAD\n+static const efx_virtio_ops_t\t__efx_virtio_rhead_ops = {\n+\trhead_virtio_qstart,\t\t\t/* evo_virtio_qstart */\n+\trhead_virtio_qstop,\t\t\t/* evo_virtio_qstop */\n+};\n+#endif /* EFSYS_OPT_RIVERHEAD */\n+\n+\t__checkReturn\tefx_rc_t\n+efx_virtio_init(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\tconst efx_virtio_ops_t *evop;\n+\tefx_rc_t rc;\n+\n+\tEFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);\n+\tEFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);\n+\tEFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_VIRTIO));\n+\n+\tswitch (enp->en_family) {\n+#if EFSYS_OPT_RIVERHEAD\n+\tcase EFX_FAMILY_RIVERHEAD:\n+\t\tevop = &__efx_virtio_rhead_ops;\n+\t\tbreak;\n+#endif /* EFSYS_OPT_RIVERHEAD */\n+\n+\tdefault:\n+\t\tEFSYS_ASSERT(0);\n+\t\trc = ENOTSUP;\n+\t\tgoto fail1;\n+\t}\n+\n+\tenp->en_evop = evop;\n+\tenp->en_mod_flags |= EFX_MOD_VIRTIO;\n+\n+\treturn (0);\n+\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\tenp->en_evop = NULL;\n+\tenp->en_mod_flags &= ~EFX_MOD_VIRTIO;\n+\n+\treturn (rc);\n+}\n+\n+\tvoid\n+efx_virtio_fini(\n+\t__in\t\tefx_nic_t *enp)\n+{\n+\tEFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);\n+\tEFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);\n+\tEFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_VIRTIO);\n+\n+\tenp->en_evop = NULL;\n+\tenp->en_mod_flags &= ~EFX_MOD_VIRTIO;\n+}\n+\n+\t__checkReturn   efx_rc_t\n+efx_virtio_qcreate(\n+\t__in\t\tefx_nic_t *enp,\n+\t__deref_out\tefx_virtio_vq_t **evvpp)\n+{\n+\tconst efx_virtio_ops_t *evop = enp->en_evop;\n+\tefx_virtio_vq_t *evvp;\n+\tefx_rc_t rc;\n+\n+\tEFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);\n+\tEFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_VIRTIO);\n+\n+\t/* Allocate a virtqueue object */\n+\tEFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_virtio_vq_t), evvp);\n+\tif (evvp == NULL) {\n+\t\trc = ENOMEM;\n+\t\tgoto fail1;\n+\t}\n+\n+\tevvp->evv_magic = EFX_VQ_MAGIC;\n+\tevvp->evv_enp = enp;\n+\tevvp->evv_state = EFX_VIRTIO_VQ_STATE_INITIALIZED;\n+\n+\t*evvpp = evvp;\n+\n+\treturn (0);\n+\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+\t__checkReturn   efx_rc_t\n+efx_virtio_qstart(\n+\t__in\t\tefx_virtio_vq_t *evvp,\n+\t__in\t\tefx_virtio_vq_cfg_t *evvcp,\n+\t__in_opt\tefx_virtio_vq_dyncfg_t *evvdp)\n+{\n+\tconst efx_virtio_ops_t *evop;\n+\tefx_rc_t rc;\n+\n+\tif ((evvcp == NULL) || (evvp == NULL)) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\n+\tif (evvp->evv_state != EFX_VIRTIO_VQ_STATE_INITIALIZED) {\n+\t\trc = EINVAL;\n+\t\tgoto fail2;\n+\t}\n+\n+\tevop = evvp->evv_enp->en_evop;\n+\tif (evop == NULL) {\n+\t\trc = ENOTSUP;\n+\t\tgoto fail3;\n+\t}\n+\n+\tif ((rc = evop->evo_virtio_qstart(evvp, evvcp, evvdp)) != 0)\n+\t\tgoto fail4;\n+\n+\tevvp->evv_type = evvcp->evvc_type;\n+\tevvp->evv_target_vf = evvcp->evvc_target_vf;\n+\tevvp->evv_state = EFX_VIRTIO_VQ_STATE_STARTED;\n+\n+\treturn (0);\n+\n+fail4:\n+\tEFSYS_PROBE(fail4);\n+fail3:\n+\tEFSYS_PROBE(fail3);\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+\t__checkReturn   efx_rc_t\n+efx_virtio_qstop(\n+\t__in\t\tefx_virtio_vq_t *evvp,\n+\t__out_opt\tefx_virtio_vq_dyncfg_t *evvdp)\n+{\n+\tefx_nic_t *enp;\n+\tconst efx_virtio_ops_t *evop;\n+\tefx_rc_t rc;\n+\n+\tif (evvp == NULL) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\n+\tenp = evvp->evv_enp;\n+\tevop = enp->en_evop;\n+\n+\tEFSYS_ASSERT3U(evvp->evv_magic, ==, EFX_VQ_MAGIC);\n+\tEFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);\n+\tEFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_VIRTIO);\n+\n+\tif (evop == NULL) {\n+\t\trc = ENOTSUP;\n+\t\tgoto fail2;\n+\t}\n+\n+\tif (evvp->evv_state != EFX_VIRTIO_VQ_STATE_STARTED) {\n+\t\trc = EINVAL;\n+\t\tgoto fail3;\n+\t}\n+\n+\tif ((rc = evop->evo_virtio_qstop(evvp, evvdp)) != 0)\n+\t\tgoto fail4;\n+\n+\tevvp->evv_state = EFX_VIRTIO_VQ_STATE_INITIALIZED;\n+\n+\treturn 0;\n+\n+fail4:\n+\tEFSYS_PROBE(fail4);\n+fail3:\n+\tEFSYS_PROBE(fail3);\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+\tvoid\n+efx_virtio_qdestroy(\n+\t__in\t\tefx_virtio_vq_t *evvp)\n+{\n+\tefx_nic_t *enp;\n+\n+\tif (evvp == NULL)\n+\t\treturn;\n+\n+\tenp = evvp->evv_enp;\n+\n+\tEFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);\n+\n+\tif (evvp->evv_state == EFX_VIRTIO_VQ_STATE_INITIALIZED) {\n+\t\t/* Free the virtqueue object */\n+\t\tEFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_virtio_vq_t), evvp);\n+\t}\n+}\n+\n+#endif /* EFSYS_OPT_VIRTIO */\ndiff --git a/drivers/common/sfc_efx/base/meson.build b/drivers/common/sfc_efx/base/meson.build\nindex f995eacac2..1a39418c65 100644\n--- a/drivers/common/sfc_efx/base/meson.build\n+++ b/drivers/common/sfc_efx/base/meson.build\n@@ -29,6 +29,7 @@ sources = [\n \t'efx_tunnel.c',\n \t'efx_tx.c',\n \t'efx_vpd.c',\n+\t'efx_virtio.c',\n \t'mcdi_mon.c',\n \t'siena_mac.c',\n \t'siena_mcdi.c',\n@@ -61,6 +62,7 @@ sources = [\n \t'rhead_rx.c',\n \t'rhead_tunnel.c',\n \t'rhead_tx.c',\n+\t'rhead_virtio.c',\n ]\n \n extra_flags = [\ndiff --git a/drivers/common/sfc_efx/base/rhead_impl.h b/drivers/common/sfc_efx/base/rhead_impl.h\nindex 50262b16a8..a15ac52a58 100644\n--- a/drivers/common/sfc_efx/base/rhead_impl.h\n+++ b/drivers/common/sfc_efx/base/rhead_impl.h\n@@ -477,6 +477,23 @@ rhead_nic_xilinx_cap_tbl_read_ef100_locator(\n \t__in\t\t\t\tefsys_dma_addr_t offset,\n \t__out\t\t\t\tefx_bar_region_t *ebrp);\n \n+#if EFSYS_OPT_VIRTIO\n+\n+LIBEFX_INTERNAL\n+extern\t__checkReturn\t\t\tefx_rc_t\n+rhead_virtio_qstart(\n+\t__in\t\t\t\tefx_virtio_vq_t *evvp,\n+\t__in\t\t\t\tefx_virtio_vq_cfg_t *evvcp,\n+\t__in_opt\t\t\tefx_virtio_vq_dyncfg_t *evvdp);\n+\n+LIBEFX_INTERNAL\n+extern\t__checkReturn\t\t\tefx_rc_t\n+rhead_virtio_qstop(\n+\t__in\t\t\t\tefx_virtio_vq_t *evvp,\n+\t__out_opt\t\t\tefx_virtio_vq_dyncfg_t *evvdp);\n+\n+#endif /* EFSYS_OPT_VIRTIO */\n+\n #ifdef\t__cplusplus\n }\n #endif\ndiff --git a/drivers/common/sfc_efx/base/rhead_virtio.c b/drivers/common/sfc_efx/base/rhead_virtio.c\nnew file mode 100644\nindex 0000000000..d1719f834e\n--- /dev/null\n+++ b/drivers/common/sfc_efx/base/rhead_virtio.c\n@@ -0,0 +1,190 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ *\n+ * Copyright(c) 2020 Xilinx, Inc.\n+ */\n+\n+#include \"efx.h\"\n+#include \"efx_impl.h\"\n+\n+#if EFSYS_OPT_RIVERHEAD && EFSYS_OPT_VIRTIO\n+\n+/*\n+ * Get function-local index of the associated VI from the\n+ * virtqueue number queue 0 is reserved for MCDI\n+ */\n+#define EFX_VIRTIO_GET_VI_INDEX(vq_num) (((vq_num) / 2) + 1)\n+\n+\t__checkReturn   efx_rc_t\n+rhead_virtio_qstart(\n+\t__in\t\tefx_virtio_vq_t *evvp,\n+\t__in\t\tefx_virtio_vq_cfg_t *evvcp,\n+\t__in_opt\tefx_virtio_vq_dyncfg_t *evvdp)\n+\n+{\n+\tefx_nic_t *enp = evvp->evv_enp;\n+\tefx_mcdi_req_t req;\n+\tuint32_t vi_index;\n+\tEFX_MCDI_DECLARE_BUF(payload, MC_CMD_VIRTIO_INIT_QUEUE_REQ_LEN,\n+\t\tMC_CMD_VIRTIO_INIT_QUEUE_RESP_LEN);\n+\tefx_rc_t rc;\n+\n+\tEFX_STATIC_ASSERT(EFX_VIRTIO_VQ_TYPE_NET_RXQ ==\n+\t\tMC_CMD_VIRTIO_INIT_QUEUE_REQ_NET_RXQ);\n+\tEFX_STATIC_ASSERT(EFX_VIRTIO_VQ_TYPE_NET_TXQ ==\n+\t\tMC_CMD_VIRTIO_INIT_QUEUE_REQ_NET_TXQ);\n+\tEFX_STATIC_ASSERT(EFX_VIRTIO_VQ_TYPE_BLOCK ==\n+\t\tMC_CMD_VIRTIO_INIT_QUEUE_REQ_BLOCK);\n+\n+\tif (evvcp->evvc_type >= EFX_VIRTIO_VQ_NTYPES) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\n+\t/* virtqueue size must be power of 2 */\n+\tif ((!ISP2(evvcp->evvc_vq_size)) ||\n+\t    (evvcp->evvc_vq_size > EFX_VIRTIO_MAX_VQ_SIZE)) {\n+\t\trc = EINVAL;\n+\t\tgoto fail2;\n+\t}\n+\n+\tif (evvdp != NULL) {\n+\t\tif ((evvdp->evvd_vq_cidx > evvcp->evvc_vq_size) ||\n+\t\t    (evvdp->evvd_vq_pidx > evvcp->evvc_vq_size)) {\n+\t\t\trc = EINVAL;\n+\t\t\tgoto fail3;\n+\t\t}\n+\t}\n+\n+\treq.emr_cmd = MC_CMD_VIRTIO_INIT_QUEUE;\n+\treq.emr_in_buf = payload;\n+\treq.emr_in_length = MC_CMD_VIRTIO_INIT_QUEUE_REQ_LEN;\n+\treq.emr_out_buf = payload;\n+\treq.emr_out_length = MC_CMD_VIRTIO_INIT_QUEUE_RESP_LEN;\n+\n+\tMCDI_IN_SET_BYTE(req, VIRTIO_INIT_QUEUE_REQ_QUEUE_TYPE,\n+\t\tevvcp->evvc_type);\n+\tMCDI_IN_SET_WORD(req, VIRTIO_INIT_QUEUE_REQ_TARGET_VF,\n+\t\tevvcp->evvc_target_vf);\n+\n+\tvi_index = EFX_VIRTIO_GET_VI_INDEX(evvcp->evvc_vq_num);\n+\tMCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_INSTANCE, vi_index);\n+\n+\tMCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_SIZE,\n+\t\tevvcp->evvc_vq_size);\n+\n+\tMCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_DESC_TBL_ADDR_LO,\n+\t\tevvcp->evvc_desc_tbl_addr & 0xFFFFFFFF);\n+\tMCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_DESC_TBL_ADDR_HI,\n+\t\tevvcp->evvc_desc_tbl_addr >> 32);\n+\n+\tMCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_AVAIL_RING_ADDR_LO,\n+\t\tevvcp->evvc_avail_ring_addr & 0xFFFFFFFF);\n+\tMCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_AVAIL_RING_ADDR_HI,\n+\t\tevvcp->evvc_avail_ring_addr >> 32);\n+\n+\tMCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_USED_RING_ADDR_LO,\n+\t\tevvcp->evvc_used_ring_addr & 0xFFFFFFFF);\n+\tMCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_USED_RING_ADDR_HI,\n+\t\tevvcp->evvc_used_ring_addr >> 32);\n+\n+\tif (evvcp->evvc_use_pasid) {\n+\t\tMCDI_IN_POPULATE_DWORD_1(req, VIRTIO_INIT_QUEUE_REQ_FLAGS,\n+\t\t\tVIRTIO_INIT_QUEUE_REQ_USE_PASID, 1);\n+\t\tMCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_PASID,\n+\t\t\tevvcp->evvc_pas_id);\n+\t}\n+\n+\tMCDI_IN_SET_WORD(req, VIRTIO_INIT_QUEUE_REQ_MSIX_VECTOR,\n+\t\tevvcp->evvc_msix_vector);\n+\n+\tMCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_FEATURES_LO,\n+\t\tevvcp->evcc_features & 0xFFFFFFFF);\n+\tMCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_FEATURES_HI,\n+\t\tevvcp->evcc_features >> 32);\n+\n+\tif (evvdp != NULL) {\n+\t\tMCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_INITIAL_PIDX,\n+\t\t\tevvdp->evvd_vq_pidx);\n+\t\tMCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_INITIAL_CIDX,\n+\t\t\tevvdp->evvd_vq_cidx);\n+\t}\n+\n+\tMCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_MPORT_SELECTOR,\n+\t\tMAE_MPORT_SELECTOR_ASSIGNED);\n+\n+\tefx_mcdi_execute(enp, &req);\n+\n+\tif (req.emr_rc != 0) {\n+\t\trc = req.emr_rc;\n+\t\tgoto fail4;\n+\t}\n+\n+\tevvp->evv_vi_index = vi_index;\n+\n+\treturn (0);\n+\n+fail4:\n+\tEFSYS_PROBE(fail4);\n+fail3:\n+\tEFSYS_PROBE(fail3);\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+\t__checkReturn   efx_rc_t\n+rhead_virtio_qstop(\n+\t__in\t\tefx_virtio_vq_t *evvp,\n+\t__out_opt\tefx_virtio_vq_dyncfg_t *evvdp)\n+{\n+\tefx_mcdi_req_t req;\n+\tefx_nic_t *enp = evvp->evv_enp;\n+\tEFX_MCDI_DECLARE_BUF(payload, MC_CMD_VIRTIO_FINI_QUEUE_REQ_LEN,\n+\t\tMC_CMD_VIRTIO_FINI_QUEUE_RESP_LEN);\n+\tefx_rc_t rc;\n+\n+\treq.emr_cmd = MC_CMD_VIRTIO_FINI_QUEUE;\n+\treq.emr_in_buf = payload;\n+\treq.emr_in_length = MC_CMD_VIRTIO_FINI_QUEUE_REQ_LEN;\n+\treq.emr_out_buf = payload;\n+\treq.emr_out_length = MC_CMD_VIRTIO_FINI_QUEUE_RESP_LEN;\n+\n+\tMCDI_IN_SET_BYTE(req, VIRTIO_FINI_QUEUE_REQ_QUEUE_TYPE, evvp->evv_type);\n+\tMCDI_IN_SET_WORD(req, VIRTIO_INIT_QUEUE_REQ_TARGET_VF,\n+\t\tevvp->evv_target_vf);\n+\tMCDI_IN_SET_DWORD(req, VIRTIO_INIT_QUEUE_REQ_INSTANCE,\n+\t\tevvp->evv_vi_index);\n+\n+\tefx_mcdi_execute(enp, &req);\n+\n+\tif (req.emr_rc != 0) {\n+\t\trc = req.emr_rc;\n+\t\tgoto fail1;\n+\t}\n+\n+\tif (req.emr_out_length_used < MC_CMD_VIRTIO_FINI_QUEUE_RESP_LEN) {\n+\t\trc = EMSGSIZE;\n+\t\tgoto fail2;\n+\t}\n+\n+\tif (evvdp != NULL) {\n+\t\tevvdp->evvd_vq_pidx =\n+\t\t    MCDI_OUT_DWORD(req, VIRTIO_FINI_QUEUE_RESP_FINAL_PIDX);\n+\t\tevvdp->evvd_vq_cidx =\n+\t\t    MCDI_OUT_DWORD(req, VIRTIO_FINI_QUEUE_RESP_FINAL_CIDX);\n+\t}\n+\n+\treturn (0);\n+\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+#endif\t/* EFSYS_OPT_RIVERHEAD && EFSYS_OPT_VIRTIO */\ndiff --git a/drivers/common/sfc_efx/efsys.h b/drivers/common/sfc_efx/efsys.h\nindex 663601412e..d133d61b3d 100644\n--- a/drivers/common/sfc_efx/efsys.h\n+++ b/drivers/common/sfc_efx/efsys.h\n@@ -187,6 +187,8 @@ prefetch_read_once(const volatile void *addr)\n \n #define EFSYS_OPT_MAE 1\n \n+#define EFSYS_OPT_VIRTIO 0\n+\n /* ID */\n \n typedef struct __efsys_identifier_s efsys_identifier_t;\n",
    "prefixes": [
        "v3",
        "1/8"
    ]
}