get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 29403,
    "url": "http://patches.dpdk.org/api/patches/29403/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1506653786-28970-2-git-send-email-wei.zhao1@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": "<1506653786-28970-2-git-send-email-wei.zhao1@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1506653786-28970-2-git-send-email-wei.zhao1@intel.com",
    "date": "2017-09-29T02:56:24",
    "name": "[dpdk-dev,v5,1/3] net/i40e: queue region set and flush",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "35abda422163edf7cb5dd5999da3bda0d485624a",
    "submitter": {
        "id": 495,
        "url": "http://patches.dpdk.org/api/people/495/?format=api",
        "name": "Zhao1, Wei",
        "email": "wei.zhao1@intel.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1506653786-28970-2-git-send-email-wei.zhao1@intel.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/29403/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/29403/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id A21B62661;\n\tFri, 29 Sep 2017 05:07:52 +0200 (CEST)",
            "from mga03.intel.com (mga03.intel.com [134.134.136.65])\n\tby dpdk.org (Postfix) with ESMTP id D9BFEFFA\n\tfor <dev@dpdk.org>; Fri, 29 Sep 2017 05:07:46 +0200 (CEST)",
            "from fmsmga003.fm.intel.com ([10.253.24.29])\n\tby orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t28 Sep 2017 20:07:26 -0700",
            "from dpdk4.bj.intel.com ([172.16.182.85])\n\tby FMSMGA003.fm.intel.com with ESMTP; 28 Sep 2017 20:07:25 -0700"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.42,451,1500966000\"; d=\"scan'208\";a=\"904981490\"",
        "From": "Wei Zhao <wei.zhao1@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "Wei Zhao <wei.zhao1@intel.com>",
        "Date": "Fri, 29 Sep 2017 10:56:24 +0800",
        "Message-Id": "<1506653786-28970-2-git-send-email-wei.zhao1@intel.com>",
        "X-Mailer": "git-send-email 2.7.4",
        "In-Reply-To": "<1506653786-28970-1-git-send-email-wei.zhao1@intel.com>",
        "References": "<1506589809-59533-1-git-send-email-wei.zhao1@intel.com>\n\t<1506653786-28970-1-git-send-email-wei.zhao1@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v5 1/3] net/i40e: queue region set and flush",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "This feature enable queue regions configuration for RSS in PF,\nso that different traffic classes or different packet\nclassification types can be separated to different queues in\ndifferent queue regions.This patch can set queue region range,\nit include queue number in a region and the index of first queue.\nThis patch enable mapping between different priorities (UP) and\ndifferent traffic classes.It also enable mapping between a region\nindex and a sepcific flowtype(PCTYPE).It also provide the solution\nof flush all configuration about queue region the above described.\n\nSigned-off-by: Wei Zhao <wei.zhao1@intel.com>\n---\n drivers/net/i40e/i40e_ethdev.c            |  27 +-\n drivers/net/i40e/i40e_ethdev.h            |  39 +++\n drivers/net/i40e/rte_pmd_i40e.c           | 537 ++++++++++++++++++++++++++++++\n drivers/net/i40e/rte_pmd_i40e.h           |  60 ++++\n drivers/net/i40e/rte_pmd_i40e_version.map |   1 +\n 5 files changed, 658 insertions(+), 6 deletions(-)",
    "diff": "diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c\nindex 720f067..1a5b73e 100644\n--- a/drivers/net/i40e/i40e_ethdev.c\n+++ b/drivers/net/i40e/i40e_ethdev.c\n@@ -137,10 +137,6 @@\n #define I40E_PRTTSYN_TSYNTYPE    0x0e000000\n #define I40E_CYCLECOUNTER_MASK   0xffffffffffffffffULL\n \n-#define I40E_MAX_PERCENT            100\n-#define I40E_DEFAULT_DCB_APP_NUM    1\n-#define I40E_DEFAULT_DCB_APP_PRIO   3\n-\n /**\n  * Below are values for writing un-exposed registers suggested\n  * by silicon experts\n@@ -309,7 +305,6 @@ static int i40e_pf_parameter_init(struct rte_eth_dev *dev);\n static int i40e_pf_setup(struct i40e_pf *pf);\n static int i40e_dev_rxtx_init(struct i40e_pf *pf);\n static int i40e_vmdq_setup(struct rte_eth_dev *dev);\n-static int i40e_dcb_init_configure(struct rte_eth_dev *dev, bool sw_dcb);\n static int i40e_dcb_setup(struct rte_eth_dev *dev);\n static void i40e_stat_update_32(struct i40e_hw *hw, uint32_t reg,\n \t\tbool offset_loaded, uint64_t *offset, uint64_t *stat);\n@@ -1036,6 +1031,20 @@ i40e_init_fdir_filter_list(struct rte_eth_dev *dev)\n \treturn ret;\n }\n \n+void\n+i40e_init_queue_region_conf(struct rte_eth_dev *dev)\n+{\n+\tstruct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tstruct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);\n+\tstruct i40e_queue_region_info *info = &pf->queue_region;\n+\tuint16_t i;\n+\n+\tfor (i = 0; i < I40E_PFQF_HREGION_MAX_INDEX; i++)\n+\t\ti40e_write_rx_ctl(hw, I40E_PFQF_HREGION(i), 0);\n+\n+\tmemset(info, 0, sizeof(struct i40e_queue_region_info));\n+}\n+\n static int\n eth_i40e_dev_init(struct rte_eth_dev *dev)\n {\n@@ -1311,6 +1320,9 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)\n \tif (ret < 0)\n \t\tgoto err_init_fdir_filter_list;\n \n+\t\t/* initialize queue region configuration */\n+\ti40e_init_queue_region_conf(dev);\n+\n \treturn 0;\n \n err_init_fdir_filter_list:\n@@ -1466,6 +1478,9 @@ eth_i40e_dev_uninit(struct rte_eth_dev *dev)\n \t/* Remove all Traffic Manager configuration */\n \ti40e_tm_conf_uninit(dev);\n \n+\t\t/* Remove all the queue region configuration */\n+\ti40e_flush_queue_region_all_conf(dev, hw, pf, 0);\n+\n \treturn 0;\n }\n \n@@ -10419,7 +10434,7 @@ i40e_dcb_hw_configure(struct i40e_pf *pf,\n  *\n  * Returns 0 on success, negative value on failure\n  */\n-static int\n+int\n i40e_dcb_init_configure(struct rte_eth_dev *dev, bool sw_dcb)\n {\n \tstruct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);\ndiff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h\nindex ad80f0f..3d237cd 100644\n--- a/drivers/net/i40e/i40e_ethdev.h\n+++ b/drivers/net/i40e/i40e_ethdev.h\n@@ -260,6 +260,12 @@ enum i40e_flxpld_layer_idx {\n #define I40E_QOS_BW_WEIGHT_MIN 1\n /* The max bandwidth weight is 127. */\n #define I40E_QOS_BW_WEIGHT_MAX 127\n+/* The max queue region index is 7. */\n+#define I40E_REGION_MAX_INDEX 7\n+\n+#define I40E_MAX_PERCENT            100\n+#define I40E_DEFAULT_DCB_APP_NUM    1\n+#define I40E_DEFAULT_DCB_APP_PRIO   3\n \n /**\n  * The overhead from MTU to max frame size.\n@@ -541,6 +547,34 @@ struct i40e_ethertype_rule {\n \tstruct rte_hash *hash_table;\n };\n \n+/* queue region info */\n+struct i40e_region_info {\n+\t/* the region id for this configuration */\n+\tuint8_t region_id;\n+\t/* the start queue index for this region */\n+\tuint8_t queue_start_index;\n+\t/* the total queue number of this queue region */\n+\tuint8_t queue_num;\n+\t/* the total number of user priority for this region */\n+\tuint8_t user_priority_num;\n+\t/* the packet's user priority for this region */\n+\tuint8_t user_priority[I40E_MAX_USER_PRIORITY];\n+\t/* the total number of flowtype for this region */\n+\tuint8_t flowtype_num;\n+\t/**\n+\t * the pctype or hardware flowtype of packet,\n+\t * the specific index for each type has been defined\n+\t * in file i40e_type.h as enum i40e_filter_pctype.\n+\t */\n+\tuint8_t hw_flowtype[I40E_FILTER_PCTYPE_MAX];\n+};\n+\n+struct i40e_queue_region_info {\n+\t/* the total number of queue region for this port */\n+\tuint16_t queue_region_number;\n+\tstruct i40e_region_info region[I40E_REGION_MAX_INDEX + 1];\n+};\n+\n /* Tunnel filter number HW supports */\n #define I40E_MAX_TUNNEL_FILTER_NUM 400\n \n@@ -776,6 +810,7 @@ struct i40e_pf {\n \tstruct i40e_fdir_info fdir; /* flow director info */\n \tstruct i40e_ethertype_rule ethertype; /* Ethertype filter rule */\n \tstruct i40e_tunnel_rule tunnel; /* Tunnel filter rule */\n+\tstruct i40e_queue_region_info queue_region; /* queue region info */\n \tstruct i40e_fc_conf fc_conf; /* Flow control conf */\n \tstruct i40e_mirror_rule_list mirror_list;\n \tuint16_t nb_mirror_rule;   /* The number of mirror rules */\n@@ -1003,6 +1038,10 @@ void i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val);\n int i40e_tm_ops_get(struct rte_eth_dev *dev, void *ops);\n void i40e_tm_conf_init(struct rte_eth_dev *dev);\n void i40e_tm_conf_uninit(struct rte_eth_dev *dev);\n+int i40e_dcb_init_configure(struct rte_eth_dev *dev, bool sw_dcb);\n+int i40e_flush_queue_region_all_conf(struct rte_eth_dev *dev,\n+\t\tstruct i40e_hw *hw, struct i40e_pf *pf, uint16_t on);\n+void i40e_init_queue_region_conf(struct rte_eth_dev *dev);\n \n #define I40E_DEV_TO_PCI(eth_dev) \\\n \tRTE_DEV_TO_PCI((eth_dev)->device)\ndiff --git a/drivers/net/i40e/rte_pmd_i40e.c b/drivers/net/i40e/rte_pmd_i40e.c\nindex c08e07a..68be84b 100644\n--- a/drivers/net/i40e/rte_pmd_i40e.c\n+++ b/drivers/net/i40e/rte_pmd_i40e.c\n@@ -35,6 +35,7 @@\n #include <rte_tailq.h>\n \n #include \"base/i40e_prototype.h\"\n+#include \"base/i40e_dcb.h\"\n #include \"i40e_ethdev.h\"\n #include \"i40e_pf.h\"\n #include \"i40e_rxtx.h\"\n@@ -2161,3 +2162,539 @@ rte_pmd_i40e_add_vf_mac_addr(uint8_t port, uint16_t vf_id,\n \n \treturn 0;\n }\n+\n+static int\n+i40e_vsi_update_queue_region_mapping(struct i40e_hw *hw,\n+\t\t\t      struct i40e_pf *pf)\n+{\n+\tuint16_t i;\n+\tstruct i40e_vsi *vsi = pf->main_vsi;\n+\tuint16_t queue_offset, bsf, tc_index;\n+\tstruct i40e_vsi_context ctxt;\n+\tstruct i40e_aqc_vsi_properties_data *vsi_info;\n+\tstruct i40e_queue_region_info *region_info =\n+\t\t\t\t&pf->queue_region;\n+\tint32_t ret = -EINVAL;\n+\n+\tif (!region_info->queue_region_number) {\n+\t\tPMD_INIT_LOG(ERR, \"there is no that region id been set before\");\n+\t\treturn ret;\n+\t}\n+\n+\tmemset(&ctxt, 0, sizeof(struct i40e_vsi_context));\n+\n+\t/* Update Queue Pairs Mapping for currently enabled UPs */\n+\tctxt.seid = vsi->seid;\n+\tctxt.pf_num = hw->pf_id;\n+\tctxt.vf_num = 0;\n+\tctxt.uplink_seid = vsi->uplink_seid;\n+\tctxt.info = vsi->info;\n+\tvsi_info = &ctxt.info;\n+\n+\tmemset(vsi_info->tc_mapping, 0, sizeof(uint16_t) * 8);\n+\tmemset(vsi_info->queue_mapping, 0, sizeof(uint16_t) * 16);\n+\n+\t/**\n+\t * Configure queue region and queue mapping parameters,\n+\t * for enabled queue region, allocate queues to this region.\n+\t */\n+\n+\tfor (i = 0; i < region_info->queue_region_number; i++) {\n+\t\ttc_index = region_info->region[i].region_id;\n+\t\tbsf = rte_bsf32(region_info->region[i].queue_num);\n+\t\tqueue_offset = region_info->region[i].queue_start_index;\n+\t\tvsi_info->tc_mapping[tc_index] = rte_cpu_to_le_16(\n+\t\t\t(queue_offset << I40E_AQ_VSI_TC_QUE_OFFSET_SHIFT) |\n+\t\t\t\t(bsf << I40E_AQ_VSI_TC_QUE_NUMBER_SHIFT));\n+\t}\n+\n+\t/* Associate queue number with VSI, Keep vsi->nb_qps unchanged */\n+\tif (vsi->type == I40E_VSI_SRIOV) {\n+\t\tvsi_info->mapping_flags |=\n+\t\t\trte_cpu_to_le_16(I40E_AQ_VSI_QUE_MAP_NONCONTIG);\n+\t\tfor (i = 0; i < vsi->nb_qps; i++)\n+\t\t\tvsi_info->queue_mapping[i] =\n+\t\t\t\trte_cpu_to_le_16(vsi->base_queue + i);\n+\t} else {\n+\t\tvsi_info->mapping_flags |=\n+\t\t\trte_cpu_to_le_16(I40E_AQ_VSI_QUE_MAP_CONTIG);\n+\t\tvsi_info->queue_mapping[0] = rte_cpu_to_le_16(vsi->base_queue);\n+\t}\n+\tvsi_info->valid_sections |=\n+\t\trte_cpu_to_le_16(I40E_AQ_VSI_PROP_QUEUE_MAP_VALID);\n+\n+\t/* Update the VSI after updating the VSI queue-mapping information */\n+\tret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);\n+\tif (ret) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to configure queue region mapping = %d \",\n+\t\t\t\thw->aq.asq_last_status);\n+\t\treturn ret;\n+\t}\n+\t/* update the local VSI info with updated queue map */\n+\t(void)rte_memcpy(&vsi->info.tc_mapping, &ctxt.info.tc_mapping,\n+\t\t\t\t\tsizeof(vsi->info.tc_mapping));\n+\t(void)rte_memcpy(&vsi->info.queue_mapping,\n+\t\t\t&ctxt.info.queue_mapping,\n+\t\t\tsizeof(vsi->info.queue_mapping));\n+\tvsi->info.mapping_flags = ctxt.info.mapping_flags;\n+\tvsi->info.valid_sections = 0;\n+\n+\treturn 0;\n+}\n+\n+\n+static int\n+i40e_queue_region_set_region(struct i40e_pf *pf,\n+\t\t\t\tstruct rte_i40e_rss_region_conf *conf_ptr)\n+{\n+\tuint16_t i;\n+\tstruct i40e_vsi *main_vsi = pf->main_vsi;\n+\tstruct i40e_queue_region_info *info = &pf->queue_region;\n+\tint32_t ret = -EINVAL;\n+\n+\tif (!((rte_is_power_of_2(conf_ptr->queue_num)) &&\n+\t\t\t\tconf_ptr->queue_num <= 64)) {\n+\t\tPMD_DRV_LOG(ERR, \"The region sizes should be any of the following values: 1, 2, 4, 8, 16, 32, 64 as long as the \"\n+\t\t\t\"total number of queues do not exceed the VSI allocation\");\n+\t\treturn ret;\n+\t}\n+\n+\tif (conf_ptr->region_id > I40E_REGION_MAX_INDEX) {\n+\t\tPMD_DRV_LOG(ERR, \"the queue region max index is 7\");\n+\t\treturn ret;\n+\t}\n+\n+\tif ((conf_ptr->queue_start_index + conf_ptr->queue_num)\n+\t\t\t\t\t> main_vsi->nb_used_qps) {\n+\t\tPMD_DRV_LOG(ERR, \"the queue index exceeds the VSI range\");\n+\t\treturn ret;\n+\t}\n+\n+\tfor (i = 0; i < info->queue_region_number; i++)\n+\t\tif (conf_ptr->region_id == info->region[i].region_id)\n+\t\t\tbreak;\n+\n+\tif (i == info->queue_region_number &&\n+\t\t\t\ti <= I40E_REGION_MAX_INDEX) {\n+\t\tinfo->region[i].region_id = conf_ptr->region_id;\n+\t\tinfo->region[i].queue_num = conf_ptr->queue_num;\n+\t\tinfo->region[i].queue_start_index =\n+\t\t\tconf_ptr->queue_start_index;\n+\t\tinfo->queue_region_number++;\n+\t} else {\n+\t\tPMD_DRV_LOG(ERR, \"queue region number exceeds maxnum 8 or the queue region id has been set before\");\n+\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+i40e_queue_region_set_flowtype(struct i40e_pf *pf,\n+\t\t\tstruct rte_i40e_rss_region_conf *rss_region_conf)\n+{\n+\tint32_t ret = -EINVAL;\n+\tstruct i40e_queue_region_info *info = &pf->queue_region;\n+\tuint16_t i, j, flowtype_set = 0;\n+\tuint16_t region_index, flowtype_index;\n+\n+\t/**\n+\t * For the pctype or hardware flowtype of packet,\n+\t * the specific index for each type has been defined\n+\t * in file i40e_type.h as enum i40e_filter_pctype.\n+\t */\n+\n+\tif (rss_region_conf->region_id > I40E_PFQF_HREGION_MAX_INDEX) {\n+\t\tPMD_DRV_LOG(ERR, \"the queue region max index is 7\");\n+\t\treturn ret;\n+\t}\n+\n+\tif (rss_region_conf->hw_flowtype >= I40E_FILTER_PCTYPE_MAX) {\n+\t\tPMD_DRV_LOG(ERR, \"the hw_flowtype or PCTYPE max index is 63\");\n+\t\treturn ret;\n+\t}\n+\n+\n+\tfor (i = 0; i < info->queue_region_number; i++)\n+\t\tif (rss_region_conf->region_id == info->region[i].region_id)\n+\t\t\tbreak;\n+\n+\tif (i == info->queue_region_number) {\n+\t\tPMD_DRV_LOG(ERR, \"that region id has not been set before\");\n+\t\tret = -ENODATA;\n+\t\treturn ret;\n+\t}\n+\tregion_index = i;\n+\n+\tfor (i = 0; i < info->queue_region_number; i++) {\n+\t\tfor (j = 0; j < info->region[i].flowtype_num; j++) {\n+\t\t\tif (rss_region_conf->hw_flowtype ==\n+\t\t\t\tinfo->region[i].hw_flowtype[j]) {\n+\t\t\t\tflowtype_set = 1;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\tif (flowtype_set) {\n+\t\tPMD_DRV_LOG(ERR, \"that hw_flowtype has been set before\");\n+\t\treturn 0;\n+\t}\n+\tflowtype_index = info->region[region_index].flowtype_num;\n+\tinfo->region[region_index].hw_flowtype[flowtype_index] =\n+\t\t\t\t\trss_region_conf->hw_flowtype;\n+\tinfo->region[region_index].flowtype_num++;\n+\n+\treturn 0;\n+}\n+\n+static void\n+i40e_queue_region_pf_flowtype_conf(struct i40e_hw *hw,\n+\t\t\t\tstruct i40e_pf *pf)\n+{\n+\tuint8_t hw_flowtype;\n+\tuint32_t pfqf_hregion;\n+\tuint16_t i, j, index;\n+\tstruct i40e_queue_region_info *info = &pf->queue_region;\n+\n+\t/**\n+\t * For the pctype or hardware flowtype of packet,\n+\t * the specific index for each type has been defined\n+\t * in file i40e_type.h as enum i40e_filter_pctype.\n+\t */\n+\n+\tfor (i = 0; i < info->queue_region_number; i++) {\n+\t\tfor (j = 0; j < info->region[i].flowtype_num; j++) {\n+\t\t\thw_flowtype = info->region[i].hw_flowtype[j];\n+\t\t\tindex = hw_flowtype >> 3;\n+\t\t\tpfqf_hregion =\n+\t\t\t\ti40e_read_rx_ctl(hw, I40E_PFQF_HREGION(index));\n+\n+\t\t\tif ((hw_flowtype & 0x7) == 0) {\n+\t\t\t\tpfqf_hregion |= info->region[i].region_id <<\n+\t\t\t\t\tI40E_PFQF_HREGION_REGION_0_SHIFT;\n+\t\t\t\tpfqf_hregion |= 1 <<\n+\t\t\t\t\tI40E_PFQF_HREGION_OVERRIDE_ENA_0_SHIFT;\n+\t\t\t} else if ((hw_flowtype & 0x7) == 1) {\n+\t\t\t\tpfqf_hregion |= info->region[i].region_id  <<\n+\t\t\t\t\tI40E_PFQF_HREGION_REGION_1_SHIFT;\n+\t\t\t\tpfqf_hregion |= 1 <<\n+\t\t\t\t\tI40E_PFQF_HREGION_OVERRIDE_ENA_1_SHIFT;\n+\t\t\t} else if ((hw_flowtype & 0x7) == 2) {\n+\t\t\t\tpfqf_hregion |= info->region[i].region_id  <<\n+\t\t\t\t\tI40E_PFQF_HREGION_REGION_2_SHIFT;\n+\t\t\t\tpfqf_hregion |= 1 <<\n+\t\t\t\t\tI40E_PFQF_HREGION_OVERRIDE_ENA_2_SHIFT;\n+\t\t\t} else if ((hw_flowtype & 0x7) == 3) {\n+\t\t\t\tpfqf_hregion |= info->region[i].region_id  <<\n+\t\t\t\t\tI40E_PFQF_HREGION_REGION_3_SHIFT;\n+\t\t\t\tpfqf_hregion |= 1 <<\n+\t\t\t\t\tI40E_PFQF_HREGION_OVERRIDE_ENA_3_SHIFT;\n+\t\t\t} else if ((hw_flowtype & 0x7) == 4) {\n+\t\t\t\tpfqf_hregion |= info->region[i].region_id  <<\n+\t\t\t\t\tI40E_PFQF_HREGION_REGION_4_SHIFT;\n+\t\t\t\tpfqf_hregion |= 1 <<\n+\t\t\t\t\tI40E_PFQF_HREGION_OVERRIDE_ENA_4_SHIFT;\n+\t\t\t} else if ((hw_flowtype & 0x7) == 5) {\n+\t\t\t\tpfqf_hregion |= info->region[i].region_id  <<\n+\t\t\t\t\tI40E_PFQF_HREGION_REGION_5_SHIFT;\n+\t\t\t\tpfqf_hregion |= 1 <<\n+\t\t\t\t\tI40E_PFQF_HREGION_OVERRIDE_ENA_5_SHIFT;\n+\t\t\t} else if ((hw_flowtype & 0x7) == 6) {\n+\t\t\t\tpfqf_hregion |= info->region[i].region_id  <<\n+\t\t\t\t\tI40E_PFQF_HREGION_REGION_6_SHIFT;\n+\t\t\t\tpfqf_hregion |= 1 <<\n+\t\t\t\t\tI40E_PFQF_HREGION_OVERRIDE_ENA_6_SHIFT;\n+\t\t\t} else {\n+\t\t\t\tpfqf_hregion |= info->region[i].region_id  <<\n+\t\t\t\t\tI40E_PFQF_HREGION_REGION_7_SHIFT;\n+\t\t\t\tpfqf_hregion |= 1 <<\n+\t\t\t\t\tI40E_PFQF_HREGION_OVERRIDE_ENA_7_SHIFT;\n+\t\t\t}\n+\n+\t\t\ti40e_write_rx_ctl(hw, I40E_PFQF_HREGION(index),\n+\t\t\t\t\t\tpfqf_hregion);\n+\t\t}\n+\t}\n+}\n+static int\n+i40e_queue_region_set_user_priority(struct i40e_pf *pf,\n+\t\tstruct rte_i40e_rss_region_conf *rss_region_conf)\n+{\n+\tstruct i40e_queue_region_info *info = &pf->queue_region;\n+\tint32_t ret = -EINVAL;\n+\tuint16_t i, j, region_index, user_priority_set = 0;\n+\n+\tif (rss_region_conf->user_priority >= I40E_MAX_USER_PRIORITY) {\n+\t\tPMD_DRV_LOG(ERR, \"the queue region max index is 7\");\n+\t\treturn ret;\n+\t}\n+\n+\tif (rss_region_conf->region_id >= I40E_REGION_MAX_INDEX) {\n+\t\tPMD_DRV_LOG(ERR, \"the region_id max index is 7\");\n+\t\treturn ret;\n+\t}\n+\n+\tfor (i = 0; i < info->queue_region_number; i++)\n+\t\tif (rss_region_conf->region_id == info->region[i].region_id)\n+\t\t\tbreak;\n+\n+\tif (i == info->queue_region_number) {\n+\t\tPMD_DRV_LOG(ERR, \"that region id has not been set before\");\n+\t\tret = -ENODATA;\n+\t\treturn ret;\n+\t}\n+\tregion_index = i;\n+\n+\tfor (i = 0; i < info->queue_region_number; i++) {\n+\t\tfor (j = 0; j < info->region[i].user_priority_num; j++) {\n+\t\t\tif (info->region[i].user_priority[j] ==\n+\t\t\t\trss_region_conf->user_priority) {\n+\t\t\t\tuser_priority_set = 1;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\tif (user_priority_set) {\n+\t\tPMD_DRV_LOG(ERR, \"that user priority has been set before\");\n+\t\treturn 0;\n+\t}\n+\n+\tj = info->region[region_index].user_priority_num;\n+\tinfo->region[region_index].user_priority[j] =\n+\t\t\t\t\trss_region_conf->user_priority;\n+\tinfo->region[region_index].user_priority_num++;\n+\n+\treturn 0;\n+}\n+\n+static int\n+i40e_queue_region_dcb_configure(struct i40e_hw *hw,\n+\t\t\t\tstruct i40e_pf *pf)\n+{\n+\tstruct i40e_dcbx_config dcb_cfg_local;\n+\tstruct i40e_dcbx_config *dcb_cfg;\n+\tstruct i40e_queue_region_info *info = &pf->queue_region;\n+\tstruct i40e_dcbx_config *old_cfg = &hw->local_dcbx_config;\n+\tint32_t ret = -EINVAL;\n+\tuint16_t i, j, prio_index, region_index;\n+\tuint8_t tc_map, tc_bw, bw_lf;\n+\n+\tif (!info->queue_region_number) {\n+\t\tPMD_DRV_LOG(ERR, \"there is no that region id been set before\");\n+\t\treturn ret;\n+\t}\n+\n+\tdcb_cfg = &dcb_cfg_local;\n+\tmemset(dcb_cfg, 0, sizeof(struct i40e_dcbx_config));\n+\n+\t/* assume each tc has the same bw */\n+\ttc_bw = I40E_MAX_PERCENT / info->queue_region_number;\n+\tfor (i = 0; i < info->queue_region_number; i++)\n+\t\tdcb_cfg->etscfg.tcbwtable[i] = tc_bw;\n+\t/* to ensure the sum of tcbw is equal to 100 */\n+\tbw_lf = I40E_MAX_PERCENT %  info->queue_region_number;\n+\tfor (i = 0; i < bw_lf; i++)\n+\t\tdcb_cfg->etscfg.tcbwtable[i]++;\n+\n+\t/* assume each tc has the same Transmission Selection Algorithm */\n+\tfor (i = 0; i < info->queue_region_number; i++)\n+\t\tdcb_cfg->etscfg.tsatable[i] = I40E_IEEE_TSA_ETS;\n+\n+\tfor (i = 0; i < info->queue_region_number; i++) {\n+\t\tfor (j = 0; j < info->region[i].user_priority_num; j++) {\n+\t\t\tprio_index = info->region[i].user_priority[j];\n+\t\t\tregion_index = info->region[i].region_id;\n+\t\t\tdcb_cfg->etscfg.prioritytable[prio_index] =\n+\t\t\t\t\t\tregion_index;\n+\t\t}\n+\t}\n+\n+\t/* FW needs one App to configure HW */\n+\tdcb_cfg->numapps = I40E_DEFAULT_DCB_APP_NUM;\n+\tdcb_cfg->app[0].selector = I40E_APP_SEL_ETHTYPE;\n+\tdcb_cfg->app[0].priority = I40E_DEFAULT_DCB_APP_PRIO;\n+\tdcb_cfg->app[0].protocolid = I40E_APP_PROTOID_FCOE;\n+\n+\ttc_map = RTE_LEN2MASK(info->queue_region_number, uint8_t);\n+\n+\tdcb_cfg->pfc.willing = 0;\n+\tdcb_cfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS;\n+\tdcb_cfg->pfc.pfcenable = tc_map;\n+\n+\t/* Copy the new config to the current config */\n+\t*old_cfg = *dcb_cfg;\n+\told_cfg->etsrec = old_cfg->etscfg;\n+\tret = i40e_set_dcb_config(hw);\n+\n+\tif (ret) {\n+\t\tPMD_DRV_LOG(ERR, \"Set queue region DCB Config failed, err %s aq_err %s\",\n+\t\t\t i40e_stat_str(hw, ret),\n+\t\t\t i40e_aq_str(hw, hw->aq.asq_last_status));\n+\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int\n+i40e_flush_queue_region_all_conf(struct rte_eth_dev *dev,\n+\tstruct i40e_hw *hw, struct i40e_pf *pf, uint16_t on)\n+{\n+\tint32_t ret = -EINVAL;\n+\tstruct i40e_queue_region_info *info = &pf->queue_region;\n+\n+\tif (on) {\n+\t\ti40e_queue_region_pf_flowtype_conf(hw, pf);\n+\n+\t\tret = i40e_vsi_update_queue_region_mapping(hw, pf);\n+\t\tif (ret != I40E_SUCCESS) {\n+\t\t\tPMD_DRV_LOG(INFO, \"Failed to flush queue region mapping.\");\n+\t\t\treturn ret;\n+\t\t}\n+\n+\t\tret = i40e_queue_region_dcb_configure(hw, pf);\n+\t\tif (ret != I40E_SUCCESS) {\n+\t\t\tPMD_DRV_LOG(INFO, \"Failed to flush dcb.\");\n+\t\t\treturn ret;\n+\t\t}\n+\n+\t\treturn 0;\n+\t}\n+\n+\tinfo->queue_region_number = 1;\n+\tinfo->region[0].queue_num = 64;\n+\tinfo->region[0].queue_start_index = 0;\n+\n+\tret = i40e_vsi_update_queue_region_mapping(hw, pf);\n+\tif (ret != I40E_SUCCESS)\n+\t\tPMD_DRV_LOG(INFO, \"Failed to flush queue region mapping.\");\n+\n+\tret = i40e_dcb_init_configure(dev, TRUE);\n+\tif (ret != I40E_SUCCESS) {\n+\t\tPMD_DRV_LOG(INFO, \"Failed to flush dcb.\");\n+\t\tpf->flags &= ~I40E_FLAG_DCB;\n+\t}\n+\n+\ti40e_init_queue_region_conf(dev);\n+\n+\treturn 0;\n+}\n+\n+static int\n+i40e_queue_region_pf_check_rss(struct i40e_pf *pf)\n+{\n+\tstruct i40e_hw *hw = I40E_PF_TO_HW(pf);\n+\tuint64_t hena;\n+\n+\thena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));\n+\thena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;\n+\tif (hw->mac.type == I40E_MAC_X722)\n+\t\thena &= I40E_RSS_HENA_ALL_X722;\n+\telse\n+\t\thena &= I40E_RSS_HENA_ALL;\n+\n+\tif (!hena)\n+\t\treturn -ENOTSUP;\n+\n+\treturn 0;\n+}\n+\n+static void\n+i40e_queue_region_get_all_info(struct i40e_pf *pf, uint16_t port_id)\n+{\n+\tuint16_t i, j;\n+\tstruct i40e_queue_region_info *info = &pf->queue_region;\n+\tstatic const char *queue_region_info_stats_border = \"-------\";\n+\n+\tif (!info->queue_region_number)\n+\t\tPMD_DRV_LOG(ERR, \"there is no has been region set before\");\n+\n+\tprintf(\"\\n  %s All queue region info for port=%2d %s\",\n+\t\t\tqueue_region_info_stats_border, port_id,\n+\t\t\tqueue_region_info_stats_border);\n+\tprintf(\"\\n  queue_region_number: %-14u \\n\", info->queue_region_number);\n+\n+\tfor (i = 0; i < info->queue_region_number; i++) {\n+\t\tprintf(\"\\n  region_id: %-14u queue_number: %-14u \"\n+\t\t\t\"queue_start_index: %-14u \\n\",\n+\t\t\tinfo->region[i].region_id,\n+\t\t\tinfo->region[i].queue_num,\n+\t\t\tinfo->region[i].queue_start_index);\n+\n+\t\tprintf(\"  user_priority_num is  %-14u :\",\n+\t\t\t\tinfo->region[i].user_priority_num);\n+\t\tfor (j = 0; j < info->region[i].user_priority_num; j++)\n+\t\t\tprintf(\" %-14u \", info->region[i].user_priority[j]);\n+\n+\t\tprintf(\"\\n  flowtype_num is  %-14u :\",\n+\t\t\t\tinfo->region[i].flowtype_num);\n+\t\tfor (j = 0; j < info->region[i].flowtype_num; j++)\n+\t\t\tprintf(\" %-14u \", info->region[i].hw_flowtype[j]);\n+\t}\n+\n+\tprintf(\"\\n\\n\");\n+}\n+\n+int rte_pmd_i40e_rss_queue_region_conf(uint16_t port_id,\n+\t\t\tstruct rte_i40e_rss_region_conf *rss_region_conf)\n+{\n+\tstruct rte_eth_dev *dev = &rte_eth_devices[port_id];\n+\tstruct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);\n+\tstruct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tenum rte_pmd_i40e_queue_region_op op_type = rss_region_conf->op;\n+\tint32_t ret;\n+\n+\tRTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);\n+\n+\tif (!is_i40e_supported(dev))\n+\t\treturn -ENOTSUP;\n+\n+\tif (!(!i40e_queue_region_pf_check_rss(pf)))\n+\t\treturn -ENOTSUP;\n+\n+\t/**\n+\t * This queue region feature only support pf by now.\n+\t * \"RTE_PMD_I40E_RSS_QUEUE_REGION_ALL_FLUSH_ON\"\n+\t * is just an enable function which server for other configuration,\n+\t * it is for all configuration about queue region from up layer,\n+\t * at first will only keep in DPDK softwarestored in driver,\n+\t * only after \"FLUSH_ON\", it commit all configuration to HW.\n+\t * Because PMD had to set hardware configuration at a time, so\n+\t * it will record all up layer command at first.\n+\t * \"RTE_PMD_I40E_RSS_QUEUE_REGION_ALL_FLUSH_OFF\" is\n+\t * just clean all configuration about queue region just now,\n+\t * and restore all to DPDK i40e driver default\n+\t * config when start up.\n+\t */\n+\n+\tswitch (op_type) {\n+\tcase RTE_PMD_I40E_QUEUE_REGION_SET:\n+\t\tret = i40e_queue_region_set_region(pf, rss_region_conf);\n+\t\tbreak;\n+\tcase RTE_PMD_I40E_REGION_FLOWTYPE_SET:\n+\t\tret = i40e_queue_region_set_flowtype(pf, rss_region_conf);\n+\t\tbreak;\n+\tcase RTE_PMD_I40E_USER_PRIORITY_REGION_SET:\n+\t\tret = i40e_queue_region_set_user_priority(pf, rss_region_conf);\n+\t\tbreak;\n+\tcase RTE_PMD_I40E_RSS_QUEUE_REGION_ALL_FLUSH_ON:\n+\t\tret = i40e_flush_queue_region_all_conf(dev, hw, pf, 1);\n+\t\tbreak;\n+\tcase RTE_PMD_I40E_RSS_QUEUE_REGION_ALL_FLUSH_OFF:\n+\t\tret = i40e_flush_queue_region_all_conf(dev, hw, pf, 0);\n+\t\tbreak;\n+\tcase RTE_PMD_I40E_RSS_QUEUE_REGION_INFO_GET:\n+\t\ti40e_queue_region_get_all_info(pf, port_id);\n+\t\tbreak;\n+\tdefault:\n+\t\tPMD_DRV_LOG(WARNING, \"op type (%d) not supported\",\n+\t\t\t    op_type);\n+\t\tret = -EINVAL;\n+\t}\n+\n+\tI40E_WRITE_FLUSH(hw);\n+\n+\treturn ret;\n+}\ndiff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h\nindex 155b7e8..2806cc1 100644\n--- a/drivers/net/i40e/rte_pmd_i40e.h\n+++ b/drivers/net/i40e/rte_pmd_i40e.h\n@@ -91,6 +91,33 @@ enum rte_pmd_i40e_package_info {\n \tRTE_PMD_I40E_PKG_INFO_MAX = 0xFFFFFFFF\n };\n \n+/**\n+ *  Option types of queue region.\n+ */\n+enum rte_pmd_i40e_queue_region_op {\n+\tRTE_PMD_I40E_REGION_UNDEFINED,\n+\tRTE_PMD_I40E_QUEUE_REGION_SET,      /**< add queue region set */\n+\tRTE_PMD_I40E_REGION_FLOWTYPE_SET,   /**< add pf region pctype set */\n+\t/**< add queue region user priority set */\n+\tRTE_PMD_I40E_USER_PRIORITY_REGION_SET,\n+\t/**\n+\t * ALL configuration about queue region from up layer\n+\t * at first will only keep in DPDK softwarestored in driver,\n+\t * only after \" FLUSH_ON \", it commit all configuration to HW.\n+\t * Because PMD had to set hardware configuration at a time, so\n+\t * it will record all up layer command at first.\n+\t */\n+\tRTE_PMD_I40E_RSS_QUEUE_REGION_ALL_FLUSH_ON,\n+\t/**\n+\t * \"FLUSH_OFF \" is just clean all configuration about queue\n+\t * region just now, and restore all to DPDK i40e driver default\n+\t * config when start up.\n+\t */\n+\tRTE_PMD_I40E_RSS_QUEUE_REGION_ALL_FLUSH_OFF,\n+\tRTE_PMD_I40E_RSS_QUEUE_REGION_INFO_GET,\n+\tRTE_PMD_I40E_QUEUE_REGION_OP_MAX\n+};\n+\n #define RTE_PMD_I40E_DDP_NAME_SIZE 32\n \n /**\n@@ -146,6 +173,27 @@ struct rte_pmd_i40e_ptype_mapping {\n };\n \n /**\n+ * Queue region related information.\n+ */\n+struct rte_i40e_rss_region_conf {\n+\t/**< the region id for this configuration */\n+\tuint8_t region_id;\n+\t/**< the pctype or hardware flowtype of packet,\n+\t * the specific index for each type has been defined\n+\t * in file i40e_type.h as enum i40e_filter_pctype.\n+\t */\n+\tuint8_t hw_flowtype;\n+\t/**< the start queue index for this region */\n+\tuint8_t queue_start_index;\n+\t/**< the total queue number of this queue region */\n+\tuint8_t queue_num;\n+\t/**< the packet's user priority for this region */\n+\tuint8_t user_priority;\n+\t /**< Option types of queue region */\n+\tenum rte_pmd_i40e_queue_region_op op;\n+};\n+\n+/**\n  * Notify VF when PF link status changes.\n  *\n  * @param port\n@@ -657,4 +705,16 @@ int rte_pmd_i40e_ptype_mapping_replace(uint8_t port,\n int rte_pmd_i40e_add_vf_mac_addr(uint8_t port, uint16_t vf_id,\n \t\t\t\t struct ether_addr *mac_addr);\n \n+/**\n+ * Do RSS queue region configuration for that port as\n+ * the command option type\n+ *\n+ * @param port\n+ *    pointer id for that port device\n+ * @param conf_ptr\n+ *    pointer to the struct that contain all the\n+ *    region configuration parameters\n+ */\n+int rte_pmd_i40e_rss_queue_region_conf(uint16_t port_id,\n+\t\tstruct rte_i40e_rss_region_conf *rss_region_conf);\n #endif /* _PMD_I40E_H_ */\ndiff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map\nindex ef8882b..29d6b74 100644\n--- a/drivers/net/i40e/rte_pmd_i40e_version.map\n+++ b/drivers/net/i40e/rte_pmd_i40e_version.map\n@@ -50,5 +50,6 @@ DPDK_17.11 {\n \tglobal:\n \n \trte_pmd_i40e_add_vf_mac_addr;\n+\trte_pmd_i40e_rss_queue_region_conf;\n \n } DPDK_17.08;\n",
    "prefixes": [
        "dpdk-dev",
        "v5",
        "1/3"
    ]
}