get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 1292,
    "url": "https://patches.dpdk.org/api/patches/1292/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1416067424-31699-8-git-send-email-helin.zhang@intel.com/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1416067424-31699-8-git-send-email-helin.zhang@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1416067424-31699-8-git-send-email-helin.zhang@intel.com",
    "date": "2014-11-15T16:03:43",
    "name": "[dpdk-dev,v6,7/8] ethdev: support of multiple sizes of redirection table",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "aa6c1f499b2a4d21f6cde429cd85b0b9685095c5",
    "submitter": {
        "id": 14,
        "url": "https://patches.dpdk.org/api/people/14/?format=api",
        "name": "Zhang, Helin",
        "email": "helin.zhang@intel.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1416067424-31699-8-git-send-email-helin.zhang@intel.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/1292/comments/",
    "check": "pending",
    "checks": "https://patches.dpdk.org/api/patches/1292/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 [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id AD7507F84;\n\tSat, 15 Nov 2014 16:54:22 +0100 (CET)",
            "from mga14.intel.com (mga14.intel.com [192.55.52.115])\n\tby dpdk.org (Postfix) with ESMTP id 118BA7F95\n\tfor <dev@dpdk.org>; Sat, 15 Nov 2014 16:54:01 +0100 (CET)",
            "from fmsmga003.fm.intel.com ([10.253.24.29])\n\tby fmsmga103.fm.intel.com with ESMTP; 15 Nov 2014 07:57:27 -0800",
            "from shvmail01.sh.intel.com ([10.239.29.42])\n\tby FMSMGA003.fm.intel.com with ESMTP; 15 Nov 2014 07:54:59 -0800",
            "from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com\n\t[10.239.29.89])\n\tby shvmail01.sh.intel.com with ESMTP id sAFG45GN022463;\n\tSun, 16 Nov 2014 00:04:05 +0800",
            "from shecgisg004.sh.intel.com (localhost [127.0.0.1])\n\tby shecgisg004.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP\n\tid sAFG43LG031786; Sun, 16 Nov 2014 00:04:05 +0800",
            "(from hzhan75@localhost)\n\tby shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id sAFG434G031782; \n\tSun, 16 Nov 2014 00:04:03 +0800"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"4.97,862,1389772800\"; d=\"scan'208\";a=\"417015863\"",
        "From": "Helin Zhang <helin.zhang@intel.com>",
        "To": "dev@dpdk.org",
        "Date": "Sun, 16 Nov 2014 00:03:43 +0800",
        "Message-Id": "<1416067424-31699-8-git-send-email-helin.zhang@intel.com>",
        "X-Mailer": "git-send-email 1.7.4.1",
        "In-Reply-To": "<1416067424-31699-1-git-send-email-helin.zhang@intel.com>",
        "References": "<1415283932-20724-1-git-send-email-helin.zhang@intel.com>\n\t<1416067424-31699-1-git-send-email-helin.zhang@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v6 7/8] ethdev: support of multiple sizes of\n\tredirection table",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "patches and discussions about DPDK <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": "As 40G NIC supports different sizes (128/512/64 entries) of\nredirection table from that (128 entries) of 1G and 10G NICs,\nsupport of multiple sizes of redirection table is needed.\nIt includes,\n* Redefine 'struct rte_eth_rss_reta' in ethdev.\n  - To 'struct rte_eth_rss_reta_entry64' which contains 64\n    entries and 64 bits mask.\n  - Array of above new structure can be used for any number of\n    redirection table entries, as long as the number is multiple\n    of 64. This is quite flexible for the future expanding of\n    redirection table.\n* Redefinition of relevant interfaces in ethdev.\n  - Interface of reta update has been redefined with new parameters.\n  - Interface of reta query has been redefined with new parameters.\n* Rework of 1G PMD in igb.\n  - reta update has been reworked.\n  - reta query has been reworked.\n* Rework of 10G PMD in ixgbe.\n  - reta update has been reworked.\n  - reta query has been reworked.\n* Rework of 40G PMD (PF only) in i40e.\n  - reta update has been reworked.\n  - reta query has been reworked.\n* Implement relevant commands in testpmd.\n\nSigned-off-by: Helin Zhang <helin.zhang@intel.com>\n---\n app/test-pmd/cmdline.c              | 150 ++++++++++++++++++++++++++----------\n app/test-pmd/config.c               |  37 +++++----\n app/test-pmd/testpmd.h              |   4 +-\n lib/librte_ether/rte_ethdev.c       | 121 ++++++++++++++++++-----------\n lib/librte_ether/rte_ethdev.h       |  40 ++++++----\n lib/librte_pmd_e1000/igb_ethdev.c   | 118 +++++++++++++++-------------\n lib/librte_pmd_i40e/i40e_ethdev.c   |  93 ++++++++++++----------\n lib/librte_pmd_i40e/i40e_ethdev.h   |  13 +++-\n lib/librte_pmd_ixgbe/ixgbe_ethdev.c | 118 ++++++++++++++++------------\n 9 files changed, 431 insertions(+), 263 deletions(-)\n\nv2 changes:\n* Put rework of updating/querying igb reta to a single patch.\n* Put rework of updating/querying ixgbe reta to a single patch.\n* Put rework of updating/querying i40e reta to a single patch.\n\nv3 changes:\n* Put all redefinitions of structures and interfaces into a single patch.\n* Put all reworks of igb/igbe/i40e of supporting multiple sizes of reta into\n  the same patch.\n* Put all relevant testpmd reworks of supporting multiple sizes of reta into\n  the same patch.\n\nv4 changes:\n* Renamed RTE_BIT_WIDTH_64 to RTE_RETA_GROUP_SIZE.\n* Added more comments to rte_eth_dev_rss_reta_update() and\n  rte_eth_dev_rss_reta_query().\n\nv6 changes:\n* Checking if the input parameter of reta size is 64 aligned has been added.\n* Use macros to replace numerics in all the igb, ixgbe and i40e PMDs of\n  updating/querying reta.",
    "diff": "diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c\nindex daba286..cf252e1 100644\n--- a/app/test-pmd/cmdline.c\n+++ b/app/test-pmd/cmdline.c\n@@ -59,6 +59,7 @@\n #include <rte_cycles.h>\n #include <rte_memory.h>\n #include <rte_memzone.h>\n+#include <rte_malloc.h>\n #include <rte_launch.h>\n #include <rte_tailq.h>\n #include <rte_eal.h>\n@@ -186,6 +187,11 @@ static void cmd_help_long_parsed(void *parsed_result,\n \t\t\t\"show port (info|stats|xstats|fdir|stat_qmap) (port_id|all)\\n\"\n \t\t\t\"    Display information for port_id, or all.\\n\\n\"\n \n+\t\t\t\"show port X rss reta (size) (mask0,mask1,...)\\n\"\n+\t\t\t\"    Display the rss redirection table entry indicated\"\n+\t\t\t\" by masks on port X. size is used to indicate the\"\n+\t\t\t\" hardware supported reta size\\n\\n\"\n+\n \t\t\t\"show port rss-hash [key]\\n\"\n \t\t\t\"    Display the RSS hash functions and RSS hash key\"\n \t\t\t\" of port X\\n\\n\"\n@@ -1562,11 +1568,13 @@ struct cmd_config_rss_reta {\n };\n \n static int\n-parse_reta_config(const char *str, struct rte_eth_rss_reta *reta_conf)\n+parse_reta_config(const char *str,\n+\t\t  struct rte_eth_rss_reta_entry64 *reta_conf,\n+\t\t  uint16_t nb_entries)\n {\n \tint i;\n \tunsigned size;\n-\tuint8_t hash_index;\n+\tuint16_t hash_index, idx, shift;\n \tuint8_t nb_queue;\n \tchar s[256];\n \tconst char *p, *p0 = str;\n@@ -1594,24 +1602,23 @@ parse_reta_config(const char *str, struct rte_eth_rss_reta *reta_conf)\n \t\tfor (i = 0; i < _NUM_FLD; i++) {\n \t\t\terrno = 0;\n \t\t\tint_fld[i] = strtoul(str_fld[i], &end, 0);\n-\t\t\tif (errno != 0 || end == str_fld[i] || int_fld[i] > 255)\n+\t\t\tif (errno != 0 || end == str_fld[i] ||\n+\t\t\t\t\tint_fld[i] > 65535)\n \t\t\t\treturn -1;\n \t\t}\n \n-\t\thash_index = (uint8_t)int_fld[FLD_HASH_INDEX];\n+\t\thash_index = (uint16_t)int_fld[FLD_HASH_INDEX];\n \t\tnb_queue = (uint8_t)int_fld[FLD_QUEUE];\n \n-\t\tif (hash_index >= ETH_RSS_RETA_NUM_ENTRIES) {\n-\t\t\tprintf(\"Invalid RETA hash index=%d\", hash_index);\n+\t\tif (hash_index >= nb_entries) {\n+\t\t\tprintf(\"Invalid RETA hash index=%d\\n\", hash_index);\n \t\t\treturn -1;\n \t\t}\n \n-\t\tif (hash_index < ETH_RSS_RETA_NUM_ENTRIES/2)\n-\t\t\treta_conf->mask_lo |= (1ULL << hash_index);\n-\t\telse\n-\t\t\treta_conf->mask_hi |= (1ULL << (hash_index - ETH_RSS_RETA_NUM_ENTRIES/2));\n-\n-\t\treta_conf->reta[hash_index] = nb_queue;\n+\t\tidx = hash_index / RTE_RETA_GROUP_SIZE;\n+\t\tshift = hash_index % RTE_RETA_GROUP_SIZE;\n+\t\treta_conf[idx].mask |= (1ULL << shift);\n+\t\treta_conf[idx].reta[shift] = nb_queue;\n \t}\n \n \treturn 0;\n@@ -1623,17 +1630,35 @@ cmd_set_rss_reta_parsed(void *parsed_result,\n \t\t\t__attribute__((unused)) void *data)\n {\n \tint ret;\n-\tstruct rte_eth_rss_reta reta_conf;\n+\tstruct rte_eth_dev_info dev_info;\n+\tstruct rte_eth_rss_reta_entry64 reta_conf[8];\n \tstruct cmd_config_rss_reta *res = parsed_result;\n \n-\tmemset(&reta_conf, 0, sizeof(struct rte_eth_rss_reta));\n+\tmemset(&dev_info, 0, sizeof(dev_info));\n+\trte_eth_dev_info_get(res->port_id, &dev_info);\n+\tif (dev_info.reta_size == 0) {\n+\t\tprintf(\"Redirection table size is 0 which is \"\n+\t\t\t\t\t\"invalid for RSS\\n\");\n+\t\treturn;\n+\t} else\n+\t\tprintf(\"The reta size of port %d is %u\\n\",\n+\t\t\tres->port_id, dev_info.reta_size);\n+\tif (dev_info.reta_size > ETH_RSS_RETA_SIZE_512) {\n+\t\tprintf(\"Currently do not support more than %u entries of \"\n+\t\t\t\"redirection table\\n\", ETH_RSS_RETA_SIZE_512);\n+\t\treturn;\n+\t}\n+\n+\tmemset(reta_conf, 0, sizeof(reta_conf));\n \tif (!strcmp(res->list_name, \"reta\")) {\n-\t\tif (parse_reta_config(res->list_of_items, &reta_conf)) {\n-\t\t\tprintf(\"Invalid RSS Redirection Table config \"\n-\t\t\t\t\t\t\t\"entered\\n\");\n+\t\tif (parse_reta_config(res->list_of_items, reta_conf,\n+\t\t\t\t\t\tdev_info.reta_size)) {\n+\t\t\tprintf(\"Invalid RSS Redirection Table \"\n+\t\t\t\t\t\"config entered\\n\");\n \t\t\treturn;\n \t\t}\n-\t\tret = rte_eth_dev_rss_reta_update(res->port_id, &reta_conf);\n+\t\tret = rte_eth_dev_rss_reta_update(res->port_id,\n+\t\t\t\treta_conf, dev_info.reta_size);\n \t\tif (ret != 0)\n \t\t\tprintf(\"Bad redirection table parameter, \"\n \t\t\t\t\t\"return code = %d \\n\", ret);\n@@ -1675,26 +1700,73 @@ struct cmd_showport_reta {\n \tuint8_t port_id;\n \tcmdline_fixed_string_t rss;\n \tcmdline_fixed_string_t reta;\n-\tuint64_t mask_lo;\n-\tuint64_t mask_hi;\n+\tuint16_t size;\n+\tcmdline_fixed_string_t list_of_items;\n };\n \n-static void cmd_showport_reta_parsed(void *parsed_result,\n-\t\t\t\t__attribute__((unused)) struct cmdline *cl,\n-\t\t\t\t__attribute__((unused)) void *data)\n+static int\n+showport_parse_reta_config(struct rte_eth_rss_reta_entry64 *conf,\n+\t\t\t   uint16_t nb_entries,\n+\t\t\t   char *str)\n {\n-\tstruct cmd_showport_reta *res = parsed_result;\n-\tstruct rte_eth_rss_reta reta_conf;\n+\tuint32_t size;\n+\tconst char *p, *p0 = str;\n+\tchar s[256];\n+\tchar *end;\n+\tchar *str_fld[8];\n+\tuint16_t i, num = nb_entries / RTE_RETA_GROUP_SIZE;\n+\tint ret;\n \n-\tif ((res->mask_lo == 0) && (res->mask_hi == 0)) {\n-\t\tprintf(\"Invalid RSS Redirection Table config entered\\n\");\n-\t\treturn;\n+\tp = strchr(p0, '(');\n+\tif (p == NULL)\n+\t\treturn -1;\n+\tp++;\n+\tp0 = strchr(p, ')');\n+\tif (p0 == NULL)\n+\t\treturn -1;\n+\tsize = p0 - p;\n+\tif (size >= sizeof(s)) {\n+\t\tprintf(\"The string size exceeds the internal buffer size\\n\");\n+\t\treturn -1;\n \t}\n+\tsnprintf(s, sizeof(s), \"%.*s\", size, p);\n+\tret = rte_strsplit(s, sizeof(s), str_fld, num, ',');\n+\tif (ret <= 0 || ret != num) {\n+\t\tprintf(\"The bits of masks do not match the number of \"\n+\t\t\t\t\t\"reta entries: %u\\n\", num);\n+\t\treturn -1;\n+\t}\n+\tfor (i = 0; i < ret; i++)\n+\t\tconf[i].mask = (uint64_t)strtoul(str_fld[i], &end, 0);\n \n-\treta_conf.mask_lo = res->mask_lo;\n-\treta_conf.mask_hi = res->mask_hi;\n+\treturn 0;\n+}\n \n-\tport_rss_reta_info(res->port_id,&reta_conf);\n+static void\n+cmd_showport_reta_parsed(void *parsed_result,\n+\t\t\t __attribute__((unused)) struct cmdline *cl,\n+\t\t\t __attribute__((unused)) void *data)\n+{\n+\tstruct cmd_showport_reta *res = parsed_result;\n+\tstruct rte_eth_rss_reta_entry64 reta_conf[8];\n+\tstruct rte_eth_dev_info dev_info;\n+\n+\tmemset(&dev_info, 0, sizeof(dev_info));\n+\trte_eth_dev_info_get(res->port_id, &dev_info);\n+\tif (dev_info.reta_size == 0 || res->size != dev_info.reta_size ||\n+\t\t\t\tres->size > ETH_RSS_RETA_SIZE_512) {\n+\t\tprintf(\"Invalid redirection table size: %u\\n\", res->size);\n+\t\treturn;\n+\t}\n+\n+\tmemset(reta_conf, 0, sizeof(reta_conf));\n+\tif (showport_parse_reta_config(reta_conf, res->size,\n+\t\t\t\tres->list_of_items) < 0) {\n+\t\tprintf(\"Invalid string: %s for reta masks\\n\",\n+\t\t\t\t\tres->list_of_items);\n+\t\treturn;\n+\t}\n+\tport_rss_reta_info(res->port_id, reta_conf, res->size);\n }\n \n cmdline_parse_token_string_t cmd_showport_reta_show =\n@@ -1707,24 +1779,24 @@ cmdline_parse_token_string_t cmd_showport_reta_rss =\n \tTOKEN_STRING_INITIALIZER(struct cmd_showport_reta, rss, \"rss\");\n cmdline_parse_token_string_t cmd_showport_reta_reta =\n \tTOKEN_STRING_INITIALIZER(struct cmd_showport_reta, reta, \"reta\");\n-cmdline_parse_token_num_t cmd_showport_reta_mask_lo =\n-\tTOKEN_NUM_INITIALIZER(struct cmd_showport_reta, mask_lo, UINT64);\n-cmdline_parse_token_num_t cmd_showport_reta_mask_hi =\n-\tTOKEN_NUM_INITIALIZER(struct cmd_showport_reta, mask_hi, UINT64);\n+cmdline_parse_token_num_t cmd_showport_reta_size =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_showport_reta, size, UINT16);\n+cmdline_parse_token_string_t cmd_showport_reta_list_of_items =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_showport_reta,\n+\t\t\t\t\tlist_of_items, NULL);\n \n cmdline_parse_inst_t cmd_showport_reta = {\n \t.f = cmd_showport_reta_parsed,\n \t.data = NULL,\n-\t.help_str = \"show port X rss reta mask_lo mask_hi (X = port number)\\n\\\n-\t\t\t(mask_lo and mask_hi is UINT64)\",\n+\t.help_str = \"show port X rss reta (size) (mask0,mask1,...)\",\n \t.tokens = {\n \t\t(void *)&cmd_showport_reta_show,\n \t\t(void *)&cmd_showport_reta_port,\n \t\t(void *)&cmd_showport_reta_port_id,\n \t\t(void *)&cmd_showport_reta_rss,\n \t\t(void *)&cmd_showport_reta_reta,\n-\t\t(void *)&cmd_showport_reta_mask_lo,\n-\t\t(void *)&cmd_showport_reta_mask_hi,\n+\t\t(void *)&cmd_showport_reta_size,\n+\t\t(void *)&cmd_showport_reta_list_of_items,\n \t\tNULL,\n \t},\n };\ndiff --git a/app/test-pmd/config.c b/app/test-pmd/config.c\nindex 97a8715..749a23f 100644\n--- a/app/test-pmd/config.c\n+++ b/app/test-pmd/config.c\n@@ -284,6 +284,7 @@ port_infos_display(portid_t port_id)\n \tstruct rte_port *port;\n \tstruct ether_addr mac_addr;\n \tstruct rte_eth_link link;\n+\tstruct rte_eth_dev_info dev_info;\n \tint vlan_offload;\n \tstruct rte_mempool * mp;\n \tstatic const char *info_border = \"*********************\";\n@@ -339,6 +340,11 @@ port_infos_display(portid_t port_id)\n \t\telse\n \t\t\tprintf(\"  qinq(extend) off \\n\");\n \t}\n+\n+\tmemset(&dev_info, 0, sizeof(dev_info));\n+\trte_eth_dev_info_get(port_id, &dev_info);\n+\tif (dev_info.reta_size > 0)\n+\t\tprintf(\"Redirection table size: %u\\n\", dev_info.reta_size);\n }\n \n int\n@@ -758,36 +764,29 @@ rxtx_config_display(void)\n }\n \n void\n-port_rss_reta_info(portid_t port_id,struct rte_eth_rss_reta *reta_conf)\n+port_rss_reta_info(portid_t port_id,\n+\t\t   struct rte_eth_rss_reta_entry64 *reta_conf,\n+\t\t   uint16_t nb_entries)\n {\n-\tuint8_t i, j;\n+\tuint16_t i, idx, shift;\n \tint ret;\n \n \tif (port_id_is_invalid(port_id))\n \t\treturn;\n \n-\tret = rte_eth_dev_rss_reta_query(port_id, reta_conf);\n+\tret = rte_eth_dev_rss_reta_query(port_id, reta_conf, nb_entries);\n \tif (ret != 0) {\n \t\tprintf(\"Failed to get RSS RETA info, return code = %d\\n\", ret);\n \t\treturn;\n \t}\n \n-\tif (reta_conf->mask_lo != 0) {\n-\t\tfor (i = 0; i< ETH_RSS_RETA_NUM_ENTRIES/2; i++) {\n-\t\t\tif (reta_conf->mask_lo & (uint64_t)(1ULL << i))\n-\t\t\t\tprintf(\"RSS RETA configuration: hash index=%d,\"\n-\t\t\t\t\t\"queue=%d\\n\",i,reta_conf->reta[i]);\n-\t\t}\n-\t}\n-\n-\tif (reta_conf->mask_hi != 0) {\n-\t\tfor (i = 0; i< ETH_RSS_RETA_NUM_ENTRIES/2; i++) {\n-\t\t\tif(reta_conf->mask_hi & (uint64_t)(1ULL << i)) {\n-\t\t\t\tj = (uint8_t)(i + ETH_RSS_RETA_NUM_ENTRIES/2);\n-\t\t\t\tprintf(\"RSS RETA configuration: hash index=%d,\"\n-\t\t\t\t\t\"queue=%d\\n\",j,reta_conf->reta[j]);\n-\t\t\t}\n-\t\t}\n+\tfor (i = 0; i < nb_entries; i++) {\n+\t\tidx = i / RTE_RETA_GROUP_SIZE;\n+\t\tshift = i % RTE_RETA_GROUP_SIZE;\n+\t\tif (!(reta_conf[idx].mask & (1ULL << shift)))\n+\t\t\tcontinue;\n+\t\tprintf(\"RSS RETA configuration: hash index=%u, queue=%u\\n\",\n+\t\t\t\t\ti, reta_conf[idx].reta[shift]);\n \t}\n }\n \ndiff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h\nindex 9cbfeac..10bf13f 100644\n--- a/app/test-pmd/testpmd.h\n+++ b/app/test-pmd/testpmd.h\n@@ -533,7 +533,9 @@ void fdir_remove_perfect_filter(portid_t port_id, uint16_t soft_id,\n \t\t\t\tstruct rte_fdir_filter *fdir_filter);\n void fdir_set_masks(portid_t port_id, struct rte_fdir_masks *fdir_masks);\n \n-void port_rss_reta_info(portid_t port_id, struct rte_eth_rss_reta *reta_conf);\n+void port_rss_reta_info(portid_t port_id,\n+\t\t\tstruct rte_eth_rss_reta_entry64 *reta_conf,\n+\t\t\tuint16_t nb_entries);\n \n void set_vf_traffic(portid_t port_id, uint8_t is_rx, uint16_t vf, uint8_t on);\n void set_vf_rx_vlan(portid_t port_id, uint16_t vlan_id,\ndiff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c\nindex 8c65d72..3e2b5d8 100644\n--- a/lib/librte_ether/rte_ethdev.c\n+++ b/lib/librte_ether/rte_ethdev.c\n@@ -1927,78 +1927,111 @@ rte_eth_dev_priority_flow_ctrl_set(uint8_t port_id, struct rte_eth_pfc_conf *pfc\n \treturn (-ENOTSUP);\n }\n \n-int\n-rte_eth_dev_rss_reta_update(uint8_t port_id, struct rte_eth_rss_reta *reta_conf)\n+static inline int\n+rte_eth_check_reta_mask(struct rte_eth_rss_reta_entry64 *reta_conf,\n+\t\t\tuint16_t reta_size)\n {\n-\tstruct rte_eth_dev *dev;\n-\tuint16_t max_rxq;\n-\tuint8_t i,j;\n+\tuint16_t i, num;\n \n-\tif (port_id >= nb_ports) {\n-\t\tPMD_DEBUG_TRACE(\"Invalid port_id=%d\\n\", port_id);\n-\t\treturn (-ENODEV);\n+\tif (!reta_conf)\n+\t\treturn -EINVAL;\n+\n+\tif (reta_size != RTE_ALIGN(reta_size, RTE_RETA_GROUP_SIZE)) {\n+\t\tPMD_DEBUG_TRACE(\"Invalid reta size, should be %u aligned\\n\",\n+\t\t\t\t\t\t\tRTE_RETA_GROUP_SIZE);\n+\t\treturn -EINVAL;\n \t}\n \n-\t/* Invalid mask bit(s) setting */\n-\tif ((reta_conf->mask_lo == 0) && (reta_conf->mask_hi == 0)) {\n-\t\tPMD_DEBUG_TRACE(\"Invalid update mask bits for port=%d\\n\",port_id);\n-\t\treturn (-EINVAL);\n+\tnum = reta_size / RTE_RETA_GROUP_SIZE;\n+\tfor (i = 0; i < num; i++) {\n+\t\tif (reta_conf[i].mask)\n+\t\t\treturn 0;\n \t}\n \n-\tdev = &rte_eth_devices[port_id];\n-\tmax_rxq = (dev->data->nb_rx_queues <= ETH_RSS_RETA_MAX_QUEUE) ?\n-\t\tdev->data->nb_rx_queues : ETH_RSS_RETA_MAX_QUEUE;\n-\tif (reta_conf->mask_lo != 0) {\n-\t\tfor (i = 0; i < ETH_RSS_RETA_NUM_ENTRIES/2; i++) {\n-\t\t\tif ((reta_conf->mask_lo & (1ULL << i)) &&\n-\t\t\t\t(reta_conf->reta[i] >= max_rxq)) {\n-\t\t\t\tPMD_DEBUG_TRACE(\"RETA hash index output\"\n-\t\t\t\t\t\"configration for port=%d,invalid\"\n-\t\t\t\t\t\"queue=%d\\n\",port_id,reta_conf->reta[i]);\n+\treturn -EINVAL;\n+}\n \n-\t\t\t\treturn (-EINVAL);\n-\t\t\t}\n+static inline int\n+rte_eth_check_reta_entry(struct rte_eth_rss_reta_entry64 *reta_conf,\n+\t\t\t uint16_t reta_size,\n+\t\t\t uint8_t max_rxq)\n+{\n+\tuint16_t i, idx, shift;\n+\n+\tif (!reta_conf)\n+\t\treturn -EINVAL;\n+\n+\tif (max_rxq == 0) {\n+\t\tPMD_DEBUG_TRACE(\"No receive queue is available\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tfor (i = 0; i < reta_size; i++) {\n+\t\tidx = i / RTE_RETA_GROUP_SIZE;\n+\t\tshift = i % RTE_RETA_GROUP_SIZE;\n+\t\tif ((reta_conf[idx].mask & (1ULL << shift)) &&\n+\t\t\t(reta_conf[idx].reta[shift] >= max_rxq)) {\n+\t\t\tPMD_DEBUG_TRACE(\"reta_conf[%u]->reta[%u]: %u exceeds \"\n+\t\t\t\t\"the maximum rxq index: %u\\n\", idx, shift,\n+\t\t\t\treta_conf[idx].reta[shift], max_rxq);\n+\t\t\treturn -EINVAL;\n \t\t}\n \t}\n \n-\tif (reta_conf->mask_hi != 0) {\n-\t\tfor (i = 0; i< ETH_RSS_RETA_NUM_ENTRIES/2; i++) {\n-\t\t\tj = (uint8_t)(i + ETH_RSS_RETA_NUM_ENTRIES/2);\n+\treturn 0;\n+}\n \n-\t\t\t/* Check if the max entry >= 128 */\n-\t\t\tif ((reta_conf->mask_hi & (1ULL << i)) &&\n-\t\t\t\t(reta_conf->reta[j] >= max_rxq)) {\n-\t\t\t\tPMD_DEBUG_TRACE(\"RETA hash index output\"\n-\t\t\t\t\t\"configration for port=%d,invalid\"\n-\t\t\t\t\t\"queue=%d\\n\",port_id,reta_conf->reta[j]);\n+int\n+rte_eth_dev_rss_reta_update(uint8_t port_id,\n+\t\t\t    struct rte_eth_rss_reta_entry64 *reta_conf,\n+\t\t\t    uint16_t reta_size)\n+{\n+\tstruct rte_eth_dev *dev;\n+\tint ret;\n \n-\t\t\t\treturn (-EINVAL);\n-\t\t\t}\n-\t\t}\n+\tif (port_id >= nb_ports) {\n+\t\tPMD_DEBUG_TRACE(\"Invalid port_id=%d\\n\", port_id);\n+\t\treturn -ENODEV;\n \t}\n \n+\t/* Check mask bits */\n+\tret = rte_eth_check_reta_mask(reta_conf, reta_size);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tdev = &rte_eth_devices[port_id];\n+\n+\t/* Check entry value */\n+\tret = rte_eth_check_reta_entry(reta_conf, reta_size,\n+\t\t\t\tdev->data->nb_rx_queues);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n \tFUNC_PTR_OR_ERR_RET(*dev->dev_ops->reta_update, -ENOTSUP);\n-\treturn (*dev->dev_ops->reta_update)(dev, reta_conf);\n+\treturn (*dev->dev_ops->reta_update)(dev, reta_conf, reta_size);\n }\n \n int\n-rte_eth_dev_rss_reta_query(uint8_t port_id, struct rte_eth_rss_reta *reta_conf)\n+rte_eth_dev_rss_reta_query(uint8_t port_id,\n+\t\t\t   struct rte_eth_rss_reta_entry64 *reta_conf,\n+\t\t\t   uint16_t reta_size)\n {\n \tstruct rte_eth_dev *dev;\n+\tint ret;\n \n \tif (port_id >= nb_ports) {\n \t\tPMD_DEBUG_TRACE(\"Invalid port_id=%d\\n\", port_id);\n-\t\treturn (-ENODEV);\n+\t\treturn -ENODEV;\n \t}\n \n-\tif((reta_conf->mask_lo == 0) && (reta_conf->mask_hi == 0)) {\n-\t\tPMD_DEBUG_TRACE(\"Invalid update mask bits for the port=%d\\n\",port_id);\n-\t\treturn (-EINVAL);\n-\t}\n+\t/* Check mask bits */\n+\tret = rte_eth_check_reta_mask(reta_conf, reta_size);\n+\tif (ret < 0)\n+\t\treturn ret;\n \n \tdev = &rte_eth_devices[port_id];\n \tFUNC_PTR_OR_ERR_RET(*dev->dev_ops->reta_query, -ENOTSUP);\n-\treturn (*dev->dev_ops->reta_query)(dev, reta_conf);\n+\treturn (*dev->dev_ops->reta_query)(dev, reta_conf, reta_size);\n }\n \n int\ndiff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h\nindex 58dd2bf..fec4d4c 100644\n--- a/lib/librte_ether/rte_ethdev.h\n+++ b/lib/librte_ether/rte_ethdev.h\n@@ -448,11 +448,10 @@ struct rte_eth_rss_conf {\n  * Some RSS RETA sizes may not be supported by some drivers, check the\n  * documentation or the description of relevant functions for more details.\n  */\n-#define ETH_RSS_RETA_NUM_ENTRIES 128\n-#define ETH_RSS_RETA_MAX_QUEUE   16\n #define ETH_RSS_RETA_SIZE_64  64\n #define ETH_RSS_RETA_SIZE_128 128\n #define ETH_RSS_RETA_SIZE_512 512\n+#define RTE_RETA_GROUP_SIZE   64\n \n /* Definitions used for VMDQ and DCB functionality */\n #define ETH_VMDQ_MAX_VLAN_FILTERS   64 /**< Maximum nb. of VMDQ vlan filters. */\n@@ -516,15 +515,16 @@ struct rte_eth_vmdq_mirror_conf {\n };\n \n /**\n- * A structure used to configure Redirection Table of  the Receive Side\n- * Scaling (RSS) feature of an Ethernet port.\n+ * A structure used to configure 64 entries of Redirection Table of the\n+ * Receive Side Scaling (RSS) feature of an Ethernet port. To configure\n+ * more than 64 entries supported by hardware, an array of this structure\n+ * is needed.\n  */\n-struct rte_eth_rss_reta {\n-\t/** First 64 mask bits indicate which entry(s) need to updated/queried. */\n-\tuint64_t mask_lo;\n-\t/** Second 64 mask bits indicate which entry(s) need to updated/queried. */\n-\tuint64_t mask_hi;\n-\tuint8_t reta[ETH_RSS_RETA_NUM_ENTRIES];  /**< 128 RETA entries*/\n+struct rte_eth_rss_reta_entry64 {\n+\tuint64_t mask;\n+\t/**< Mask bits indicate which entries need to be updated/queried. */\n+\tuint8_t reta[RTE_RETA_GROUP_SIZE];\n+\t/**< Group of 64 redirection table entries. */\n };\n \n /**\n@@ -1221,11 +1221,13 @@ typedef int (*priority_flow_ctrl_set_t)(struct rte_eth_dev *dev,\n /**< @internal Setup priority flow control parameter on an Ethernet device */\n \n typedef int (*reta_update_t)(struct rte_eth_dev *dev,\n-\t\t\t\tstruct rte_eth_rss_reta *reta_conf);\n+\t\t\t     struct rte_eth_rss_reta_entry64 *reta_conf,\n+\t\t\t     uint16_t reta_size);\n /**< @internal Update RSS redirection table on an Ethernet device */\n \n typedef int (*reta_query_t)(struct rte_eth_dev *dev,\n-\t\t\t\tstruct rte_eth_rss_reta *reta_conf);\n+\t\t\t    struct rte_eth_rss_reta_entry64 *reta_conf,\n+\t\t\t    uint16_t reta_size);\n /**< @internal Query RSS redirection table on an Ethernet device */\n \n typedef int (*rss_hash_update_t)(struct rte_eth_dev *dev,\n@@ -2961,14 +2963,18 @@ int rte_eth_dev_mac_addr_remove(uint8_t port, struct ether_addr *mac_addr);\n  * @param port\n  *   The port identifier of the Ethernet device.\n  * @param reta_conf\n- *    RETA to update.\n+ *   RETA to update.\n+ * @param reta_size\n+ *   Redirection table size. The table size can be queried by\n+ *   rte_eth_dev_info_get().\n  * @return\n  *   - (0) if successful.\n  *   - (-ENOTSUP) if hardware doesn't support.\n  *   - (-EINVAL) if bad parameter.\n  */\n int rte_eth_dev_rss_reta_update(uint8_t port,\n-\t\t\tstruct rte_eth_rss_reta *reta_conf);\n+\t\t\t\tstruct rte_eth_rss_reta_entry64 *reta_conf,\n+\t\t\t\tuint16_t reta_size);\n \n  /**\n  * Query Redirection Table(RETA) of Receive Side Scaling of Ethernet device.\n@@ -2977,13 +2983,17 @@ int rte_eth_dev_rss_reta_update(uint8_t port,\n  *   The port identifier of the Ethernet device.\n  * @param reta_conf\n  *   RETA to query.\n+ * @param reta_size\n+ *   Redirection table size. The table size can be queried by\n+ *   rte_eth_dev_info_get().\n  * @return\n  *   - (0) if successful.\n  *   - (-ENOTSUP) if hardware doesn't support.\n  *   - (-EINVAL) if bad parameter.\n  */\n int rte_eth_dev_rss_reta_query(uint8_t port,\n-\t\t\tstruct rte_eth_rss_reta *reta_conf);\n+\t\t\t       struct rte_eth_rss_reta_entry64 *reta_conf,\n+\t\t\t       uint16_t reta_size);\n \n  /**\n  * Updates unicast hash table for receiving packet with the given destination\ndiff --git a/lib/librte_pmd_e1000/igb_ethdev.c b/lib/librte_pmd_e1000/igb_ethdev.c\nindex bae4eb2..873d65e 100644\n--- a/lib/librte_pmd_e1000/igb_ethdev.c\n+++ b/lib/librte_pmd_e1000/igb_ethdev.c\n@@ -69,6 +69,12 @@\n #define IGB_DEFAULT_TX_HTHRESH      0\n #define IGB_DEFAULT_TX_WTHRESH      0\n \n+/* Bit shift and mask */\n+#define IGB_4_BIT_WIDTH  (CHAR_BIT / 2)\n+#define IGB_4_BIT_MASK   RTE_LEN2MASK(IGB_4_BIT_WIDTH, uint8_t)\n+#define IGB_8_BIT_WIDTH  CHAR_BIT\n+#define IGB_8_BIT_MASK   UINT8_MAX\n+\n static int  eth_igb_configure(struct rte_eth_dev *dev);\n static int  eth_igb_start(struct rte_eth_dev *dev);\n static void eth_igb_stop(struct rte_eth_dev *dev);\n@@ -138,10 +144,11 @@ static int igbvf_vlan_filter_set(struct rte_eth_dev *dev,\n static int igbvf_set_vfta(struct e1000_hw *hw, uint16_t vid, bool on);\n static void igbvf_set_vfta_all(struct rte_eth_dev *dev, bool on);\n static int eth_igb_rss_reta_update(struct rte_eth_dev *dev,\n-\t\t struct rte_eth_rss_reta *reta_conf);\n+\t\t\t\t   struct rte_eth_rss_reta_entry64 *reta_conf,\n+\t\t\t\t   uint16_t reta_size);\n static int eth_igb_rss_reta_query(struct rte_eth_dev *dev,\n-\t\tstruct rte_eth_rss_reta *reta_conf);\n-\n+\t\t\t\t  struct rte_eth_rss_reta_entry64 *reta_conf,\n+\t\t\t\t  uint16_t reta_size);\n static int eth_igb_add_syn_filter(struct rte_eth_dev *dev,\n \t\t\tstruct rte_syn_filter *filter, uint16_t rx_queue);\n static int eth_igb_remove_syn_filter(struct rte_eth_dev *dev);\n@@ -2303,38 +2310,40 @@ igbvf_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)\n \n static int\n eth_igb_rss_reta_update(struct rte_eth_dev *dev,\n-                                struct rte_eth_rss_reta *reta_conf)\n+\t\t\tstruct rte_eth_rss_reta_entry64 *reta_conf,\n+\t\t\tuint16_t reta_size)\n {\n-\tuint8_t i,j,mask;\n-\tuint32_t reta;\n-\tstruct e1000_hw *hw =\n-\t\t\tE1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tuint8_t i, j, mask;\n+\tuint32_t reta, r;\n+\tuint16_t idx, shift;\n+\tstruct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n \n-\t/*\n-\t * Update Redirection Table RETA[n],n=0...31,The redirection table has\n-\t * 128-entries in 32 registers\n-\t */\n-\tfor(i = 0; i < ETH_RSS_RETA_NUM_ENTRIES; i += 4) {\n-\t\tif (i < ETH_RSS_RETA_NUM_ENTRIES/2)\n-\t\t\tmask = (uint8_t)((reta_conf->mask_lo >> i) & 0xF);\n+\tif (reta_size != ETH_RSS_RETA_SIZE_128) {\n+\t\tPMD_DRV_LOG(ERR, \"The size of hash lookup table configured \"\n+\t\t\t\"(%d) doesn't match the number hardware can supported \"\n+\t\t\t\"(%d)\\n\", reta_size, ETH_RSS_RETA_SIZE_128);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tfor (i = 0; i < reta_size; i += IGB_4_BIT_WIDTH) {\n+\t\tidx = i / RTE_RETA_GROUP_SIZE;\n+\t\tshift = i % RTE_RETA_GROUP_SIZE;\n+\t\tmask = (uint8_t)((reta_conf[idx].mask >> shift) &\n+\t\t\t\t\t\tIGB_4_BIT_MASK);\n+\t\tif (!mask)\n+\t\t\tcontinue;\n+\t\tif (mask == IGB_4_BIT_MASK)\n+\t\t\tr = 0;\n \t\telse\n-\t\t\tmask = (uint8_t)((reta_conf->mask_hi >>\n-\t\t\t\t(i - ETH_RSS_RETA_NUM_ENTRIES/2)) & 0xF);\n-\t\tif (mask != 0) {\n-\t\t\treta = 0;\n-\t\t\t/* If all 4 entries were set,don't need read RETA register */\n-\t\t\tif (mask != 0xF)\n-\t\t\t\treta = E1000_READ_REG(hw,E1000_RETA(i >> 2));\n-\n-\t\t\tfor (j = 0; j < 4; j++) {\n-\t\t\t\tif (mask & (0x1 << j)) {\n-\t\t\t\t\tif (mask != 0xF)\n-\t\t\t\t\t\treta &= ~(0xFF << 8 * j);\n-\t\t\t\t\treta |= reta_conf->reta[i + j] << 8 * j;\n-\t\t\t\t}\n-\t\t\t}\n-\t\t\tE1000_WRITE_REG(hw, E1000_RETA(i >> 2),reta);\n+\t\t\tr = E1000_READ_REG(hw, E1000_RETA(i >> 2));\n+\t\tfor (j = 0, reta = 0; j < IGB_4_BIT_WIDTH; j++) {\n+\t\t\tif (mask & (0x1 << j))\n+\t\t\t\treta |= reta_conf[idx].reta[shift + j] <<\n+\t\t\t\t\t\t\t(CHAR_BIT * j);\n+\t\t\telse\n+\t\t\t\treta |= r & (IGB_8_BIT_MASK << (CHAR_BIT * j));\n \t\t}\n+\t\tE1000_WRITE_REG(hw, E1000_RETA(i >> 2), reta);\n \t}\n \n \treturn 0;\n@@ -2342,31 +2351,34 @@ eth_igb_rss_reta_update(struct rte_eth_dev *dev,\n \n static int\n eth_igb_rss_reta_query(struct rte_eth_dev *dev,\n-                                struct rte_eth_rss_reta *reta_conf)\n+\t\t       struct rte_eth_rss_reta_entry64 *reta_conf,\n+\t\t       uint16_t reta_size)\n {\n-\tuint8_t i,j,mask;\n+\tuint8_t i, j, mask;\n \tuint32_t reta;\n-\tstruct e1000_hw *hw =\n-\t\t\tE1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tuint16_t idx, shift;\n+\tstruct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n \n-\t/*\n-\t * Read Redirection Table RETA[n],n=0...31,The redirection table has\n-\t * 128-entries in 32 registers\n-\t */\n-\tfor(i = 0; i < ETH_RSS_RETA_NUM_ENTRIES; i += 4) {\n-\t\tif (i < ETH_RSS_RETA_NUM_ENTRIES/2)\n-\t\t\tmask = (uint8_t)((reta_conf->mask_lo >> i) & 0xF);\n-\t\telse\n-\t\t\tmask = (uint8_t)((reta_conf->mask_hi >>\n-\t\t\t\t(i - ETH_RSS_RETA_NUM_ENTRIES/2)) & 0xF);\n-\n-\t\tif (mask != 0) {\n-\t\t\treta = E1000_READ_REG(hw,E1000_RETA(i >> 2));\n-\t\t\tfor (j = 0; j < 4; j++) {\n-\t\t\t\tif (mask & (0x1 << j))\n-\t\t\t\t\treta_conf->reta[i + j] =\n-\t\t\t\t\t\t(uint8_t)((reta >> 8 * j) & 0xFF);\n-\t\t\t}\n+\tif (reta_size != ETH_RSS_RETA_SIZE_128) {\n+\t\tPMD_DRV_LOG(ERR, \"The size of hash lookup table configured \"\n+\t\t\t\"(%d) doesn't match the number hardware can supported \"\n+\t\t\t\"(%d)\\n\", reta_size, ETH_RSS_RETA_SIZE_128);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tfor (i = 0; i < reta_size; i += IGB_4_BIT_WIDTH) {\n+\t\tidx = i / RTE_RETA_GROUP_SIZE;\n+\t\tshift = i % RTE_RETA_GROUP_SIZE;\n+\t\tmask = (uint8_t)((reta_conf[idx].mask >> shift) &\n+\t\t\t\t\t\tIGB_4_BIT_MASK);\n+\t\tif (!mask)\n+\t\t\tcontinue;\n+\t\treta = E1000_READ_REG(hw, E1000_RETA(i >> 2));\n+\t\tfor (j = 0; j < IGB_4_BIT_WIDTH; j++) {\n+\t\t\tif (mask & (0x1 << j))\n+\t\t\t\treta_conf[idx].reta[shift + j] =\n+\t\t\t\t\t((reta >> (CHAR_BIT * j)) &\n+\t\t\t\t\t\tIGB_8_BIT_MASK);\n \t\t}\n \t}\n \ndiff --git a/lib/librte_pmd_i40e/i40e_ethdev.c b/lib/librte_pmd_i40e/i40e_ethdev.c\nindex 279ef52..3bd2416 100644\n--- a/lib/librte_pmd_i40e/i40e_ethdev.c\n+++ b/lib/librte_pmd_i40e/i40e_ethdev.c\n@@ -73,14 +73,6 @@\n /* Maximun number of VSI */\n #define I40E_MAX_NUM_VSIS          (384UL)\n \n-/* Bit shift and mask */\n-#define I40E_16_BIT_SHIFT 16\n-#define I40E_16_BIT_MASK  0xFFFF\n-#define I40E_32_BIT_SHIFT 32\n-#define I40E_32_BIT_MASK  0xFFFFFFFF\n-#define I40E_48_BIT_SHIFT 48\n-#define I40E_48_BIT_MASK  0xFFFFFFFFFFFFULL\n-\n /* Default queue interrupt throttling time in microseconds*/\n #define I40E_ITR_INDEX_DEFAULT          0\n #define I40E_QUEUE_ITR_INTERVAL_DEFAULT 32 /* 32 us */\n@@ -144,9 +136,11 @@ static void i40e_macaddr_add(struct rte_eth_dev *dev,\n \t\t\t  uint32_t pool);\n static void i40e_macaddr_remove(struct rte_eth_dev *dev, uint32_t index);\n static int i40e_dev_rss_reta_update(struct rte_eth_dev *dev,\n-\t\t\t\t    struct rte_eth_rss_reta *reta_conf);\n+\t\t\t\t    struct rte_eth_rss_reta_entry64 *reta_conf,\n+\t\t\t\t    uint16_t reta_size);\n static int i40e_dev_rss_reta_query(struct rte_eth_dev *dev,\n-\t\t\t\t   struct rte_eth_rss_reta *reta_conf);\n+\t\t\t\t   struct rte_eth_rss_reta_entry64 *reta_conf,\n+\t\t\t\t   uint16_t reta_size);\n \n static int i40e_get_cap(struct i40e_hw *hw);\n static int i40e_pf_parameter_init(struct rte_eth_dev *dev);\n@@ -1777,32 +1771,41 @@ i40e_mac_filter_handle(struct rte_eth_dev *dev, enum rte_filter_op filter_op,\n \n static int\n i40e_dev_rss_reta_update(struct rte_eth_dev *dev,\n-\t\t\t struct rte_eth_rss_reta *reta_conf)\n+\t\t\t struct rte_eth_rss_reta_entry64 *reta_conf,\n+\t\t\t uint16_t reta_size)\n {\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 \tuint32_t lut, l;\n-\tuint8_t i, j, mask, max = ETH_RSS_RETA_NUM_ENTRIES / 2;\n-\n-\tfor (i = 0; i < ETH_RSS_RETA_NUM_ENTRIES; i += 4) {\n-\t\tif (i < max)\n-\t\t\tmask = (uint8_t)((reta_conf->mask_lo >> i) & 0xF);\n-\t\telse\n-\t\t\tmask = (uint8_t)((reta_conf->mask_hi >>\n-\t\t\t\t\t\t(i - max)) & 0xF);\n+\tuint16_t i, j, lut_size = pf->hash_lut_size;\n+\tuint16_t idx, shift;\n+\tuint8_t mask;\n+\n+\tif (reta_size != lut_size ||\n+\t\treta_size > ETH_RSS_RETA_SIZE_512) {\n+\t\tPMD_DRV_LOG(ERR, \"The size of hash lookup table configured \"\n+\t\t\t\"(%d) doesn't match the number hardware can supported \"\n+\t\t\t\t\t\"(%d)\\n\", reta_size, lut_size);\n+\t\treturn -EINVAL;\n+\t}\n \n+\tfor (i = 0; i < reta_size; i += I40E_4_BIT_WIDTH) {\n+\t\tidx = i / RTE_RETA_GROUP_SIZE;\n+\t\tshift = i % RTE_RETA_GROUP_SIZE;\n+\t\tmask = (uint8_t)((reta_conf[idx].mask >> shift) &\n+\t\t\t\t\t\tI40E_4_BIT_MASK);\n \t\tif (!mask)\n \t\t\tcontinue;\n-\n-\t\tif (mask == 0xF)\n+\t\tif (mask == I40E_4_BIT_MASK)\n \t\t\tl = 0;\n \t\telse\n \t\t\tl = I40E_READ_REG(hw, I40E_PFQF_HLUT(i >> 2));\n-\n-\t\tfor (j = 0, lut = 0; j < 4; j++) {\n+\t\tfor (j = 0, lut = 0; j < I40E_4_BIT_WIDTH; j++) {\n \t\t\tif (mask & (0x1 << j))\n-\t\t\t\tlut |= reta_conf->reta[i + j] << (8 * j);\n+\t\t\t\tlut |= reta_conf[idx].reta[shift + j] <<\n+\t\t\t\t\t\t\t(CHAR_BIT * j);\n \t\t\telse\n-\t\t\t\tlut |= l & (0xFF << (8 * j));\n+\t\t\t\tlut |= l & (I40E_8_BIT_MASK << (CHAR_BIT * j));\n \t\t}\n \t\tI40E_WRITE_REG(hw, I40E_PFQF_HLUT(i >> 2), lut);\n \t}\n@@ -1812,27 +1815,37 @@ i40e_dev_rss_reta_update(struct rte_eth_dev *dev,\n \n static int\n i40e_dev_rss_reta_query(struct rte_eth_dev *dev,\n-\t\t\tstruct rte_eth_rss_reta *reta_conf)\n+\t\t\tstruct rte_eth_rss_reta_entry64 *reta_conf,\n+\t\t\tuint16_t reta_size)\n {\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 \tuint32_t lut;\n-\tuint8_t i, j, mask, max = ETH_RSS_RETA_NUM_ENTRIES / 2;\n-\n-\tfor (i = 0; i < ETH_RSS_RETA_NUM_ENTRIES; i += 4) {\n-\t\tif (i < max)\n-\t\t\tmask = (uint8_t)((reta_conf->mask_lo >> i) & 0xF);\n-\t\telse\n-\t\t\tmask = (uint8_t)((reta_conf->mask_hi >>\n-\t\t\t\t\t\t(i - max)) & 0xF);\n+\tuint16_t i, j, lut_size = pf->hash_lut_size;\n+\tuint16_t idx, shift;\n+\tuint8_t mask;\n+\n+\tif (reta_size != lut_size ||\n+\t\treta_size > ETH_RSS_RETA_SIZE_512) {\n+\t\tPMD_DRV_LOG(ERR, \"The size of hash lookup table configured \"\n+\t\t\t\"(%d) doesn't match the number hardware can supported \"\n+\t\t\t\t\t\"(%d)\\n\", reta_size, lut_size);\n+\t\treturn -EINVAL;\n+\t}\n \n+\tfor (i = 0; i < reta_size; i += I40E_4_BIT_WIDTH) {\n+\t\tidx = i / RTE_RETA_GROUP_SIZE;\n+\t\tshift = i % RTE_RETA_GROUP_SIZE;\n+\t\tmask = (uint8_t)((reta_conf[idx].mask >> shift) &\n+\t\t\t\t\t\tI40E_4_BIT_MASK);\n \t\tif (!mask)\n \t\t\tcontinue;\n \n \t\tlut = I40E_READ_REG(hw, I40E_PFQF_HLUT(i >> 2));\n-\t\tfor (j = 0; j < 4; j++) {\n+\t\tfor (j = 0; j < I40E_4_BIT_WIDTH; j++) {\n \t\t\tif (mask & (0x1 << j))\n-\t\t\t\treta_conf->reta[i + j] =\n-\t\t\t\t\t(uint8_t)((lut >> (8 * j)) & 0xFF);\n+\t\t\t\treta_conf[idx].reta[shift] = ((lut >>\n+\t\t\t\t\t(CHAR_BIT * j)) & I40E_8_BIT_MASK);\n \t\t}\n \t}\n \n@@ -3584,7 +3597,7 @@ i40e_stat_update_32(struct i40e_hw *hw,\n \t\t*stat = (uint64_t)(new_data - *offset);\n \telse\n \t\t*stat = (uint64_t)((new_data +\n-\t\t\t((uint64_t)1 << I40E_32_BIT_SHIFT)) - *offset);\n+\t\t\t((uint64_t)1 << I40E_32_BIT_WIDTH)) - *offset);\n }\n \n static void\n@@ -3599,7 +3612,7 @@ i40e_stat_update_48(struct i40e_hw *hw,\n \n \tnew_data = (uint64_t)I40E_READ_REG(hw, loreg);\n \tnew_data |= ((uint64_t)(I40E_READ_REG(hw, hireg) &\n-\t\t\tI40E_16_BIT_MASK)) << I40E_32_BIT_SHIFT;\n+\t\t\tI40E_16_BIT_MASK)) << I40E_32_BIT_WIDTH;\n \n \tif (!offset_loaded)\n \t\t*offset = new_data;\n@@ -3608,7 +3621,7 @@ i40e_stat_update_48(struct i40e_hw *hw,\n \t\t*stat = new_data - *offset;\n \telse\n \t\t*stat = (uint64_t)((new_data +\n-\t\t\t((uint64_t)1 << I40E_48_BIT_SHIFT)) - *offset);\n+\t\t\t((uint64_t)1 << I40E_48_BIT_WIDTH)) - *offset);\n \n \t*stat &= I40E_48_BIT_MASK;\n }\ndiff --git a/lib/librte_pmd_i40e/i40e_ethdev.h b/lib/librte_pmd_i40e/i40e_ethdev.h\nindex dcb2adb..c30208e 100644\n--- a/lib/librte_pmd_i40e/i40e_ethdev.h\n+++ b/lib/librte_pmd_i40e/i40e_ethdev.h\n@@ -67,6 +67,18 @@\n #define I40E_DEFAULT_TX_WTHRESH      0\n #define I40E_DEFAULT_TX_RSBIT_THRESH 32\n \n+/* Bit shift and mask */\n+#define I40E_4_BIT_WIDTH  (CHAR_BIT / 2)\n+#define I40E_4_BIT_MASK   RTE_LEN2MASK(I40E_4_BIT_WIDTH, uint8_t)\n+#define I40E_8_BIT_WIDTH  CHAR_BIT\n+#define I40E_8_BIT_MASK   UINT8_MAX\n+#define I40E_16_BIT_WIDTH (CHAR_BIT * 2)\n+#define I40E_16_BIT_MASK  UINT16_MAX\n+#define I40E_32_BIT_WIDTH (CHAR_BIT * 4)\n+#define I40E_32_BIT_MASK  UINT32_MAX\n+#define I40E_48_BIT_WIDTH (CHAR_BIT * 6)\n+#define I40E_48_BIT_MASK  RTE_LEN2MASK(I40E_48_BIT_WIDTH, uint64_t)\n+\n /* i40e flags */\n #define I40E_FLAG_RSS                   (1ULL << 0)\n #define I40E_FLAG_DCB                   (1ULL << 1)\n@@ -282,7 +294,6 @@ struct i40e_pf {\n \tuint16_t vf_nb_qps; /* The number of queue pairs of VF */\n \tuint16_t fdir_nb_qps; /* The number of queue pairs of Flow Director */\n \tuint16_t hash_lut_size; /* The size of hash lookup table */\n-\n \t/* store VXLAN UDP ports */\n \tuint16_t vxlan_ports[I40E_MAX_PF_UDP_OFFLOAD_PORTS];\n \tuint16_t vxlan_bitmap; /* Vxlan bit mask */\ndiff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c\nindex 099dfb0..08e3db4 100644\n--- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c\n+++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c\n@@ -106,6 +106,12 @@\n #define IXGBE_DEFAULT_TX_WTHRESH      0\n #define IXGBE_DEFAULT_TX_RSBIT_THRESH 32\n \n+/* Bit shift and mask */\n+#define IXGBE_4_BIT_WIDTH  (CHAR_BIT / 2)\n+#define IXGBE_4_BIT_MASK   RTE_LEN2MASK(IXGBE_4_BIT_WIDTH, uint8_t)\n+#define IXGBE_8_BIT_WIDTH  CHAR_BIT\n+#define IXGBE_8_BIT_MASK   UINT8_MAX\n+\n #define IXGBEVF_PMD_NAME \"rte_ixgbevf_pmd\" /* PMD name */\n \n #define IXGBE_QUEUE_STAT_COUNTERS (sizeof(hw_stats->qprc) / sizeof(hw_stats->qprc[0]))\n@@ -159,9 +165,11 @@ static int ixgbe_flow_ctrl_set(struct rte_eth_dev *dev,\n static int ixgbe_priority_flow_ctrl_set(struct rte_eth_dev *dev,\n \t\tstruct rte_eth_pfc_conf *pfc_conf);\n static int ixgbe_dev_rss_reta_update(struct rte_eth_dev *dev,\n-\t\tstruct rte_eth_rss_reta *reta_conf);\n+\t\t\tstruct rte_eth_rss_reta_entry64 *reta_conf,\n+\t\t\tuint16_t reta_size);\n static int ixgbe_dev_rss_reta_query(struct rte_eth_dev *dev,\n-\t\tstruct rte_eth_rss_reta *reta_conf);\n+\t\t\tstruct rte_eth_rss_reta_entry64 *reta_conf,\n+\t\t\tuint16_t reta_size);\n static void ixgbe_dev_link_status_print(struct rte_eth_dev *dev);\n static int ixgbe_dev_lsc_interrupt_setup(struct rte_eth_dev *dev);\n static int ixgbe_dev_interrupt_get_status(struct rte_eth_dev *dev);\n@@ -2715,38 +2723,42 @@ ixgbe_priority_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_pfc_conf *p\n \n static int\n ixgbe_dev_rss_reta_update(struct rte_eth_dev *dev,\n-\t\t\t\tstruct rte_eth_rss_reta *reta_conf)\n+\t\t\t  struct rte_eth_rss_reta_entry64 *reta_conf,\n+\t\t\t  uint16_t reta_size)\n {\n-\tuint8_t i,j,mask;\n-\tuint32_t reta;\n-\tstruct ixgbe_hw *hw =\n-\t\t\tIXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tuint8_t i, j, mask;\n+\tuint32_t reta, r;\n+\tuint16_t idx, shift;\n+\tstruct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n \n \tPMD_INIT_FUNC_TRACE();\n-\t/*\n-\t* Update Redirection Table RETA[n],n=0...31,The redirection table has\n-\t* 128-entries in 32 registers\n-\t */\n-\tfor(i = 0; i < ETH_RSS_RETA_NUM_ENTRIES; i += 4) {\n-\t\tif (i < ETH_RSS_RETA_NUM_ENTRIES/2)\n-\t\t\tmask = (uint8_t)((reta_conf->mask_lo >> i) & 0xF);\n+\tif (reta_size != ETH_RSS_RETA_SIZE_128) {\n+\t\tPMD_DRV_LOG(ERR, \"The size of hash lookup table configured \"\n+\t\t\t\"(%d) doesn't match the number hardware can supported \"\n+\t\t\t\"(%d)\\n\", reta_size, ETH_RSS_RETA_SIZE_128);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tfor (i = 0; i < reta_size; i += IXGBE_4_BIT_WIDTH) {\n+\t\tidx = i / RTE_RETA_GROUP_SIZE;\n+\t\tshift = i % RTE_RETA_GROUP_SIZE;\n+\t\tmask = (uint8_t)((reta_conf[idx].mask >> shift) &\n+\t\t\t\t\t\tIXGBE_4_BIT_MASK);\n+\t\tif (!mask)\n+\t\t\tcontinue;\n+\t\tif (mask == IXGBE_4_BIT_MASK)\n+\t\t\tr = 0;\n \t\telse\n-\t\t\tmask = (uint8_t)((reta_conf->mask_hi >>\n-\t\t\t\t(i - ETH_RSS_RETA_NUM_ENTRIES/2)) & 0xF);\n-\t\tif (mask != 0) {\n-\t\t\treta = 0;\n-\t\t\tif (mask != 0xF)\n-\t\t\t\treta = IXGBE_READ_REG(hw,IXGBE_RETA(i >> 2));\n-\n-\t\t\tfor (j = 0; j < 4; j++) {\n-\t\t\t\tif (mask & (0x1 << j)) {\n-\t\t\t\t\tif (mask != 0xF)\n-\t\t\t\t\t\treta &= ~(0xFF << 8 * j);\n-\t\t\t\t\treta |= reta_conf->reta[i + j] << 8*j;\n-\t\t\t\t}\n-\t\t\t}\n-\t\t\tIXGBE_WRITE_REG(hw, IXGBE_RETA(i >> 2),reta);\n+\t\t\tr = IXGBE_READ_REG(hw, IXGBE_RETA(i >> 2));\n+\t\tfor (j = 0, reta = 0; j < IXGBE_4_BIT_WIDTH; j++) {\n+\t\t\tif (mask & (0x1 << j))\n+\t\t\t\treta |= reta_conf[idx].reta[shift + j] <<\n+\t\t\t\t\t\t\t(CHAR_BIT * j);\n+\t\t\telse\n+\t\t\t\treta |= r & (IXGBE_8_BIT_MASK <<\n+\t\t\t\t\t\t(CHAR_BIT * j));\n \t\t}\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_RETA(i >> 2), reta);\n \t}\n \n \treturn 0;\n@@ -2754,32 +2766,36 @@ ixgbe_dev_rss_reta_update(struct rte_eth_dev *dev,\n \n static int\n ixgbe_dev_rss_reta_query(struct rte_eth_dev *dev,\n-\t\t\t\tstruct rte_eth_rss_reta *reta_conf)\n+\t\t\t struct rte_eth_rss_reta_entry64 *reta_conf,\n+\t\t\t uint16_t reta_size)\n {\n-\tuint8_t i,j,mask;\n+\tuint8_t i, j, mask;\n \tuint32_t reta;\n-\tstruct ixgbe_hw *hw =\n-\t\t\tIXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tuint16_t idx, shift;\n+\tstruct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n \n \tPMD_INIT_FUNC_TRACE();\n-\t/*\n-\t * Read Redirection Table RETA[n],n=0...31,The redirection table has\n-\t * 128-entries in 32 registers\n-\t */\n-\tfor(i = 0; i < ETH_RSS_RETA_NUM_ENTRIES; i += 4) {\n-\t\tif (i < ETH_RSS_RETA_NUM_ENTRIES/2)\n-\t\t\tmask = (uint8_t)((reta_conf->mask_lo >> i) & 0xF);\n-\t\telse\n-\t\t\tmask = (uint8_t)((reta_conf->mask_hi >>\n-\t\t\t\t(i - ETH_RSS_RETA_NUM_ENTRIES/2)) & 0xF);\n-\n-\t\tif (mask != 0) {\n-\t\t\treta = IXGBE_READ_REG(hw,IXGBE_RETA(i >> 2));\n-\t\t\tfor (j = 0; j < 4; j++) {\n-\t\t\t\tif (mask & (0x1 << j))\n-\t\t\t\t\treta_conf->reta[i + j] =\n-\t\t\t\t\t\t(uint8_t)((reta >> 8 * j) & 0xFF);\n-\t\t\t}\n+\tif (reta_size != ETH_RSS_RETA_SIZE_128) {\n+\t\tPMD_DRV_LOG(ERR, \"The size of hash lookup table configured \"\n+\t\t\t\"(%d) doesn't match the number hardware can supported \"\n+\t\t\t\t\"(%d)\\n\", reta_size, ETH_RSS_RETA_SIZE_128);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tfor (i = 0; i < ETH_RSS_RETA_SIZE_128; i += IXGBE_4_BIT_WIDTH) {\n+\t\tidx = i / RTE_RETA_GROUP_SIZE;\n+\t\tshift = i % RTE_RETA_GROUP_SIZE;\n+\t\tmask = (uint8_t)((reta_conf[idx].mask >> shift) &\n+\t\t\t\t\t\tIXGBE_4_BIT_MASK);\n+\t\tif (!mask)\n+\t\t\tcontinue;\n+\n+\t\treta = IXGBE_READ_REG(hw, IXGBE_RETA(i >> 2));\n+\t\tfor (j = 0; j < IXGBE_4_BIT_WIDTH; j++) {\n+\t\t\tif (mask & (0x1 << j))\n+\t\t\t\treta_conf[idx].reta[shift + j] =\n+\t\t\t\t\t((reta >> (CHAR_BIT * j)) &\n+\t\t\t\t\t\tIXGBE_8_BIT_MASK);\n \t\t}\n \t}\n \n",
    "prefixes": [
        "dpdk-dev",
        "v6",
        "7/8"
    ]
}