get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 85509,
    "url": "https://patches.dpdk.org/api/patches/85509/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20201219143816.64174-3-jingjing.wu@intel.com/",
    "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": "<20201219143816.64174-3-jingjing.wu@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20201219143816.64174-3-jingjing.wu@intel.com",
    "date": "2020-12-19T14:38:16",
    "name": "[v1,2/2] net/iavf: introduce iavf driver on vfio-user client",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "6178f44fba2c3141671dabc383eaea78182dce18",
    "submitter": {
        "id": 47,
        "url": "https://patches.dpdk.org/api/people/47/?format=api",
        "name": "Jingjing Wu",
        "email": "jingjing.wu@intel.com"
    },
    "delegate": {
        "id": 1540,
        "url": "https://patches.dpdk.org/api/users/1540/?format=api",
        "username": "qzhan15",
        "first_name": "Qi",
        "last_name": "Zhang",
        "email": "qi.z.zhang@intel.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20201219143816.64174-3-jingjing.wu@intel.com/mbox/",
    "series": [
        {
            "id": 14387,
            "url": "https://patches.dpdk.org/api/series/14387/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=14387",
            "date": "2020-12-19T14:38:14",
            "name": "introduce new iavf driver on vfio-user client",
            "version": 1,
            "mbox": "https://patches.dpdk.org/series/14387/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/85509/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/85509/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 dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id A5154A04B5;\n\tSat, 19 Dec 2020 15:50:12 +0100 (CET)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id E8C56CB46;\n\tSat, 19 Dec 2020 15:49:34 +0100 (CET)",
            "from mga03.intel.com (mga03.intel.com [134.134.136.65])\n by dpdk.org (Postfix) with ESMTP id D8E92CB33\n for <dev@dpdk.org>; Sat, 19 Dec 2020 15:49:31 +0100 (CET)",
            "from orsmga001.jf.intel.com ([10.7.209.18])\n by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 19 Dec 2020 06:49:31 -0800",
            "from dpdk-wujingji.sh.intel.com ([10.67.119.101])\n by orsmga001.jf.intel.com with ESMTP; 19 Dec 2020 06:49:29 -0800"
        ],
        "IronPort-SDR": [
            "\n q/LLbocSzkvPeYMDYNKmSfcDAAUqXxRj3yo+jULGFcH7wW8GamW/INu4pGlyw+CzYO6LsNr9H9\n 8Rx4I+Mz006Q==",
            "\n t6IepPBM7X3dY+u3xUiqcfu/vRnQ2E1dMMO7aHRuy/b9m387qCHd3gf7h6qW5q3YN26JY2qKk4\n hTYoX/FS1nYg=="
        ],
        "X-IronPort-AV": [
            "E=McAfee;i=\"6000,8403,9839\"; a=\"175678241\"",
            "E=Sophos;i=\"5.78,433,1599548400\"; d=\"scan'208\";a=\"175678241\"",
            "E=Sophos;i=\"5.78,433,1599548400\"; d=\"scan'208\";a=\"414722511\""
        ],
        "X-ExtLoop1": "1",
        "From": "Jingjing Wu <jingjing.wu@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "jingjing.wu@intel.com, beilei.xing@intel.com, chenbo.xia@intel.com,\n xiuchun.lu@intel.com",
        "Date": "Sat, 19 Dec 2020 22:38:16 +0800",
        "Message-Id": "<20201219143816.64174-3-jingjing.wu@intel.com>",
        "X-Mailer": "git-send-email 2.21.1",
        "In-Reply-To": "<20201219143816.64174-1-jingjing.wu@intel.com>",
        "References": "<20201219143816.64174-1-jingjing.wu@intel.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH v1 2/2] net/iavf: introduce iavf driver on\n\tvfio-user client",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "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": "This patch add a new net driver based on vdev abstraction,\ni.e. iavf_client_ethdev.c. It is using common iavf functions\nto talk with Emulated pci interfaces based on vfio-user.\n\n      ----------------------\n      | ------------------ |\n      | |  iavf driver   | |----> (iavf_client_ethdev.c)\n      | ------------------ |\n      | ------------------ |\n      | | device emulate | |\n      | | vfio-user adapt| |\n      | ------------------ |\n      ----------------------\n                |\n                |\n      ----------------------\n      |      vfio-user     |\n      |       client       |\n      ----------------------\n\nSigned-off-by: Jingjing Wu <jingjing.wu@intel.com>\n---\n drivers/common/iavf/iavf_prototype.h  |   1 +\n drivers/common/iavf/version.map       |   1 +\n drivers/net/iavf/iavf.h               |  18 +-\n drivers/net/iavf/iavf_client_ethdev.c | 298 ++++++++++++++++++++++++++\n drivers/net/iavf/iavf_ethdev.c        |  26 +--\n drivers/net/iavf/iavf_rxtx.c          |  23 +-\n drivers/net/iavf/meson.build          |   1 +\n 7 files changed, 347 insertions(+), 21 deletions(-)\n create mode 100644 drivers/net/iavf/iavf_client_ethdev.c",
    "diff": "diff --git a/drivers/common/iavf/iavf_prototype.h b/drivers/common/iavf/iavf_prototype.h\nindex f34e77db0f..3998d26dc0 100644\n--- a/drivers/common/iavf/iavf_prototype.h\n+++ b/drivers/common/iavf/iavf_prototype.h\n@@ -83,6 +83,7 @@ void iavf_destroy_spinlock(struct iavf_spinlock *sp);\n __rte_internal\n void iavf_vf_parse_hw_config(struct iavf_hw *hw,\n \t\t\t     struct virtchnl_vf_resource *msg);\n+__rte_internal\n enum iavf_status iavf_vf_reset(struct iavf_hw *hw);\n __rte_internal\n enum iavf_status iavf_aq_send_msg_to_pf(struct iavf_hw *hw,\ndiff --git a/drivers/common/iavf/version.map b/drivers/common/iavf/version.map\nindex 8808779ab7..4dc2d42196 100644\n--- a/drivers/common/iavf/version.map\n+++ b/drivers/common/iavf/version.map\n@@ -7,6 +7,7 @@ INTERNAL {\n \tiavf_set_mac_type;\n \tiavf_shutdown_adminq;\n \tiavf_vf_parse_hw_config;\n+\tiavf_vf_reset;\n \tclient_vfio_user_setup;\n \tclient_vfio_user_get_bar_addr;\n \tiavf_write_addr;\ndiff --git a/drivers/net/iavf/iavf.h b/drivers/net/iavf/iavf.h\nindex 6d5912d8c1..c34f971721 100644\n--- a/drivers/net/iavf/iavf.h\n+++ b/drivers/net/iavf/iavf.h\n@@ -195,7 +195,10 @@ struct iavf_adapter {\n \tstruct iavf_hw hw;\n \tstruct rte_eth_dev *eth_dev;\n \tstruct iavf_info vf;\n-\n+#ifdef RTE_LIBRTE_IAVF_CLIENT\n+\t/* used for avf_client driver */\n+\tstruct vfio_device *user_dev;\n+#endif\n \tbool rx_bulk_alloc_allowed;\n \t/* For vector PMD */\n \tbool rx_vec_allowed;\n@@ -231,6 +234,16 @@ iavf_init_adminq_parameter(struct iavf_hw *hw)\n \thw->aq.asq_buf_size = IAVF_AQ_BUF_SZ;\n }\n \n+static inline void\n+iavf_disable_irq0(struct iavf_hw *hw)\n+{\n+\t/* Disable all interrupt types */\n+\tIAVF_WRITE_REG(hw, IAVF_VFINT_ICR0_ENA1, 0);\n+\tIAVF_WRITE_REG(hw, IAVF_VFINT_DYN_CTL01,\n+\t\t       IAVF_VFINT_DYN_CTL01_ITR_INDX_MASK);\n+\tIAVF_WRITE_FLUSH(hw);\n+}\n+\n static inline uint16_t\n iavf_calc_itr_interval(int16_t interval)\n {\n@@ -284,6 +297,9 @@ _atomic_set_cmd(struct iavf_info *vf, enum virtchnl_ops ops)\n \treturn !ret;\n }\n \n+extern const struct eth_dev_ops iavf_eth_dev_ops;\n+\n+int iavf_init_vf(struct rte_eth_dev *dev);\n int iavf_check_api_version(struct iavf_adapter *adapter);\n int iavf_get_vf_resource(struct iavf_adapter *adapter);\n void iavf_handle_virtchnl_msg(struct rte_eth_dev *dev);\ndiff --git a/drivers/net/iavf/iavf_client_ethdev.c b/drivers/net/iavf/iavf_client_ethdev.c\nnew file mode 100644\nindex 0000000000..03f759c761\n--- /dev/null\n+++ b/drivers/net/iavf/iavf_client_ethdev.c\n@@ -0,0 +1,298 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2017 Intel Corporation\n+ */\n+\n+#include <errno.h>\n+#include <stdint.h>\n+#include <string.h>\n+\n+#include <rte_common.h>\n+#include <rte_ether.h>\n+#include <rte_ethdev_driver.h>\n+#include <rte_ethdev_vdev.h>\n+#include <rte_alarm.h>\n+#include <rte_bus_vdev.h>\n+#include <rte_malloc.h>\n+#include <vfio_user/vfio_user_pci.h>\n+\n+#include \"iavf.h\"\n+#include \"iavf_rxtx.h\"\n+\n+static int iavf_client_dev_close(struct rte_eth_dev *dev);\n+static int iavf_client_dev_reset(struct rte_eth_dev *dev);\n+\n+/* set iavf_client_dev_ops to iavf's by default */\n+static struct eth_dev_ops iavf_client_eth_dev_ops;\n+\n+static const char *valid_args[] = {\n+#define AVF_CLIENT_ARG_PATH           \"path\"\n+\tAVF_CLIENT_ARG_PATH,\n+\tNULL\n+};\n+\n+/* set up vfio_device for iavf_client*/\n+static int\n+iavf_client_vfio_user_setup(struct rte_eth_dev *dev, const char *path)\n+{\n+\tstruct iavf_adapter *adapter =\n+\t\tIAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);\n+\tstruct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(adapter);\n+\tstruct vfio_device *vfio_dev;\n+\tint max_fds, i;\n+\n+\tvfio_dev = client_vfio_user_setup(path, dev->device->numa_node);\n+\tif (vfio_dev == NULL) {\n+\t\tprintf(\"Error to create vfio_device for iavf_client\\n\");\n+\t\treturn -1;\n+\t}\n+\thw->bus.type = iavf_bus_type_vfio_user;\n+\n+\t/* Use hw_addr to record dev ptr */\n+\thw->hw_addr = (uint8_t *)vfio_dev;\n+\n+\thw->back = IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);\n+\n+\tif (!dev->intr_handle) {\n+\t\tdev->intr_handle = malloc(sizeof(*dev->intr_handle));\n+\t\tif (!dev->intr_handle) {\n+\t\t\tPMD_INIT_LOG(ERR, \"fail to allocate intr_handle\");\n+\t\t\treturn -1;\n+\t\t}\n+\t\tmemset(dev->intr_handle, 0, sizeof(*dev->intr_handle));\n+\t}\n+\n+\tmax_fds = RTE_MIN(RTE_MAX_RXTX_INTR_VEC_ID, adapter->vf.num_queue_pairs);\n+\n+\t/* FD for control has been enabled */\n+\tdev->intr_handle->fd = -1;\n+\tdev->intr_handle->type = RTE_INTR_HANDLE_VDEV;\n+\tdev->intr_handle->max_intr = max_fds + 1;\n+\tdev->intr_handle->nb_efd = max_fds;\n+\tfor (i = 0; i < max_fds; ++i)\n+\t\tdev->intr_handle->efds[i] = vfio_dev->irqfds[i];\n+\tdev->intr_handle->efd_counter_size = 0;\n+\n+\treturn 0;\n+}\n+\n+\n+static inline void\n+avf_client_init_eth_ops(void)\n+{\n+\tiavf_client_eth_dev_ops = iavf_eth_dev_ops;\n+\t/* keep other unchanged */\n+\tiavf_client_eth_dev_ops.dev_close  = iavf_client_dev_close,\n+\tiavf_client_eth_dev_ops.dev_reset  = iavf_client_dev_reset,\n+\tiavf_client_eth_dev_ops.dev_supported_ptypes_get   = NULL;\n+\tiavf_client_eth_dev_ops.reta_update                = NULL;\n+\tiavf_client_eth_dev_ops.reta_query                 = NULL;\n+\tiavf_client_eth_dev_ops.rss_hash_update            = NULL;\n+\tiavf_client_eth_dev_ops.rss_hash_conf_get          = NULL;\n+\tiavf_client_eth_dev_ops.rx_queue_intr_enable       = NULL;\n+\tiavf_client_eth_dev_ops.rx_queue_intr_disable      = NULL;\n+}\n+\n+#define IAVF_CLIENT_ALARM_INTERVAL 50000 /* us */\n+static void\n+iavf_client_dev_alarm_handler(void *param)\n+{\n+\tstruct rte_eth_dev *dev = (struct rte_eth_dev *)param;\n+\n+\tiavf_handle_virtchnl_msg(dev);\n+\n+\trte_eal_alarm_set(IAVF_CLIENT_ALARM_INTERVAL,\n+\t\t\t  iavf_client_dev_alarm_handler, dev);\n+}\n+\n+/* init ethdev for the avf client device*/\n+static int\n+iavf_client_eth_init(struct rte_eth_dev *eth_dev)\n+{\n+\tstruct iavf_adapter *adapter =\n+\t\tIAVF_DEV_PRIVATE_TO_ADAPTER(eth_dev->data->dev_private);\n+\tstruct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(adapter);\n+\n+\t/* update eth_dev_op by assigning ops func pointer */\n+\tavf_client_init_eth_ops();\n+\teth_dev->dev_ops = (const struct eth_dev_ops *)(&iavf_client_eth_dev_ops);\n+\n+\teth_dev->rx_pkt_burst = &iavf_recv_pkts;\n+\teth_dev->tx_pkt_burst = &iavf_xmit_pkts;\n+\teth_dev->tx_pkt_prepare = &iavf_prep_pkts;\n+\n+\thw->back = IAVF_DEV_PRIVATE_TO_ADAPTER(eth_dev->data->dev_private);\n+\tadapter->eth_dev = eth_dev;\n+\tadapter->stopped = 1;\n+\n+\tif (iavf_init_vf(eth_dev) != 0) {\n+\t\tPMD_INIT_LOG(ERR, \"Init vf failed\");\n+\t\treturn -1;\n+\t}\n+\n+\t/* copy mac addr */\n+\teth_dev->data->mac_addrs = rte_zmalloc(\n+\t\t\t\"iavf_client_mac\",\n+\t\t\tRTE_ETHER_ADDR_LEN * IAVF_NUM_MACADDR_MAX, 0);\n+\tif (!eth_dev->data->mac_addrs) {\n+\t\tPMD_INIT_LOG(ERR, \"Failed to allocate %d bytes needed to\"\n+\t\t\t     \" store MAC addresses\",\n+\t\t\t     RTE_ETHER_ADDR_LEN * IAVF_NUM_MACADDR_MAX);\n+\t\treturn -ENOMEM;\n+\t}\n+\t/* If the MAC address is not configured by host,\n+\t * generate a random one.\n+\t */\n+\tif (!rte_is_valid_assigned_ether_addr(\n+\t\t\t(struct rte_ether_addr *)hw->mac.addr))\n+\t\trte_eth_random_addr(hw->mac.addr);\n+\trte_ether_addr_copy((struct rte_ether_addr *)hw->mac.addr,\n+\t\t\t&eth_dev->data->mac_addrs[0]);\n+\n+\trte_eal_alarm_set(IAVF_CLIENT_ALARM_INTERVAL,\n+\t\t\t  iavf_client_dev_alarm_handler, eth_dev);\n+\treturn 0;\n+}\n+\n+static int\n+iavf_client_dev_reset(struct rte_eth_dev *dev)\n+{\n+\tstruct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tint ret;\n+\n+\trte_eal_alarm_cancel(iavf_client_dev_alarm_handler, dev);\n+\n+\tiavf_shutdown_adminq(hw);\n+\tret = iavf_init_vf(dev);\n+\n+\t/* send reset msg to PF */\n+\tiavf_vf_reset(hw);\n+\trte_eal_alarm_set(IAVF_CLIENT_ALARM_INTERVAL,\n+\t\t\t  iavf_client_dev_alarm_handler, dev);\n+\n+\treturn ret;\n+}\n+\n+static int\n+iavf_client_dev_close(struct rte_eth_dev *dev)\n+{\n+\tstruct iavf_adapter *adapter =\n+\t\tIAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);\n+\tstruct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tstruct rte_intr_handle *intr_handle = dev->intr_handle;\n+\n+\tif (!adapter->stopped) {\n+\t\tiavf_stop_queues(dev);\n+\n+\t\tif (intr_handle) {\n+\t\t\t/* Disable the interrupt for Rx */\n+\t\t\trte_intr_efd_disable(intr_handle);\n+\t\t\t/* Rx interrupt vector mapping free */\n+\t\t\tif (intr_handle->intr_vec) {\n+\t\t\t\trte_free(intr_handle->intr_vec);\n+\t\t\t\tintr_handle->intr_vec = NULL;\n+\t\t\t}\n+\t\t}\n+\t\t/* Remove all mac addrs */\n+\t\tiavf_add_del_all_mac_addr(adapter, false);\n+\t\tadapter->stopped = 1;\n+\t}\n+\tiavf_shutdown_adminq(hw);\n+\tiavf_disable_irq0(hw);\n+\trte_eal_alarm_cancel(iavf_client_dev_alarm_handler, dev);\n+\n+\treturn 0;\n+}\n+\n+static int\n+iavf_client_get_string_arg(const char *key __rte_unused,\n+\t       const char *value, void *extra_args)\n+{\n+\tif (!value || !extra_args)\n+\t\treturn -EINVAL;\n+\n+\t*(char **)extra_args = strdup(value);\n+\n+\tif (!*(char **)extra_args)\n+\t\treturn -ENOMEM;\n+\n+\treturn 0;\n+}\n+\n+static int\n+avf_client_pmd_probe(struct rte_vdev_device *vdev)\n+{\n+\tstruct rte_kvargs *kvlist = NULL;\n+\tstruct rte_eth_dev *eth_dev;\n+\tstruct iavf_adapter *adapter;\n+\tchar *path = NULL;\n+\tint ret;\n+\n+\tkvlist = rte_kvargs_parse(rte_vdev_device_args(vdev), valid_args);\n+\tif (!kvlist) {\n+\t\tPMD_INIT_LOG(ERR, \"error when parsing param\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (rte_kvargs_count(kvlist, AVF_CLIENT_ARG_PATH) == 1) {\n+\t\tif (rte_kvargs_process(kvlist, AVF_CLIENT_ARG_PATH,\n+\t\t\t\t       &iavf_client_get_string_arg, &path) < 0) {\n+\t\t\tPMD_INIT_LOG(ERR, \"error to parse %s\",\n+\t\t\t\t     AVF_CLIENT_ARG_PATH);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t} else {\n+\t\tPMD_INIT_LOG(ERR, \"arg %s is mandatory for virtio_user\",\n+\t\t\t     AVF_CLIENT_ARG_PATH);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\teth_dev = rte_eth_vdev_allocate(vdev, sizeof(*adapter));\n+\n+\tret = iavf_client_vfio_user_setup(eth_dev, path);\n+\tif (ret) {\n+\t\tgoto err;\n+\t}\n+\n+\tret = iavf_client_eth_init(eth_dev);\n+\tif (ret) {\n+\t\tgoto err;\n+\t}\n+\n+\trte_eth_dev_probing_finish(eth_dev);\n+\trte_kvargs_free(kvlist);\n+\n+\treturn 0;\n+err:\n+\trte_eth_dev_release_port(eth_dev);\n+\trte_kvargs_free(kvlist);\n+\treturn ret;\n+}\n+\n+\n+static int\n+avf_client_pmd_remove(struct rte_vdev_device *vdev)\n+{\n+\tstruct rte_eth_dev *eth_dev = NULL;\n+\n+\tif (vdev == NULL)\n+\t\treturn -1;\n+\n+\t/* find the ethdev entry */\n+\teth_dev = rte_eth_dev_allocated(rte_vdev_device_name(vdev));\n+\tif (eth_dev == NULL)\n+\t\treturn 0;\n+\n+\tiavf_client_dev_close(eth_dev);\n+\trte_eth_dev_release_port(eth_dev);\n+\treturn 0;\n+}\n+\n+static struct rte_vdev_driver iavf_client_driver = {\n+\t.probe = avf_client_pmd_probe,\n+\t.remove = avf_client_pmd_remove,\n+};\n+\n+RTE_PMD_REGISTER_VDEV(net_iavf_client, iavf_client_driver);\n+RTE_PMD_REGISTER_ALIAS(net_iavf_client, iavf_client);\n+RTE_PMD_REGISTER_PARAM_STRING(net_iavf_client,\n+\t\"path=<path>\");\ndiff --git a/drivers/net/iavf/iavf_ethdev.c b/drivers/net/iavf/iavf_ethdev.c\nindex 7e3c26a94e..6b5e47adf2 100644\n--- a/drivers/net/iavf/iavf_ethdev.c\n+++ b/drivers/net/iavf/iavf_ethdev.c\n@@ -154,7 +154,7 @@ static const struct rte_iavf_xstats_name_off rte_iavf_stats_strings[] = {\n #define IAVF_NB_XSTATS (sizeof(rte_iavf_stats_strings) / \\\n \t\tsizeof(rte_iavf_stats_strings[0]))\n \n-static const struct eth_dev_ops iavf_eth_dev_ops = {\n+const struct eth_dev_ops iavf_eth_dev_ops = {\n \t.dev_configure              = iavf_dev_configure,\n \t.dev_start                  = iavf_dev_start,\n \t.dev_stop                   = iavf_dev_stop,\n@@ -1780,7 +1780,7 @@ iavf_init_proto_xtr(struct rte_eth_dev *dev)\n \t}\n }\n \n-static int\n+int\n iavf_init_vf(struct rte_eth_dev *dev)\n {\n \tint err, bufsz;\n@@ -1789,12 +1789,6 @@ iavf_init_vf(struct rte_eth_dev *dev)\n \tstruct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n \tstruct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);\n \n-\terr = iavf_parse_devargs(dev);\n-\tif (err) {\n-\t\tPMD_INIT_LOG(ERR, \"Failed to parse devargs\");\n-\t\tgoto err;\n-\t}\n-\n \terr = iavf_set_mac_type(hw);\n \tif (err) {\n \t\tPMD_INIT_LOG(ERR, \"set_mac_type failed: %d\", err);\n@@ -1891,16 +1885,6 @@ iavf_enable_irq0(struct iavf_hw *hw)\n \tIAVF_WRITE_FLUSH(hw);\n }\n \n-static inline void\n-iavf_disable_irq0(struct iavf_hw *hw)\n-{\n-\t/* Disable all interrupt types */\n-\tIAVF_WRITE_REG(hw, IAVF_VFINT_ICR0_ENA1, 0);\n-\tIAVF_WRITE_REG(hw, IAVF_VFINT_DYN_CTL01,\n-\t\t       IAVF_VFINT_DYN_CTL01_ITR_INDX_MASK);\n-\tIAVF_WRITE_FLUSH(hw);\n-}\n-\n static void\n iavf_dev_interrupt_handler(void *param)\n {\n@@ -1986,6 +1970,12 @@ iavf_dev_init(struct rte_eth_dev *eth_dev)\n \tadapter->eth_dev = eth_dev;\n \tadapter->stopped = 1;\n \n+\tret  = iavf_parse_devargs(eth_dev);\n+\tif (ret) {\n+\t\tPMD_INIT_LOG(ERR, \"Failed to parse devargs\");\n+\t\treturn ret;\n+\t}\n+\n \tif (iavf_init_vf(eth_dev) != 0) {\n \t\tPMD_INIT_LOG(ERR, \"Init vf failed\");\n \t\treturn -1;\ndiff --git a/drivers/net/iavf/iavf_rxtx.c b/drivers/net/iavf/iavf_rxtx.c\nindex 21d508b3f4..d8192f3675 100644\n--- a/drivers/net/iavf/iavf_rxtx.c\n+++ b/drivers/net/iavf/iavf_rxtx.c\n@@ -24,6 +24,9 @@\n #include <rte_ip.h>\n #include <rte_net.h>\n #include <rte_vect.h>\n+#ifdef RTE_LIBRTE_IAVF_CLIENT\n+#include <vfio_user/vfio_user_pci.h>\n+#endif\n \n #include \"iavf.h\"\n #include \"iavf_rxtx.h\"\n@@ -595,7 +598,15 @@ iavf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,\n \treset_rx_queue(rxq);\n \trxq->q_set = true;\n \tdev->data->rx_queues[queue_idx] = rxq;\n-\trxq->qrx_tail = hw->hw_addr + IAVF_QRX_TAIL1(rxq->queue_id);\n+\n+#ifdef RTE_LIBRTE_IAVF_CLIENT\n+\tif (hw->bus.type == iavf_bus_type_vfio_user)\n+\t\trxq->qrx_tail = client_vfio_user_get_bar_addr(\n+\t\t\t\t(struct vfio_device *)hw->hw_addr, 0,\n+\t\t\t\tIAVF_QRX_TAIL1(rxq->queue_id), 4);\n+\telse\n+#endif\n+\t\trxq->qrx_tail = hw->hw_addr + IAVF_QRX_TAIL1(rxq->queue_id);\n \trxq->ops = &def_rxq_ops;\n \n \tif (check_rx_bulk_allow(rxq) == true) {\n@@ -705,7 +716,15 @@ iavf_dev_tx_queue_setup(struct rte_eth_dev *dev,\n \treset_tx_queue(txq);\n \ttxq->q_set = true;\n \tdev->data->tx_queues[queue_idx] = txq;\n-\ttxq->qtx_tail = hw->hw_addr + IAVF_QTX_TAIL1(queue_idx);\n+#ifdef RTE_LIBRTE_IAVF_CLIENT\n+\tif (hw->bus.type == iavf_bus_type_vfio_user)\n+\t\ttxq->qtx_tail = client_vfio_user_get_bar_addr(\n+\t\t\t(struct vfio_device *)hw->hw_addr, 0,\n+\t\t\tIAVF_QTX_TAIL1(queue_idx), 4);\n+\telse\n+#endif\n+\t\ttxq->qtx_tail = hw->hw_addr + IAVF_QTX_TAIL1(queue_idx);\n+\n \ttxq->ops = &def_txq_ops;\n \n \tif (check_tx_vec_allow(txq) == false) {\ndiff --git a/drivers/net/iavf/meson.build b/drivers/net/iavf/meson.build\nindex 26c02c4401..580307c462 100644\n--- a/drivers/net/iavf/meson.build\n+++ b/drivers/net/iavf/meson.build\n@@ -13,6 +13,7 @@ sources = files(\n \t'iavf_generic_flow.c',\n \t'iavf_fdir.c',\n \t'iavf_hash.c',\n+\t'iavf_client_ethdev.c',\n )\n \n if arch_subdir == 'x86'\n",
    "prefixes": [
        "v1",
        "2/2"
    ]
}