get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 130962,
    "url": "https://patches.dpdk.org/api/patches/130962/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20230831095650.219964-26-wanry@3snic.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": "<20230831095650.219964-26-wanry@3snic.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20230831095650.219964-26-wanry@3snic.com",
    "date": "2023-08-31T09:56:43",
    "name": "[v2,25/32] net/sssnic: add RSS support",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "11fc3fc1958ebde501720a0f0fbbf5a0a353b734",
    "submitter": {
        "id": 3119,
        "url": "https://patches.dpdk.org/api/people/3119/?format=api",
        "name": "Renyong Wan",
        "email": "wanry@3snic.com"
    },
    "delegate": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20230831095650.219964-26-wanry@3snic.com/mbox/",
    "series": [
        {
            "id": 29383,
            "url": "https://patches.dpdk.org/api/series/29383/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=29383",
            "date": "2023-08-31T09:56:18",
            "name": "Introduce sssnic PMD for 3SNIC's 9x0 serials Ethernet adapters",
            "version": 2,
            "mbox": "https://patches.dpdk.org/series/29383/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/130962/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/130962/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 mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 92E0841FDB;\n\tThu, 31 Aug 2023 12:01:35 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 07B55410F6;\n\tThu, 31 Aug 2023 11:58:36 +0200 (CEST)",
            "from VLXDG1SPAM1.ramaxel.com (email.unionmem.com [221.4.138.186])\n by mails.dpdk.org (Postfix) with ESMTP id 33EAC4069D\n for <dev@dpdk.org>; Thu, 31 Aug 2023 11:58:25 +0200 (CEST)",
            "from V12DG1MBS03.ramaxel.local ([172.26.18.33])\n by VLXDG1SPAM1.ramaxel.com with ESMTP id 37V9vn2c064397;\n Thu, 31 Aug 2023 17:57:49 +0800 (GMT-8)\n (envelope-from wanry@3snic.com)",
            "from localhost.localdomain (10.64.136.151) by\n V12DG1MBS03.ramaxel.local (172.26.18.33) with Microsoft SMTP Server\n (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id\n 15.1.2375.17; Thu, 31 Aug 2023 17:57:48 +0800"
        ],
        "From": "<wanry@3snic.com>",
        "To": "<dev@dpdk.org>",
        "CC": "<ferruh.yigit@amd.com>, Renyong Wan <wanry@3snic.com>, Steven Song\n <steven.song@3snic.com>",
        "Subject": "[PATCH v2 25/32] net/sssnic: add RSS support",
        "Date": "Thu, 31 Aug 2023 17:56:43 +0800",
        "Message-ID": "<20230831095650.219964-26-wanry@3snic.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20230831095650.219964-1-wanry@3snic.com>",
        "References": "<20230831095650.219964-1-wanry@3snic.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "7bit",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[10.64.136.151]",
        "X-ClientProxiedBy": "V12DG1MBS03.ramaxel.local (172.26.18.33) To\n V12DG1MBS03.ramaxel.local (172.26.18.33)",
        "X-DNSRBL": "",
        "X-SPAM-SOURCE-CHECK": "pass",
        "X-MAIL": "VLXDG1SPAM1.ramaxel.com 37V9vn2c064397",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "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"
    },
    "content": "From: Renyong Wan <wanry@3snic.com>\n\nSigned-off-by: Steven Song <steven.song@3snic.com>\nSigned-off-by: Renyong Wan <wanry@3snic.com>\n---\nv2:\n* Removed error.h from including files.\n---\n doc/guides/nics/features/sssnic.ini    |   4 +\n drivers/net/sssnic/base/sssnic_api.c   | 338 ++++++++++++++++++++++\n drivers/net/sssnic/base/sssnic_api.h   |  36 +++\n drivers/net/sssnic/base/sssnic_cmd.h   |  58 ++++\n drivers/net/sssnic/meson.build         |   1 +\n drivers/net/sssnic/sssnic_ethdev.c     |  16 ++\n drivers/net/sssnic/sssnic_ethdev.h     |   2 +\n drivers/net/sssnic/sssnic_ethdev_rss.c | 377 +++++++++++++++++++++++++\n drivers/net/sssnic/sssnic_ethdev_rss.h |  20 ++\n drivers/net/sssnic/sssnic_ethdev_rx.c  |  13 +\n 10 files changed, 865 insertions(+)\n create mode 100644 drivers/net/sssnic/sssnic_ethdev_rss.c\n create mode 100644 drivers/net/sssnic/sssnic_ethdev_rss.h",
    "diff": "diff --git a/doc/guides/nics/features/sssnic.ini b/doc/guides/nics/features/sssnic.ini\nindex 7e6b70684a..020a9e7056 100644\n--- a/doc/guides/nics/features/sssnic.ini\n+++ b/doc/guides/nics/features/sssnic.ini\n@@ -15,6 +15,10 @@ Promiscuous mode     = Y\n Allmulticast mode    = Y\n Unicast MAC filter   = Y\n Multicast MAC filter = Y\n+RSS hash             = Y\n+RSS key update       = Y\n+RSS reta update      = Y\n+Inner RSS            = Y\n L3 checksum offload  = Y\n L4 checksum offload  = Y\n Inner L3 checksum    = Y\ndiff --git a/drivers/net/sssnic/base/sssnic_api.c b/drivers/net/sssnic/base/sssnic_api.c\nindex 9f063112f2..32b24e841c 100644\n--- a/drivers/net/sssnic/base/sssnic_api.c\n+++ b/drivers/net/sssnic/base/sssnic_api.c\n@@ -1159,3 +1159,341 @@ sssnic_mac_stats_clear(struct sssnic_hw *hw)\n \n \treturn 0;\n }\n+\n+int\n+sssnic_rss_enable_set(struct sssnic_hw *hw, bool state)\n+{\n+\tint ret;\n+\tstruct sssnic_rss_enable_cmd cmd;\n+\tstruct sssnic_msg msg;\n+\tuint32_t cmd_len;\n+\n+\tmemset(&cmd, 0, sizeof(cmd));\n+\tcmd.state = state ? 1 : 0;\n+\tcmd.function = SSSNIC_FUNC_IDX(hw);\n+\tcmd_len = sizeof(cmd);\n+\n+\tsssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len, SSSNIC_ENABLE_RSS_CMD,\n+\t\tSSSNIC_MPU_FUNC_IDX, SSSNIC_LAN_MODULE, SSSNIC_MSG_TYPE_REQ);\n+\n+\tret = sssnic_mbox_send(hw, &msg, (uint8_t *)&cmd, &cmd_len, 0);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to send mbox message, ret=%d\", ret);\n+\t\treturn ret;\n+\t}\n+\n+\tif (cmd_len == 0 || cmd.common.status != 0) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Bad response to SSSNIC_ENABLE_RSS_CMD, len=%u, status=%u\",\n+\t\t\tcmd_len, cmd.common.status);\n+\t\treturn -EIO;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+sssnic_rss_profile_config(struct sssnic_hw *hw, bool new)\n+{\n+\tint ret;\n+\tstruct sssnic_rss_profile_cmd cmd;\n+\tstruct sssnic_msg msg;\n+\tuint32_t cmd_len;\n+\n+\tmemset(&cmd, 0, sizeof(cmd));\n+\tcmd.opcode = new ? SSSNIC_RSS_PROFILE_CMD_OP_NEW :\n+\t\t\t\t SSSNIC_RSS_PROFILE_CMD_OP_DEL;\n+\tcmd.function = SSSNIC_FUNC_IDX(hw);\n+\tcmd_len = sizeof(cmd);\n+\n+\tsssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len, SSSNIC_RSS_PROFILE_CMD,\n+\t\tSSSNIC_MPU_FUNC_IDX, SSSNIC_LAN_MODULE, SSSNIC_MSG_TYPE_REQ);\n+\n+\tret = sssnic_mbox_send(hw, &msg, (uint8_t *)&cmd, &cmd_len, 0);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to send mbox message, ret=%d\", ret);\n+\t\treturn ret;\n+\t}\n+\n+\tif (cmd_len == 0 || cmd.common.status != 0) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Bad response to SSSNIC_RSS_PROFILE_CMD, len=%u, status=%u\",\n+\t\t\tcmd_len, cmd.common.status);\n+\t\treturn -EIO;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int\n+sssnic_rss_profile_create(struct sssnic_hw *hw)\n+{\n+\treturn sssnic_rss_profile_config(hw, true);\n+}\n+\n+int\n+sssnic_rss_profile_destroy(struct sssnic_hw *hw)\n+{\n+\treturn sssnic_rss_profile_config(hw, false);\n+}\n+\n+int\n+sssnic_rss_hash_key_set(struct sssnic_hw *hw, uint8_t *key, uint16_t len)\n+{\n+\tint ret;\n+\tstruct sssnic_rss_hash_key_cmd cmd;\n+\tstruct sssnic_msg msg;\n+\tuint32_t cmd_len;\n+\n+\tif (len > sizeof(cmd.key)) {\n+\t\tPMD_DRV_LOG(ERR, \"Invalid rss hash key length: %u\", len);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tmemset(&cmd, 0, sizeof(cmd));\n+\tcmd.opcode = SSSNIC_CMD_OPCODE_SET;\n+\tcmd.function = SSSNIC_FUNC_IDX(hw);\n+\trte_memcpy(cmd.key, key, len);\n+\tcmd_len = sizeof(cmd);\n+\n+\tsssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len, SSSNIC_RSS_HASH_KEY_CMD,\n+\t\tSSSNIC_MPU_FUNC_IDX, SSSNIC_LAN_MODULE, SSSNIC_MSG_TYPE_REQ);\n+\n+\tret = sssnic_mbox_send(hw, &msg, (uint8_t *)&cmd, &cmd_len, 0);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to send mbox message, ret=%d\", ret);\n+\t\treturn ret;\n+\t}\n+\n+\tif (cmd_len == 0 || cmd.common.status != 0) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Bad response to SSSNIC_RSS_PROFILE_CMD, len=%u, status=%u\",\n+\t\t\tcmd_len, cmd.common.status);\n+\t\treturn -EIO;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+sssnic_rss_type_set_by_mbox(struct sssnic_hw *hw, struct sssnic_rss_type *type)\n+{\n+\tint ret;\n+\tstruct sssnic_rss_type_cmd cmd;\n+\tstruct sssnic_msg msg;\n+\tuint32_t cmd_len;\n+\n+\tmemset(&cmd, 0, sizeof(cmd));\n+\tcmd.function = SSSNIC_FUNC_IDX(hw);\n+\tcmd.mask = type->mask;\n+\tcmd_len = sizeof(cmd);\n+\n+\tsssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len, SSSNIC_SET_RSS_TYPE_CMD,\n+\t\tSSSNIC_MPU_FUNC_IDX, SSSNIC_LAN_MODULE, SSSNIC_MSG_TYPE_REQ);\n+\n+\tret = sssnic_mbox_send(hw, &msg, (uint8_t *)&cmd, &cmd_len, 0);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to send mbox message, ret=%d\", ret);\n+\t\treturn ret;\n+\t}\n+\n+\tif (cmd.common.status == 0xff)\n+\t\treturn -EOPNOTSUPP;\n+\n+\tif (cmd_len == 0 || cmd.common.status != 0) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Bad response to SSSNIC_SET_RSS_TYPE_CMD, len=%u, status=%u\",\n+\t\t\tcmd_len, cmd.common.status);\n+\t\treturn -EIO;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+sssnic_rss_type_set_by_ctrlq(struct sssnic_hw *hw, struct sssnic_rss_type *type)\n+{\n+\tstruct sssnic_ctrlq_cmd cmd;\n+\tstruct sssnic_rss_hash_type_ctrlq_cmd data;\n+\tint ret;\n+\n+\tmemset(&data, 0, sizeof(data));\n+\tdata.mask = rte_cpu_to_be_32(type->mask);\n+\n+\tmemset(&cmd, 0, sizeof(cmd));\n+\tcmd.data = &data;\n+\tcmd.module = SSSNIC_LAN_MODULE;\n+\tcmd.data_len = sizeof(data);\n+\tcmd.cmd = SSSNIC_SET_RSS_KEY_CTRLQ_CMD;\n+\n+\tret = sssnic_ctrlq_cmd_exec(hw, &cmd, 0);\n+\tif (ret || cmd.result) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Failed to execulte ctrlq command %s, ret=%d, result=%\" PRIu64,\n+\t\t\t\"SSSNIC_SET_RSS_KEY_CTRLQ_CMD\", ret, cmd.result);\n+\t\treturn -EIO;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int\n+sssnic_rss_type_set(struct sssnic_hw *hw, struct sssnic_rss_type *type)\n+{\n+\tint ret;\n+\n+\tret = sssnic_rss_type_set_by_mbox(hw, type);\n+\tif (ret == -EOPNOTSUPP)\n+\t\tret = sssnic_rss_type_set_by_ctrlq(hw, type);\n+\n+\treturn ret;\n+}\n+\n+int\n+sssnic_rss_type_get(struct sssnic_hw *hw, struct sssnic_rss_type *type)\n+{\n+\tint ret;\n+\tstruct sssnic_rss_type_cmd cmd;\n+\tstruct sssnic_msg msg;\n+\tuint32_t cmd_len;\n+\n+\tmemset(&cmd, 0, sizeof(cmd));\n+\tcmd.function = SSSNIC_FUNC_IDX(hw);\n+\tcmd_len = sizeof(cmd);\n+\n+\tsssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len, SSSNIC_GET_RSS_TYPE_CMD,\n+\t\tSSSNIC_MPU_FUNC_IDX, SSSNIC_LAN_MODULE, SSSNIC_MSG_TYPE_REQ);\n+\n+\tret = sssnic_mbox_send(hw, &msg, (uint8_t *)&cmd, &cmd_len, 0);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to send mbox message, ret=%d\", ret);\n+\t\treturn ret;\n+\t}\n+\n+\tif (cmd_len == 0 || cmd.common.status != 0) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Bad response to SSSNIC_GET_RSS_TYPE_CMD, len=%u, status=%u\",\n+\t\t\tcmd_len, cmd.common.status);\n+\t\treturn -EIO;\n+\t}\n+\n+\ttype->mask = cmd.mask;\n+\n+\treturn 0;\n+}\n+\n+int\n+sssnic_rss_hash_engine_set(struct sssnic_hw *hw,\n+\tenum sssnic_rss_hash_engine_type engine)\n+{\n+\tint ret;\n+\tstruct sssnic_rss_hash_engine_cmd cmd;\n+\tstruct sssnic_msg msg;\n+\tuint32_t cmd_len;\n+\n+\tmemset(&cmd, 0, sizeof(cmd));\n+\tcmd.function = SSSNIC_FUNC_IDX(hw);\n+\tcmd.engine = engine;\n+\tcmd.opcode = SSSNIC_CMD_OPCODE_SET;\n+\tcmd_len = sizeof(cmd);\n+\n+\tsssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len,\n+\t\tSSSNIC_RSS_HASH_ENGINE_CMD, SSSNIC_MPU_FUNC_IDX,\n+\t\tSSSNIC_LAN_MODULE, SSSNIC_MSG_TYPE_REQ);\n+\n+\tret = sssnic_mbox_send(hw, &msg, (uint8_t *)&cmd, &cmd_len, 0);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to send mbox message, ret=%d\", ret);\n+\t\treturn ret;\n+\t}\n+\n+\tif (cmd_len == 0 || cmd.common.status != 0) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Bad response to SSSNIC_RSS_HASH_ENGINE_CMD, len=%u, status=%u\",\n+\t\t\tcmd_len, cmd.common.status);\n+\t\treturn -EIO;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int\n+sssnic_rss_indir_table_set(struct sssnic_hw *hw, const uint16_t *entry,\n+\tuint32_t num_entries)\n+{\n+\tstruct sssnic_ctrlq_cmd *cmd;\n+\tstruct sssnic_rss_indir_table_cmd *data;\n+\tuint32_t i;\n+\tint ret;\n+\n+\tcmd = sssnic_ctrlq_cmd_alloc(hw);\n+\tif (cmd == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to alloc ctrlq command\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tdata = cmd->data;\n+\tmemset(data, 0, sizeof(struct sssnic_rss_indir_table_cmd));\n+\tfor (i = 0; i < num_entries; i++)\n+\t\tdata->entry[i] = entry[i];\n+\n+\trte_wmb();\n+\n+\tsssnic_mem_cpu_to_be_32(data->entry, data->entry, sizeof(data->entry));\n+\n+\tcmd->data_len = sizeof(struct sssnic_rss_indir_table_cmd);\n+\tcmd->module = SSSNIC_LAN_MODULE;\n+\tcmd->cmd = SSSNIC_SET_RSS_INDIR_TABLE_CMD;\n+\n+\tret = sssnic_ctrlq_cmd_exec(hw, cmd, 0);\n+\tif (ret != 0 || cmd->result != 0) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Failed to execulte ctrlq command %s, ret=%d, result=%\" PRIu64,\n+\t\t\t\"SSSNIC_SET_RSS_INDIR_TABLE_CMD\", ret, cmd->result);\n+\t\tret = -EIO;\n+\t}\n+\n+\tsssnic_ctrlq_cmd_destroy(hw, cmd);\n+\n+\treturn ret;\n+}\n+\n+int\n+sssnic_rss_indir_table_get(struct sssnic_hw *hw, uint16_t *entry,\n+\tuint32_t num_entries)\n+{\n+\tstruct sssnic_ctrlq_cmd *cmd;\n+\tstruct sssnic_rss_indir_table_cmd *data;\n+\tuint32_t i;\n+\tint ret = 0;\n+\n+\tcmd = sssnic_ctrlq_cmd_alloc(hw);\n+\tif (cmd == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to alloc ctrlq command\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tdata = cmd->data;\n+\tmemset(data, 0, sizeof(struct sssnic_rss_indir_table_cmd));\n+\tcmd->data_len = sizeof(struct sssnic_rss_indir_table_cmd);\n+\tcmd->module = SSSNIC_LAN_MODULE;\n+\tcmd->cmd = SSSNIC_GET_RSS_INDIR_TABLE_CMD;\n+\tcmd->response_len = sizeof(data->entry);\n+\tcmd->response_data = data->entry;\n+\n+\tret = sssnic_ctrlq_cmd_exec(hw, cmd, 0);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Failed to execulte ctrlq command %s, ret=%d, result=%\" PRIu64,\n+\t\t\t\"SSSNIC_GET_RSS_INDIR_TABLE_CMD\", ret, cmd->result);\n+\t\tret = -EIO;\n+\t\tgoto out;\n+\t}\n+\n+\tfor (i = 0; i < num_entries; i++)\n+\t\tentry[i] = data->entry[i];\n+\n+out:\n+\tsssnic_ctrlq_cmd_destroy(hw, cmd);\n+\treturn ret;\n+}\ndiff --git a/drivers/net/sssnic/base/sssnic_api.h b/drivers/net/sssnic/base/sssnic_api.h\nindex c2f4f90209..1d80b93e38 100644\n--- a/drivers/net/sssnic/base/sssnic_api.h\n+++ b/drivers/net/sssnic/base/sssnic_api.h\n@@ -378,6 +378,30 @@ struct sssnic_mac_stats {\n \tuint64_t rx_unfilter_pkts;\n };\n \n+struct sssnic_rss_type {\n+\tunion {\n+\t\tuint32_t mask;\n+\t\tstruct {\n+\t\t\tuint32_t resvd : 23;\n+\t\t\tuint32_t valid : 1;\n+\t\t\tuint32_t ipv6_tcp_ex : 1;\n+\t\t\tuint32_t ipv6_ex : 1;\n+\t\t\tuint32_t ipv6_tcp : 1;\n+\t\t\tuint32_t ipv6 : 1;\n+\t\t\tuint32_t ipv4_tcp : 1;\n+\t\t\tuint32_t ipv4 : 1;\n+\t\t\tuint32_t ipv6_udp : 1;\n+\t\t\tuint32_t ipv4_udp : 1;\n+\t\t};\n+\t};\n+};\n+\n+enum sssnic_rss_hash_engine_type {\n+\tSSSNIC_RSS_HASH_ENGINE_XOR,\n+\tSSSNIC_RSS_HASH_ENGINE_TOEP,\n+\tSSSNIC_RSS_HASH_ENGINE_COUNT,\n+};\n+\n int sssnic_msix_attr_get(struct sssnic_hw *hw, uint16_t msix_idx,\n \tstruct sssnic_msix_attr *attr);\n int sssnic_msix_attr_set(struct sssnic_hw *hw, uint16_t msix_idx,\n@@ -420,5 +444,17 @@ int sssnic_port_stats_get(struct sssnic_hw *hw,\n int sssnic_port_stats_clear(struct sssnic_hw *hw);\n int sssnic_mac_stats_get(struct sssnic_hw *hw, struct sssnic_mac_stats *stats);\n int sssnic_mac_stats_clear(struct sssnic_hw *hw);\n+int sssnic_rss_enable_set(struct sssnic_hw *hw, bool state);\n+int sssnic_rss_profile_create(struct sssnic_hw *hw);\n+int sssnic_rss_profile_destroy(struct sssnic_hw *hw);\n+int sssnic_rss_hash_key_set(struct sssnic_hw *hw, uint8_t *key, uint16_t len);\n+int sssnic_rss_type_set(struct sssnic_hw *hw, struct sssnic_rss_type *type);\n+int sssnic_rss_type_get(struct sssnic_hw *hw, struct sssnic_rss_type *type);\n+int sssnic_rss_hash_engine_set(struct sssnic_hw *hw,\n+\tenum sssnic_rss_hash_engine_type engine);\n+int sssnic_rss_indir_table_set(struct sssnic_hw *hw, const uint16_t *entry,\n+\tuint32_t num_entries);\n+int sssnic_rss_indir_table_get(struct sssnic_hw *hw, uint16_t *entry,\n+\tuint32_t num_entries);\n \n #endif /* _SSSNIC_API_H_ */\ndiff --git a/drivers/net/sssnic/base/sssnic_cmd.h b/drivers/net/sssnic/base/sssnic_cmd.h\nindex bc7303ff57..56818471b6 100644\n--- a/drivers/net/sssnic/base/sssnic_cmd.h\n+++ b/drivers/net/sssnic/base/sssnic_cmd.h\n@@ -66,6 +66,15 @@ enum sssnic_ctrlq_cmd_id {\n \tSSSNIC_FLUSH_RXQ_CMD = 10,\n };\n \n+enum sssnic_rss_cmd_id {\n+\tSSSNIC_ENABLE_RSS_CMD = 60,\n+\tSSSNIC_RSS_PROFILE_CMD = 61,\n+\tSSSNIC_GET_RSS_TYPE_CMD = 62,\n+\tSSSNIC_RSS_HASH_KEY_CMD = 63,\n+\tSSSNIC_RSS_HASH_ENGINE_CMD = 64,\n+\tSSSNIC_SET_RSS_TYPE_CMD = 65,\n+};\n+\n struct sssnic_cmd_common {\n \tuint8_t status;\n \tuint8_t version;\n@@ -348,4 +357,53 @@ struct sssnic_mac_stats_cmd {\n \tuint8_t resvd[3];\n };\n \n+struct sssnic_rss_enable_cmd {\n+\tstruct sssnic_cmd_common common;\n+\tuint16_t function;\n+\tuint8_t state;\n+\tuint8_t resvd[13];\n+};\n+\n+#define SSSNIC_RSS_PROFILE_CMD_OP_NEW 1 /* Allocate RSS profile */\n+#define SSSNIC_RSS_PROFILE_CMD_OP_DEL 2 /* Delete RSS profile */\n+struct sssnic_rss_profile_cmd {\n+\tstruct sssnic_cmd_common common;\n+\tuint16_t function;\n+\tuint8_t opcode; /* see SSSNIC_RSS_PROFILE_CMD_OP_xx */\n+\tuint8_t profile;\n+\tuint32_t resvd[4];\n+};\n+\n+struct sssnic_rss_hash_key_cmd {\n+\tstruct sssnic_cmd_common common;\n+\tuint16_t function;\n+\tuint8_t opcode;\n+\tuint8_t resvd;\n+\tuint8_t key[40];\n+};\n+\n+struct sssnic_rss_type_cmd {\n+\tstruct sssnic_cmd_common common;\n+\tuint16_t function;\n+\tuint16_t resvd0;\n+\tuint32_t mask; /* mask of types */\n+};\n+\n+struct sssnic_rss_hash_type_ctrlq_cmd {\n+\tuint32_t resvd[4];\n+\tuint32_t mask;\n+};\n+struct sssnic_rss_hash_engine_cmd {\n+\tstruct sssnic_cmd_common common;\n+\tuint16_t function;\n+\tuint8_t opcode;\n+\tuint8_t engine;\n+\tuint8_t resvd[4];\n+};\n+\n+struct sssnic_rss_indir_table_cmd {\n+\tuint32_t resvd[4];\n+\tuint16_t entry[256];\n+};\n+\n #endif /* _SSSNIC_CMD_H_ */\ndiff --git a/drivers/net/sssnic/meson.build b/drivers/net/sssnic/meson.build\nindex dea24f4b06..3541b75c30 100644\n--- a/drivers/net/sssnic/meson.build\n+++ b/drivers/net/sssnic/meson.build\n@@ -22,4 +22,5 @@ sources = files(\n         'sssnic_ethdev_rx.c',\n         'sssnic_ethdev_tx.c',\n         'sssnic_ethdev_stats.c',\n+        'sssnic_ethdev_rss.c',\n )\ndiff --git a/drivers/net/sssnic/sssnic_ethdev.c b/drivers/net/sssnic/sssnic_ethdev.c\nindex 328fb85d30..a00e96bebe 100644\n--- a/drivers/net/sssnic/sssnic_ethdev.c\n+++ b/drivers/net/sssnic/sssnic_ethdev.c\n@@ -13,6 +13,7 @@\n #include \"sssnic_ethdev_rx.h\"\n #include \"sssnic_ethdev_tx.h\"\n #include \"sssnic_ethdev_stats.h\"\n+#include \"sssnic_ethdev_rss.h\"\n \n static int sssnic_ethdev_init(struct rte_eth_dev *ethdev);\n \n@@ -542,6 +543,13 @@ sssnic_ethdev_start(struct rte_eth_dev *ethdev)\n \t\tgoto rx_mode_reset;\n \t}\n \n+\t/* setup RSS */\n+\tret = sssnic_ethdev_rss_setup(ethdev);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to setup RSS\");\n+\t\tgoto rx_mode_reset;\n+\t}\n+\n \t/* start all rx queues */\n \tret = sssnic_ethdev_rx_queue_all_start(ethdev);\n \tif (ret != 0) {\n@@ -572,6 +580,7 @@ sssnic_ethdev_start(struct rte_eth_dev *ethdev)\n clean_port_res:\n \tsssnic_ethdev_resource_clean(ethdev);\n rx_mode_reset:\n+\tsssnic_ethdev_rss_shutdown(ethdev);\n \tsssnic_ethdev_rx_mode_set(ethdev, SSSNIC_ETHDEV_RX_MODE_NONE);\n rxtx_ctx_clean:\n \tsssnic_ethdev_rxtx_ctx_clean(ethdev);\n@@ -614,6 +623,9 @@ sssnic_ethdev_stop(struct rte_eth_dev *ethdev)\n \t/* shut down rx queue interrupt */\n \tsssnic_ethdev_rx_intr_shutdown(ethdev);\n \n+\t/* Disable RSS */\n+\tsssnic_ethdev_rss_shutdown(ethdev);\n+\n \t/* clean rxtx context */\n \tsssnic_ethdev_rxtx_ctx_clean(ethdev);\n \n@@ -754,6 +766,10 @@ static const struct eth_dev_ops sssnic_ethdev_ops = {\n \t.xstats_get_names = sssnic_ethdev_xstats_get_names,\n \t.xstats_get = sssnic_ethdev_xstats_get,\n \t.xstats_reset = sssnic_ethdev_xstats_reset,\n+\t.rss_hash_conf_get = sssnic_ethdev_rss_hash_config_get,\n+\t.rss_hash_update = sssnic_ethdev_rss_hash_update,\n+\t.reta_update = sssnic_ethdev_rss_reta_update,\n+\t.reta_query = sssnic_ethdev_rss_reta_query,\n };\n \n static int\ndiff --git a/drivers/net/sssnic/sssnic_ethdev.h b/drivers/net/sssnic/sssnic_ethdev.h\nindex 1f1e991780..f19b2bd88f 100644\n--- a/drivers/net/sssnic/sssnic_ethdev.h\n+++ b/drivers/net/sssnic/sssnic_ethdev.h\n@@ -88,6 +88,8 @@ struct sssnic_netdev {\n \tuint16_t num_started_txqs;\n \tuint16_t max_rx_size;\n \tuint32_t rx_mode;\n+\tuint32_t rss_enable;\n+\tuint8_t rss_hash_key[SSSNIC_ETHDEV_RSS_KEY_SZ];\n };\n \n #define SSSNIC_ETHDEV_PRIVATE(eth_dev)                                         \\\ndiff --git a/drivers/net/sssnic/sssnic_ethdev_rss.c b/drivers/net/sssnic/sssnic_ethdev_rss.c\nnew file mode 100644\nindex 0000000000..690a30d7bc\n--- /dev/null\n+++ b/drivers/net/sssnic/sssnic_ethdev_rss.c\n@@ -0,0 +1,377 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2018-2022 Shenzhen 3SNIC Information Technology Co., Ltd.\n+ */\n+\n+#include <rte_common.h>\n+#include <ethdev_pci.h>\n+\n+#include \"sssnic_log.h\"\n+#include \"sssnic_ethdev.h\"\n+#include \"sssnic_ethdev_rx.h\"\n+#include \"sssnic_ethdev_tx.h\"\n+#include \"sssnic_ethdev_stats.h\"\n+#include \"sssnic_ethdev_rss.h\"\n+#include \"base/sssnic_hw.h\"\n+#include \"base/sssnic_api.h\"\n+\n+static uint8_t default_rss_hash_key[SSSNIC_ETHDEV_RSS_KEY_SZ] = { 0x6d, 0x5a,\n+\t0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3,\n+\t0x8f, 0xb0, 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4, 0x77, 0xcb,\n+\t0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c, 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac,\n+\t0x01, 0xfa };\n+\n+#define SSSNIC_ETHDEV_RSS_IPV4                                                 \\\n+\t(RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4 |                            \\\n+\t\tRTE_ETH_RSS_NONFRAG_IPV4_OTHER)\n+#define SSSNIC_ETHDEV_RSS_IPV6                                                 \\\n+\t(RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 |                            \\\n+\t\tRTE_ETH_RSS_NONFRAG_IPV6_OTHER)\n+\n+static inline void\n+sssnic_ethdev_rss_type_from_rss_hf(struct sssnic_rss_type *rss_type,\n+\tuint64_t rss_hf)\n+{\n+\trss_type->mask = 0;\n+\trss_type->ipv4 = (rss_hf & SSSNIC_ETHDEV_RSS_IPV4) ? 1 : 0;\n+\trss_type->ipv6 = (rss_hf & SSSNIC_ETHDEV_RSS_IPV6) ? 1 : 0;\n+\trss_type->ipv6_ex = (rss_hf & RTE_ETH_RSS_IPV6_EX) ? 1 : 0;\n+\trss_type->ipv4_tcp = (rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_TCP) ? 1 : 0;\n+\trss_type->ipv6_tcp = (rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_TCP) ? 1 : 0;\n+\trss_type->ipv6_tcp_ex = (rss_hf & RTE_ETH_RSS_IPV6_TCP_EX) ? 1 : 0;\n+\trss_type->ipv4_udp = (rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_UDP) ? 1 : 0;\n+\trss_type->ipv6_udp = (rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_UDP) ? 1 : 0;\n+}\n+\n+static inline uint64_t\n+sssnic_ethdev_rss_type_to_rss_hf(struct sssnic_rss_type *rss_type)\n+{\n+\tuint64_t rss_hf = 0;\n+\n+\trss_hf |= (rss_type->ipv4 == 0) ? 0 : SSSNIC_ETHDEV_RSS_IPV4;\n+\trss_hf |= (rss_type->ipv6 == 0) ? 0 : SSSNIC_ETHDEV_RSS_IPV6;\n+\trss_hf |= (rss_type->ipv6_ex == 0) ? 0 : RTE_ETH_RSS_IPV6_EX;\n+\trss_hf |= (rss_type->ipv4_tcp == 0) ? 0 : RTE_ETH_RSS_NONFRAG_IPV4_TCP;\n+\trss_hf |= (rss_type->ipv6_tcp == 0) ? 0 : RTE_ETH_RSS_NONFRAG_IPV6_TCP;\n+\trss_hf |= (rss_type->ipv6_tcp_ex == 0) ? 0 : RTE_ETH_RSS_IPV6_TCP_EX;\n+\trss_hf |= (rss_type->ipv4_udp == 0) ? 0 : RTE_ETH_RSS_NONFRAG_IPV4_UDP;\n+\trss_hf |= (rss_type->ipv6_udp == 0) ? 0 : RTE_ETH_RSS_NONFRAG_IPV6_UDP;\n+\n+\treturn rss_hf;\n+}\n+\n+int\n+sssnic_ethdev_rss_hash_update(struct rte_eth_dev *ethdev,\n+\tstruct rte_eth_rss_conf *rss_conf)\n+{\n+\tstruct sssnic_netdev *netdev = SSSNIC_ETHDEV_PRIVATE(ethdev);\n+\tstruct sssnic_hw *hw = SSSNIC_ETHDEV_TO_HW(ethdev);\n+\tstruct sssnic_rss_type rss_type;\n+\tuint64_t rss_hf;\n+\tuint8_t *rss_key;\n+\tuint16_t rss_key_len;\n+\tint ret;\n+\n+\trss_key = rss_conf->rss_key;\n+\trss_key_len = rss_conf->rss_key_len;\n+\tif (rss_key == NULL) {\n+\t\trss_key = default_rss_hash_key;\n+\t\trss_key_len = SSSNIC_ETHDEV_RSS_KEY_SZ;\n+\t} else if (rss_key_len > SSSNIC_ETHDEV_RSS_KEY_SZ) {\n+\t\tPMD_DRV_LOG(ERR, \"RSS hash key length too long\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tret = sssnic_rss_hash_key_set(hw, rss_key, rss_key_len);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to set RSS hash key\");\n+\t\treturn ret;\n+\t}\n+\n+\trte_memcpy(netdev->rss_hash_key, rss_key, rss_key_len);\n+\n+\trss_hf = rss_conf->rss_hf;\n+\n+\tif (rss_hf == 0)\n+\t\trss_hf = SSSNIC_ETHDEV_RSS_OFFLOAD_FLOW_TYPES;\n+\telse\n+\t\trss_hf &= SSSNIC_ETHDEV_RSS_OFFLOAD_FLOW_TYPES;\n+\n+\tsssnic_ethdev_rss_type_from_rss_hf(&rss_type, rss_hf);\n+\trss_type.valid = 1;\n+\tret = sssnic_rss_type_set(hw, &rss_type);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to set RSS type: %x\", rss_type.mask);\n+\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int\n+sssnic_ethdev_rss_hash_config_get(struct rte_eth_dev *ethdev,\n+\tstruct rte_eth_rss_conf *rss_conf)\n+{\n+\tstruct sssnic_netdev *netdev = SSSNIC_ETHDEV_PRIVATE(ethdev);\n+\tstruct sssnic_hw *hw;\n+\tstruct sssnic_rss_type rss_type;\n+\tint ret;\n+\n+\thw = SSSNIC_NETDEV_TO_HW(netdev);\n+\n+\tif (!netdev->rss_enable) {\n+\t\tPMD_DRV_LOG(NOTICE, \"Port %u RSS is not enabled\",\n+\t\t\tethdev->data->port_id);\n+\t\trss_conf->rss_hf = 0;\n+\t\treturn 0;\n+\t}\n+\n+\tret = sssnic_rss_type_get(hw, &rss_type);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to get RSS type\");\n+\t\treturn ret;\n+\t}\n+\trss_conf->rss_hf = sssnic_ethdev_rss_type_to_rss_hf(&rss_type);\n+\n+\tif (rss_conf->rss_key != NULL &&\n+\t\trss_conf->rss_key_len >= SSSNIC_ETHDEV_RSS_KEY_SZ) {\n+\t\trte_memcpy(rss_conf->rss_key, netdev->rss_hash_key,\n+\t\t\tSSSNIC_ETHDEV_RSS_KEY_SZ);\n+\t\trss_conf->rss_key_len = SSSNIC_ETHDEV_RSS_KEY_SZ;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int\n+sssnic_ethdev_rss_reta_update(struct rte_eth_dev *ethdev,\n+\tstruct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size)\n+{\n+\tstruct sssnic_netdev *netdev = SSSNIC_ETHDEV_PRIVATE(ethdev);\n+\tstruct sssnic_hw *hw;\n+\tuint16_t *entries;\n+\tint i, group, idx;\n+\tint ret;\n+\n+\tif (!netdev->rss_enable) {\n+\t\tPMD_DRV_LOG(ERR, \"Port %u RSS is not enabled\",\n+\t\t\tethdev->data->port_id);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (reta_size != SSSNIC_ETHDEV_RSS_RETA_SZ) {\n+\t\tPMD_DRV_LOG(ERR, \"Invalid reta size:%u, expected reta size:%u \",\n+\t\t\treta_size, SSSNIC_ETHDEV_RSS_RETA_SZ);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\thw = SSSNIC_NETDEV_TO_HW(netdev);\n+\n+\tentries = rte_zmalloc(NULL,\n+\t\tSSSNIC_ETHDEV_RSS_RETA_SZ * sizeof(uint16_t), 0);\n+\tif (entries == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Could not allocate memory\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tret = sssnic_rss_indir_table_get(hw, entries,\n+\t\tSSSNIC_ETHDEV_RSS_RETA_SZ);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to get RSS indirect table\");\n+\t\tgoto out;\n+\t}\n+\n+\tfor (i = 0; i < SSSNIC_ETHDEV_RSS_RETA_SZ; i++) {\n+\t\tgroup = i / RTE_ETH_RETA_GROUP_SIZE;\n+\t\tidx = i % RTE_ETH_RETA_GROUP_SIZE;\n+\t\tif ((reta_conf[group].mask & RTE_BIT64(idx)) != 0)\n+\t\t\tentries[i] = reta_conf[group].reta[idx];\n+\t}\n+\n+\tret = sssnic_rss_indir_table_set(hw, entries,\n+\t\tSSSNIC_ETHDEV_RSS_RETA_SZ);\n+\tif (ret != 0)\n+\t\tPMD_DRV_LOG(ERR, \"Failed to set RSS indirect table\");\n+\n+out:\n+\trte_free(entries);\n+\treturn ret;\n+}\n+\n+int\n+sssnic_ethdev_rss_reta_query(struct rte_eth_dev *ethdev,\n+\tstruct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size)\n+{\n+\tstruct sssnic_netdev *netdev = SSSNIC_ETHDEV_PRIVATE(ethdev);\n+\tstruct sssnic_hw *hw;\n+\tuint16_t *entries;\n+\tint i, group, idx;\n+\tint ret;\n+\n+\tif (!netdev->rss_enable) {\n+\t\tPMD_DRV_LOG(ERR, \"Port %u RSS is not enabled\",\n+\t\t\tethdev->data->port_id);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (reta_size != SSSNIC_ETHDEV_RSS_RETA_SZ) {\n+\t\tPMD_DRV_LOG(ERR, \"Invalid reta size:%u, expected reta size:%u \",\n+\t\t\treta_size, SSSNIC_ETHDEV_RSS_RETA_SZ);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\thw = SSSNIC_NETDEV_TO_HW(netdev);\n+\n+\tentries = rte_zmalloc(NULL,\n+\t\tSSSNIC_ETHDEV_RSS_RETA_SZ * sizeof(uint16_t), 0);\n+\tif (entries == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Could not allocate memory\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tret = sssnic_rss_indir_table_get(hw, entries,\n+\t\tSSSNIC_ETHDEV_RSS_RETA_SZ);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to get RSS indirect table\");\n+\t\tgoto out;\n+\t}\n+\n+\tfor (i = 0; i < SSSNIC_ETHDEV_RSS_RETA_SZ; i++) {\n+\t\tgroup = i / RTE_ETH_RETA_GROUP_SIZE;\n+\t\tidx = i % RTE_ETH_RETA_GROUP_SIZE;\n+\t\tif ((reta_conf[group].mask & RTE_BIT64(idx)) != 0)\n+\t\t\treta_conf[group].reta[idx] = entries[i];\n+\t}\n+\n+out:\n+\trte_free(entries);\n+\treturn ret;\n+}\n+\n+int\n+sssnic_ethdev_rss_reta_reset(struct rte_eth_dev *ethdev)\n+{\n+\tstruct sssnic_netdev *netdev = SSSNIC_ETHDEV_PRIVATE(ethdev);\n+\tstruct sssnic_hw *hw = SSSNIC_ETHDEV_TO_HW(ethdev);\n+\tuint16_t *entries;\n+\tuint16_t nb_rxq;\n+\tuint8_t rxq_state;\n+\tuint16_t qid, i = 0;\n+\tint ret;\n+\n+\tif (!netdev->rss_enable)\n+\t\treturn 0;\n+\n+\tentries = rte_zmalloc(NULL,\n+\t\tSSSNIC_ETHDEV_RSS_RETA_SZ * sizeof(uint16_t), 0);\n+\tif (entries == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Could not allocate memory\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tnb_rxq = ethdev->data->nb_rx_queues;\n+\n+\tif (netdev->num_started_rxqs == 0) {\n+\t\twhile (i < SSSNIC_ETHDEV_RSS_RETA_SZ)\n+\t\t\tentries[i++] = 0xffff;\n+\t} else {\n+\t\twhile (i < SSSNIC_ETHDEV_RSS_RETA_SZ) {\n+\t\t\tfor (qid = 0; qid < nb_rxq; qid++) {\n+\t\t\t\tif (i >= SSSNIC_ETHDEV_RSS_RETA_SZ)\n+\t\t\t\t\tbreak;\n+\t\t\t\trxq_state = ethdev->data->rx_queue_state[qid];\n+\t\t\t\tif (rxq_state == RTE_ETH_QUEUE_STATE_STARTED)\n+\t\t\t\t\tentries[i++] = qid;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\tret = sssnic_rss_indir_table_set(hw, entries,\n+\t\tSSSNIC_ETHDEV_RSS_RETA_SZ);\n+\tif (ret != 0)\n+\t\tPMD_DRV_LOG(ERR, \"Failed to set RSS indirect table\");\n+\n+\trte_free(entries);\n+\n+\treturn ret;\n+}\n+\n+int\n+sssnic_ethdev_rss_setup(struct rte_eth_dev *ethdev)\n+{\n+\tstruct sssnic_netdev *netdev = SSSNIC_ETHDEV_PRIVATE(ethdev);\n+\tstruct sssnic_hw *hw = SSSNIC_ETHDEV_TO_HW(ethdev);\n+\tstruct rte_eth_conf *dev_conf = &ethdev->data->dev_conf;\n+\tstruct rte_eth_rss_conf *rss_conf;\n+\tint ret;\n+\n+\tif (!((dev_conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_RSS_HASH) &&\n+\t\t    ethdev->data->nb_rx_queues > 1)) {\n+\t\tPMD_DRV_LOG(INFO, \"RSS is not enabled\");\n+\t\treturn 0;\n+\t}\n+\n+\tif (netdev->rss_enable)\n+\t\treturn 0;\n+\n+\tret = sssnic_rss_profile_create(hw);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to create RSS profile\");\n+\t\treturn ret;\n+\t}\n+\n+\trss_conf = &dev_conf->rx_adv_conf.rss_conf;\n+\tret = sssnic_ethdev_rss_hash_update(ethdev, rss_conf);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to setup RSS config\");\n+\t\tgoto err_out;\n+\t}\n+\n+\tret = sssnic_rss_hash_engine_set(hw, SSSNIC_RSS_HASH_ENGINE_TOEP);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to set RSS hash engine\");\n+\t\tgoto err_out;\n+\t}\n+\n+\tret = sssnic_rss_enable_set(hw, true);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to enable RSS\");\n+\t\tgoto err_out;\n+\t}\n+\n+\tnetdev->rss_enable = true;\n+\n+\tPMD_DRV_LOG(INFO, \"Enabled RSS\");\n+\n+\treturn 0;\n+\n+err_out:\n+\tsssnic_rss_profile_destroy(hw);\n+\treturn ret;\n+}\n+\n+int\n+sssnic_ethdev_rss_shutdown(struct rte_eth_dev *ethdev)\n+{\n+\tstruct sssnic_netdev *netdev = SSSNIC_ETHDEV_PRIVATE(ethdev);\n+\tstruct sssnic_hw *hw = SSSNIC_ETHDEV_TO_HW(ethdev);\n+\tint ret;\n+\n+\tif (!netdev->rss_enable)\n+\t\treturn 0;\n+\n+\tret = sssnic_rss_enable_set(hw, false);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to disable rss\");\n+\t\treturn ret;\n+\t}\n+\n+\tret = sssnic_rss_profile_destroy(hw);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to delete rss profile\");\n+\t\treturn ret;\n+\t}\n+\n+\tnetdev->rss_enable = false;\n+\n+\treturn 0;\n+}\ndiff --git a/drivers/net/sssnic/sssnic_ethdev_rss.h b/drivers/net/sssnic/sssnic_ethdev_rss.h\nnew file mode 100644\nindex 0000000000..559722eec7\n--- /dev/null\n+++ b/drivers/net/sssnic/sssnic_ethdev_rss.h\n@@ -0,0 +1,20 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2018-2022 Shenzhen 3SNIC Information Technology Co., Ltd.\n+ */\n+\n+#ifndef _SSSNIC_ETHDEV_RSS_H_\n+#define _SSSNIC_ETHDEV_RSS_H_\n+\n+int sssnic_ethdev_rss_hash_update(struct rte_eth_dev *ethdev,\n+\tstruct rte_eth_rss_conf *rss_conf);\n+int sssnic_ethdev_rss_hash_config_get(struct rte_eth_dev *ethdev,\n+\tstruct rte_eth_rss_conf *rss_conf);\n+int sssnic_ethdev_rss_reta_update(struct rte_eth_dev *ethdev,\n+\tstruct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size);\n+int sssnic_ethdev_rss_reta_query(struct rte_eth_dev *ethdev,\n+\tstruct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size);\n+int sssnic_ethdev_rss_reta_reset(struct rte_eth_dev *ethdev);\n+int sssnic_ethdev_rss_setup(struct rte_eth_dev *ethdev);\n+int sssnic_ethdev_rss_shutdown(struct rte_eth_dev *ethdev);\n+\n+#endif /* _SSSNIC_ETHDEV_RSS_H_ */\ndiff --git a/drivers/net/sssnic/sssnic_ethdev_rx.c b/drivers/net/sssnic/sssnic_ethdev_rx.c\nindex 82e65f2482..2874a93a54 100644\n--- a/drivers/net/sssnic/sssnic_ethdev_rx.c\n+++ b/drivers/net/sssnic/sssnic_ethdev_rx.c\n@@ -10,6 +10,7 @@\n #include \"sssnic_log.h\"\n #include \"sssnic_ethdev.h\"\n #include \"sssnic_ethdev_rx.h\"\n+#include \"sssnic_ethdev_rss.h\"\n #include \"base/sssnic_hw.h\"\n #include \"base/sssnic_workq.h\"\n #include \"base/sssnic_api.h\"\n@@ -640,6 +641,10 @@ sssnic_ethdev_rx_queue_start(struct rte_eth_dev *ethdev, uint16_t queue_id)\n \tnetdev->num_started_rxqs++;\n \tethdev->data->rx_queue_state[queue_id] = RTE_ETH_QUEUE_STATE_STARTED;\n \n+\tret = sssnic_ethdev_rss_reta_reset(ethdev);\n+\tif (ret)\n+\t\tPMD_DRV_LOG(WARNING, \"Failed to reset RSS reta\");\n+\n \tPMD_DRV_LOG(DEBUG, \"port %u rxq %u started\", ethdev->data->port_id,\n \t\tqueue_id);\n \n@@ -673,6 +678,10 @@ sssnic_ethdev_rx_queue_stop(struct rte_eth_dev *ethdev, uint16_t queue_id)\n \tnetdev->num_started_rxqs--;\n \tethdev->data->rx_queue_state[queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;\n \n+\tret = sssnic_ethdev_rss_reta_reset(ethdev);\n+\tif (ret)\n+\t\tPMD_DRV_LOG(WARNING, \"Failed to reset RSS reta\");\n+\n \tPMD_DRV_LOG(DEBUG, \"port %u rxq %u stopped\", ethdev->data->port_id,\n \t\tqueue_id);\n \n@@ -704,6 +713,10 @@ sssnic_ethdev_rx_queue_all_start(struct rte_eth_dev *ethdev)\n \t\t\tethdev->data->port_id, qid);\n \t}\n \n+\tret = sssnic_ethdev_rss_reta_reset(ethdev);\n+\tif (ret)\n+\t\tPMD_DRV_LOG(WARNING, \"Failed to reset RSS reta\");\n+\n \tret = sssnic_port_enable_set(hw, true);\n \tif (ret) {\n \t\tPMD_DRV_LOG(ERR, \"Failed to enable port:%u\",\n",
    "prefixes": [
        "v2",
        "25/32"
    ]
}