get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 81011,
    "url": "http://patches.dpdk.org/api/patches/81011/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20201016012142.54144-3-ting.xu@intel.com/",
    "project": {
        "id": 1,
        "url": "http://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": "<20201016012142.54144-3-ting.xu@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20201016012142.54144-3-ting.xu@intel.com",
    "date": "2020-10-16T01:21:42",
    "name": "[v5,2/2] net/iavf: enable large VF configuration",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "fdb9eff0906e71b9ab300e1bc1fc3de6228be04c",
    "submitter": {
        "id": 1363,
        "url": "http://patches.dpdk.org/api/people/1363/?format=api",
        "name": "Xu, Ting",
        "email": "ting.xu@intel.com"
    },
    "delegate": {
        "id": 1540,
        "url": "http://patches.dpdk.org/api/users/1540/?format=api",
        "username": "qzhan15",
        "first_name": "Qi",
        "last_name": "Zhang",
        "email": "qi.z.zhang@intel.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20201016012142.54144-3-ting.xu@intel.com/mbox/",
    "series": [
        {
            "id": 13032,
            "url": "http://patches.dpdk.org/api/series/13032/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=13032",
            "date": "2020-10-16T01:21:40",
            "name": "enable large VF configuration",
            "version": 5,
            "mbox": "http://patches.dpdk.org/series/13032/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/81011/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/81011/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 0A027A04DB;\n\tFri, 16 Oct 2020 03:18:42 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 620CA1E0AC;\n\tFri, 16 Oct 2020 03:18:07 +0200 (CEST)",
            "from mga11.intel.com (mga11.intel.com [192.55.52.93])\n by dpdk.org (Postfix) with ESMTP id 105B51DCD8\n for <dev@dpdk.org>; Fri, 16 Oct 2020 03:18:03 +0200 (CEST)",
            "from orsmga005.jf.intel.com ([10.7.209.41])\n by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 15 Oct 2020 18:18:03 -0700",
            "from dpdk-xuting-second.sh.intel.com ([10.67.116.154])\n by orsmga005.jf.intel.com with ESMTP; 15 Oct 2020 18:18:00 -0700"
        ],
        "IronPort-SDR": [
            "\n PZtuz4h1H5NCprZi7Sc8e92IcuBBtmfz8cZ3WHhLZxDawGPGjsUGRfonxt2/RgLS6Xcq3lzBTM\n mwcL91g0ZKzw==",
            "\n NNzrgHRMbZH9am/7mht4+0bjUwe/KN/PMrkZ/sBfU7j4cnL0t+jaxwpdNkP5X3EgW4GshZTRD/\n 1OY2sK8cOWyA=="
        ],
        "X-IronPort-AV": [
            "E=McAfee;i=\"6000,8403,9775\"; a=\"163023864\"",
            "E=Sophos;i=\"5.77,380,1596524400\"; d=\"scan'208\";a=\"163023864\"",
            "E=Sophos;i=\"5.77,380,1596524400\"; d=\"scan'208\";a=\"531485934\""
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "From": "Ting Xu <ting.xu@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "qi.z.zhang@intel.com, beilei.xing@intel.com, jingjing.wu@intel.com,\n Ting Xu <ting.xu@intel.com>",
        "Date": "Fri, 16 Oct 2020 09:21:42 +0800",
        "Message-Id": "<20201016012142.54144-3-ting.xu@intel.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20201016012142.54144-1-ting.xu@intel.com>",
        "References": "<20200909072028.16726-1-ting.xu@intel.com>\n <20201016012142.54144-1-ting.xu@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v5 2/2] net/iavf: enable large VF configuration",
        "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": "Add support to negotiate large VF capability, including configure VSI\nqueues, enable/disable queues and IRQ mapping for large VF. Use new\nvirtchnl opcodes and structures to help indicate up to 256 queue pairs.\nNeed to request additional queues from PF first if the current allocated\nqueues are not enough. Add the step to query the current max RSS queue\nregion for RSS configuration since the max RSS queue region could be\nsmaller than the allocated queue pairs.\n\nSigned-off-by: Ting Xu <ting.xu@intel.com>\n---\n drivers/net/iavf/iavf.h        |  27 +++-\n drivers/net/iavf/iavf_ethdev.c | 145 +++++++++++++++++++--\n drivers/net/iavf/iavf_rxtx.c   |  27 +++-\n drivers/net/iavf/iavf_vchnl.c  | 224 +++++++++++++++++++++++++++++++--\n 4 files changed, 391 insertions(+), 32 deletions(-)",
    "diff": "diff --git a/drivers/net/iavf/iavf.h b/drivers/net/iavf/iavf.h\nindex 93c165c62..3de096879 100644\n--- a/drivers/net/iavf/iavf.h\n+++ b/drivers/net/iavf/iavf.h\n@@ -19,7 +19,11 @@\n #define IAVF_FRAME_SIZE_MAX       9728\n #define IAVF_QUEUE_BASE_ADDR_UNIT 128\n \n-#define IAVF_MAX_NUM_QUEUES       16\n+#define IAVF_MAX_NUM_QUEUES_DFLT\t 16\n+#define IAVF_MAX_NUM_QUEUES_LV\t\t 256\n+#define IAVF_RXTX_QUEUE_CHUNKS_NUM\t 2\n+#define IAVF_CFG_Q_NUM_PER_BUF\t\t 32\n+#define IAVF_IRQ_MAP_NUM_PER_BUF\t 128\n \n #define IAVF_NUM_MACADDR_MAX      64\n \n@@ -104,8 +108,10 @@ struct iavf_fdir_info {\n \tstruct iavf_fdir_conf conf;\n };\n \n-/* TODO: is that correct to assume the max number to be 16 ?*/\n-#define IAVF_MAX_MSIX_VECTORS   16\n+struct iavf_qv_map {\n+\tuint16_t queue_id;\n+\tuint16_t vector_id;\n+};\n \n /* Message type read in admin queue from PF */\n enum iavf_aq_result {\n@@ -149,14 +155,16 @@ struct iavf_info {\n \tuint8_t *rss_key;\n \tuint16_t nb_msix;   /* number of MSI-X interrupts on Rx */\n \tuint16_t msix_base; /* msix vector base from */\n-\t/* queue bitmask for each vector */\n-\tuint16_t rxq_map[IAVF_MAX_MSIX_VECTORS];\n+\tuint16_t max_rss_qregion; /* max RSS queue region supported by PF */\n+\tstruct iavf_qv_map *qv_map; /* queue vector mapping */\n \tstruct iavf_flow_list flow_list;\n \trte_spinlock_t flow_ops_lock;\n \tstruct iavf_parser_list rss_parser_list;\n \tstruct iavf_parser_list dist_parser_list;\n \n \tstruct iavf_fdir_info fdir; /* flow director info */\n+\t/* indicate large VF support enabled or not */\n+\tbool lv_enabled;\n };\n \n #define IAVF_MAX_PKT_TYPE 1024\n@@ -283,13 +291,19 @@ int iavf_enable_vlan_strip(struct iavf_adapter *adapter);\n int iavf_disable_vlan_strip(struct iavf_adapter *adapter);\n int iavf_switch_queue(struct iavf_adapter *adapter, uint16_t qid,\n \t\t     bool rx, bool on);\n+int iavf_switch_queue_lv(struct iavf_adapter *adapter, uint16_t qid,\n+\t\t     bool rx, bool on);\n int iavf_enable_queues(struct iavf_adapter *adapter);\n+int iavf_enable_queues_lv(struct iavf_adapter *adapter);\n int iavf_disable_queues(struct iavf_adapter *adapter);\n+int iavf_disable_queues_lv(struct iavf_adapter *adapter);\n int iavf_configure_rss_lut(struct iavf_adapter *adapter);\n int iavf_configure_rss_key(struct iavf_adapter *adapter);\n-int iavf_configure_queues(struct iavf_adapter *adapter);\n+int iavf_configure_queues(struct iavf_adapter *adapter,\n+\t\t\tuint16_t num_queue_pairs, uint16_t index);\n int iavf_get_supported_rxdid(struct iavf_adapter *adapter);\n int iavf_config_irq_map(struct iavf_adapter *adapter);\n+int iavf_config_irq_map_lv(struct iavf_adapter *adapter, uint16_t num);\n void iavf_add_del_all_mac_addr(struct iavf_adapter *adapter, bool add);\n int iavf_dev_link_update(struct rte_eth_dev *dev,\n \t\t\t__rte_unused int wait_to_complete);\n@@ -310,4 +324,5 @@ int iavf_add_del_mc_addr_list(struct iavf_adapter *adapter,\n \t\t\tstruct rte_ether_addr *mc_addrs,\n \t\t\tuint32_t mc_addrs_num, bool add);\n int iavf_request_queues(struct iavf_adapter *adapter, uint16_t num);\n+int iavf_get_max_rss_queue_region(struct iavf_adapter *adapter);\n #endif /* _IAVF_ETHDEV_H_ */\ndiff --git a/drivers/net/iavf/iavf_ethdev.c b/drivers/net/iavf/iavf_ethdev.c\nindex a4a28b885..c33021178 100644\n--- a/drivers/net/iavf/iavf_ethdev.c\n+++ b/drivers/net/iavf/iavf_ethdev.c\n@@ -238,7 +238,7 @@ iavf_init_rss(struct iavf_adapter *adapter)\n \n \trss_conf = &adapter->eth_dev->data->dev_conf.rx_adv_conf.rss_conf;\n \tnb_q = RTE_MIN(adapter->eth_dev->data->nb_rx_queues,\n-\t\t       IAVF_MAX_NUM_QUEUES);\n+\t\t       vf->max_rss_qregion);\n \n \tif (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF)) {\n \t\tPMD_DRV_LOG(DEBUG, \"RSS is not supported\");\n@@ -284,6 +284,31 @@ iavf_init_rss(struct iavf_adapter *adapter)\n \treturn 0;\n }\n \n+static int\n+iavf_queues_req_reset(struct rte_eth_dev *dev, uint16_t num)\n+{\n+\tstruct iavf_adapter *ad =\n+\t\tIAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);\n+\tstruct iavf_info *vf =  IAVF_DEV_PRIVATE_TO_VF(ad);\n+\tint ret = 0;\n+\n+\tret = iavf_request_queues(ad, num);\n+\tif (ret) {\n+\t\tPMD_DRV_LOG(ERR, \"request queues from PF failed\");\n+\t\treturn ret;\n+\t}\n+\tPMD_DRV_LOG(INFO, \"change queue pairs from %u to %u\",\n+\t\t\tvf->vsi_res->num_queue_pairs, num);\n+\n+\tret = iavf_dev_reset(dev);\n+\tif (ret) {\n+\t\tPMD_DRV_LOG(ERR, \"vf reset failed\");\n+\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n static int\n iavf_dev_configure(struct rte_eth_dev *dev)\n {\n@@ -292,6 +317,8 @@ iavf_dev_configure(struct rte_eth_dev *dev)\n \tstruct iavf_info *vf =  IAVF_DEV_PRIVATE_TO_VF(ad);\n \tstruct rte_eth_conf *dev_conf = &dev->data->dev_conf;\n \tuint32_t frame_size = dev->data->mtu + IAVF_ETH_OVERHEAD;\n+\tuint16_t num_queue_pairs = RTE_MAX(dev->data->nb_rx_queues,\n+\t\tdev->data->nb_tx_queues);\n \tint ret;\n \n \tad->rx_bulk_alloc_allowed = true;\n@@ -314,6 +341,46 @@ iavf_dev_configure(struct rte_eth_dev *dev)\n \t\t\treturn ret;\n \t}\n \n+\t/* Large VF setting */\n+\tif (num_queue_pairs > IAVF_MAX_NUM_QUEUES_DFLT) {\n+\t\tif (!(vf->vf_res->vf_cap_flags &\n+\t\t\t\tVIRTCHNL_VF_LARGE_NUM_QPAIRS)) {\n+\t\t\tPMD_DRV_LOG(ERR, \"large VF is not supported\");\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tif (num_queue_pairs > IAVF_MAX_NUM_QUEUES_LV) {\n+\t\t\tPMD_DRV_LOG(ERR, \"queue pairs number cannot be larger \"\n+\t\t\t\t\"than %u\", IAVF_MAX_NUM_QUEUES_LV);\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tret = iavf_queues_req_reset(dev, num_queue_pairs);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\n+\t\tret = iavf_get_max_rss_queue_region(ad);\n+\t\tif (ret) {\n+\t\t\tPMD_INIT_LOG(ERR, \"get max rss queue region failed\");\n+\t\t\treturn ret;\n+\t\t}\n+\n+\t\tvf->lv_enabled = true;\n+\t} else {\n+\t\t/* Check if large VF is already enabled. If so, disable and\n+\t\t * release redundant queue resource.\n+\t\t */\n+\t\tif (vf->lv_enabled) {\n+\t\t\tret = iavf_queues_req_reset(dev, num_queue_pairs);\n+\t\t\tif (ret)\n+\t\t\t\treturn ret;\n+\n+\t\t\tvf->lv_enabled = false;\n+\t\t}\n+\t\t/* if large VF is not required, use default rss queue region */\n+\t\tvf->max_rss_qregion = IAVF_MAX_NUM_QUEUES_DFLT;\n+\t}\n+\n \t/* Vlan stripping setting */\n \tif (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN) {\n \t\tif (dev_conf->rxmode.offloads & DEV_RX_OFFLOAD_VLAN_STRIP)\n@@ -328,6 +395,7 @@ iavf_dev_configure(struct rte_eth_dev *dev)\n \t\t\treturn -1;\n \t\t}\n \t}\n+\n \treturn 0;\n }\n \n@@ -410,6 +478,7 @@ static int iavf_config_rx_queues_irqs(struct rte_eth_dev *dev,\n \t\tIAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);\n \tstruct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);\n \tstruct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(adapter);\n+\tstruct iavf_qv_map *qv_map;\n \tuint16_t interval, i;\n \tint vec;\n \n@@ -430,6 +499,14 @@ static int iavf_config_rx_queues_irqs(struct rte_eth_dev *dev,\n \t\t}\n \t}\n \n+\tqv_map = rte_zmalloc(\"qv_map\",\n+\t\tdev->data->nb_rx_queues * sizeof(struct iavf_qv_map), 0);\n+\tif (!qv_map) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to allocate %d queue-vector map\",\n+\t\t\t\tdev->data->nb_rx_queues);\n+\t\treturn -1;\n+\t}\n+\n \tif (!dev->data->dev_conf.intr_conf.rxq ||\n \t    !rte_intr_dp_is_en(intr_handle)) {\n \t\t/* Rx interrupt disabled, Map interrupt only for writeback */\n@@ -460,16 +537,21 @@ static int iavf_config_rx_queues_irqs(struct rte_eth_dev *dev,\n \t\t}\n \t\tIAVF_WRITE_FLUSH(hw);\n \t\t/* map all queues to the same interrupt */\n-\t\tfor (i = 0; i < dev->data->nb_rx_queues; i++)\n-\t\t\tvf->rxq_map[vf->msix_base] |= 1 << i;\n+\t\tfor (i = 0; i < dev->data->nb_rx_queues; i++) {\n+\t\t\tqv_map[i].queue_id = i;\n+\t\t\tqv_map[i].vector_id = vf->msix_base;\n+\t\t}\n+\t\tvf->qv_map = qv_map;\n \t} else {\n \t\tif (!rte_intr_allow_others(intr_handle)) {\n \t\t\tvf->nb_msix = 1;\n \t\t\tvf->msix_base = IAVF_MISC_VEC_ID;\n \t\t\tfor (i = 0; i < dev->data->nb_rx_queues; i++) {\n-\t\t\t\tvf->rxq_map[vf->msix_base] |= 1 << i;\n+\t\t\t\tqv_map[i].queue_id = i;\n+\t\t\t\tqv_map[i].vector_id = vf->msix_base;\n \t\t\t\tintr_handle->intr_vec[i] = IAVF_MISC_VEC_ID;\n \t\t\t}\n+\t\t\tvf->qv_map = qv_map;\n \t\t\tPMD_DRV_LOG(DEBUG,\n \t\t\t\t    \"vector %u are mapping to all Rx queues\",\n \t\t\t\t    vf->msix_base);\n@@ -482,21 +564,44 @@ static int iavf_config_rx_queues_irqs(struct rte_eth_dev *dev,\n \t\t\tvf->msix_base = IAVF_RX_VEC_START;\n \t\t\tvec = IAVF_RX_VEC_START;\n \t\t\tfor (i = 0; i < dev->data->nb_rx_queues; i++) {\n-\t\t\t\tvf->rxq_map[vec] |= 1 << i;\n+\t\t\t\tqv_map[i].queue_id = i;\n+\t\t\t\tqv_map[i].vector_id = vec;\n \t\t\t\tintr_handle->intr_vec[i] = vec++;\n \t\t\t\tif (vec >= vf->nb_msix)\n \t\t\t\t\tvec = IAVF_RX_VEC_START;\n \t\t\t}\n+\t\t\tvf->qv_map = qv_map;\n \t\t\tPMD_DRV_LOG(DEBUG,\n \t\t\t\t    \"%u vectors are mapping to %u Rx queues\",\n \t\t\t\t    vf->nb_msix, dev->data->nb_rx_queues);\n \t\t}\n \t}\n \n-\tif (iavf_config_irq_map(adapter)) {\n-\t\tPMD_DRV_LOG(ERR, \"config interrupt mapping failed\");\n-\t\treturn -1;\n+\tif (!vf->lv_enabled) {\n+\t\tif (iavf_config_irq_map(adapter)) {\n+\t\t\tPMD_DRV_LOG(ERR, \"config interrupt mapping failed\");\n+\t\t\treturn -1;\n+\t\t}\n+\t} else {\n+\t\tuint16_t num_qv_maps = dev->data->nb_rx_queues;\n+\n+\t\twhile (num_qv_maps > IAVF_IRQ_MAP_NUM_PER_BUF) {\n+\t\t\tif (iavf_config_irq_map_lv(adapter,\n+\t\t\t\t\tIAVF_IRQ_MAP_NUM_PER_BUF)) {\n+\t\t\t\tPMD_DRV_LOG(ERR, \"config interrupt mapping \"\n+\t\t\t\t\t\"for large VF failed\");\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tnum_qv_maps -= IAVF_IRQ_MAP_NUM_PER_BUF;\n+\t\t}\n+\n+\t\tif (iavf_config_irq_map_lv(adapter, num_qv_maps)) {\n+\t\t\tPMD_DRV_LOG(ERR, \"config interrupt mapping \"\n+\t\t\t\t\"for large VF failed\");\n+\t\t\treturn -1;\n+\t\t}\n \t}\n+\n \treturn 0;\n }\n \n@@ -537,6 +642,8 @@ iavf_dev_start(struct rte_eth_dev *dev)\n \t\tIAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);\n \tstruct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);\n \tstruct rte_intr_handle *intr_handle = dev->intr_handle;\n+\tuint16_t num_queue_pairs;\n+\tuint16_t index = 0;\n \n \tPMD_INIT_FUNC_TRACE();\n \n@@ -545,13 +652,27 @@ iavf_dev_start(struct rte_eth_dev *dev)\n \tvf->max_pkt_len = dev->data->dev_conf.rxmode.max_rx_pkt_len;\n \tvf->num_queue_pairs = RTE_MAX(dev->data->nb_rx_queues,\n \t\t\t\t      dev->data->nb_tx_queues);\n+\tnum_queue_pairs = vf->num_queue_pairs;\n \n \tif (iavf_init_queues(dev) != 0) {\n \t\tPMD_DRV_LOG(ERR, \"failed to do Queue init\");\n \t\treturn -1;\n \t}\n \n-\tif (iavf_configure_queues(adapter) != 0) {\n+\t/* If needed, send configure queues msg multiple times to make the\n+\t * adminq buffer length smaller than the 4K limitation.\n+\t */\n+\twhile (num_queue_pairs > IAVF_CFG_Q_NUM_PER_BUF) {\n+\t\tif (iavf_configure_queues(adapter,\n+\t\t\t\tIAVF_CFG_Q_NUM_PER_BUF, index) != 0) {\n+\t\t\tPMD_DRV_LOG(ERR, \"configure queues failed\");\n+\t\t\tgoto err_queue;\n+\t\t}\n+\t\tnum_queue_pairs -= IAVF_CFG_Q_NUM_PER_BUF;\n+\t\tindex += IAVF_CFG_Q_NUM_PER_BUF;\n+\t}\n+\n+\tif (iavf_configure_queues(adapter, num_queue_pairs, index) != 0) {\n \t\tPMD_DRV_LOG(ERR, \"configure queues failed\");\n \t\tgoto err_queue;\n \t}\n@@ -560,6 +681,7 @@ iavf_dev_start(struct rte_eth_dev *dev)\n \t\tPMD_DRV_LOG(ERR, \"configure irq failed\");\n \t\tgoto err_queue;\n \t}\n+\n \t/* re-enable intr again, because efd assign may change */\n \tif (dev->data->dev_conf.intr_conf.rxq != 0) {\n \t\trte_intr_disable(intr_handle);\n@@ -624,8 +746,8 @@ iavf_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)\n {\n \tstruct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);\n \n-\tdev_info->max_rx_queues = vf->vsi_res->num_queue_pairs;\n-\tdev_info->max_tx_queues = vf->vsi_res->num_queue_pairs;\n+\tdev_info->max_rx_queues = IAVF_MAX_NUM_QUEUES_LV;\n+\tdev_info->max_tx_queues = IAVF_MAX_NUM_QUEUES_LV;\n \tdev_info->min_rx_bufsize = IAVF_BUF_SIZE_MIN;\n \tdev_info->max_rx_pktlen = IAVF_FRAME_SIZE_MAX;\n \tdev_info->max_mtu = dev_info->max_rx_pktlen - IAVF_ETH_OVERHEAD;\n@@ -1703,6 +1825,7 @@ iavf_init_vf(struct rte_eth_dev *dev)\n \t\tPMD_INIT_LOG(ERR, \"iavf_get_vf_config failed\");\n \t\tgoto err_alloc;\n \t}\n+\n \t/* Allocate memort for RSS info */\n \tif (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF) {\n \t\tvf->rss_key = rte_zmalloc(\"rss_key\",\ndiff --git a/drivers/net/iavf/iavf_rxtx.c b/drivers/net/iavf/iavf_rxtx.c\nindex ca0f5d072..987eb3c4e 100644\n--- a/drivers/net/iavf/iavf_rxtx.c\n+++ b/drivers/net/iavf/iavf_rxtx.c\n@@ -720,6 +720,7 @@ iavf_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id)\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 iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);\n \tstruct iavf_rx_queue *rxq;\n \tint err = 0;\n \n@@ -743,7 +744,11 @@ iavf_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id)\n \tIAVF_WRITE_FLUSH(hw);\n \n \t/* Ready to switch the queue on */\n-\terr = iavf_switch_queue(adapter, rx_queue_id, true, true);\n+\tif (!vf->lv_enabled)\n+\t\terr = iavf_switch_queue(adapter, rx_queue_id, true, true);\n+\telse\n+\t\terr = iavf_switch_queue_lv(adapter, rx_queue_id, true, true);\n+\n \tif (err)\n \t\tPMD_DRV_LOG(ERR, \"Failed to switch RX queue %u on\",\n \t\t\t    rx_queue_id);\n@@ -760,6 +765,7 @@ iavf_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id)\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 iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);\n \tstruct iavf_tx_queue *txq;\n \tint err = 0;\n \n@@ -775,7 +781,10 @@ iavf_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id)\n \tIAVF_WRITE_FLUSH(hw);\n \n \t/* Ready to switch the queue on */\n-\terr = iavf_switch_queue(adapter, tx_queue_id, false, true);\n+\tif (!vf->lv_enabled)\n+\t\terr = iavf_switch_queue(adapter, tx_queue_id, false, true);\n+\telse\n+\t\terr = iavf_switch_queue_lv(adapter, tx_queue_id, false, true);\n \n \tif (err)\n \t\tPMD_DRV_LOG(ERR, \"Failed to switch TX queue %u on\",\n@@ -876,14 +885,22 @@ iavf_stop_queues(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_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);\n \tstruct iavf_rx_queue *rxq;\n \tstruct iavf_tx_queue *txq;\n \tint ret, i;\n \n \t/* Stop All queues */\n-\tret = iavf_disable_queues(adapter);\n-\tif (ret)\n-\t\tPMD_DRV_LOG(WARNING, \"Fail to stop queues\");\n+\tif (!vf->lv_enabled) {\n+\t\tret = iavf_disable_queues(adapter);\n+\t\tif (ret)\n+\t\t\tPMD_DRV_LOG(WARNING, \"Fail to stop queues\");\n+\t} else {\n+\t\tret = iavf_disable_queues_lv(adapter);\n+\t\tif (ret)\n+\t\t\tPMD_DRV_LOG(WARNING, \"Fail to stop queues for large VF\");\n+\t}\n+\n \n \tfor (i = 0; i < dev->data->nb_tx_queues; i++) {\n \t\ttxq = dev->data->tx_queues[i];\ndiff --git a/drivers/net/iavf/iavf_vchnl.c b/drivers/net/iavf/iavf_vchnl.c\nindex 11a1ff608..0ad353b4f 100644\n--- a/drivers/net/iavf/iavf_vchnl.c\n+++ b/drivers/net/iavf/iavf_vchnl.c\n@@ -457,7 +457,8 @@ iavf_get_vf_resource(struct iavf_adapter *adapter)\n \t\tVIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC |\n \t\tVIRTCHNL_VF_OFFLOAD_FDIR_PF |\n \t\tVIRTCHNL_VF_OFFLOAD_ADV_RSS_PF |\n-\t\tVIRTCHNL_VF_OFFLOAD_REQ_QUEUES;\n+\t\tVIRTCHNL_VF_OFFLOAD_REQ_QUEUES |\n+\t\tVIRTCHNL_VF_LARGE_NUM_QPAIRS;\n \n \targs.in_args = (uint8_t *)&caps;\n \targs.in_args_size = sizeof(caps);\n@@ -607,6 +608,138 @@ iavf_switch_queue(struct iavf_adapter *adapter, uint16_t qid,\n \treturn err;\n }\n \n+int\n+iavf_enable_queues_lv(struct iavf_adapter *adapter)\n+{\n+\tstruct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);\n+\tstruct virtchnl_del_ena_dis_queues *queue_select;\n+\tstruct virtchnl_queue_chunk *queue_chunk;\n+\tstruct iavf_cmd_info args;\n+\tint err, len;\n+\n+\tlen = sizeof(struct virtchnl_del_ena_dis_queues) +\n+\t\t  sizeof(struct virtchnl_queue_chunk) *\n+\t\t  (IAVF_RXTX_QUEUE_CHUNKS_NUM - 1);\n+\tqueue_select = rte_zmalloc(\"queue_select\", len, 0);\n+\tif (!queue_select)\n+\t\treturn -ENOMEM;\n+\n+\tqueue_chunk = queue_select->chunks.chunks;\n+\tqueue_select->chunks.num_chunks = IAVF_RXTX_QUEUE_CHUNKS_NUM;\n+\tqueue_select->vport_id = vf->vsi_res->vsi_id;\n+\n+\tqueue_chunk[VIRTCHNL_QUEUE_TYPE_TX].type = VIRTCHNL_QUEUE_TYPE_TX;\n+\tqueue_chunk[VIRTCHNL_QUEUE_TYPE_TX].start_queue_id = 0;\n+\tqueue_chunk[VIRTCHNL_QUEUE_TYPE_TX].num_queues =\n+\t\tadapter->eth_dev->data->nb_tx_queues;\n+\n+\tqueue_chunk[VIRTCHNL_QUEUE_TYPE_RX].type = VIRTCHNL_QUEUE_TYPE_RX;\n+\tqueue_chunk[VIRTCHNL_QUEUE_TYPE_RX].start_queue_id = 0;\n+\tqueue_chunk[VIRTCHNL_QUEUE_TYPE_RX].num_queues =\n+\t\tadapter->eth_dev->data->nb_rx_queues;\n+\n+\targs.ops = VIRTCHNL_OP_ENABLE_QUEUES_V2;\n+\targs.in_args = (u8 *)queue_select;\n+\targs.in_args_size = len;\n+\targs.out_buffer = vf->aq_resp;\n+\targs.out_size = IAVF_AQ_BUF_SZ;\n+\terr = iavf_execute_vf_cmd(adapter, &args);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t    \"Failed to execute command of OP_ENABLE_QUEUES_V2\");\n+\t\treturn err;\n+\t}\n+\treturn 0;\n+}\n+\n+int\n+iavf_disable_queues_lv(struct iavf_adapter *adapter)\n+{\n+\tstruct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);\n+\tstruct virtchnl_del_ena_dis_queues *queue_select;\n+\tstruct virtchnl_queue_chunk *queue_chunk;\n+\tstruct iavf_cmd_info args;\n+\tint err, len;\n+\n+\tlen = sizeof(struct virtchnl_del_ena_dis_queues) +\n+\t\t  sizeof(struct virtchnl_queue_chunk) *\n+\t\t  (IAVF_RXTX_QUEUE_CHUNKS_NUM - 1);\n+\tqueue_select = rte_zmalloc(\"queue_select\", len, 0);\n+\tif (!queue_select)\n+\t\treturn -ENOMEM;\n+\n+\tqueue_chunk = queue_select->chunks.chunks;\n+\tqueue_select->chunks.num_chunks = IAVF_RXTX_QUEUE_CHUNKS_NUM;\n+\tqueue_select->vport_id = vf->vsi_res->vsi_id;\n+\n+\tqueue_chunk[VIRTCHNL_QUEUE_TYPE_TX].type = VIRTCHNL_QUEUE_TYPE_TX;\n+\tqueue_chunk[VIRTCHNL_QUEUE_TYPE_TX].start_queue_id = 0;\n+\tqueue_chunk[VIRTCHNL_QUEUE_TYPE_TX].num_queues =\n+\t\tadapter->eth_dev->data->nb_tx_queues;\n+\n+\tqueue_chunk[VIRTCHNL_QUEUE_TYPE_RX].type = VIRTCHNL_QUEUE_TYPE_RX;\n+\tqueue_chunk[VIRTCHNL_QUEUE_TYPE_RX].start_queue_id = 0;\n+\tqueue_chunk[VIRTCHNL_QUEUE_TYPE_RX].num_queues =\n+\t\tadapter->eth_dev->data->nb_rx_queues;\n+\n+\targs.ops = VIRTCHNL_OP_DISABLE_QUEUES_V2;\n+\targs.in_args = (u8 *)queue_select;\n+\targs.in_args_size = len;\n+\targs.out_buffer = vf->aq_resp;\n+\targs.out_size = IAVF_AQ_BUF_SZ;\n+\terr = iavf_execute_vf_cmd(adapter, &args);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t    \"Failed to execute command of OP_DISABLE_QUEUES_V2\");\n+\t\treturn err;\n+\t}\n+\treturn 0;\n+}\n+\n+int\n+iavf_switch_queue_lv(struct iavf_adapter *adapter, uint16_t qid,\n+\t\t bool rx, bool on)\n+{\n+\tstruct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);\n+\tstruct virtchnl_del_ena_dis_queues *queue_select;\n+\tstruct virtchnl_queue_chunk *queue_chunk;\n+\tstruct iavf_cmd_info args;\n+\tint err, len;\n+\n+\tlen = sizeof(struct virtchnl_del_ena_dis_queues);\n+\tqueue_select = rte_zmalloc(\"queue_select\", len, 0);\n+\tif (!queue_select)\n+\t\treturn -ENOMEM;\n+\n+\tqueue_chunk = queue_select->chunks.chunks;\n+\tqueue_select->chunks.num_chunks = 1;\n+\tqueue_select->vport_id = vf->vsi_res->vsi_id;\n+\n+\tif (rx) {\n+\t\tqueue_chunk->type = VIRTCHNL_QUEUE_TYPE_RX;\n+\t\tqueue_chunk->start_queue_id = qid;\n+\t\tqueue_chunk->num_queues = 1;\n+\t} else {\n+\t\tqueue_chunk->type = VIRTCHNL_QUEUE_TYPE_TX;\n+\t\tqueue_chunk->start_queue_id = qid;\n+\t\tqueue_chunk->num_queues = 1;\n+\t}\n+\n+\tif (on)\n+\t\targs.ops = VIRTCHNL_OP_ENABLE_QUEUES_V2;\n+\telse\n+\t\targs.ops = VIRTCHNL_OP_DISABLE_QUEUES_V2;\n+\targs.in_args = (u8 *)queue_select;\n+\targs.in_args_size = len;\n+\targs.out_buffer = vf->aq_resp;\n+\targs.out_size = IAVF_AQ_BUF_SZ;\n+\terr = iavf_execute_vf_cmd(adapter, &args);\n+\tif (err)\n+\t\tPMD_DRV_LOG(ERR, \"Failed to execute command of %s\",\n+\t\t\t    on ? \"OP_ENABLE_QUEUES_V2\" : \"OP_DISABLE_QUEUES_V2\");\n+\treturn err;\n+}\n+\n int\n iavf_configure_rss_lut(struct iavf_adapter *adapter)\n {\n@@ -672,7 +805,8 @@ iavf_configure_rss_key(struct iavf_adapter *adapter)\n }\n \n int\n-iavf_configure_queues(struct iavf_adapter *adapter)\n+iavf_configure_queues(struct iavf_adapter *adapter,\n+\t\tuint16_t num_queue_pairs, uint16_t index)\n {\n \tstruct iavf_rx_queue **rxq =\n \t\t(struct iavf_rx_queue **)adapter->eth_dev->data->rx_queues;\n@@ -686,16 +820,16 @@ iavf_configure_queues(struct iavf_adapter *adapter)\n \tint err;\n \n \tsize = sizeof(*vc_config) +\n-\t       sizeof(vc_config->qpair[0]) * vf->num_queue_pairs;\n+\t       sizeof(vc_config->qpair[0]) * num_queue_pairs;\n \tvc_config = rte_zmalloc(\"cfg_queue\", size, 0);\n \tif (!vc_config)\n \t\treturn -ENOMEM;\n \n \tvc_config->vsi_id = vf->vsi_res->vsi_id;\n-\tvc_config->num_queue_pairs = vf->num_queue_pairs;\n+\tvc_config->num_queue_pairs = num_queue_pairs;\n \n-\tfor (i = 0, vc_qp = vc_config->qpair;\n-\t     i < vf->num_queue_pairs;\n+\tfor (i = index, vc_qp = vc_config->qpair;\n+\t     i < index + num_queue_pairs;\n \t     i++, vc_qp++) {\n \t\tvc_qp->txq.vsi_id = vf->vsi_res->vsi_id;\n \t\tvc_qp->txq.queue_id = i;\n@@ -775,13 +909,14 @@ iavf_config_irq_map(struct iavf_adapter *adapter)\n \t\treturn -ENOMEM;\n \n \tmap_info->num_vectors = vf->nb_msix;\n-\tfor (i = 0; i < vf->nb_msix; i++) {\n-\t\tvecmap = &map_info->vecmap[i];\n+\tfor (i = 0; i < adapter->eth_dev->data->nb_rx_queues; i++) {\n+\t\tvecmap =\n+\t\t    &map_info->vecmap[vf->qv_map[i].vector_id - vf->msix_base];\n \t\tvecmap->vsi_id = vf->vsi_res->vsi_id;\n \t\tvecmap->rxitr_idx = IAVF_ITR_INDEX_DEFAULT;\n-\t\tvecmap->vector_id = vf->msix_base + i;\n+\t\tvecmap->vector_id = vf->qv_map[i].vector_id;\n \t\tvecmap->txq_map = 0;\n-\t\tvecmap->rxq_map = vf->rxq_map[vf->msix_base + i];\n+\t\tvecmap->rxq_map |= 1 << vf->qv_map[i].queue_id;\n \t}\n \n \targs.ops = VIRTCHNL_OP_CONFIG_IRQ_MAP;\n@@ -797,6 +932,45 @@ iavf_config_irq_map(struct iavf_adapter *adapter)\n \treturn err;\n }\n \n+int\n+iavf_config_irq_map_lv(struct iavf_adapter *adapter, uint16_t num)\n+{\n+\tstruct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);\n+\tstruct virtchnl_queue_vector_maps *map_info;\n+\tstruct virtchnl_queue_vector *qv_maps;\n+\tstruct iavf_cmd_info args;\n+\tint len, i, err;\n+\n+\tlen = sizeof(struct virtchnl_queue_vector_maps) +\n+\t      sizeof(struct virtchnl_queue_vector) * (num - 1);\n+\n+\tmap_info = rte_zmalloc(\"map_info\", len, 0);\n+\tif (!map_info)\n+\t\treturn -ENOMEM;\n+\n+\tmap_info->vport_id = vf->vsi_res->vsi_id;\n+\tmap_info->num_qv_maps = num;\n+\tfor (i = 0; i < map_info->num_qv_maps; i++) {\n+\t\tqv_maps = &map_info->qv_maps[i];\n+\t\tqv_maps->itr_idx = VIRTCHNL_ITR_IDX_0;\n+\t\tqv_maps->queue_type = VIRTCHNL_QUEUE_TYPE_RX;\n+\t\tqv_maps->queue_id = vf->qv_map[i].queue_id;\n+\t\tqv_maps->vector_id = vf->qv_map[i].vector_id;\n+\t}\n+\n+\targs.ops = VIRTCHNL_OP_MAP_QUEUE_VECTOR;\n+\targs.in_args = (u8 *)map_info;\n+\targs.in_args_size = len;\n+\targs.out_buffer = vf->aq_resp;\n+\targs.out_size = IAVF_AQ_BUF_SZ;\n+\terr = iavf_execute_vf_cmd(adapter, &args);\n+\tif (err)\n+\t\tPMD_DRV_LOG(ERR, \"fail to execute command OP_MAP_QUEUE_VECTOR\");\n+\n+\trte_free(map_info);\n+\treturn err;\n+}\n+\n void\n iavf_add_del_all_mac_addr(struct iavf_adapter *adapter, bool add)\n {\n@@ -1272,3 +1446,33 @@ iavf_request_queues(struct iavf_adapter *adapter, uint16_t num)\n \n \treturn -1;\n }\n+\n+int\n+iavf_get_max_rss_queue_region(struct iavf_adapter *adapter)\n+{\n+\tstruct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);\n+\tstruct iavf_cmd_info args;\n+\tuint16_t qregion_width;\n+\tint err;\n+\n+\targs.ops = VIRTCHNL_OP_GET_MAX_RSS_QREGION;\n+\targs.in_args = NULL;\n+\targs.in_args_size = 0;\n+\targs.out_buffer = vf->aq_resp;\n+\targs.out_size = IAVF_AQ_BUF_SZ;\n+\n+\terr = iavf_execute_vf_cmd(adapter, &args);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t    \"Failed to execute command of \"\n+\t\t\t    \"VIRTCHNL_OP_GET_MAX_RSS_QREGION\");\n+\t\treturn err;\n+\t}\n+\n+\tqregion_width =\n+\t((struct virtchnl_max_rss_qregion *)args.out_buffer)->qregion_width;\n+\n+\tvf->max_rss_qregion = (uint16_t)(1 << qregion_width);\n+\n+\treturn 0;\n+}\n",
    "prefixes": [
        "v5",
        "2/2"
    ]
}