get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 85503,
    "url": "https://patches.dpdk.org/api/patches/85503/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20201219075454.40266-4-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": "<20201219075454.40266-4-jingjing.wu@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20201219075454.40266-4-jingjing.wu@intel.com",
    "date": "2020-12-19T07:54:52",
    "name": "[v1,3/5] net/iavf_be: virtchnl messages process",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "72d788099da4264b700a1c84c1e96415b5920bdf",
    "submitter": {
        "id": 47,
        "url": "https://patches.dpdk.org/api/people/47/?format=api",
        "name": "Jingjing Wu",
        "email": "jingjing.wu@intel.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20201219075454.40266-4-jingjing.wu@intel.com/mbox/",
    "series": [
        {
            "id": 14385,
            "url": "https://patches.dpdk.org/api/series/14385/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=14385",
            "date": "2020-12-19T07:54:49",
            "name": "introduce iavf backend driver",
            "version": 1,
            "mbox": "https://patches.dpdk.org/series/14385/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/85503/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/85503/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 796D0A04B5;\n\tSat, 19 Dec 2020 09:07:08 +0100 (CET)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 95D10CB77;\n\tSat, 19 Dec 2020 09:06:13 +0100 (CET)",
            "from mga17.intel.com (mga17.intel.com [192.55.52.151])\n by dpdk.org (Postfix) with ESMTP id 10ED5CB35\n for <dev@dpdk.org>; Sat, 19 Dec 2020 09:06:09 +0100 (CET)",
            "from fmsmga001.fm.intel.com ([10.253.24.23])\n by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 19 Dec 2020 00:06:09 -0800",
            "from dpdk-wujingji.sh.intel.com ([10.67.119.101])\n by fmsmga001.fm.intel.com with ESMTP; 19 Dec 2020 00:06:06 -0800"
        ],
        "IronPort-SDR": [
            "\n iyzYacX0j4Osnlp3SowKSBJ52wKbeYArk2fS0iIqs4X2/mZCRJu2OG0eOwr93k2HOqIirVkPrU\n Pw01zj42ta8Q==",
            "\n tz7vstmsAp/gCRcBG/UuCUt6A+KBcfs4VSAV3LxBI/5h7sKp8ZBS5xLzXvJ71bxEHVPVc/qb8H\n sRRIMvJvKY7w=="
        ],
        "X-IronPort-AV": [
            "E=McAfee;i=\"6000,8403,9839\"; a=\"155353439\"",
            "E=Sophos;i=\"5.78,432,1599548400\"; d=\"scan'208\";a=\"155353439\"",
            "E=Sophos;i=\"5.78,432,1599548400\"; d=\"scan'208\";a=\"454532427\""
        ],
        "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 15:54:52 +0800",
        "Message-Id": "<20201219075454.40266-4-jingjing.wu@intel.com>",
        "X-Mailer": "git-send-email 2.21.1",
        "In-Reply-To": "<20201219075454.40266-1-jingjing.wu@intel.com>",
        "References": "<20201219075454.40266-1-jingjing.wu@intel.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH v1 3/5] net/iavf_be: virtchnl messages process",
        "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": "1. Process virtchnl messages from Front End.\n2. Ethdev ops implemention for queues setup.\n\nSigned-off-by: Jingjing Wu <jingjing.wu@intel.com>\nSigned-off-by: Xiuchun Lu <xiuchun.lu@intel.com>\n---\n drivers/net/iavf_be/iavf_be.h        |  44 ++\n drivers/net/iavf_be/iavf_be_ethdev.c | 335 ++++++++++-\n drivers/net/iavf_be/iavf_be_rxtx.c   | 162 ++++++\n drivers/net/iavf_be/iavf_be_rxtx.h   | 103 ++++\n drivers/net/iavf_be/iavf_be_vchnl.c  | 815 ++++++++++++++++++++++++++-\n drivers/net/iavf_be/meson.build      |   1 +\n 6 files changed, 1446 insertions(+), 14 deletions(-)\n create mode 100644 drivers/net/iavf_be/iavf_be_rxtx.c\n create mode 100644 drivers/net/iavf_be/iavf_be_rxtx.h",
    "diff": "diff --git a/drivers/net/iavf_be/iavf_be.h b/drivers/net/iavf_be/iavf_be.h\nindex aff7bb9c56..6e8774ebb0 100644\n--- a/drivers/net/iavf_be/iavf_be.h\n+++ b/drivers/net/iavf_be/iavf_be.h\n@@ -9,6 +9,30 @@\n #define IAVF_BE_AQ_BUF_SZ            4096\n #define IAVF_BE_32_TO_64(hi, lo) ((((uint64_t)(hi)) << 32) + (lo))\n \n+/* Default setting on number of VSIs that VF can contain */\n+#define IAVF_BE_DEFAULT_VSI_NUM     1\n+#define AVF_DEFAULT_MAX_MTU         1500\n+/* Set the MAX vectors and queus to 16,\n+ * as base mode virtchnl support 16 queue pairs mapping in max.\n+ */\n+#define IAVF_BE_MAX_NUM_QUEUES      16\n+#define IAVF_BE_MAX_VECTORS         16\n+#define IAVF_BE_BUF_SIZE_MIN        1024\n+#define IAVF_BE_FRAME_SIZE_MAX      9728\n+#define IAVF_BE_NUM_MACADDR_MAX     64\n+\n+/* The overhead from MTU to max frame size.\n+ * Considering QinQ packet, the VLAN tag needs to be counted twice.\n+ */\n+#define AVF_VLAN_TAG_SIZE           4\n+#define AVF_ETH_OVERHEAD \\\n+\t(ETHER_HDR_LEN + ETHER_CRC_LEN + AVF_VLAN_TAG_SIZE * 2)\n+\n+/* Structure that defines a VSI, associated with a adapter. */\n+\n+/* Assume the max number be 16 right now */\n+#define AVF_MAX_MSIX_VECTORS        16\n+\n #define IAVFBE_READ_32(addr)        \\\n \trte_le_to_cpu_32(*(volatile uint32_t *)(addr))\n #define IAVFBE_WRITE_32(addr, val)  \\\n@@ -48,8 +72,15 @@ struct iavfbe_adapter {\n \t/* Adminq handle thread info */\n \tvolatile int thread_status;\n \tpthread_t thread_id;\n+\n+\tstruct virtchnl_version_info virtchnl_version;\n+\tstruct virtchnl_vf_resource *vf_res; /* Resource to VF */\n+\t/* Pointer to array of queue pairs info. */\n+\tstruct virtchnl_queue_pair_info *qps;\n \tuint16_t nb_qps;\n+\tuint16_t nb_used_qps;\n \tbool link_up;\n+\tstruct virtchnl_eth_stats eth_stats; /* Stats to VF */\n \tint cq_irqfd;\n \trte_atomic32_t irq_enable;\n \n@@ -67,11 +98,24 @@ struct iavfbe_adapter {\n #define IAVFBE_DEV_PRIVATE_TO_ADAPTER(adapter) \\\n \t((struct iavfbe_adapter *)adapter)\n \n+void iavfbe_reset_all_queues(struct iavfbe_adapter *adapter);\n int iavfbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete);\n+int iavfbe_lock_lanq(struct iavfbe_adapter *adapter);\n+int iavfbe_unlock_lanq(struct iavfbe_adapter *adapter);\n+void iavfbe_notify_vf_reset(struct iavfbe_adapter *adapter);\n+void iavfbe_notify(struct iavfbe_adapter *adapter);\n void iavfbe_handle_virtchnl_msg(void *arg);\n void iavfbe_reset_asq(struct iavfbe_adapter *adapter, bool lock);\n void iavfbe_reset_arq(struct iavfbe_adapter *adapter, bool lock);\n \n+static inline uint64_t stats_update(uint64_t offset, uint64_t stat)\n+{\n+\tif (stat >= offset)\n+\t\treturn (stat - offset);\n+\telse\n+\t\treturn (uint64_t)(((uint64_t)-1) - offset + stat + 1);\n+}\n+\n extern int iavfbe_logtype;\n #define IAVF_BE_LOG(level, fmt, args...) \\\n \trte_log(RTE_LOG_ ## level, iavfbe_logtype, \"%s(): \" fmt \"\\n\", \\\ndiff --git a/drivers/net/iavf_be/iavf_be_ethdev.c b/drivers/net/iavf_be/iavf_be_ethdev.c\nindex 2ab66f889d..e809f52312 100644\n--- a/drivers/net/iavf_be/iavf_be_ethdev.c\n+++ b/drivers/net/iavf_be/iavf_be_ethdev.c\n@@ -16,6 +16,7 @@\n #include <iavf_type.h>\n #include <virtchnl.h>\n #include \"iavf_be.h\"\n+#include \"iavf_be_rxtx.h\"\n \n #define AVFBE_EDEV_ID_ARG \"emu\"\n #define AVFBE_MAC_ARG \"mac\"\n@@ -46,6 +47,8 @@ static int iavfbe_dev_start(struct rte_eth_dev *dev);\n static int iavfbe_dev_stop(struct rte_eth_dev *dev);\n static int iavfbe_dev_info_get(struct rte_eth_dev *dev,\n \t\t\t\tstruct rte_eth_dev_info *dev_info);\n+static int iavfbe_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats);\n+static int iavfbe_stats_reset(struct rte_eth_dev *dev);\n static void iavfbe_destroy_adapter(struct rte_eth_dev *dev);\n \n struct rte_iavf_emu_notify_ops iavfbe_notify_ops = {\n@@ -64,17 +67,80 @@ static const struct eth_dev_ops iavfbe_eth_dev_ops = {\n \t.dev_start                  = iavfbe_dev_start,\n \t.dev_stop                   = iavfbe_dev_stop,\n \t.dev_infos_get              = iavfbe_dev_info_get,\n+\t.rx_queue_setup             = iavfbe_dev_rx_queue_setup,\n+\t.tx_queue_setup             = iavfbe_dev_tx_queue_setup,\n+\t.rx_queue_release           = iavfbe_dev_rx_queue_release,\n+\t.tx_queue_release           = iavfbe_dev_tx_queue_release,\n+\t.rxq_info_get               = iavfbe_dev_rxq_info_get,\n+\t.txq_info_get               = iavfbe_dev_txq_info_get,\n \t.link_update                = iavfbe_dev_link_update,\n+\t.stats_get                  = iavfbe_stats_get,\n+\t.stats_reset                = iavfbe_stats_reset,\n };\n \n static int\n-iavfbe_dev_info_get(struct rte_eth_dev *dev  __rte_unused,\n-\t\t    struct rte_eth_dev_info *dev_info)\n+iavfbe_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)\n {\n-\tdev_info->max_rx_queues = 0;\n-\tdev_info->max_tx_queues = 0;\n-\tdev_info->min_rx_bufsize = 0;\n-\tdev_info->max_rx_pktlen = 0;\n+\tstruct iavfbe_rx_queue *rxq;\n+\tstruct iavfbe_tx_queue *txq;\n+\tuint64_t tx_pkts = 0;\n+\tuint64_t tx_bytes = 0;\n+\tuint64_t tx_missed = 0;\n+\tuint64_t rx_pkts = 0;\n+\tuint64_t rx_bytes = 0;\n+\tint i;\n+\n+\tfor (i = 0; i < dev->data->nb_rx_queues; i++) {\n+\t\trxq = dev->data->rx_queues[i];\n+\t\tif (rxq == NULL)\n+\t\t\tcontinue;\n+\t\trx_pkts += stats_update(rxq->stats_off.recv_pkt_num,\n+\t\t\t\t\trxq->stats.recv_pkt_num);\n+\t\trx_bytes += stats_update(rxq->stats_off.recv_bytes,\n+\t\t\t\t\t rxq->stats.recv_bytes);\n+\t}\n+\n+\tfor (i = 0; i < dev->data->nb_tx_queues; i++) {\n+\t\ttxq = dev->data->tx_queues[i];\n+\t\tif (txq == NULL)\n+\t\t\tcontinue;\n+\t\ttx_pkts += stats_update(txq->stats_off.sent_pkt_num,\n+\t\t\t\t\ttxq->stats.sent_pkt_num);\n+\t\ttx_bytes += stats_update(txq->stats_off.sent_bytes,\n+\t\t\t\t\t txq->stats.sent_bytes);\n+\t\ttx_missed += stats_update(txq->stats_off.sent_miss_num,\n+\t\t\t\t\t  txq->stats.sent_miss_num);\n+\t}\n+\n+\tstats->ipackets = rx_pkts;\n+\tstats->opackets = tx_pkts;\n+\tstats->oerrors = tx_missed;\n+\tstats->ibytes = rx_bytes;\n+\tstats->obytes = tx_bytes;\n+\n+\treturn 0;\n+}\n+\n+static int\n+iavfbe_stats_reset(struct rte_eth_dev *dev)\n+{\n+\tstruct iavfbe_rx_queue *rxq;\n+\tstruct iavfbe_tx_queue *txq;\n+\tunsigned i;\n+\n+\tfor (i = 0; i < dev->data->nb_rx_queues; i++) {\n+\t\trxq = dev->data->rx_queues[i];\n+\t\tif (rxq == NULL)\n+\t\t\tcontinue;\n+\t\trxq->stats_off = rxq->stats;\n+\t}\n+\n+\tfor (i = 0; i < dev->data->nb_tx_queues; i++) {\n+\t\ttxq = dev->data->tx_queues[i];\n+\t\tif (txq == NULL)\n+\t\t\tcontinue;\n+\t\ttxq->stats_off = txq->stats;\n+\t}\n \n \treturn 0;\n }\n@@ -86,6 +152,84 @@ iavfbe_dev_configure(struct rte_eth_dev *dev __rte_unused)\n \treturn 0;\n }\n \n+static int\n+iavfbe_start_queues(struct rte_eth_dev *dev)\n+{\n+\tstruct iavfbe_rx_queue *rxq;\n+\tstruct iavfbe_tx_queue *txq;\n+\tuint32_t i;\n+\n+\tfor (i = 0; i < dev->data->nb_tx_queues; i++) {\n+\t\ttxq = dev->data->tx_queues[i];\n+\t\tif (!txq || rte_atomic32_read(&txq->enable) != 0)\n+\t\t\tcontinue;\n+\t\tdev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED;\n+\t}\n+\n+\tfor (i = 0; i < dev->data->nb_rx_queues; i++) {\n+\t\trxq = dev->data->rx_queues[i];\n+\t\tif (!rxq || rte_atomic32_read(&rxq->enable) != 0)\n+\t\t\tcontinue;\n+\t\tdev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static void\n+iavfbe_stop_queues(struct rte_eth_dev *dev)\n+{\n+\tstruct iavfbe_rx_queue *rxq;\n+\tstruct iavfbe_tx_queue *txq;\n+\tint i;\n+\n+\tfor (i = 0; i < dev->data->nb_tx_queues; i++) {\n+\t\ttxq = dev->data->tx_queues[i];\n+\t\tif (!txq)\n+\t\t\tcontinue;\n+\t\tdev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;\n+\t}\n+\tfor (i = 0; i < dev->data->nb_rx_queues; i++) {\n+\t\trxq = dev->data->rx_queues[i];\n+\t\tif (!rxq)\n+\t\t\tcontinue;\n+\t\tdev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;\n+\t}\n+}\n+\n+static int\n+iavfbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)\n+{\n+\tstruct iavfbe_adapter *adapter =\n+\t\tIAVFBE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);\n+\n+\tdev_info->max_rx_queues = adapter->nb_qps;\n+\tdev_info->max_tx_queues = adapter->nb_qps;\n+\tdev_info->min_rx_bufsize = IAVF_BE_BUF_SIZE_MIN;\n+\tdev_info->max_rx_pktlen = IAVF_BE_FRAME_SIZE_MAX;\n+\tdev_info->max_mac_addrs = IAVF_BE_NUM_MACADDR_MAX;\n+\n+\tdev_info->rx_desc_lim = (struct rte_eth_desc_lim) {\n+\t\t.nb_max = IAVF_BE_MAX_RING_DESC,\n+\t\t.nb_min = IAVF_BE_MIN_RING_DESC,\n+\t\t.nb_align = IAVF_BE_ALIGN_RING_DESC,\n+\t};\n+\n+\tdev_info->tx_desc_lim = (struct rte_eth_desc_lim) {\n+\t\t.nb_max = IAVF_BE_MAX_RING_DESC,\n+\t\t.nb_min = IAVF_BE_MIN_RING_DESC,\n+\t\t.nb_align = IAVF_BE_ALIGN_RING_DESC,\n+\t};\n+\n+\tdev_info->rx_offload_capa =\n+\t\tDEV_RX_OFFLOAD_SCATTER |\n+\t\tDEV_RX_OFFLOAD_JUMBO_FRAME;\n+\tdev_info->tx_offload_capa =\n+\t\tDEV_TX_OFFLOAD_MULTI_SEGS;\n+\n+\treturn 0;\n+}\n+\n static int\n iavfbe_dev_start(struct rte_eth_dev *dev)\n {\n@@ -94,6 +238,8 @@ iavfbe_dev_start(struct rte_eth_dev *dev)\n \n \tadapter->adapter_stopped = 0;\n \n+\tiavfbe_start_queues(dev);\n+\n \treturn 0;\n }\n \n@@ -106,6 +252,8 @@ iavfbe_dev_stop(struct rte_eth_dev *dev)\n \tif (adapter->adapter_stopped == 1)\n \t\treturn 0;\n \n+\tiavfbe_stop_queues(dev);\n+\n \tadapter->adapter_stopped = 1;\n \n \treturn 0;\n@@ -133,6 +281,13 @@ iavfbe_dev_link_update(struct rte_eth_dev *dev,\n static int\n iavfbe_dev_close(struct rte_eth_dev *dev)\n {\n+\tstruct iavfbe_adapter *adapter =\n+\t\tIAVFBE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);\n+\n+\t/* Only send event when the emudev is alive */\n+\tif (adapter->started & adapter->cq_info.arq.len)\n+\t\tiavfbe_notify_vf_reset(adapter);\n+\n \tiavfbe_destroy_adapter(dev);\n \trte_eth_dev_release_port(dev);\n \n@@ -236,8 +391,28 @@ iavfbe_destroy_device(struct rte_emudev *dev)\n {\n \tstruct iavfbe_adapter *adapter =\n \t\t(struct iavfbe_adapter *)dev->backend_priv;\n+\tstruct rte_eth_dev_data *data = adapter->eth_dev->data;\n+\tstruct iavfbe_rx_queue *rxq;\n+\tstruct iavfbe_tx_queue *txq;\n+\tuint16_t i;\n \n-\t/* TODO: Disable all lan queues */\n+\t/* Disable all queues */\n+\tfor (i = 0; i < data->nb_rx_queues; i++) {\n+\t\trxq = data->rx_queues[i];\n+\t\tif (!rxq)\n+\t\t\tcontinue;\n+\t\trte_atomic32_set(&rxq->enable, false);\n+\t\trxq->q_set = false;\n+\t}\n+\n+\tfor (i = 0; i < data->nb_tx_queues; i++) {\n+\t\ttxq = data->tx_queues[i];\n+\t\tif (!txq)\n+\t\t\tcontinue;\n+\t\trte_atomic32_set(&txq->enable, false);\n+\t\ttxq->q_set = false;\n+\t}\n+\tadapter->started = 0;\n \n \t/* update link status */\n \tadapter->link_up = false;\n@@ -249,9 +424,13 @@ iavfbe_update_device(struct rte_emudev *dev)\n {\n \tstruct iavfbe_adapter *adapter =\n \t\t(struct iavfbe_adapter *)dev->backend_priv;\n+\tstruct rte_eth_dev_data *data = adapter->eth_dev->data;\n \tstruct rte_iavf_emu_mem **mem = &(adapter->mem_table);\n \tstruct rte_emudev_q_info q_info;\n \tstruct rte_emudev_irq_info irq_info;\n+\tstruct iavfbe_rx_queue *rxq;\n+\tstruct iavfbe_tx_queue *txq;\n+\tuint16_t i;\n \n \tif (rte_emudev_get_mem_table(dev->dev_id, (void **)mem)) {\n \t\tIAVF_BE_LOG(ERR, \"Can not get mem table\\n\");\n@@ -271,10 +450,87 @@ iavfbe_update_device(struct rte_emudev *dev)\n \t\treturn -1;\n \t}\n \n-\t/* TODO: Lan queue info update */\n \tadapter->cq_irqfd = irq_info.eventfd;\n \trte_atomic32_set(&adapter->irq_enable, irq_info.enable);\n \n+\tfor (i = 0; i < data->nb_rx_queues; i++) {\n+\t\trxq = data->rx_queues[i];\n+\t\tif (!rxq || rxq->vector == -1)\n+\t\t\tcontinue;\n+\n+\t\tif (rte_emudev_get_irq_info(dev->dev_id,\n+\t\t\trxq->vector, &irq_info)) {\n+\t\t\tIAVF_BE_LOG(ERR,\n+\t\t\t\t\"Can not get irq info of rxq %d\\n\", i);\n+\t\t\treturn -1;\n+\t\t}\n+\t\trte_atomic32_set(&rxq->irq_enable, irq_info.enable);\n+\t}\n+\n+\tfor (i = 0; i < data->nb_tx_queues; i++) {\n+\t\ttxq = data->tx_queues[i];\n+\t\tif (!txq || txq->vector == -1)\n+\t\t\tcontinue;\n+\n+\t\tif (rte_emudev_get_irq_info(dev->dev_id,\n+\t\t\ttxq->vector, &irq_info)) {\n+\t\t\tIAVF_BE_LOG(ERR,\n+\t\t\t\t\"Can not get irq info of txq %d\\n\", i);\n+\t\t\treturn -1;\n+\t\t}\n+\t\trte_atomic32_set(&txq->irq_enable, irq_info.enable);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int\n+iavfbe_lock_lanq(struct iavfbe_adapter *adapter)\n+{\n+\tstruct rte_eth_dev *eth_dev = adapter->eth_dev;\n+\tstruct iavfbe_rx_queue *rxq;\n+\tstruct iavfbe_tx_queue *txq;\n+\tuint16_t i;\n+\n+\tfor (i = 0; i < eth_dev->data->nb_rx_queues; i++) {\n+\t\trxq = eth_dev->data->rx_queues[i];\n+\t\tif (!rxq)\n+\t\t\tcontinue;\n+\t\trte_spinlock_lock(&rxq->access_lock);\n+\t}\n+\n+\tfor (i = 0; i < eth_dev->data->nb_tx_queues; i++) {\n+\t\ttxq = eth_dev->data->tx_queues[i];\n+\t\tif (!txq)\n+\t\t\tcontinue;\n+\t\trte_spinlock_lock(&txq->access_lock);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int\n+iavfbe_unlock_lanq(struct iavfbe_adapter *adapter)\n+{\n+\tstruct rte_eth_dev *eth_dev = adapter->eth_dev;\n+\tstruct iavfbe_rx_queue *rxq;\n+\tstruct iavfbe_tx_queue *txq;\n+\tuint16_t i;\n+\n+\tfor (i = 0; i < eth_dev->data->nb_rx_queues; i++) {\n+\t\trxq = eth_dev->data->rx_queues[i];\n+\t\tif (!rxq)\n+\t\t\tcontinue;\n+\t\trte_spinlock_unlock(&rxq->access_lock);\n+\t}\n+\n+\tfor (i = 0; i < eth_dev->data->nb_tx_queues; i++) {\n+\t\ttxq = eth_dev->data->tx_queues[i];\n+\t\tif (!txq)\n+\t\t\tcontinue;\n+\t\trte_spinlock_unlock(&txq->access_lock);\n+\t}\n+\n \treturn 0;\n }\n \n@@ -287,11 +543,11 @@ iavfbe_lock_dp(struct rte_emudev *dev, int lock)\n \t/* Acquire/Release lock of control queue and lan queue */\n \n \tif (lock) {\n-\t\t/* TODO: Lan queue lock */\n+\t\tiavfbe_lock_lanq(adapter);\n \t\trte_spinlock_lock(&adapter->cq_info.asq.access_lock);\n \t\trte_spinlock_lock(&adapter->cq_info.arq.access_lock);\n \t} else {\n-\t\t/* TODO: Lan queue unlock */\n+\t\tiavfbe_unlock_lanq(adapter);\n \t\trte_spinlock_unlock(&adapter->cq_info.asq.access_lock);\n \t\trte_spinlock_unlock(&adapter->cq_info.arq.access_lock);\n \t}\n@@ -358,11 +614,16 @@ iavfbe_reset_device(struct rte_emudev *dev)\n \tstruct iavfbe_adapter *adapter =\n \t\t(struct iavfbe_adapter *)dev->backend_priv;\n \n+\tiavfbe_notify(adapter);\n+\n \t/* Lock has been acquired by lock_dp */\n-\t/* TODO: reset all queues */\n+\tiavfbe_reset_all_queues(adapter);\n \tiavfbe_reset_asq(adapter, false);\n \tiavfbe_reset_arq(adapter, false);\n \n+\tmemset(adapter->qps, 0, sizeof(struct virtchnl_queue_pair_info));\n+\tmemset(&adapter->eth_stats, 0, sizeof(struct virtchnl_eth_stats));\n+\tadapter->nb_used_qps = 0;\n \tadapter->link_up = 0;\n \tadapter->unicast_promisc = true;\n \tadapter->multicast_promisc = true;\n@@ -433,7 +694,7 @@ iavfbe_init_adapter(struct rte_eth_dev *eth_dev,\n {\n \tstruct iavfbe_adapter *adapter;\n \tstruct rte_iavf_emu_config *conf;\n-\tint ret;\n+\tint bufsz, ret;\n \n \tadapter = IAVFBE_DEV_PRIVATE_TO_ADAPTER(eth_dev->data->dev_private);\n \n@@ -472,6 +733,48 @@ iavfbe_init_adapter(struct rte_eth_dev *eth_dev,\n \trte_spinlock_init(&adapter->cq_info.asq.access_lock);\n \trte_spinlock_init(&adapter->cq_info.arq.access_lock);\n \n+\t/* Set VF Backend defaults during initialization */\n+\tadapter->virtchnl_version.major = VIRTCHNL_VERSION_MAJOR;\n+\tadapter->virtchnl_version.minor = VIRTCHNL_VERSION_MINOR;\n+\n+\tbufsz = sizeof(struct virtchnl_vf_resource) +\n+\t\t(IAVF_BE_DEFAULT_VSI_NUM *\n+\t\t sizeof(struct virtchnl_vsi_resource));\n+\tadapter->vf_res = rte_zmalloc_socket(\"iavfbe\", bufsz, 0,\n+\t\t\t\t\t     eth_dev->device->numa_node);\n+\tif (!adapter->vf_res) {\n+\t\tIAVF_BE_LOG(ERR, \"Fail to allocate vf_res memory\");\n+\t\tret = -ENOMEM;\n+\t\tgoto err_res;\n+\t}\n+\n+\tadapter->vf_res->num_vsis = IAVF_BE_DEFAULT_VSI_NUM;\n+\tadapter->vf_res->vf_cap_flags = VIRTCHNL_VF_OFFLOAD_L2 |\n+\t\t\t\t\tVIRTCHNL_VF_OFFLOAD_VLAN |\n+\t\t\t\t\tVIRTCHNL_VF_OFFLOAD_WB_ON_ITR |\n+\t\t\t\t\tVIRTCHNL_VF_OFFLOAD_RX_POLLING;\n+\tadapter->vf_res->max_vectors = IAVF_BE_MAX_VECTORS;\n+\tadapter->vf_res->num_queue_pairs = adapter->nb_qps;\n+\tadapter->vf_res->max_mtu = AVF_DEFAULT_MAX_MTU;\n+\t/* Make vsi_id change with diffient emu device */\n+\tadapter->vf_res->vsi_res[0].vsi_id = emu_dev->dev_id;\n+\tadapter->vf_res->vsi_res[0].vsi_type = VIRTCHNL_VSI_SRIOV;\n+\tadapter->vf_res->vsi_res[0].num_queue_pairs = adapter->nb_qps;\n+\trte_ether_addr_copy(ether_addr,\n+\t\t(struct rte_ether_addr *)\n+\t\tadapter->vf_res->vsi_res[0].default_mac_addr);\n+\n+\tadapter->qps =\n+\t\trte_zmalloc_socket(\"iavfbe\",\n+\t\t\t\t   adapter->nb_qps * sizeof(adapter->qps[0]),\n+\t\t\t\t   0,\n+\t\t\t\t   eth_dev->device->numa_node);\n+\tif (!adapter->qps) {\n+\t\tIAVF_BE_LOG(ERR, \"fail to allocate memeory for queue info\");\n+\t\tret = -ENOMEM;\n+\t\tgoto err_qps;\n+\t}\n+\n \tadapter->unicast_promisc = true;\n \tadapter->multicast_promisc = true;\n \tadapter->vlan_filter = false;\n@@ -494,6 +797,11 @@ iavfbe_init_adapter(struct rte_eth_dev *eth_dev,\n \treturn 0;\n \n err_thread:\n+\trte_free(adapter->qps);\n+err_qps:\n+\trte_free(adapter->vf_res);\n+err_res:\n+\trte_free(adapter->cq_info.asq.aq_req);\n err_aq:\n err_info:\n \trte_free(conf);\n@@ -513,6 +821,9 @@ iavfbe_destroy_adapter(struct rte_eth_dev *dev)\n \t}\n \n \trte_free(adapter->dev_info.dev_priv);\n+\trte_free(adapter->cq_info.asq.aq_req);\n+\trte_free(adapter->vf_res);\n+\trte_free(adapter->qps);\n }\n \n static int\ndiff --git a/drivers/net/iavf_be/iavf_be_rxtx.c b/drivers/net/iavf_be/iavf_be_rxtx.c\nnew file mode 100644\nindex 0000000000..72cbead45a\n--- /dev/null\n+++ b/drivers/net/iavf_be/iavf_be_rxtx.c\n@@ -0,0 +1,162 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2020 Intel Corporation\n+ */\n+\n+#include <unistd.h>\n+#include <inttypes.h>\n+#include <sys/queue.h>\n+\n+#include <rte_string_fns.h>\n+#include <rte_mbuf.h>\n+#include <rte_ether.h>\n+#include <rte_ethdev_driver.h>\n+#include <rte_net.h>\n+#include <rte_iavf_emu.h>\n+\n+#include <iavf_type.h>\n+#include <virtchnl.h>\n+#include \"iavf_be.h\"\n+#include \"iavf_be_rxtx.h\"\n+\n+int\n+iavfbe_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,\n+\t\t\t  uint16_t nb_desc __rte_unused,\n+\t\t\t  unsigned int socket_id,\n+\t\t\t  const struct rte_eth_rxconf *rx_conf __rte_unused,\n+\t\t\t  struct rte_mempool *mp)\n+{\n+\tstruct iavfbe_adapter *ad =\n+\t\tIAVFBE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);\n+\tstruct iavfbe_rx_queue *rxq;\n+\tuint16_t len;\n+\n+\t/* Free memory if needed */\n+\tif (dev->data->rx_queues[queue_idx]) {\n+\t\tiavfbe_dev_rx_queue_release(dev->data->rx_queues[queue_idx]);\n+\t\tdev->data->rx_queues[queue_idx] = NULL;\n+\t}\n+\n+\t/* Allocate the rx queue data structure */\n+\trxq = rte_zmalloc_socket(\"iavfbe rxq\",\n+\t\t\t\t sizeof(struct iavfbe_rx_queue),\n+\t\t\t\t RTE_CACHE_LINE_SIZE,\n+\t\t\t\t socket_id);\n+\tif (!rxq) {\n+\t\tIAVF_BE_LOG(ERR, \"Failed to allocate memory for \"\n+\t\t\t\t \"rx queue data structure\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\trxq->mp = mp;\n+\trxq->nb_rx_desc = 0; /* Update when queue from fe is ready */\n+\trxq->queue_id = queue_idx;\n+\trxq->port_id = dev->data->port_id;\n+\trxq->rx_hdr_len = 0;\n+\trxq->vector = -1;\n+\tlen = rte_pktmbuf_data_room_size(rxq->mp) - RTE_PKTMBUF_HEADROOM;\n+\trxq->rx_buf_len = RTE_ALIGN(len, (1 << AVF_RXQ_CTX_DBUFF_SHIFT));\n+\n+\t/* More ring info will be gotten in virtchnl msg */\n+\n+\trxq->adapter = (void *)ad;\n+\tdev->data->rx_queues[queue_idx] = rxq;\n+\n+\treturn 0;\n+}\n+\n+int\n+iavfbe_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,\n+\t\t\t  uint16_t nb_desc __rte_unused,\n+\t\t\t  unsigned int socket_id,\n+\t\t\t  const struct rte_eth_txconf *tx_conf __rte_unused)\n+{\n+\tstruct iavfbe_adapter *ad =\n+\t\tIAVFBE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);\n+\tstruct iavfbe_tx_queue *txq;\n+\n+\t/* Free memory if needed. */\n+\tif (dev->data->tx_queues[queue_idx]) {\n+\t\tiavfbe_dev_tx_queue_release(dev->data->tx_queues[queue_idx]);\n+\t\tdev->data->tx_queues[queue_idx] = NULL;\n+\t}\n+\n+\t/* Allocate the TX queue data structure. */\n+\ttxq = rte_zmalloc_socket(\"iavfbe txq\",\n+\t\t\t\t sizeof(struct iavfbe_tx_queue),\n+\t\t\t\t RTE_CACHE_LINE_SIZE,\n+\t\t\t\t socket_id);\n+\tif (!txq) {\n+\t\tIAVF_BE_LOG(ERR, \"Failed to allocate memory for \"\n+\t\t\t\t \"tx queue structure\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\ttxq->queue_id = queue_idx;\n+\ttxq->port_id = dev->data->port_id;\n+\ttxq->vector = -1;\n+\n+\t/* More ring info will be gotten in virtchnl msg */\n+\n+\ttxq->adapter = (void *)ad;\n+\tdev->data->tx_queues[queue_idx] = txq;\n+\n+\treturn 0;\n+}\n+\n+void\n+iavfbe_dev_rx_queue_release(void *rxq)\n+{\n+\tstruct iavfbe_rx_queue *q = (struct iavfbe_rx_queue *)rxq;\n+\n+\tif (!q)\n+\t\treturn;\n+\trte_free(q);\n+}\n+\n+void\n+iavfbe_dev_tx_queue_release(void *txq)\n+{\n+\tstruct iavfbe_tx_queue *q = (struct iavfbe_tx_queue *)txq;\n+\n+\tif (!q)\n+\t\treturn;\n+\trte_free(q);\n+}\n+\n+void\n+iavfbe_dev_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,\n+\t\t     struct rte_eth_rxq_info *qinfo)\n+{\n+\tstruct iavfbe_rx_queue *rxq;\n+\n+\trxq = dev->data->rx_queues[queue_id];\n+\tif (!rxq)\n+\t\treturn;\n+\n+\tqinfo->mp = rxq->mp;\n+\tqinfo->scattered_rx = true;\n+\tqinfo->nb_desc = rxq->nb_rx_desc;\n+\n+\tqinfo->conf.rx_free_thresh = 0;\n+\tqinfo->conf.rx_drop_en = false;\n+\tqinfo->conf.rx_deferred_start = false;\n+}\n+\n+void\n+iavfbe_dev_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,\n+\t\t     struct rte_eth_txq_info *qinfo)\n+{\n+\tstruct iavfbe_tx_queue *txq;\n+\n+\ttxq = dev->data->tx_queues[queue_id];\n+\n+\tif (!txq)\n+\t\treturn;\n+\n+\tqinfo->nb_desc = txq->nb_tx_desc;\n+\n+\tqinfo->conf.tx_free_thresh = 0;\n+\tqinfo->conf.tx_rs_thresh = 0;\n+\tqinfo->conf.offloads = DEV_TX_OFFLOAD_MULTI_SEGS;\n+\tqinfo->conf.tx_deferred_start = false;\n+}\ndiff --git a/drivers/net/iavf_be/iavf_be_rxtx.h b/drivers/net/iavf_be/iavf_be_rxtx.h\nnew file mode 100644\nindex 0000000000..e8be3f532d\n--- /dev/null\n+++ b/drivers/net/iavf_be/iavf_be_rxtx.h\n@@ -0,0 +1,103 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2020 Intel Corporation\n+ */\n+\n+#ifndef _AVF_BE_RXTX_H_\n+#define _AVF_BE_RXTX_H_\n+\n+/* In QLEN must be whole number of 32 descriptors. */\n+#define IAVF_BE_ALIGN_RING_DESC      32\n+#define IAVF_BE_MIN_RING_DESC        64\n+#define IAVF_BE_MAX_RING_DESC        4096\n+\n+#define AVF_RXQ_CTX_DBUFF_SHIFT 7\n+#define AVF_RXQ_CTX_HBUFF_SHIFT 6\n+\n+#define AVF_RX_MAX_SEG           5\n+\n+#define iavf_rx_desc iavf_32byte_rx_desc\n+\n+/* Structure associated with each Rx queue in AVF_BE. */\n+struct iavfbe_rx_queue {\n+\trte_spinlock_t access_lock;\n+\tstruct rte_mempool *mp;       /* mbuf pool to populate Rx ring */\n+\tvolatile struct iavf_tx_desc *tx_ring; /* AVF Tx ring virtual address */\n+\tuint64_t tx_ring_phys_addr;   /* AVF Tx ring DMA address */\n+\tuint16_t nb_rx_desc;          /* ring length */\n+\tvolatile uint8_t *qtx_tail;   /* register address of tail */\n+\n+\tuint16_t tx_head;\n+\tint vector;\n+\tint kickfd;\n+\trte_atomic32_t irq_enable;\n+\n+\tuint16_t port_id;       /* device port ID */\n+\tuint8_t crc_len;        /* 0 if CRC stripped, 4 otherwise */\n+\tuint16_t queue_id;      /* Rx queue index */\n+\tuint16_t rx_buf_len;    /* The packet buffer size */\n+\tuint16_t rx_hdr_len;    /* The header buffer size */\n+\tuint16_t max_pkt_len;   /* Maximum packet length */\n+\tbool q_set;             /* If queue has been set by virtchnl */\n+\trte_atomic32_t enable;  /* If queue has been enabled set by virtchnl */\n+\n+\tstruct iavfbe_adapter *adapter; /* Point to adapter the tx queue belong to */\n+\tstruct {\n+\t\tuint64_t recv_pkt_num;\n+\t\tuint64_t recv_bytes;\n+\t\tuint64_t recv_miss_num;\n+\t\tuint64_t recv_multi_num;\n+\t\tuint64_t recv_broad_num;\n+\t} stats, stats_off;   /* Stats information */\n+};\n+\n+/* Structure associated with each TX queue. */\n+struct iavfbe_tx_queue {\n+\trte_spinlock_t access_lock;\n+\tvolatile union iavf_rx_desc *rx_ring; /* AVF Rx ring virtual address */\n+\tuint64_t rx_ring_phys_addr;    /* Rx ring DMA address */\n+\tuint16_t nb_tx_desc;           /* ring length */\n+\tvolatile uint8_t *qrx_tail;    /* tail address of fe's rx ring */\n+\tuint32_t buffer_size;          /* max buffer size of fe's rx ring */\n+\tuint32_t max_pkt_size;         /* max buffer size of fe's rx ring */\n+\n+\tuint16_t rx_head;\n+\tint vector;\n+\tint callfd;\n+\trte_atomic32_t irq_enable;\n+\n+\tuint16_t port_id;\n+\tuint16_t queue_id;\n+\n+\tbool q_set;             /* If queue has been set by virtchnl */\n+\trte_atomic32_t enable;  /* If queue has been enabled set by virtchnl */\n+\n+\tstruct iavfbe_adapter *adapter; /* Point to adapter the tx queue belong to */\n+\tstruct {\n+\t\tuint64_t sent_pkt_num;\n+\t\tuint64_t sent_bytes;\n+\t\tuint64_t sent_miss_num;\n+\t\tuint64_t sent_multi_num;\n+\t\tuint64_t sent_broad_num;\n+\t} stats, stats_off;   /* Stats information */\n+};\n+\n+\n+int iavfbe_dev_rx_queue_setup(struct rte_eth_dev *dev,\n+\t\t\t      uint16_t queue_idx,\n+\t\t\t      uint16_t nb_desc,\n+\t\t\t      unsigned int socket_id,\n+\t\t\t      const struct rte_eth_rxconf *rx_conf,\n+\t\t\t      struct rte_mempool *mp);\n+void iavfbe_dev_rx_queue_release(void *rxq);\n+int iavfbe_dev_tx_queue_setup(struct rte_eth_dev *dev,\n+\t\t\t      uint16_t queue_idx,\n+\t\t\t      uint16_t nb_desc,\n+\t\t\t      unsigned int socket_id,\n+\t\t\t      const struct rte_eth_txconf *tx_conf);\n+void iavfbe_dev_tx_queue_release(void *txq);\n+void iavfbe_dev_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,\n+\t\t\t     struct rte_eth_rxq_info *qinfo);\n+void iavfbe_dev_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,\n+\t\t\t     struct rte_eth_txq_info *qinfo);\n+\n+#endif /* _AVF_BE_RXTX_H_ */\ndiff --git a/drivers/net/iavf_be/iavf_be_vchnl.c b/drivers/net/iavf_be/iavf_be_vchnl.c\nindex 646c967252..a1165cd5b5 100644\n--- a/drivers/net/iavf_be/iavf_be_vchnl.c\n+++ b/drivers/net/iavf_be/iavf_be_vchnl.c\n@@ -21,8 +21,94 @@\n #include <virtchnl.h>\n \n #include \"iavf_be.h\"\n+#include \"iavf_be_rxtx.h\"\n \n-__rte_unused  static int\n+static inline void\n+reset_rxq_stats(struct iavfbe_rx_queue *rxq)\n+{\n+\trxq->stats.recv_pkt_num = 0;\n+\trxq->stats.recv_bytes = 0;\n+\trxq->stats.recv_miss_num = 0;\n+\trxq->stats.recv_multi_num = 0;\n+\trxq->stats.recv_broad_num = 0;\n+\n+\trxq->stats_off.recv_pkt_num = 0;\n+\trxq->stats_off.recv_bytes = 0;\n+\trxq->stats_off.recv_miss_num = 0;\n+\trxq->stats_off.recv_multi_num = 0;\n+\trxq->stats_off.recv_broad_num = 0;\n+}\n+\n+static inline void\n+reset_txq_stats(struct iavfbe_tx_queue *txq)\n+{\n+\ttxq->stats.sent_pkt_num = 0;\n+\ttxq->stats.sent_bytes = 0;\n+\ttxq->stats.sent_miss_num = 0;\n+\ttxq->stats.sent_multi_num = 0;\n+\ttxq->stats.sent_broad_num = 0;\n+}\n+\n+void\n+iavfbe_reset_all_queues(struct iavfbe_adapter *adapter)\n+{\n+\tstruct iavfbe_rx_queue *rxq;\n+\tstruct iavfbe_tx_queue *txq;\n+\tuint16_t i;\n+\n+\t/* Disable queues and mark them unset */\n+\tfor (i = 0; i < adapter->eth_dev->data->nb_rx_queues; i++) {\n+\t\trxq = adapter->eth_dev->data->rx_queues[i];\n+\t\tif (rxq) {\n+\t\t\trte_atomic32_set(&rxq->enable, false);\n+\t\t\trxq->q_set = false;\n+\t\t\trxq->tx_head = 0;\n+\t\t\treset_rxq_stats(rxq);\n+\t\t}\n+\t}\n+\n+\tfor (i = 0; i < adapter->eth_dev->data->nb_tx_queues; i++) {\n+\t\ttxq = adapter->eth_dev->data->tx_queues[i];\n+\t\tif (txq) {\n+\t\t\trte_atomic32_set(&txq->enable, false);\n+\t\t\ttxq->q_set = false;\n+\t\t\ttxq->rx_head = 0;\n+\t\t\treset_txq_stats(txq);\n+\t\t}\n+\t}\n+}\n+\n+static enum iavf_status\n+apply_tx_irq(struct iavfbe_tx_queue *txq, uint16_t vector)\n+{\n+\tstruct rte_emudev_irq_info info;\n+\n+\ttxq->vector = vector;\n+\tif (rte_emudev_get_irq_info(txq->adapter->edev_id, vector, &info)) {\n+\t\tIAVF_BE_LOG(ERR, \"Can not get irq info\\n\");\n+\t\treturn IAVF_ERR_DEVICE_NOT_SUPPORTED;\n+\t}\n+\ttxq->callfd = info.eventfd;\n+\n+\treturn 0;\n+}\n+\n+static enum iavf_status\n+apply_rx_irq(struct iavfbe_rx_queue *rxq, uint16_t vector)\n+{\n+\tstruct rte_emudev_irq_info info;\n+\n+\trxq->vector = vector;\n+\tif (rte_emudev_get_irq_info(rxq->adapter->edev_id, vector, &info)) {\n+\t\tIAVF_BE_LOG(ERR, \"Can not get irq info\\n\");\n+\t\treturn IAVF_ERR_DEVICE_NOT_SUPPORTED;\n+\t}\n+\trxq->kickfd = info.eventfd;\n+\n+\treturn 0;\n+}\n+\n+static int\n iavfbe_send_msg_to_vf(struct iavfbe_adapter *adapter,\n \t\t\tuint32_t opcode,\n \t\t\tuint32_t retval,\n@@ -93,6 +179,431 @@ iavfbe_send_msg_to_vf(struct iavfbe_adapter *adapter,\n \treturn status;\n }\n \n+static void\n+iavfbe_process_cmd_version(struct iavfbe_adapter *adapter,\n+\t\t\t\tuint8_t *msg)\n+{\n+\tstruct virtchnl_version_info *info =\n+\t\t(struct virtchnl_version_info *)msg;\n+\n+\t/* Only support V1.1 */\n+\tif (adapter->virtchnl_version.major == info->major &&\n+\t    adapter->virtchnl_version.minor == info->minor)\n+\t\tiavfbe_send_msg_to_vf(adapter, VIRTCHNL_OP_VERSION,\n+\t\t\t\t      VIRTCHNL_STATUS_SUCCESS,\n+\t\t\t\t      (uint8_t *)&adapter->virtchnl_version,\n+\t\t\t\t      sizeof(adapter->virtchnl_version));\n+\telse\n+\t\tiavfbe_send_msg_to_vf(adapter, VIRTCHNL_OP_VERSION,\n+\t\t\t\t      VIRTCHNL_STATUS_NOT_SUPPORTED,\n+\t\t\t\t      NULL, 0);\n+}\n+\n+static int\n+iavfbe_renew_device_info(struct iavfbe_adapter *adapter)\n+{\n+\tstruct rte_iavf_emu_mem **mem = &(adapter->mem_table);\n+\tuint64_t addr;\n+\n+\tif (rte_emudev_get_mem_table(adapter->edev_id, (void **)mem)) {\n+\t\tIAVF_BE_LOG(ERR, \"Can not get mem table\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tif (rte_emudev_get_attr(adapter->edev_id, RTE_IAVF_EMU_ATTR_RESET,\n+\t\t(rte_emudev_attr_t)&addr)) {\n+\t\tIAVF_BE_LOG(ERR, \"Can not get arq head\\n\");\n+\t\treturn -1;\n+\t}\n+\tadapter->reset = (uint8_t *)(uintptr_t)addr;\n+\n+\tIAVF_BE_LOG(DEBUG, \"DEVICE memtable re-acquired, %p\\n\",\n+\t\t    adapter->mem_table);\n+\n+\treturn 0;\n+}\n+\n+static int\n+iavfbe_process_cmd_reset_vf(struct iavfbe_adapter *adapter)\n+{\n+\tadapter->started = 0;\n+\tIAVFBE_WRITE_32(adapter->reset, RTE_IAVF_EMU_RESET_IN_PROGRESS);\n+\n+\tiavfbe_lock_lanq(adapter);\n+\tiavfbe_reset_all_queues(adapter);\n+\tiavfbe_unlock_lanq(adapter);\n+\n+\tmemset(adapter->qps, 0, sizeof(struct virtchnl_queue_pair_info));\n+\tmemset(&adapter->eth_stats, 0, sizeof(struct virtchnl_eth_stats));\n+\tadapter->nb_used_qps = 0;\n+\tadapter->link_up = 0;\n+\tadapter->unicast_promisc = true;\n+\tadapter->multicast_promisc = true;\n+\tadapter->vlan_filter = false;\n+\tadapter->vlan_strip = false;\n+\tadapter->adapter_stopped = 1;\n+\n+\tiavfbe_renew_device_info(adapter);\n+\tIAVFBE_WRITE_32(adapter->reset, RTE_IAVF_EMU_RESET_COMPLETED);\n+\tadapter->started = 1;\n+\n+\treturn IAVF_SUCCESS;\n+}\n+\n+static int\n+iavfbe_process_cmd_get_vf_resource(struct iavfbe_adapter *adapter,\n+\t\t\t\tuint8_t *msg)\n+{\n+\tstruct virtchnl_vf_resource vf_res;\n+\tuint32_t request_caps;\n+\tuint32_t len = 0;\n+\n+\tlen = sizeof(struct virtchnl_vf_resource) +\n+\t\t(adapter->vf_res->num_vsis - 1) *\n+\t\tsizeof(struct virtchnl_vsi_resource);\n+\n+\trequest_caps = *(uint32_t *)msg;\n+\n+\trte_memcpy(&vf_res, adapter->vf_res, len);\n+\tvf_res.vf_cap_flags = request_caps &\n+\t\t\t\tadapter->vf_res->vf_cap_flags;\n+\n+\tiavfbe_send_msg_to_vf(adapter, VIRTCHNL_OP_GET_VF_RESOURCES,\n+\t\t\t      VIRTCHNL_STATUS_SUCCESS, (uint8_t *)&vf_res, len);\n+\n+\treturn IAVF_SUCCESS;\n+}\n+\n+static int\n+iavfbe_process_cmd_config_vsi_queues(struct iavfbe_adapter *adapter,\n+\t\t\t\t     uint8_t *msg,\n+\t\t\t\t     uint16_t msglen __rte_unused)\n+{\n+\tstruct virtchnl_vsi_queue_config_info *vc_vqci =\n+\t\t(struct virtchnl_vsi_queue_config_info *)msg;\n+\tstruct virtchnl_queue_pair_info *vc_qpi;\n+\tstruct rte_eth_dev *dev = adapter->eth_dev;\n+\tstruct iavfbe_rx_queue *rxq;\n+\tstruct iavfbe_tx_queue *txq;\n+\tuint16_t nb_qps, queue_id;\n+\tint i, ret = VIRTCHNL_STATUS_SUCCESS;\n+\n+\t/* Check valid */\n+\tif (!msg || vc_vqci->num_queue_pairs > adapter->nb_qps) {\n+\t\tIAVF_BE_LOG(ERR, \"number of queue pairs (%u) exceeds max (%u)\",\n+\t\t\t    vc_vqci->num_queue_pairs, adapter->nb_qps);\n+\t\tret = VIRTCHNL_STATUS_ERR_PARAM;\n+\t\tgoto send_msg;\n+\t}\n+\n+\tnb_qps = vc_vqci->num_queue_pairs;\n+\tvc_qpi = vc_vqci->qpair;\n+\n+\tfor (i = 0; i < nb_qps; i++) {\n+\t\tif (vc_qpi[i].txq.vsi_id != vc_vqci->vsi_id ||\n+\t\t    vc_qpi[i].rxq.vsi_id != vc_vqci->vsi_id ||\n+\t\t    vc_qpi[i].rxq.queue_id != vc_qpi[i].txq.queue_id ||\n+\t\t    vc_qpi[i].rxq.queue_id > adapter->nb_qps - 1 ||\n+\t\t    vc_qpi[i].rxq.ring_len > IAVF_BE_MAX_RING_DESC ||\n+\t\t    vc_qpi[i].txq.ring_len > IAVF_BE_MAX_RING_DESC ||\n+\t\t    vc_vqci->vsi_id != adapter->vf_res->vsi_res[0].vsi_id) {\n+\t\t\tret = VIRTCHNL_STATUS_ERR_PARAM;\n+\t\t\tgoto send_msg;\n+\t\t}\n+\t}\n+\n+\t/* Store queues info internally */\n+\tadapter->nb_used_qps = nb_qps;\n+\trte_memcpy(adapter->qps, &vc_vqci->qpair,\n+\t\t   nb_qps * sizeof(adapter->qps[0]));\n+\n+\tfor (i = 0; i < nb_qps; i++) {\n+\t\tstruct rte_emudev_db_info db_info;\n+\n+\t\tqueue_id = adapter->qps[i].rxq.queue_id;\n+\t\trxq = dev->data->rx_queues[queue_id];\n+\t\ttxq = dev->data->tx_queues[queue_id];\n+\t\tif (!rxq || !txq) {\n+\t\t\tIAVF_BE_LOG(ERR, \"Queue Pair %u \"\n+\t\t\t\t    \" hasn't been setup\", rxq->queue_id);\n+\t\t\tret = VIRTCHNL_STATUS_NOT_SUPPORTED;\n+\t\t\tgoto send_msg;\n+\t\t}\n+\n+\t\t/* Configure Rx Queue */\n+\t\trxq->nb_rx_desc = vc_qpi[i].txq.ring_len;\n+\t\trxq->tx_ring_phys_addr = vc_qpi[i].txq.dma_ring_addr;\n+\t\trxq->max_pkt_len = vc_qpi[i].rxq.max_pkt_size;\n+\t\tmemset(&db_info, 0, sizeof(db_info));\n+\t\tret = rte_emudev_get_db_info(adapter->edev_id,\n+\t\t\t\t\t  i * 2 + RTE_IAVF_EMU_ADMINQ_NUM,\n+\t\t\t\t\t  &db_info);\n+\t\tif (ret || (db_info.flag & RTE_EMUDEV_DB_MEM) != RTE_EMUDEV_DB_MEM) {\n+\t\t\tIAVF_BE_LOG(ERR, \"Fail to get Door Bell of RXQ %u\",\n+\t\t\t\t    rxq->queue_id);\n+\t\t\tret = VIRTCHNL_STATUS_NOT_SUPPORTED;\n+\t\t\tgoto send_msg;\n+\t\t}\n+\t\trxq->qtx_tail = (uint8_t *)db_info.data.mem.base;\n+\t\t/* Reset stats */\n+\t\treset_rxq_stats(rxq);\n+\t\trxq->q_set = true;\n+\n+\t\t/* Configure Tx Queue */\n+\t\ttxq->nb_tx_desc = vc_qpi[i].rxq.ring_len;\n+\t\ttxq->rx_ring_phys_addr = vc_qpi[i].rxq.dma_ring_addr;\n+\t\ttxq->buffer_size = vc_qpi[i].rxq.databuffer_size;\n+\t\ttxq->max_pkt_size = vc_qpi[i].rxq.max_pkt_size;\n+\t\tmemset(&db_info, 0, sizeof(db_info));\n+\t\tret = rte_emudev_get_db_info(adapter->edev_id,\n+\t\t\t\t\t  i * 2 + RTE_IAVF_EMU_ADMINQ_NUM + 1,\n+\t\t\t\t\t  &db_info);\n+\t\tif (ret || (db_info.flag & RTE_EMUDEV_DB_MEM) != RTE_EMUDEV_DB_MEM) {\n+\t\t\tIAVF_BE_LOG(ERR, \"Fail to get Door Bell of TXQ %u\",\n+\t\t\t\t    txq->queue_id);\n+\t\t\tret = VIRTCHNL_STATUS_NOT_SUPPORTED;\n+\t\t\tgoto send_msg;\n+\t\t}\n+\t\ttxq->qrx_tail = (uint8_t *)db_info.data.mem.base;\n+\t\t/* Reset stats */\n+\t\treset_txq_stats(txq);\n+\t\ttxq->q_set = true;\n+\t}\n+\n+send_msg:\n+\tiavfbe_send_msg_to_vf(adapter, VIRTCHNL_OP_CONFIG_VSI_QUEUES,\n+\t\t\t      ret, NULL, 0);\n+\treturn ret;\n+}\n+\n+static int\n+iavfbe_process_cmd_enable_queues(struct iavfbe_adapter *adapter,\n+\t\t\t\t uint8_t *msg,\n+\t\t\t\t uint16_t msglen __rte_unused)\n+{\n+\tstruct virtchnl_queue_select *q_sel =\n+\t\t(struct virtchnl_queue_select *)msg;\n+\tstruct rte_eth_dev *dev = adapter->eth_dev;\n+\tstruct iavfbe_rx_queue *rxq;\n+\tstruct iavfbe_tx_queue *txq;\n+\tint i, ret = VIRTCHNL_STATUS_SUCCESS;\n+\n+\tif (!msg) {\n+\t\tret = VIRTCHNL_STATUS_ERR_PARAM;\n+\t\tgoto send_msg;\n+\t}\n+\n+\tfor (i = 0; i < adapter->nb_used_qps; i++) {\n+\t\tuint64_t len;\n+\n+\t\trxq = dev->data->rx_queues[i];\n+\t\ttxq = dev->data->tx_queues[i];\n+\t\tif (!rxq || !txq) {\n+\t\t\tIAVF_BE_LOG(ERR, \"Queue Pair %u \"\n+\t\t\t\t    \" hasn't been setup\", rxq->queue_id);\n+\t\t\tret = IAVF_ERR_DEVICE_NOT_SUPPORTED;\n+\t\t\tgoto send_msg;\n+\t\t}\n+\t\tif (q_sel->tx_queues & (1 << i)) {\n+\t\t\tif (!rxq->q_set) {\n+\t\t\t\tIAVF_BE_LOG(ERR, \"RXQ %u hasn't been setup\", i);\n+\t\t\t\tret = VIRTCHNL_STATUS_ERR_NOT_SUPPORTED;\n+\t\t\t\tgoto send_msg;\n+\t\t\t}\n+\t\t\tlen = rxq->nb_rx_desc * sizeof(struct iavf_tx_desc);\n+\t\t\trxq->tx_ring = (void *)(uintptr_t)rte_iavf_emu_get_dma_vaddr(\n+\t\t\t\t\t\tadapter->mem_table,\n+\t\t\t\t\t\trxq->tx_ring_phys_addr,\n+\t\t\t\t\t\t&len);\n+\t\t\trte_atomic32_set(&rxq->enable, true);\n+\t\t}\n+\t\tif (q_sel->rx_queues & (1 << i)) {\n+\t\t\tif (!txq->q_set) {\n+\t\t\t\tIAVF_BE_LOG(ERR, \"TXQ %u hasn't been setup\", i);\n+\t\t\t\tret = VIRTCHNL_STATUS_ERR_NOT_SUPPORTED;\n+\t\t\t\tgoto send_msg;\n+\t\t\t}\n+\t\t\tlen = txq->nb_tx_desc * sizeof(union iavf_32byte_rx_desc);\n+\t\t\ttxq->rx_ring = (void *)(uintptr_t)\n+\t\t\t\trte_iavf_emu_get_dma_vaddr(adapter->mem_table,\n+\t\t\t\t\t\t       txq->rx_ring_phys_addr,\n+\t\t\t\t\t\t       &len);\n+\t\t\trte_atomic32_set(&txq->enable, true);\n+\t\t}\n+\t}\n+\n+\t/* Set link UP after queues are enabled */\n+\tadapter->link_up = true;\n+\tiavfbe_dev_link_update(adapter->eth_dev, 0);\n+\n+send_msg:\n+\tiavfbe_send_msg_to_vf(adapter, VIRTCHNL_OP_ENABLE_QUEUES, ret, NULL, 0);\n+\n+\treturn ret;\n+}\n+\n+static int\n+iavfbe_process_cmd_disable_queues(struct iavfbe_adapter *adapter,\n+\t\t\t\t  uint8_t *msg,\n+\t\t\t\t  uint16_t msglen __rte_unused)\n+{\n+\tstruct virtchnl_queue_select *q_sel =\n+\t\t(struct virtchnl_queue_select *)msg;\n+\tstruct rte_eth_dev *dev = adapter->eth_dev;\n+\tstruct iavfbe_rx_queue *rxq;\n+\tstruct iavfbe_tx_queue *txq;\n+\tint ret = VIRTCHNL_STATUS_SUCCESS;\n+\tuint16_t i;\n+\n+\tif (!msg) {\n+\t\tret = VIRTCHNL_STATUS_ERR_PARAM;\n+\t\tgoto send_msg;\n+\t}\n+\n+\tfor (i = 0; i < adapter->nb_used_qps; i++) {\n+\t\trxq = dev->data->rx_queues[i];\n+\t\ttxq = dev->data->tx_queues[i];\n+\n+\t\tif (q_sel->tx_queues & (1 << i)) {\n+\t\t\tif (!rxq)\n+\t\t\t\tcontinue;\n+\t\t\trte_atomic32_set(&rxq->enable, false);\n+\t\t\treset_rxq_stats(rxq);\n+\t\t}\n+\t\tif (q_sel->rx_queues & (1 << i)) {\n+\t\t\tif (!txq)\n+\t\t\t\tcontinue;\n+\t\t\trte_atomic32_set(&txq->enable, false);\n+\t\t\treset_txq_stats(txq);\n+\t\t}\n+\t}\n+send_msg:\n+\tiavfbe_send_msg_to_vf(adapter, VIRTCHNL_OP_DISABLE_QUEUES,\n+\t\t\t      ret, NULL, 0);\n+\n+\treturn ret;\n+}\n+\n+static int\n+iavfbe_process_cmd_config_irq_map(struct iavfbe_adapter *adapter,\n+\t\t\t\t  uint8_t *msg,\n+\t\t\t\t  uint16_t msglen __rte_unused)\n+{\n+\tstruct rte_eth_dev *dev = adapter->eth_dev;\n+\tstruct iavfbe_tx_queue *txq;\n+\tstruct iavfbe_rx_queue *rxq;\n+\tuint16_t i, j, vector_id;\n+\tint ret = VIRTCHNL_STATUS_SUCCESS;\n+\n+\tstruct virtchnl_irq_map_info *irqmap =\n+\t\t(struct virtchnl_irq_map_info *)msg;\n+\tstruct virtchnl_vector_map *map;\n+\n+\tif (msg == NULL) {\n+\t\tret = VIRTCHNL_STATUS_ERR_PARAM;\n+\t\tgoto send_msg;\n+\t}\n+\n+\tIAVF_BE_LOG(DEBUG, \"irqmap->num_vectors = %d\\n\", irqmap->num_vectors);\n+\n+\tfor (i = 0; i < irqmap->num_vectors; i++) {\n+\t\tmap = &irqmap->vecmap[i];\n+\t\tvector_id = map->vector_id;\n+\n+\t\tfor (j = 0; j < adapter->nb_used_qps; j++) {\n+\t\t\trxq = dev->data->rx_queues[j];\n+\t\t\ttxq = dev->data->tx_queues[j];\n+\n+\t\t\tif ((1 << j) & map->rxq_map) {\n+\t\t\t\ttxq->vector = vector_id;\n+\t\t\t\tret = apply_tx_irq(txq, vector_id);\n+\t\t\t\tif (ret)\n+\t\t\t\t\tgoto send_msg;\n+\t\t\t}\n+\t\t\tif ((1 << j) & map->txq_map) {\n+\t\t\t\trxq->vector = vector_id;\n+\t\t\t\tret = apply_rx_irq(rxq, vector_id);\n+\t\t\t\tif (ret)\n+\t\t\t\t\tgoto send_msg;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+send_msg:\n+\tiavfbe_send_msg_to_vf(adapter, VIRTCHNL_OP_CONFIG_IRQ_MAP,\n+\t\t\t      ret, NULL, 0);\n+\n+\treturn ret;\n+}\n+\n+\n+static int\n+iavfbe_process_cmd_get_stats(struct iavfbe_adapter *adapter,\n+\t\t\t\tuint8_t *msg __rte_unused,\n+\t\t\t\tuint16_t msglen __rte_unused)\n+{\n+\tstruct iavfbe_rx_queue *rxq;\n+\tstruct iavfbe_tx_queue *txq;\n+\tint i;\n+\n+\tmemset(&adapter->eth_stats, 0, sizeof(adapter->eth_stats));\n+\n+\tfor (i = 0; i < adapter->eth_dev->data->nb_rx_queues; i++) {\n+\t\trxq = adapter->eth_dev->data->rx_queues[i];\n+\t\tif (rxq == NULL)\n+\t\t\tcontinue;\n+\t\tadapter->eth_stats.tx_broadcast += rxq->stats.recv_broad_num;;\n+\t\tadapter->eth_stats.tx_bytes += rxq->stats.recv_bytes;\n+\t\tadapter->eth_stats.tx_discards += rxq->stats.recv_miss_num;\n+\t\tadapter->eth_stats.tx_multicast += rxq->stats.recv_multi_num;\n+\t\tadapter->eth_stats.tx_unicast += rxq->stats.recv_pkt_num -\n+\t\t\t\t\t\trxq->stats.recv_broad_num -\n+\t\t\t\t\t\trxq->stats.recv_multi_num;\n+\t}\n+\n+\tfor (i = 0; i < adapter->eth_dev->data->nb_tx_queues; i++) {\n+\t\ttxq = adapter->eth_dev->data->tx_queues[i];\n+\t\tif (txq == NULL)\n+\t\t\tcontinue;\n+\t\tadapter->eth_stats.rx_broadcast += txq->stats.sent_broad_num;\n+\t\tadapter->eth_stats.rx_bytes += txq->stats.sent_bytes;\n+\t\t/* Dont add discards as recv count doesn't include this part */\n+\t\tadapter->eth_stats.rx_multicast += txq->stats.sent_multi_num;\n+\t\tadapter->eth_stats.rx_unicast += txq->stats.sent_pkt_num -\n+\t\t\t\t\t\ttxq->stats.sent_broad_num -\n+\t\t\t\t\t\ttxq->stats.sent_multi_num;\n+\t}\n+\n+\tIAVF_BE_LOG(DEBUG, \"rx_bytes:            %\"PRIu64\"\",\n+\t\t\t\t\tadapter->eth_stats.tx_bytes);\n+\tIAVF_BE_LOG(DEBUG, \"rx_unicast:          %\"PRIu64\"\",\n+\t\t\t\t\tadapter->eth_stats.tx_unicast);\n+\tIAVF_BE_LOG(DEBUG, \"rx_multicast:        %\"PRIu64\"\",\n+\t\t\t\t\tadapter->eth_stats.tx_multicast);\n+\tIAVF_BE_LOG(DEBUG, \"rx_broadcast:        %\"PRIu64\"\",\n+\t\t\t\t\tadapter->eth_stats.tx_broadcast);\n+\tIAVF_BE_LOG(DEBUG, \"rx_discards:         %\"PRIu64\"\",\n+\t\t\t\t\tadapter->eth_stats.tx_discards);\n+\n+\tIAVF_BE_LOG(DEBUG, \"tx_bytes:            %\"PRIu64\"\",\n+\t\t\t\t\tadapter->eth_stats.rx_bytes);\n+\tIAVF_BE_LOG(DEBUG, \"tx_unicast:          %\"PRIu64\"\",\n+\t\t\t\t\tadapter->eth_stats.rx_unicast);\n+\tIAVF_BE_LOG(DEBUG, \"tx_multicast:        %\"PRIu64\"\",\n+\t\t\t\t\tadapter->eth_stats.rx_multicast);\n+\tIAVF_BE_LOG(DEBUG, \"tx_broadcast:        %\"PRIu64\"\",\n+\t\t\t\t\tadapter->eth_stats.rx_broadcast);\n+\tIAVF_BE_LOG(DEBUG, \"tx_discards:         %\"PRIu64\"\",\n+\t\t\t\t\tadapter->eth_stats.rx_discards);\n+\n+\tiavfbe_send_msg_to_vf(adapter, VIRTCHNL_OP_GET_STATS,\n+\t\t\t      VIRTCHNL_STATUS_SUCCESS,\n+\t\t\t      (uint8_t *)&adapter->eth_stats,\n+\t\t\t      sizeof(struct virtchnl_eth_stats));\n+\n+\treturn IAVF_SUCCESS;\n+}\n+\n /* Read data in admin queue to get msg from vf driver */\n static enum iavf_status\n iavfbe_read_msg_from_vf(struct iavfbe_adapter *adapter,\n@@ -166,6 +677,306 @@ iavfbe_read_msg_from_vf(struct iavfbe_adapter *adapter,\n \treturn ret;\n }\n \n+static void\n+iavfbe_notify_vf_link_status(struct iavfbe_adapter *adapter)\n+{\n+\tstruct virtchnl_pf_event event;\n+\n+\tevent.severity = PF_EVENT_SEVERITY_INFO;\n+\tevent.event = VIRTCHNL_EVENT_LINK_CHANGE;\n+\tevent.event_data.link_event.link_status = adapter->link_up ? 1 : 0;\n+\tevent.event_data.link_event.link_speed = VIRTCHNL_LINK_SPEED_UNKNOWN;\n+\n+\tiavfbe_send_msg_to_vf(adapter, VIRTCHNL_OP_EVENT,\n+\t\t\t\tIAVF_SUCCESS, (uint8_t *)&event, sizeof(event));\n+}\n+\n+void\n+iavfbe_notify_vf_reset(struct iavfbe_adapter *adapter)\n+{\n+\tstruct virtchnl_pf_event event;\n+\n+\tevent.severity = PF_EVENT_SEVERITY_CERTAIN_DOOM;\n+\tevent.event = VIRTCHNL_EVENT_RESET_IMPENDING;\n+\n+\tiavfbe_send_msg_to_vf(adapter, VIRTCHNL_OP_EVENT,\n+\t\t\t\tIAVF_SUCCESS, (uint8_t *)&event, sizeof(event));\n+}\n+\n+void\n+iavfbe_notify(struct iavfbe_adapter *adapter)\n+{\n+\tif (adapter->cq_irqfd == -1 ||\n+\t\t!rte_atomic32_read(&adapter->irq_enable))\n+\t\treturn;\n+\n+\tif (eventfd_write(adapter->cq_irqfd, (eventfd_t)1) < 0)\n+\t\tIAVF_BE_LOG(ERR, \"failed to notify front-end: %s\",\n+\t\t\t\t\tstrerror(errno));\n+}\n+\n+\n+static int\n+iavfbe_process_cmd_enable_vlan_strip(struct iavfbe_adapter *adapter)\n+{\n+\tadapter->vlan_strip = true;\n+\n+\tiavfbe_send_msg_to_vf(adapter, VIRTCHNL_OP_ENABLE_VLAN_STRIPPING,\n+\t\t\t      VIRTCHNL_STATUS_SUCCESS, NULL, 0);\n+\n+\treturn 0;\n+}\n+\n+static int\n+iavfbe_process_cmd_disable_vlan_strip(struct iavfbe_adapter *adapter)\n+{\n+\tadapter->vlan_strip = false;\n+\n+\tiavfbe_send_msg_to_vf(adapter, VIRTCHNL_OP_DISABLE_VLAN_STRIPPING,\n+\t\t\t      VIRTCHNL_STATUS_SUCCESS, NULL, 0);\n+\n+\treturn 0;\n+}\n+\n+static int\n+iavfbe_process_cmd_config_promisc_mode(struct iavfbe_adapter *adapter,\n+\t\t\t\tuint8_t *msg,\n+\t\t\t\tuint16_t msglen __rte_unused)\n+{\n+\tint ret = VIRTCHNL_STATUS_SUCCESS;\n+\tstruct virtchnl_promisc_info *promisc =\n+\t\t(struct virtchnl_promisc_info *)msg;\n+\n+\tif (msg == NULL) {\n+\t\tret = VIRTCHNL_STATUS_ERR_PARAM;\n+\t\tgoto send_msg;\n+\t}\n+\n+\tadapter->unicast_promisc =\n+\t\t(promisc->flags & FLAG_VF_UNICAST_PROMISC) ? true : false;\n+\tadapter->multicast_promisc =\n+\t\t(promisc->flags & FLAG_VF_MULTICAST_PROMISC) ? true : false;\n+\n+send_msg:\n+\tiavfbe_send_msg_to_vf(adapter, VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE,\n+\t\t\t      ret, NULL, 0);\n+\treturn ret;\n+}\n+\n+static int\n+iavfbe_process_cmd_add_ether_address(struct iavfbe_adapter *adapter,\n+\t\t\t\t     uint8_t *msg,\n+\t\t\t\t     uint16_t msglen __rte_unused)\n+{\n+\tstruct virtchnl_ether_addr_list *addr_list =\n+\t\t(struct virtchnl_ether_addr_list *)msg;\n+\tint ret = VIRTCHNL_STATUS_SUCCESS;\n+\tint i;\n+\n+\tif (msg == NULL) {\n+\t\tret = VIRTCHNL_STATUS_ERR_PARAM;\n+\t\tgoto send_msg;\n+\t}\n+\n+\n+\tfor (i = 0; i < addr_list->num_elements; i++) {\n+\n+\t\t/* TODO: mac filter havn't been enabled yet */\n+\n+\t}\n+\n+send_msg:\n+\tiavfbe_send_msg_to_vf(adapter, VIRTCHNL_OP_ADD_ETH_ADDR,\n+\t\t\t      ret, NULL, 0);\n+\treturn ret;\n+}\n+\n+static int\n+iavfbe_process_cmd_del_ether_address(struct iavfbe_adapter *adapter,\n+\t\t\t\t     uint8_t *msg,\n+\t\t\t\t     uint16_t msglen __rte_unused)\n+{\n+\tint ret = VIRTCHNL_STATUS_SUCCESS;\n+\tstruct virtchnl_ether_addr_list *addr_list =\n+\t\t(struct virtchnl_ether_addr_list *)msg;\n+\tint i;\n+\n+\tif (msg == NULL) {\n+\t\tret = VIRTCHNL_STATUS_ERR_PARAM;\n+\t\tgoto send_msg;\n+\t}\n+\n+\tfor (i = 0; i < addr_list->num_elements; i++) {\n+\n+\t\t/* TODO: mac filter havn't been enabled yet */\n+\n+\t}\n+\n+send_msg:\n+\tiavfbe_send_msg_to_vf(adapter, VIRTCHNL_OP_DEL_ETH_ADDR,\n+\t\t\t      ret, NULL, 0);\n+\treturn ret;\n+}\n+\n+static int\n+iavfbe_process_cmd_add_vlan(struct iavfbe_adapter *adapter,\n+\t\t\t    uint8_t *msg, uint16_t msglen __rte_unused)\n+{\n+\tint ret = VIRTCHNL_STATUS_SUCCESS;\n+\tstruct virtchnl_vlan_filter_list *vlan_list =\n+\t\t(struct virtchnl_vlan_filter_list *)msg;\n+\tint i;\n+\n+\tif (msg == NULL) {\n+\t\tret = VIRTCHNL_STATUS_ERR_PARAM;\n+\t\tgoto send_msg;\n+\t}\n+\n+\tfor (i = 0; i < vlan_list->num_elements; i++) {\n+\n+\t\t/* TODO: vlan filter havn't been enabled yet */\n+\n+\t}\n+\n+send_msg:\n+\tiavfbe_send_msg_to_vf(adapter, VIRTCHNL_OP_ADD_VLAN,\n+\t\t\t      ret, NULL, 0);\n+\treturn ret;\n+}\n+\n+static int\n+iavfbe_process_cmd_del_vlan(struct iavfbe_adapter *adapter,\n+\t\t\t    uint8_t *msg,\n+\t\t\t    uint16_t msglen __rte_unused)\n+{\n+\tint ret = IAVF_SUCCESS;\n+\tstruct virtchnl_vlan_filter_list *vlan_list =\n+\t\t(struct virtchnl_vlan_filter_list *)msg;\n+\tint i;\n+\n+\tif (msg == NULL) {\n+\t\tret = VIRTCHNL_STATUS_ERR_PARAM;\n+\t\tgoto send_msg;\n+\t}\n+\n+\tfor (i = 0; i < vlan_list->num_elements; i++) {\n+\n+\t\t/* TODO: vlan filter havn't been enabled yet */\n+\n+\t}\n+\n+send_msg:\n+\tiavfbe_send_msg_to_vf(adapter, VIRTCHNL_OP_DEL_VLAN,\n+\t\t\t      ret, NULL, 0);\n+\treturn ret;\n+}\n+\n+static void\n+iavfbe_execute_vf_cmd(struct iavfbe_adapter *adapter,\n+\t\t\tstruct iavf_arq_event_info *event)\n+{\n+\tenum virtchnl_ops msg_opc;\n+\tint ret;\n+\n+\tmsg_opc = (enum virtchnl_ops)rte_le_to_cpu_32(\n+\t\tevent->desc.cookie_high);\n+\t/* perform basic checks on the msg */\n+\tret = virtchnl_vc_validate_vf_msg(&adapter->virtchnl_version, msg_opc,\n+\t\t\t\t\t  event->msg_buf, event->msg_len);\n+\tif (ret) {\n+\t\tIAVF_BE_LOG(ERR, \"Invalid message opcode %u, len %u\",\n+\t\t\t    msg_opc, event->msg_len);\n+\t\tiavfbe_send_msg_to_vf(adapter, msg_opc,\n+\t\t\t\t      VIRTCHNL_STATUS_ERR_NOT_SUPPORTED,\n+\t\t\t\t      NULL, 0);\n+\t}\n+\n+\tswitch (msg_opc) {\n+\tcase VIRTCHNL_OP_VERSION:\n+\t\tIAVF_BE_LOG(INFO, \"OP_VERSION received\");\n+\t\tiavfbe_process_cmd_version(adapter, event->msg_buf);\n+\t\tbreak;\n+\tcase VIRTCHNL_OP_RESET_VF:\n+\t\tIAVF_BE_LOG(INFO, \"OP_RESET_VF received\");\n+\t\tiavfbe_process_cmd_reset_vf(adapter);\n+\t\tbreak;\n+\tcase VIRTCHNL_OP_GET_VF_RESOURCES:\n+\t\tIAVF_BE_LOG(INFO, \"OP_GET_VF_RESOURCES received\");\n+\t\tiavfbe_process_cmd_get_vf_resource(adapter, event->msg_buf);\n+\t\tbreak;\n+\tcase VIRTCHNL_OP_CONFIG_VSI_QUEUES:\n+\t\tIAVF_BE_LOG(INFO, \"OP_CONFIG_VSI_QUEUES received\");\n+\t\tiavfbe_process_cmd_config_vsi_queues(adapter, event->msg_buf,\n+\t\t\t\t\t\t     event->msg_len);\n+\t\tbreak;\n+\tcase VIRTCHNL_OP_ENABLE_QUEUES:\n+\t\tIAVF_BE_LOG(INFO, \"OP_ENABLE_QUEUES received\");\n+\t\tiavfbe_process_cmd_enable_queues(adapter, event->msg_buf,\n+\t\t\t\t\t\t event->msg_len);\n+\t\tiavfbe_notify_vf_link_status(adapter);\n+\t\tbreak;\n+\tcase VIRTCHNL_OP_DISABLE_QUEUES:\n+\t\tIAVF_BE_LOG(INFO, \"OP_DISABLE_QUEUE received\");\n+\t\tiavfbe_process_cmd_disable_queues(adapter, event->msg_buf,\n+\t\t\t\t\t\t  event->msg_len);\n+\t\tbreak;\n+\tcase VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE:\n+\t\tIAVF_BE_LOG(INFO, \"OP_CONFIG_PROMISCUOUS_MODE received\");\n+\t\tiavfbe_process_cmd_config_promisc_mode(adapter, event->msg_buf,\n+\t\t\t\t\t\t       event->msg_len);\n+\t\tbreak;\n+\tcase VIRTCHNL_OP_CONFIG_IRQ_MAP:\n+\t\tIAVF_BE_LOG(INFO, \"VIRTCHNL_OP_CONFIG_IRQ_MAP received\");\n+\t\tiavfbe_process_cmd_config_irq_map(adapter, event->msg_buf,\n+\t\t\t\t\t\t  event->msg_len);\n+\t\tbreak;\n+\tcase VIRTCHNL_OP_ADD_ETH_ADDR:\n+\t\tIAVF_BE_LOG(INFO, \"VIRTCHNL_OP_ADD_ETH_ADDR received\");\n+\t\tiavfbe_process_cmd_add_ether_address(adapter, event->msg_buf,\n+\t\t\t\t\t\t     event->msg_len);\n+\t\tbreak;\n+\tcase VIRTCHNL_OP_DEL_ETH_ADDR:\n+\t\tIAVF_BE_LOG(INFO, \"VIRTCHNL_OP_DEL_ETH_ADDR received\");\n+\t\tiavfbe_process_cmd_del_ether_address(adapter, event->msg_buf,\n+\t\t\t\t\t\t     event->msg_len);\n+\t\tbreak;\n+\tcase VIRTCHNL_OP_GET_STATS:\n+\t\tIAVF_BE_LOG(INFO, \"VIRTCHNL_OP_GET_STATS received\");\n+\t\tiavfbe_process_cmd_get_stats(adapter, event->msg_buf,\n+\t\t\t\t\t     event->msg_len);\n+\t\tbreak;\n+\tcase VIRTCHNL_OP_ADD_VLAN:\n+\t\tIAVF_BE_LOG(INFO, \"VIRTCHNL_OP_ADD_VLAN received\");\n+\t\tiavfbe_process_cmd_add_vlan(adapter, event->msg_buf,\n+\t\t\t\t\t    event->msg_len);\n+\t\tiavfbe_notify(adapter);\n+\t\tbreak;\n+\tcase VIRTCHNL_OP_DEL_VLAN:\n+\t\tIAVF_BE_LOG(INFO, \"VIRTCHNL_OP_ADD_VLAN received\");\n+\t\tiavfbe_process_cmd_del_vlan(adapter, event->msg_buf,\n+\t\t\t\t\t    event->msg_len);\n+\t\tiavfbe_notify(adapter);\n+\t\tbreak;\n+\tcase VIRTCHNL_OP_ENABLE_VLAN_STRIPPING:\n+\t\tIAVF_BE_LOG(INFO, \"VIRTCHNL_OP_ENABLE_VLAN_STRIPPING received\");\n+\t\tiavfbe_process_cmd_enable_vlan_strip(adapter);\n+\t\tiavfbe_notify(adapter);\n+\t\tbreak;\n+\tcase VIRTCHNL_OP_DISABLE_VLAN_STRIPPING:\n+\t\tIAVF_BE_LOG(INFO, \"VIRTCHNL_OP_DISABLE_VLAN_STRIPPING received\");\n+\t\tiavfbe_process_cmd_disable_vlan_strip(adapter);\n+\t\tiavfbe_notify(adapter);\n+\t\tbreak;\n+\tdefault:\n+\t\tIAVF_BE_LOG(ERR, \"%u received, not supported\", msg_opc);\n+\t\tiavfbe_send_msg_to_vf(adapter, msg_opc,\n+\t\t\t\t      VIRTCHNL_STATUS_ERR_NOT_SUPPORTED,\n+\t\t\t\t      NULL, 0);\n+\t\tbreak;\n+\t}\n+\n+}\n+\n static inline int\n iavfbe_control_queue_remap(struct iavfbe_adapter *adapter,\n \t\t\t  struct iavfbe_control_q *asq,\n@@ -255,7 +1066,7 @@ iavfbe_handle_virtchnl_msg(void *arg)\n \n \t\tswitch (aq_opc) {\n \t\tcase iavf_aqc_opc_send_msg_to_pf:\n-\t\t\t/* Process msg from VF BE*/\n+\t\t\tiavfbe_execute_vf_cmd(adapter, &info);\n \t\t\tbreak;\n \t\tcase iavf_aqc_opc_queue_shutdown:\n \t\t\tiavfbe_reset_arq(adapter, true);\ndiff --git a/drivers/net/iavf_be/meson.build b/drivers/net/iavf_be/meson.build\nindex be13a2e492..e6b1c522a7 100644\n--- a/drivers/net/iavf_be/meson.build\n+++ b/drivers/net/iavf_be/meson.build\n@@ -10,4 +10,5 @@ deps += ['bus_vdev', 'common_iavf', 'vfio_user', 'emu_iavf']\n sources = files(\n \t'iavf_be_ethdev.c',\n \t'iavf_be_vchnl.c',\n+\t'iavf_be_rxtx.c',\n )\n",
    "prefixes": [
        "v1",
        "3/5"
    ]
}