get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 77013,
    "url": "http://patches.dpdk.org/api/patches/77013/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20200909072028.16726-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": "<20200909072028.16726-3-ting.xu@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20200909072028.16726-3-ting.xu@intel.com",
    "date": "2020-09-09T07:20:28",
    "name": "[v1,2/2] net/iavf: enable large VF configuration",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "d3152e714525aac3030f0ba545bfebe8db37563e",
    "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/20200909072028.16726-3-ting.xu@intel.com/mbox/",
    "series": [
        {
            "id": 12046,
            "url": "http://patches.dpdk.org/api/series/12046/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=12046",
            "date": "2020-09-09T07:20:26",
            "name": "enable large VF configuration",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/12046/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/77013/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/77013/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 96175A04B1;\n\tWed,  9 Sep 2020 09:17:09 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 83E2B1C0D2;\n\tWed,  9 Sep 2020 09:16:55 +0200 (CEST)",
            "from mga06.intel.com (mga06.intel.com [134.134.136.31])\n by dpdk.org (Postfix) with ESMTP id 20E971C0CA\n for <dev@dpdk.org>; Wed,  9 Sep 2020 09:16:51 +0200 (CEST)",
            "from fmsmga004.fm.intel.com ([10.253.24.48])\n by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 09 Sep 2020 00:16:49 -0700",
            "from dpdk-xuting-second.sh.intel.com ([10.67.116.154])\n by fmsmga004.fm.intel.com with ESMTP; 09 Sep 2020 00:16:47 -0700"
        ],
        "IronPort-SDR": [
            "\n 8P6kmiClT5/XOW5qUXKol7kAMTp3rOdgRETjCKMRD6xWSB05gU3Z4t7ljTLlZiFNInGln38LMj\n FbhvCljYbhUQ==",
            "\n gyugfNnRP+baulNiFnQzAn/2lZxTUGFdSVG0Dte6rv2XE9/YJhXzi9yqbntrxcdnBAUodFOfGP\n Bt3HIXD/xqHA=="
        ],
        "X-IronPort-AV": [
            "E=McAfee;i=\"6000,8403,9738\"; a=\"219840811\"",
            "E=Sophos;i=\"5.76,408,1592895600\"; d=\"scan'208\";a=\"219840811\"",
            "E=Sophos;i=\"5.76,408,1592895600\"; d=\"scan'208\";a=\"328804548\""
        ],
        "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, jingjing.wu@intel.com, Ting Xu <ting.xu@intel.com>",
        "Date": "Wed,  9 Sep 2020 15:20:28 +0800",
        "Message-Id": "<20200909072028.16726-3-ting.xu@intel.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20200909072028.16726-1-ting.xu@intel.com>",
        "References": "<20200909072028.16726-1-ting.xu@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v1 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 configure VSI queues, enable/disable queues and IRQ\nmapping for large VF. The max VF queue pairs number is 256. Request\nmore queues from PF if allocated queues are not enough. Add support\nto query max RSS queue regions number. Large VF offload should be\nsupported before configuring large VF.\n\nSigned-off-by: Ting Xu <ting.xu@intel.com>\n---\n drivers/net/iavf/iavf.h        |  24 ++-\n drivers/net/iavf/iavf_ethdev.c |  81 +++++++--\n drivers/net/iavf/iavf_rxtx.c   |  27 ++-\n drivers/net/iavf/iavf_vchnl.c  | 309 ++++++++++++++++++++++++++++++---\n 4 files changed, 397 insertions(+), 44 deletions(-)",
    "diff": "diff --git a/drivers/net/iavf/iavf.h b/drivers/net/iavf/iavf.h\nindex 1a42936a0..a16365d3b 100644\n--- a/drivers/net/iavf/iavf.h\n+++ b/drivers/net/iavf/iavf.h\n@@ -19,7 +19,10 @@\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 \n #define IAVF_NUM_MACADDR_MAX      64\n \n@@ -104,8 +107,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 /* Event status from PF */\n enum pending_msg {\n@@ -157,14 +162,17 @@ 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+\tuint32_t max_rss_qregion; /* max RSS queue region supported by PF */\n+\t/* queue vector mapping */\n+\tstruct iavf_qv_map *qv_map;\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@@ -269,13 +277,18 @@ 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_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);\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@@ -296,4 +309,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 rte_eth_dev *dev, 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 48e474f53..6765aac33 100644\n--- a/drivers/net/iavf/iavf_ethdev.c\n+++ b/drivers/net/iavf/iavf_ethdev.c\n@@ -160,12 +160,12 @@ iavf_init_rss(struct iavf_adapter *adapter)\n {\n \tstruct iavf_info *vf =  IAVF_DEV_PRIVATE_TO_VF(adapter);\n \tstruct rte_eth_rss_conf *rss_conf;\n-\tuint8_t i, j, nb_q;\n+\tuint16_t i, j, nb_q;\n \tint ret;\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       IAVF_MAX_NUM_QUEUES_LV);\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@@ -218,6 +218,9 @@ iavf_dev_configure(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(ad);\n \tstruct rte_eth_conf *dev_conf = &dev->data->dev_conf;\n+\tuint16_t num_queue_pairs = RTE_MAX(dev->data->nb_rx_queues,\n+\t\tdev->data->nb_tx_queues);\n+\tint ret = 0;\n \n \tad->rx_bulk_alloc_allowed = true;\n \t/* Initialize to TRUE. If any of Rx queues doesn't meet the\n@@ -229,6 +232,29 @@ iavf_dev_configure(struct rte_eth_dev *dev)\n \tif (dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG)\n \t\tdev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_RSS_HASH;\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_OFFLOAD_LARGE_VF)) {\n+\t\t\tPMD_DRV_LOG(ERR, \"large VF is not supported\");\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tret = iavf_request_queues(dev, num_queue_pairs);\n+\t\tif (ret != 0) {\n+\t\t\tPMD_DRV_LOG(ERR, \"request queues from PF failed\");\n+\t\t\treturn ret;\n+\t\t}\n+\t\tPMD_DRV_LOG(INFO, \"change queue pairs from %u to %u\",\n+\t\t\t\tvf->vsi_res->num_queue_pairs, num_queue_pairs);\n+\n+\t\tret = iavf_dev_reset(dev);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\n+\t\tvf->lv_enabled = true;\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@@ -243,6 +269,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@@ -325,6 +352,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@@ -345,6 +373,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@@ -375,16 +411,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@@ -397,21 +438,33 @@ 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\tif (iavf_config_irq_map_lv(adapter)) {\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+\trte_free(qv_map);\n \treturn 0;\n }\n \n@@ -539,8 +592,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->hash_key_size = vf->vf_res->rss_key_size;\n@@ -1269,6 +1322,12 @@ 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+\tif (iavf_get_max_rss_queue_region(adapter) != 0) {\n+\t\tPMD_INIT_LOG(ERR, \"get max rss queue region 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 05a7dd898..86004ac90 100644\n--- a/drivers/net/iavf/iavf_rxtx.c\n+++ b/drivers/net/iavf/iavf_rxtx.c\n@@ -532,6 +532,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@@ -555,7 +556,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@@ -572,6 +577,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@@ -587,7 +593,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@@ -688,14 +697,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 eab2f2a22..6090afab6 100644\n--- a/drivers/net/iavf/iavf_vchnl.c\n+++ b/drivers/net/iavf/iavf_vchnl.c\n@@ -128,6 +128,7 @@ iavf_execute_vf_cmd(struct iavf_adapter *adapter, struct iavf_cmd_info *args)\n \tcase VIRTCHNL_OP_VERSION:\n \tcase VIRTCHNL_OP_GET_VF_RESOURCES:\n \tcase VIRTCHNL_OP_GET_SUPPORTED_RXDIDS:\n+\tcase VIRTCHNL_OP_GET_MAX_RSS_QREGION:\n \t\t/* for init virtchnl ops, need to poll the response */\n \t\tdo {\n \t\t\tresult = iavf_read_msg_from_pf(adapter, args->out_size,\n@@ -448,7 +449,8 @@ iavf_get_vf_resource(struct iavf_adapter *adapter)\n \tcaps = IAVF_BASIC_OFFLOAD_CAPS | VIRTCHNL_VF_CAP_ADV_LINK_SPEED |\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_ADV_RSS_PF |\n+\t\tVIRTCHNL_VF_OFFLOAD_LARGE_VF;\n \n \targs.in_args = (uint8_t *)&caps;\n \targs.in_args_size = sizeof(caps);\n@@ -598,6 +600,142 @@ 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+\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+\tif (rx) {\n+\t\tqueue_chunk[VIRTCHNL_QUEUE_TYPE_RX].type =\n+\t\t\tVIRTCHNL_QUEUE_TYPE_RX;\n+\t\tqueue_chunk[VIRTCHNL_QUEUE_TYPE_RX].start_queue_id = qid;\n+\t\tqueue_chunk[VIRTCHNL_QUEUE_TYPE_RX].num_queues = 1;\n+\t} else {\n+\t\tqueue_chunk[VIRTCHNL_QUEUE_TYPE_TX].type =\n+\t\t\tVIRTCHNL_QUEUE_TYPE_TX;\n+\t\tqueue_chunk[VIRTCHNL_QUEUE_TYPE_TX].start_queue_id = qid;\n+\t\tqueue_chunk[VIRTCHNL_QUEUE_TYPE_TX].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@@ -662,32 +800,24 @@ iavf_configure_rss_key(struct iavf_adapter *adapter)\n \treturn err;\n }\n \n-int\n-iavf_configure_queues(struct iavf_adapter *adapter)\n+static int\n+iavf_exec_queue_cfg(struct iavf_adapter *adapter,\n+\tstruct virtchnl_vsi_queue_config_info *vc_config,\n+\tuint16_t count, uint16_t size)\n {\n \tstruct iavf_rx_queue **rxq =\n \t\t(struct iavf_rx_queue **)adapter->eth_dev->data->rx_queues;\n \tstruct iavf_tx_queue **txq =\n \t\t(struct iavf_tx_queue **)adapter->eth_dev->data->tx_queues;\n \tstruct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);\n-\tstruct virtchnl_vsi_queue_config_info *vc_config;\n \tstruct virtchnl_queue_pair_info *vc_qp;\n \tstruct iavf_cmd_info args;\n-\tuint16_t i, size;\n-\tint err;\n-\n-\tsize = sizeof(*vc_config) +\n-\t       sizeof(vc_config->qpair[0]) * vf->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+\tint err = 0;\n+\tuint16_t i;\n \n-\tfor (i = 0, vc_qp = vc_config->qpair;\n-\t     i < vf->num_queue_pairs;\n-\t     i++, vc_qp++) {\n+\tfor (i = count * IAVF_CFG_Q_NUM_PER_BUF, vc_qp = vc_config->qpair;\n+\t     i < count * IAVF_CFG_Q_NUM_PER_BUF + vc_config->num_queue_pairs;\n+\t\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 \t\t/* Virtchnnl configure queues by pairs */\n@@ -741,8 +871,73 @@ iavf_configure_queues(struct iavf_adapter *adapter)\n \terr = iavf_execute_vf_cmd(adapter, &args);\n \tif (err)\n \t\tPMD_DRV_LOG(ERR, \"Failed to execute command of\"\n-\t\t\t    \" VIRTCHNL_OP_CONFIG_VSI_QUEUES\");\n+\t\t\t\t\" VIRTCHNL_OP_CONFIG_VSI_QUEUES\");\n+\n+\treturn err;\n+}\n+\n+/* Configure VSI queues. Max VF queue pairs number is 256, may\n+ * send this command multiple times to configure all queues.\n+ */\n+int\n+iavf_configure_queues(struct iavf_adapter *adapter)\n+{\n+\tstruct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);\n+\tstruct virtchnl_vsi_queue_config_info *vc_config;\n+\tuint16_t nb_cmd_full, nb_cmd_rest, nbq_rest;\n+\tuint16_t i, size;\n+\tint err = 0;\n+\n+\t/* Compute how many times should the command to be sent */\n+\tnbq_rest = vf->num_queue_pairs % IAVF_CFG_Q_NUM_PER_BUF;\n+\tnb_cmd_rest = nbq_rest ? 1 : 0;\n+\tnb_cmd_full = vf->num_queue_pairs / IAVF_CFG_Q_NUM_PER_BUF;\n+\n+\t/* send cmd only once for small queues number */\n+\tif (!nb_cmd_full) {\n+\t\tsize = sizeof(*vc_config) +\n+\t\t       sizeof(vc_config->qpair[0]) * nbq_rest;\n+\t\tvc_config = rte_zmalloc(\"cfg_queue\", size, 0);\n+\t\tif (!vc_config)\n+\t\t\treturn -ENOMEM;\n+\n+\t\tvc_config->vsi_id = vf->vsi_res->vsi_id;\n+\t\tvc_config->num_queue_pairs = nbq_rest;\n+\t\terr = iavf_exec_queue_cfg(adapter, vc_config, 0, size);\n+\t\tgoto free;\n+\t}\n+\n+\tsize = sizeof(*vc_config) +\n+\t\t   sizeof(vc_config->qpair[0]) * IAVF_CFG_Q_NUM_PER_BUF;\n+\tvc_config = rte_zmalloc(\"cfg_queue\", size, 0);\n+\tif (!vc_config)\n+\t\treturn -ENOMEM;\n+\n+\tfor (i = 0; i < nb_cmd_full + nb_cmd_rest; i++) {\n+\t\tif (i < nb_cmd_full) {\n+\t\t\tvc_config->vsi_id = vf->vsi_res->vsi_id;\n+\t\t\tvc_config->num_queue_pairs = IAVF_CFG_Q_NUM_PER_BUF;\n+\t\t} else {\n+\t\t\t/* re-allocate virtchnl msg for less queues */\n+\t\t\trte_free(vc_config);\n+\t\t\tsize = sizeof(*vc_config) +\n+\t\t\t       sizeof(vc_config->qpair[0]) * nbq_rest;\n+\t\t\tvc_config = rte_zmalloc(\"cfg_queue\", size, 0);\n+\t\t\tif (!vc_config)\n+\t\t\t\treturn -ENOMEM;\n+\n+\t\t\tvc_config->vsi_id = vf->vsi_res->vsi_id;\n+\t\t\tvc_config->num_queue_pairs = nbq_rest;\n+\t\t}\n \n+\t\terr = iavf_exec_queue_cfg(adapter, vc_config, i, size);\n+\t\tif (err)\n+\t\t\tgoto free;\n+\n+\t\tmemset(vc_config, 0, size);\n+\t}\n+\n+free:\n \trte_free(vc_config);\n \treturn err;\n }\n@@ -797,13 +992,14 @@ iavf_config_irq_map(struct iavf_adapter *adapter)\n \n \tmap_info = (struct virtchnl_irq_map_info *)cmd_buffer;\n \tmap_info->num_vectors = nb_msix;\n-\tfor (i = 0; i < 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@@ -819,6 +1015,46 @@ 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)\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) *\n+\t      (adapter->eth_dev->data->nb_rx_queues - 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 = adapter->eth_dev->data->nb_rx_queues;\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@@ -1261,3 +1497,30 @@ iavf_request_queues(struct rte_eth_dev *dev, uint16_t num)\n \n \treturn err;\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+\tint ret;\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+\tret = iavf_execute_vf_cmd(adapter, &args);\n+\tif (ret) {\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 ret;\n+\t}\n+\n+\tvf->max_rss_qregion =\n+\t((struct virtchnl_max_rss_qregion *)args.out_buffer)->max_rss_qregion;\n+\n+\treturn 0;\n+}\n",
    "prefixes": [
        "v1",
        "2/2"
    ]
}