get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 131065,
    "url": "https://patches.dpdk.org/api/patches/131065/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20230901093514.224824-20-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": "<20230901093514.224824-20-wanry@3snic.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20230901093514.224824-20-wanry@3snic.com",
    "date": "2023-09-01T09:35:01",
    "name": "[v4,19/32] net/sssnic: support dev start and stop",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "4a9108246a2e9bb6905d91fb92b911097811f4bf",
    "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/20230901093514.224824-20-wanry@3snic.com/mbox/",
    "series": [
        {
            "id": 29401,
            "url": "https://patches.dpdk.org/api/series/29401/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=29401",
            "date": "2023-09-01T09:34:43",
            "name": "Introduce sssnic PMD for 3SNIC's 9x0 serials Ethernet adapters",
            "version": 4,
            "mbox": "https://patches.dpdk.org/series/29401/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/131065/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/131065/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 105644221E;\n\tFri,  1 Sep 2023 11:38:30 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 8897A40A87;\n\tFri,  1 Sep 2023 11:36:12 +0200 (CEST)",
            "from VLXDG1SPAM1.ramaxel.com (email.ramaxel.com [221.4.138.186])\n by mails.dpdk.org (Postfix) with ESMTP id B2C5B402A3\n for <dev@dpdk.org>; Fri,  1 Sep 2023 11:36:05 +0200 (CEST)",
            "from V12DG1MBS03.ramaxel.local ([172.26.18.33])\n by VLXDG1SPAM1.ramaxel.com with ESMTP id 3819ZVPK069847;\n Fri, 1 Sep 2023 17:35:31 +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; Fri, 1 Sep 2023 17:35:30 +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 v4 19/32] net/sssnic: support dev start and stop",
        "Date": "Fri, 1 Sep 2023 17:35:01 +0800",
        "Message-ID": "<20230901093514.224824-20-wanry@3snic.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20230901093514.224824-1-wanry@3snic.com>",
        "References": "<20230901093514.224824-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 3819ZVPK069847",
        "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---\n drivers/net/sssnic/base/sssnic_api.c  | 508 ++++++++++++++++++++++++++\n drivers/net/sssnic/base/sssnic_api.h  | 257 +++++++++++++\n drivers/net/sssnic/base/sssnic_cmd.h  | 100 +++++\n drivers/net/sssnic/base/sssnic_misc.h |  34 ++\n drivers/net/sssnic/sssnic_ethdev.c    | 284 ++++++++++++++\n drivers/net/sssnic/sssnic_ethdev.h    |  21 ++\n drivers/net/sssnic/sssnic_ethdev_rx.c | 270 +++++++++++++-\n drivers/net/sssnic/sssnic_ethdev_rx.h |   8 +\n drivers/net/sssnic/sssnic_ethdev_tx.c | 163 +++++++++\n drivers/net/sssnic/sssnic_ethdev_tx.h |   6 +\n 10 files changed, 1650 insertions(+), 1 deletion(-)",
    "diff": "diff --git a/drivers/net/sssnic/base/sssnic_api.c b/drivers/net/sssnic/base/sssnic_api.c\nindex 3050d573bf..81020387bd 100644\n--- a/drivers/net/sssnic/base/sssnic_api.c\n+++ b/drivers/net/sssnic/base/sssnic_api.c\n@@ -13,6 +13,7 @@\n #include \"sssnic_mbox.h\"\n #include \"sssnic_ctrlq.h\"\n #include \"sssnic_api.h\"\n+#include \"sssnic_misc.h\"\n \n int\n sssnic_msix_attr_get(struct sssnic_hw *hw, uint16_t msix_idx,\n@@ -497,3 +498,510 @@ sssnic_rxq_flush(struct sssnic_hw *hw, uint16_t qid)\n \n \treturn 0;\n }\n+\n+static int\n+sssnic_rxtx_size_set(struct sssnic_hw *hw, uint16_t rx_size, uint16_t tx_size,\n+\tuint32_t flags)\n+{\n+\tint ret;\n+\tstruct sssnic_rxtx_size_set_cmd cmd;\n+\tstruct sssnic_msg msg;\n+\tuint32_t cmd_len;\n+\n+\tif (hw == NULL)\n+\t\treturn -EINVAL;\n+\n+\tmemset(&cmd, 0, sizeof(cmd));\n+\tcmd.function = SSSNIC_FUNC_IDX(hw);\n+\tcmd.rx_size = rx_size;\n+\tcmd.tx_size = tx_size;\n+\tcmd.flags = flags;\n+\tcmd_len = sizeof(cmd);\n+\tsssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len,\n+\t\tSSSNIC_SET_PORT_RXTX_SIZE_CMD, SSSNIC_MPU_FUNC_IDX,\n+\t\tSSSNIC_LAN_MODULE, SSSNIC_MSG_TYPE_REQ);\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_SET_PORT_RXTX_SIZE_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_rxtx_max_size_init(struct sssnic_hw *hw, uint16_t rx_size,\n+\tuint16_t tx_size)\n+{\n+\treturn sssnic_rxtx_size_set(hw, rx_size, tx_size,\n+\t\tSSSNIC_CMD_INIT_RXTX_SIZE_FLAG | SSSNIC_CMD_SET_RX_SIZE_FLAG |\n+\t\t\tSSSNIC_CMD_SET_TX_SIZE_FLAG);\n+}\n+\n+int\n+sssnic_tx_max_size_set(struct sssnic_hw *hw, uint16_t tx_size)\n+{\n+\treturn sssnic_rxtx_size_set(hw, 0, tx_size,\n+\t\tSSSNIC_CMD_SET_TX_SIZE_FLAG);\n+}\n+\n+int\n+sssnic_port_features_get(struct sssnic_hw *hw, uint64_t *features)\n+{\n+\tint ret;\n+\tstruct sssnic_port_feature_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.opcode = SSSNIC_CMD_OPCODE_GET;\n+\tcmd_len = sizeof(cmd);\n+\tsssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len, SSSNIC_PORT_FEATURE_CMD,\n+\t\tSSSNIC_MPU_FUNC_IDX, SSSNIC_LAN_MODULE, SSSNIC_MSG_TYPE_REQ);\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_PORT_FEATURE_CMD, len=%u, status=%u\",\n+\t\t\tcmd_len, cmd.common.status);\n+\t\treturn -EIO;\n+\t}\n+\n+\t*features = cmd.features;\n+\n+\treturn 0;\n+}\n+\n+int\n+sssnic_port_features_set(struct sssnic_hw *hw, uint64_t features)\n+{\n+\tint ret;\n+\tstruct sssnic_port_feature_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.features = features;\n+\tcmd.opcode = SSSNIC_CMD_OPCODE_SET;\n+\tcmd_len = sizeof(cmd);\n+\tsssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len, SSSNIC_PORT_FEATURE_CMD,\n+\t\tSSSNIC_MPU_FUNC_IDX, SSSNIC_LAN_MODULE, SSSNIC_MSG_TYPE_REQ);\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_PORT_FEATURE_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+#define SSSNIC_MAX_NUM_RXTXQ_CTX_SET_IN_BULK                                   \\\n+\t((SSSNIC_CTRLQ_MAX_CMD_DATA_LEN - SSSNIC_RXTXQ_CTX_CMD_INFO_LEN) /     \\\n+\t\tSSSNIC_RXTXQ_CTX_SIZE)\n+\n+static int\n+sssnic_rxtxq_ctx_set(struct sssnic_hw *hw, struct sssnic_rxtxq_ctx *q_ctx,\n+\tuint16_t q_start, enum sssnic_rxtxq_ctx_type type, uint16_t count)\n+{\n+\tstruct sssnic_ctrlq_cmd *cmd;\n+\tstruct sssnic_rxtxq_ctx_cmd *data;\n+\tstruct sssnic_rxtxq_ctx *ctx;\n+\tuint32_t num, i;\n+\tuint32_t max_num;\n+\tstruct sssnic_rxtxq_ctx_cmd_info cmd_info;\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+\tctx = (struct sssnic_rxtxq_ctx *)(data + 1);\n+\tmax_num = SSSNIC_MAX_NUM_RXTXQ_CTX_SET_IN_BULK;\n+\n+\twhile (count > 0) {\n+\t\tnum = RTE_MIN(count, max_num);\n+\n+\t\tcmd_info.q_count = num;\n+\t\tcmd_info.q_type = type;\n+\t\tcmd_info.q_start = q_start;\n+\t\tcmd_info.resvd0 = 0;\n+\t\tsssnic_mem_cpu_to_be_32(&cmd_info, &data->info,\n+\t\t\tsizeof(struct sssnic_rxtxq_ctx_cmd_info));\n+\n+\t\tfor (i = 0; i < num; i++)\n+\t\t\tsssnic_mem_cpu_to_be_32(q_ctx + i, ctx + i,\n+\t\t\t\tSSSNIC_RXTXQ_CTX_SIZE);\n+\n+\t\tcmd->data_len = sizeof(struct sssnic_rxtxq_ctx_cmd_info) +\n+\t\t\t\t(SSSNIC_RXTXQ_CTX_SIZE * num);\n+\t\tcmd->module = SSSNIC_LAN_MODULE;\n+\t\tcmd->cmd = SSSNIC_SET_RXTXQ_CTX_CMD;\n+\n+\t\trte_wmb();\n+\n+\t\tret = sssnic_ctrlq_cmd_exec(hw, cmd, 0);\n+\t\tif (ret != 0 || cmd->result != 0) {\n+\t\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\t\"Failed to execulte ctrlq command %s, ret=%d, result=%\" PRIu64,\n+\t\t\t\t\"SSSNIC_SET_RXTXQ_CTX_CMD\", ret, cmd->result);\n+\t\t\tret = -EIO;\n+\t\t\tgoto out;\n+\t\t}\n+\n+\t\tcount -= num;\n+\t\tq_ctx += num;\n+\t\tq_start += num;\n+\t}\n+\n+out:\n+\tsssnic_ctrlq_cmd_destroy(hw, cmd);\n+\treturn ret;\n+}\n+\n+int\n+sssnic_txq_ctx_set(struct sssnic_hw *hw, struct sssnic_txq_ctx *ctx,\n+\tuint16_t qstart, uint16_t count)\n+{\n+\treturn sssnic_rxtxq_ctx_set(hw, (struct sssnic_rxtxq_ctx *)ctx, qstart,\n+\t\tSSSNIC_TXQ_CTX, count);\n+}\n+\n+int\n+sssnic_rxq_ctx_set(struct sssnic_hw *hw, struct sssnic_rxq_ctx *ctx,\n+\tuint16_t qstart, uint16_t count)\n+{\n+\treturn sssnic_rxtxq_ctx_set(hw, (struct sssnic_rxtxq_ctx *)ctx, qstart,\n+\t\tSSSNIC_RXQ_CTX, count);\n+}\n+\n+static int\n+sssnic_offload_ctx_reset(struct sssnic_hw *hw, uint16_t q_start,\n+\tenum sssnic_rxtxq_ctx_type q_type, uint16_t count)\n+{\n+\tstruct sssnic_ctrlq_cmd cmd;\n+\tstruct sssnic_offload_ctx_reset_cmd data;\n+\tint ret;\n+\n+\tmemset(&cmd, 0, sizeof(cmd));\n+\tmemset(&data, 0, sizeof(data));\n+\n+\tdata.info.q_count = count;\n+\tdata.info.q_start = q_start;\n+\tdata.info.q_type = q_type;\n+\n+\tcmd.data = &data;\n+\tcmd.module = SSSNIC_LAN_MODULE;\n+\tcmd.data_len = sizeof(data);\n+\tcmd.cmd = SSSNIC_RESET_OFFLOAD_CTX_CMD;\n+\n+\tsssnic_mem_cpu_to_be_32(&data, &data, sizeof(data));\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_RESET_OFFLOAD_CTX_CMD\", ret, cmd.result);\n+\n+\t\treturn -EIO;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int\n+sssnic_rx_offload_ctx_reset(struct sssnic_hw *hw)\n+{\n+\treturn sssnic_offload_ctx_reset(hw, 0, SSSNIC_RXQ_CTX,\n+\t\tSSSNIC_MAX_NUM_RXQ(hw));\n+}\n+\n+int\n+sssnic_tx_offload_ctx_reset(struct sssnic_hw *hw)\n+{\n+\treturn sssnic_offload_ctx_reset(hw, 0, SSSNIC_TXQ_CTX,\n+\t\tSSSNIC_MAX_NUM_TXQ(hw));\n+}\n+\n+int\n+sssnic_rxtx_ctx_set(struct sssnic_hw *hw, bool lro_en, uint16_t rxq_depth,\n+\tuint16_t rx_buf, uint16_t txq_depth)\n+{\n+\tint ret;\n+\tstruct sssnic_msg msg;\n+\tstruct sssnic_root_ctx_cmd cmd;\n+\tuint32_t cmd_len;\n+\n+\tmemset(&cmd, 0, sizeof(cmd));\n+\tcmd.func_id = SSSNIC_FUNC_IDX(hw);\n+\tcmd.lro_enable = lro_en ? 1 : 0;\n+\tcmd.rx_buf = rx_buf;\n+\tcmd.rxq_depth = (uint16_t)rte_log2_u32(rxq_depth);\n+\tcmd.txq_depth = (uint16_t)rte_log2_u32(txq_depth);\n+\tcmd_len = sizeof(cmd);\n+\n+\tsssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len, SSSNIC_SET_ROOT_CTX_CMD,\n+\t\tSSSNIC_MPU_FUNC_IDX, SSSNIC_COMM_MODULE, SSSNIC_MSG_TYPE_REQ);\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+\tif (cmd_len == 0 || cmd.common.status != 0) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Bad response to SET_ROOT_CTX_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_port_tx_ci_attr_set(struct sssnic_hw *hw, uint16_t tx_qid,\n+\tuint8_t pending_limit, uint8_t coalescing_time, uint64_t dma_addr)\n+{\n+\tint ret;\n+\tstruct sssnic_port_tx_ci_attr_set_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.coalescing_time = coalescing_time;\n+\tcmd.pending_limit = pending_limit;\n+\tcmd.qid = tx_qid;\n+\tcmd.dma_addr = dma_addr >> 2;\n+\tcmd_len = sizeof(cmd);\n+\tsssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len,\n+\t\tSSSNIC_SET_PORT_TX_CI_ATTR_CMD, SSSNIC_MPU_FUNC_IDX,\n+\t\tSSSNIC_LAN_MODULE, SSSNIC_MSG_TYPE_REQ);\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_SET_PORT_TX_CI_ATTR_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_port_rx_mode_set(struct sssnic_hw *hw, uint32_t mode)\n+{\n+\tint ret;\n+\tstruct sssnic_port_rx_mode_set_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.mode = mode;\n+\tcmd_len = sizeof(cmd);\n+\tsssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len,\n+\t\tSSSNIC_SET_PORT_RX_MODE_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_SET_PORT_RX_MODE_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_lro_enable_set(struct sssnic_hw *hw, bool ipv4_en, bool ipv6_en,\n+\tuint8_t nb_lro_bufs)\n+{\n+\tint ret;\n+\tstruct sssnic_lro_cfg_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.ipv4_en = ipv4_en ? 1 : 0;\n+\tcmd.opcode = SSSNIC_CMD_OPCODE_SET;\n+\tcmd.ipv6_en = ipv6_en ? 1 : 0;\n+\tcmd.nb_bufs = nb_lro_bufs;\n+\tcmd_len = sizeof(cmd);\n+\tsssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len, SSSNIC_PORT_LRO_CFG_CMD,\n+\t\tSSSNIC_MPU_FUNC_IDX, SSSNIC_LAN_MODULE, SSSNIC_MSG_TYPE_REQ);\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_PORT_LRO_CFG_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_lro_timer_set(struct sssnic_hw *hw, uint32_t timer)\n+{\n+\tint ret;\n+\tstruct sssnic_lro_timer_cmd cmd;\n+\tstruct sssnic_msg msg;\n+\tuint32_t cmd_len;\n+\n+\tif (SSSNIC_FUNC_TYPE(hw) == SSSNIC_FUNC_TYPE_VF)\n+\t\treturn 0;\n+\n+\tmemset(&cmd, 0, sizeof(cmd));\n+\tcmd.opcode = SSSNIC_CMD_OPCODE_SET;\n+\tcmd.timer = timer;\n+\tcmd_len = sizeof(cmd);\n+\tsssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len,\n+\t\tSSSNIC_PORT_LRO_TIMER_CMD, SSSNIC_MPU_FUNC_IDX,\n+\t\tSSSNIC_LAN_MODULE, SSSNIC_MSG_TYPE_REQ);\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_PORT_LRO_TIMER_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_vlan_filter_enable_set(struct sssnic_hw *hw, bool state)\n+{\n+\tint ret;\n+\tstruct sssnic_vlan_filter_enable_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.state = state ? 1 : 0;\n+\tcmd_len = sizeof(cmd);\n+\tsssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len,\n+\t\tSSSNIC_ENABLE_PORT_VLAN_FILTER_CMD, SSSNIC_MPU_FUNC_IDX,\n+\t\tSSSNIC_LAN_MODULE, SSSNIC_MSG_TYPE_REQ);\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_PORT_VLAN_FILTER_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_vlan_strip_enable_set(struct sssnic_hw *hw, bool state)\n+{\n+\tint ret;\n+\tstruct sssnic_vlan_strip_enable_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.state = state ? 1 : 0;\n+\tcmd_len = sizeof(cmd);\n+\tsssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len,\n+\t\tSSSNIC_ENABLE_PORT_VLAN_STRIP_CMD, SSSNIC_MPU_FUNC_IDX,\n+\t\tSSSNIC_LAN_MODULE, SSSNIC_MSG_TYPE_REQ);\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_PORT_VLAN_STRIP_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_port_resource_clean(struct sssnic_hw *hw)\n+{\n+\tint ret;\n+\tstruct sssnic_port_resource_clean_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+\tsssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len,\n+\t\tSSSNIC_CLEAN_PORT_RES_CMD, SSSNIC_MPU_FUNC_IDX,\n+\t\tSSSNIC_LAN_MODULE, SSSNIC_MSG_TYPE_REQ);\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_CLEAN_PORT_RES_CMD, len=%u, status=%u\",\n+\t\t\tcmd_len, cmd.common.status);\n+\t\treturn -EIO;\n+\t}\n+\n+\treturn 0;\n+}\ndiff --git a/drivers/net/sssnic/base/sssnic_api.h b/drivers/net/sssnic/base/sssnic_api.h\nindex 29962aabf8..49336f70cf 100644\n--- a/drivers/net/sssnic/base/sssnic_api.h\n+++ b/drivers/net/sssnic/base/sssnic_api.h\n@@ -32,6 +32,241 @@ struct sssnic_netif_link_info {\n \tuint8_t fec;\n };\n \n+struct sssnic_rxq_ctx {\n+\tunion {\n+\t\tuint32_t dword0;\n+\t\tstruct {\n+\t\t\t/* producer index of workq */\n+\t\t\tuint32_t pi : 16;\n+\t\t\t/* consumer index of workq */\n+\t\t\tuint32_t ci : 16;\n+\t\t};\n+\t};\n+\n+\tunion {\n+\t\tuint32_t dword1;\n+\t\tstruct {\n+\t\t\tuint32_t dw1_resvd0 : 21;\n+\t\t\tuint32_t msix_id : 10;\n+\t\t\tuint32_t intr_dis : 1;\n+\t\t};\n+\t};\n+\n+\tunion {\n+\t\tuint32_t dword2;\n+\t\tstruct {\n+\t\t\tuint32_t wq_pfn_hi : 20;\n+\t\t\tuint32_t dw2_resvd0 : 8;\n+\t\t\t/* DPDK PMD always set to 2,\n+\t\t\t * represent 16 bytes workq entry\n+\t\t\t */\n+\t\t\tuint32_t wqe_type : 2;\n+\t\t\tuint32_t dw2_resvd1 : 1;\n+\t\t\t/* DPDK PMD always set to 1 */\n+\t\t\tuint32_t wq_owner : 1;\n+\t\t};\n+\t};\n+\n+\tunion {\n+\t\tuint32_t dword3;\n+\t\tuint32_t wq_pfn_lo;\n+\t};\n+\n+\tuint32_t dword4;\n+\tuint32_t dword5;\n+\tuint32_t dword6;\n+\n+\tunion {\n+\t\tuint32_t dword7;\n+\t\tstruct {\n+\t\t\tuint32_t dw7_resvd0 : 28;\n+\t\t\t/* PMD always set to 1, represent 32 bytes CQE*/\n+\t\t\tuint32_t rxd_len : 2;\n+\t\t\tuint32_t dw7_resvd1 : 2;\n+\t\t};\n+\t};\n+\n+\tunion {\n+\t\tuint32_t dword8;\n+\t\tstruct {\n+\t\t\tuint32_t pre_cache_thd : 14;\n+\t\t\tuint32_t pre_cache_max : 11;\n+\t\t\tuint32_t pre_cache_min : 7;\n+\t\t};\n+\t};\n+\n+\tunion {\n+\t\tuint32_t dword9;\n+\t\tstruct {\n+\t\t\tuint32_t pre_ci_hi : 4;\n+\t\t\tuint32_t pre_owner : 1;\n+\t\t\tuint32_t dw9_resvd0 : 27;\n+\t\t};\n+\t};\n+\n+\tunion {\n+\t\tuint32_t dword10;\n+\t\tstruct {\n+\t\t\tuint32_t pre_wq_pfn_hi : 20;\n+\t\t\tuint32_t pre_ci_lo : 12;\n+\t\t};\n+\t};\n+\n+\tunion {\n+\t\tuint32_t dword11;\n+\t\tuint32_t pre_wq_pfn_lo;\n+\t};\n+\n+\tunion {\n+\t\tuint32_t dword12;\n+\t\t/* high 32it of PI DMA  address */\n+\t\tuint32_t pi_addr_hi;\n+\t};\n+\n+\tunion {\n+\t\tuint32_t dword13;\n+\t\t/* low 32it of PI DMA  address */\n+\t\tuint32_t pi_addr_lo;\n+\t};\n+\n+\tunion {\n+\t\tuint32_t dword14;\n+\t\tstruct {\n+\t\t\tuint32_t wq_blk_pfn_hi : 23;\n+\t\t\tuint32_t dw14_resvd0 : 9;\n+\t\t};\n+\t};\n+\n+\tunion {\n+\t\tuint32_t dword15;\n+\t\tuint32_t wq_blk_pfn_lo;\n+\t};\n+};\n+\n+struct sssnic_txq_ctx {\n+\tunion {\n+\t\tuint32_t dword0;\n+\t\tstruct {\n+\t\t\tuint32_t pi : 16;\n+\t\t\tuint32_t ci : 16;\n+\t\t};\n+\t};\n+\n+\tunion {\n+\t\tuint32_t dword1;\n+\t\tstruct {\n+\t\t\tuint32_t sp : 1;\n+\t\t\tuint32_t drop : 1;\n+\t\t\tuint32_t dw_resvd0 : 30;\n+\t\t};\n+\t};\n+\n+\tunion {\n+\t\tuint32_t dword2;\n+\t\tstruct {\n+\t\t\tuint32_t wq_pfn_hi : 20;\n+\t\t\tuint32_t dw2_resvd0 : 3;\n+\t\t\tuint32_t wq_owner : 1;\n+\t\t\tuint32_t dw2_resvd1 : 8;\n+\t\t};\n+\t};\n+\n+\tunion {\n+\t\tuint32_t dword3;\n+\t\tuint32_t wq_pfn_lo;\n+\t};\n+\n+\tuint32_t dword4;\n+\n+\tunion {\n+\t\tuint32_t dword5;\n+\t\tstruct {\n+\t\t\tuint32_t drop_on_thd : 16;\n+\t\t\tuint32_t drop_off_thd : 16;\n+\t\t};\n+\t};\n+\tunion {\n+\t\tuint32_t dword6;\n+\t\tstruct {\n+\t\t\tuint32_t qid : 13;\n+\t\t\tuint32_t dw6_resvd0 : 19;\n+\t\t};\n+\t};\n+\n+\tunion {\n+\t\tuint32_t dword7;\n+\t\tstruct {\n+\t\t\tuint32_t vlan_tag : 16;\n+\t\t\tuint32_t vlan_type : 3;\n+\t\t\tuint32_t insert_mode : 2;\n+\t\t\tuint32_t dw7_resvd0 : 2;\n+\t\t\tuint32_t ceq_en : 1;\n+\t\t\tuint32_t dw7_resvd1 : 8;\n+\t\t};\n+\t};\n+\n+\tunion {\n+\t\tuint32_t dword8;\n+\t\tstruct {\n+\t\t\tuint32_t pre_cache_thd : 14;\n+\t\t\tuint32_t pre_cache_max : 11;\n+\t\t\tuint32_t pre_cache_min : 7;\n+\t\t};\n+\t};\n+\n+\tunion {\n+\t\tuint32_t dword9;\n+\t\tstruct {\n+\t\t\tuint32_t pre_ci_hi : 4;\n+\t\t\tuint32_t pre_owner : 1;\n+\t\t\tuint32_t dw9_resvd0 : 27;\n+\t\t};\n+\t};\n+\n+\tunion {\n+\t\tuint32_t dword10;\n+\t\tstruct {\n+\t\t\tuint32_t pre_wq_pfn_hi : 20;\n+\t\t\tuint32_t pre_ci_lo : 12;\n+\t\t};\n+\t};\n+\n+\tunion {\n+\t\tuint32_t dword11;\n+\t\tuint32_t pre_wq_pfn_lo;\n+\t};\n+\n+\tuint32_t dword12;\n+\tuint32_t dword13;\n+\n+\tunion {\n+\t\tuint32_t dword14;\n+\t\tstruct {\n+\t\t\tuint32_t wq_blk_pfn_hi : 23;\n+\t\t\tuint32_t dw14_resvd0 : 9;\n+\t\t};\n+\t};\n+\n+\tunion {\n+\t\tuint32_t dword15;\n+\t\tuint32_t wq_blk_pfn_lo;\n+\t};\n+};\n+\n+enum sssnic_rxtxq_ctx_type {\n+\tSSSNIC_TXQ_CTX,\n+\tSSSNIC_RXQ_CTX,\n+};\n+\n+struct sssnic_rxtxq_ctx {\n+\tunion {\n+\t\tstruct sssnic_rxq_ctx rxq;\n+\t\tstruct sssnic_txq_ctx txq;\n+\t};\n+};\n+\n+#define SSSNIC_RXTXQ_CTX_SIZE (sizeof(struct sssnic_rxtxq_ctx))\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@@ -47,5 +282,27 @@ int sssnic_netif_link_info_get(struct sssnic_hw *hw,\n int sssnic_netif_enable_set(struct sssnic_hw *hw, uint8_t state);\n int sssnic_port_enable_set(struct sssnic_hw *hw, bool state);\n int sssnic_rxq_flush(struct sssnic_hw *hw, uint16_t qid);\n+int sssnic_rxtx_max_size_init(struct sssnic_hw *hw, uint16_t rx_size,\n+\tuint16_t tx_size);\n+int sssnic_tx_max_size_set(struct sssnic_hw *hw, uint16_t tx_size);\n+int sssnic_port_features_get(struct sssnic_hw *hw, uint64_t *features);\n+int sssnic_port_features_set(struct sssnic_hw *hw, uint64_t features);\n+int sssnic_txq_ctx_set(struct sssnic_hw *hw, struct sssnic_txq_ctx *ctx,\n+\tuint16_t qstart, uint16_t count);\n+int sssnic_rxq_ctx_set(struct sssnic_hw *hw, struct sssnic_rxq_ctx *ctx,\n+\tuint16_t qstart, uint16_t count);\n+int sssnic_rx_offload_ctx_reset(struct sssnic_hw *hw);\n+int sssnic_tx_offload_ctx_reset(struct sssnic_hw *hw);\n+int sssnic_rxtx_ctx_set(struct sssnic_hw *hw, bool lro_en, uint16_t rxq_depth,\n+\tuint16_t rx_buf, uint16_t txq_depth);\n+int sssnic_port_tx_ci_attr_set(struct sssnic_hw *hw, uint16_t tx_qid,\n+\tuint8_t pending_limit, uint8_t coalescing_time, uint64_t dma_addr);\n+int sssnic_port_rx_mode_set(struct sssnic_hw *hw, uint32_t mode);\n+int sssnic_lro_enable_set(struct sssnic_hw *hw, bool ipv4_en, bool ipv6_en,\n+\tuint8_t nb_lro_bufs);\n+int sssnic_lro_timer_set(struct sssnic_hw *hw, uint32_t timer);\n+int sssnic_vlan_filter_enable_set(struct sssnic_hw *hw, bool state);\n+int sssnic_vlan_strip_enable_set(struct sssnic_hw *hw, bool state);\n+int sssnic_port_resource_clean(struct sssnic_hw *hw);\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 6364058d36..e89719b0de 100644\n--- a/drivers/net/sssnic/base/sssnic_cmd.h\n+++ b/drivers/net/sssnic/base/sssnic_cmd.h\n@@ -236,4 +236,104 @@ struct sssnic_rxq_flush_cmd {\n \t};\n };\n \n+#define SSSNIC_CMD_INIT_RXTX_SIZE_FLAG (RTE_BIT32(0))\n+#define SSSNIC_CMD_SET_RX_SIZE_FLAG (RTE_BIT32(1))\n+#define SSSNIC_CMD_SET_TX_SIZE_FLAG (RTE_BIT32(2))\n+\n+struct sssnic_rxtx_size_set_cmd {\n+\tstruct sssnic_cmd_common common;\n+\tuint16_t function;\n+\tuint16_t resvd0;\n+\tuint32_t flags;\n+\tuint16_t rx_size;\n+\tuint16_t tx_size;\n+\tuint32_t resvd1[9];\n+};\n+\n+struct sssnic_port_feature_cmd {\n+\tstruct sssnic_cmd_common common;\n+\tuint16_t function;\n+\tuint8_t opcode;\n+\tuint8_t resvd0;\n+\tuint64_t features;\n+\tuint64_t resvd1[3];\n+};\n+\n+struct sssnic_rxtxq_ctx_cmd_info {\n+\tuint16_t q_count;\n+\tuint16_t q_type;\n+\tuint16_t q_start;\n+\tuint16_t resvd0;\n+};\n+\n+#define SSSNIC_RXTXQ_CTX_CMD_INFO_LEN (sizeof(struct sssnic_rxtxq_ctx_cmd_info))\n+\n+struct sssnic_rxtxq_ctx_cmd {\n+\tstruct sssnic_rxtxq_ctx_cmd_info info;\n+\tuint32_t ctx[0];\n+};\n+\n+struct sssnic_offload_ctx_reset_cmd {\n+\tstruct sssnic_rxtxq_ctx_cmd_info info;\n+\tuint32_t resvd;\n+};\n+\n+struct sssnic_port_tx_ci_attr_set_cmd {\n+\tstruct sssnic_cmd_common common;\n+\tuint16_t function;\n+\tuint8_t resvd0;\n+\tuint8_t pending_limit;\n+\tuint8_t coalescing_time;\n+\tuint8_t resvd1;\n+\tuint16_t resvd2;\n+\tuint16_t qid;\n+\t/* ci DMA address right shift 2 */\n+\tuint64_t dma_addr;\n+};\n+\n+struct sssnic_port_rx_mode_set_cmd {\n+\tstruct sssnic_cmd_common common;\n+\tuint16_t function;\n+\tuint16_t resvd;\n+\tuint32_t mode;\n+};\n+\n+struct sssnic_lro_cfg_cmd {\n+\tstruct sssnic_cmd_common common;\n+\tuint16_t function;\n+\tuint8_t opcode;\n+\tuint8_t resvd0;\n+\tuint8_t ipv4_en;\n+\tuint8_t ipv6_en;\n+\tuint8_t nb_bufs;\n+\tuint8_t resvd1[13];\n+};\n+\n+struct sssnic_lro_timer_cmd {\n+\tstruct sssnic_cmd_common common;\n+\tuint8_t opcode;\n+\tuint8_t resvd[3];\n+\tuint32_t timer;\n+};\n+\n+struct sssnic_vlan_filter_enable_cmd {\n+\tstruct sssnic_cmd_common common;\n+\tuint16_t function;\n+\tuint16_t resvd;\n+\tuint32_t state; /* 0: disabled 1: enabled */\n+};\n+\n+struct sssnic_vlan_strip_enable_cmd {\n+\tstruct sssnic_cmd_common common;\n+\tuint16_t function;\n+\tuint8_t state; /* 0: disabled 1: enabled */\n+\tuint8_t resvd[5];\n+};\n+\n+struct sssnic_port_resource_clean_cmd {\n+\tstruct sssnic_cmd_common common;\n+\tuint16_t function;\n+\tuint16_t resvd;\n+};\n+\n #endif /* _SSSNIC_CMD_H_ */\ndiff --git a/drivers/net/sssnic/base/sssnic_misc.h b/drivers/net/sssnic/base/sssnic_misc.h\nindex ac1bbd9c73..e30691caef 100644\n--- a/drivers/net/sssnic/base/sssnic_misc.h\n+++ b/drivers/net/sssnic/base/sssnic_misc.h\n@@ -8,4 +8,38 @@\n #define SSSNIC_LOWER_32_BITS(x) ((uint32_t)(x))\n #define SSSNIC_UPPER_32_BITS(x) ((uint32_t)(((x) >> 16) >> 16))\n \n+static inline void\n+sssnic_mem_cpu_to_be_32(void *in, void *out, int size)\n+{\n+\tuint32_t i;\n+\tuint32_t num;\n+\tuint32_t *data_in = (uint32_t *)in;\n+\tuint32_t *data_out = (uint32_t *)out;\n+\n+\tnum = size / sizeof(uint32_t);\n+\n+\tfor (i = 0; i < num; i++) {\n+\t\t*data_out = rte_cpu_to_be_32(*data_in);\n+\t\tdata_in++;\n+\t\tdata_out++;\n+\t}\n+}\n+\n+static inline void\n+sssnic_mem_be_to_cpu_32(void *in, void *out, int size)\n+{\n+\tuint32_t i;\n+\tuint32_t num;\n+\tuint32_t *data_in = (uint32_t *)in;\n+\tuint32_t *data_out = (uint32_t *)out;\n+\n+\tnum = size / sizeof(uint32_t);\n+\n+\tfor (i = 0; i < num; i++) {\n+\t\t*data_out = rte_be_to_cpu_32(*data_in);\n+\t\tdata_in++;\n+\t\tdata_out++;\n+\t}\n+}\n+\n #endif /* _SSSNIC_MISC_H_ */\ndiff --git a/drivers/net/sssnic/sssnic_ethdev.c b/drivers/net/sssnic/sssnic_ethdev.c\nindex 35bb26a0b1..8201a1e3c4 100644\n--- a/drivers/net/sssnic/sssnic_ethdev.c\n+++ b/drivers/net/sssnic/sssnic_ethdev.c\n@@ -344,7 +344,287 @@ sssnic_ethdev_release(struct rte_eth_dev *ethdev)\n \trte_free(hw);\n }\n \n+static int\n+sssnic_ethdev_rxtx_max_size_init(struct rte_eth_dev *ethdev)\n+{\n+\tint ret;\n+\tstruct sssnic_netdev *netdev = SSSNIC_ETHDEV_PRIVATE(ethdev);\n+\tstruct sssnic_hw *hw = SSSNIC_ETHDEV_TO_HW(ethdev);\n+\n+\tnetdev->max_rx_size = sssnic_ethdev_rx_max_size_determine(ethdev);\n+\n+\tret = sssnic_rxtx_max_size_init(hw, netdev->max_rx_size, 0x3fff);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to initialize max rx and tx size\");\n+\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+sssnic_ethdev_features_setup(struct rte_eth_dev *ethdev)\n+{\n+\tstruct sssnic_hw *hw = SSSNIC_ETHDEV_TO_HW(ethdev);\n+\tuint64_t features;\n+\tint ret;\n+\n+\tret = sssnic_port_features_get(hw, &features);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to get features\");\n+\t\treturn ret;\n+\t}\n+\n+\tfeatures &= SSSNIC_ETHDEV_DEFAULT_FEATURES;\n+\n+\tret = sssnic_port_features_set(hw, features);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to set features to %\" PRIx64,\n+\t\t\tfeatures);\n+\t\treturn ret;\n+\t}\n+\n+\tPMD_DRV_LOG(DEBUG, \"Set features to %\" PRIx64, features);\n+\n+\treturn 0;\n+}\n+\n+static int\n+sssnic_ethdev_queues_ctx_setup(struct rte_eth_dev *ethdev)\n+{\n+\tint ret;\n+\n+\tret = sssnic_ethdev_tx_queues_ctx_init(ethdev);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to initialize tx queues context\");\n+\t\treturn ret;\n+\t}\n+\n+\tret = sssnic_ethdev_rx_queues_ctx_init(ethdev);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to initialize rx queues context\");\n+\t\treturn ret;\n+\t}\n+\n+\tret = sssnic_ethdev_rx_offload_ctx_reset(ethdev);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to initialize rx offload context\");\n+\t\treturn ret;\n+\t}\n+\n+\tret = sssnic_ethdev_tx_offload_ctx_reset(ethdev);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to initialize tx offload context\");\n+\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+sssnic_ethdev_rxtx_ctx_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+\tuint16_t rxq_depth;\n+\tuint16_t txq_depth;\n+\tuint16_t rx_buf_idx;\n+\tint ret;\n+\n+\t/* queue 0 as default depth */\n+\trxq_depth = sssnic_ethdev_rx_queue_depth_get(ethdev, 0);\n+\trxq_depth = rxq_depth << 1;\n+\ttxq_depth = sssnic_ethdev_tx_queue_depth_get(ethdev, 0);\n+\n+\trx_buf_idx = sssnic_ethdev_rx_buf_size_index_get(netdev->max_rx_size);\n+\n+\tret = sssnic_rxtx_ctx_set(hw, true, rxq_depth, rx_buf_idx, txq_depth);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to set rxtx context\");\n+\t\treturn ret;\n+\t}\n+\n+\tPMD_DRV_LOG(INFO,\n+\t\t\"Setup rxq_depth: %u, max_rx_size: %u, rx_buf_idx: %u, txq_depth: %u\",\n+\t\trxq_depth >> 1, netdev->max_rx_size, rx_buf_idx, txq_depth);\n+\n+\treturn 0;\n+}\n+\n+static void\n+sssnic_ethdev_rxtx_ctx_clean(struct rte_eth_dev *ethdev)\n+{\n+\tsssnic_rxtx_ctx_set(SSSNIC_ETHDEV_TO_HW(ethdev), 0, 0, 0, 0);\n+}\n+\n+static int\n+sssnic_ethdev_resource_clean(struct rte_eth_dev *ethdev)\n+{\n+\treturn sssnic_port_resource_clean(SSSNIC_ETHDEV_TO_HW(ethdev));\n+}\n+\n+static int\n+sssnic_ethdev_start(struct rte_eth_dev *ethdev)\n+{\n+\tint ret;\n+\n+\t/* disable link event */\n+\tsssnic_ethdev_link_intr_disable(ethdev);\n+\n+\t/* Allocate rx intr vec */\n+\tret = sssnic_ethdev_rx_intr_init(ethdev);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to initialize rx initr of port %u\",\n+\t\t\tethdev->data->port_id);\n+\t\tgoto link_intr_enable;\n+\t}\n+\n+\t/* Initialize rx and tx max size */\n+\tret = sssnic_ethdev_rxtx_max_size_init(ethdev);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Failed to initialize rxtx max size of port %u\",\n+\t\t\tethdev->data->port_id);\n+\t\tgoto rx_intr_shutdown;\n+\t}\n+\n+\t/* Setup default features for port */\n+\tret = sssnic_ethdev_features_setup(ethdev);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to setup features\");\n+\t\tgoto rx_intr_shutdown;\n+\t}\n+\n+\t/* Setup txqs and rxqs context */\n+\tret = sssnic_ethdev_queues_ctx_setup(ethdev);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to setup queues context\");\n+\t\tgoto rx_intr_shutdown;\n+\t}\n+\n+\t/* Setup tx and rx root context */\n+\tret = sssnic_ethdev_rxtx_ctx_setup(ethdev);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to setup rxtx context\");\n+\t\tgoto rx_intr_shutdown;\n+\t}\n+\n+\t/* Initialize tx ci attributes */\n+\tret = sssnic_ethdev_tx_ci_attr_init(ethdev);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to initialize tx ci attributes\");\n+\t\tgoto rxtx_ctx_clean;\n+\t}\n+\n+\t/* Set MTU */\n+\tret = sssnic_ethdev_tx_max_size_set(ethdev, ethdev->data->mtu);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to set tx max size to %u\",\n+\t\t\tethdev->data->mtu);\n+\t\tgoto rxtx_ctx_clean;\n+\t}\n+\n+\t/* init rx mode */\n+\tret = sssnic_ethdev_rx_mode_set(ethdev, SSSNIC_ETHDEV_DEF_RX_MODE);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to set rx mode to %x\",\n+\t\t\tSSSNIC_ETHDEV_DEF_RX_MODE);\n+\t\tgoto rxtx_ctx_clean;\n+\t}\n+\n+\t/* setup rx offload */\n+\tret = sssnic_ethdev_rx_offload_setup(ethdev);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to setup rx offload\");\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+\t\tPMD_DRV_LOG(ERR, \"Failed to start all rx queues\");\n+\t\tgoto clean_port_res;\n+\t}\n+\n+\t/* start all tx queues */\n+\tsssnic_ethdev_tx_queue_all_start(ethdev);\n+\n+\t/* enable link event */\n+\tsssnic_ethdev_link_intr_enable(ethdev);\n+\n+\t/* set port link up */\n+\tret = sssnic_ethdev_set_link_up(ethdev);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to set port link up\");\n+\t\tgoto stop_queues;\n+\t}\n+\n+\tPMD_DRV_LOG(INFO, \"Port %u is started\", ethdev->data->port_id);\n+\n+\treturn 0;\n+\n+stop_queues:\n+\tsssnic_ethdev_tx_queue_all_stop(ethdev);\n+\tsssnic_ethdev_rx_queue_all_stop(ethdev);\n+clean_port_res:\n+\tsssnic_ethdev_resource_clean(ethdev);\n+rx_mode_reset:\n+\tsssnic_ethdev_rx_mode_set(ethdev, SSSNIC_ETHDEV_RX_MODE_NONE);\n+rxtx_ctx_clean:\n+\tsssnic_ethdev_rxtx_ctx_clean(ethdev);\n+rx_intr_shutdown:\n+\tsssnic_ethdev_rx_intr_shutdown(ethdev);\n+link_intr_enable:\n+\tsssnic_ethdev_link_intr_enable(ethdev);\n+\treturn ret;\n+}\n+\n+static int\n+sssnic_ethdev_stop(struct rte_eth_dev *ethdev)\n+{\n+\tstruct rte_eth_link linkstatus = { 0 };\n+\tint ret;\n+\n+\t/* disable link event */\n+\tsssnic_ethdev_link_intr_disable(ethdev);\n+\n+\t/* set link down */\n+\tret = sssnic_ethdev_set_link_down(ethdev);\n+\tif (ret != 0)\n+\t\tPMD_DRV_LOG(WARNING, \"Failed to set port %u link down\",\n+\t\t\tethdev->data->port_id);\n+\n+\trte_eth_linkstatus_set(ethdev, &linkstatus);\n+\n+\t/* wait for hw to stop rx and tx packet */\n+\trte_delay_ms(100);\n+\n+\t/* stop all tx queues */\n+\tsssnic_ethdev_tx_queue_all_stop(ethdev);\n+\n+\t/* stop all rx queues */\n+\tsssnic_ethdev_rx_queue_all_stop(ethdev);\n+\n+\t/* clean hardware resource */\n+\tsssnic_ethdev_resource_clean(ethdev);\n+\n+\t/* shut down rx queue interrupt */\n+\tsssnic_ethdev_rx_intr_shutdown(ethdev);\n+\n+\t/* clean rxtx context */\n+\tsssnic_ethdev_rxtx_ctx_clean(ethdev);\n+\n+\t/* enable link event */\n+\tsssnic_ethdev_link_intr_enable(ethdev);\n+\n+\tPMD_DRV_LOG(INFO, \"Port %u is stopped\", ethdev->data->port_id);\n+\n+\treturn 0;\n+}\n+\n static const struct eth_dev_ops sssnic_ethdev_ops = {\n+\t.dev_start = sssnic_ethdev_start,\n+\t.dev_stop = sssnic_ethdev_stop,\n \t.dev_set_link_up = sssnic_ethdev_set_link_up,\n \t.dev_set_link_down = sssnic_ethdev_set_link_down,\n \t.link_update = sssnic_ethdev_link_update,\n@@ -428,6 +708,10 @@ sssnic_ethdev_uninit(struct rte_eth_dev *ethdev)\n \tif (ethdev->state == RTE_ETH_DEV_UNUSED)\n \t\treturn 0;\n \n+\t/* stop ethdev first */\n+\tif (ethdev->data->dev_started)\n+\t\tsssnic_ethdev_stop(ethdev);\n+\n \tsssnic_ethdev_release(ethdev);\n \n \treturn 0;\ndiff --git a/drivers/net/sssnic/sssnic_ethdev.h b/drivers/net/sssnic/sssnic_ethdev.h\nindex 38e6dc0d62..1f1e991780 100644\n--- a/drivers/net/sssnic/sssnic_ethdev.h\n+++ b/drivers/net/sssnic/sssnic_ethdev.h\n@@ -59,6 +59,25 @@\n #define SSSNIC_ETHDEV_DEF_RX_FREE_THRESH 32\n #define SSSNIC_ETHDEV_DEF_TX_FREE_THRESH 32\n \n+#define SSSNIC_ETHDEV_DEFAULT_FEATURES 0x3fff\n+\n+enum sssnic_ethdev_rx_mode {\n+\tSSSNIC_ETHDEV_RX_MODE_NONE = 0,\n+\tSSSNIC_ETHDEV_RX_UCAST = RTE_BIT32(0),\n+\tSSSNIC_ETHDEV_RX_MCAST = RTE_BIT32(1),\n+\tSSSNIC_ETHDEV_RX_BCAST = RTE_BIT32(2),\n+\tSSSNIC_ETHDEV_RX_ALL_MCAST = RTE_BIT32(3),\n+\tSSSNIC_ETHDEV_RX_PROMISC = RTE_BIT32(4),\n+\tSSSNIC_ETHDEV_RX_MODE_INVAL = RTE_BIT32(5),\n+};\n+\n+#define SSSNIC_ETHDEV_DEF_RX_MODE                                              \\\n+\t(SSSNIC_ETHDEV_RX_UCAST | SSSNIC_ETHDEV_RX_MCAST |                     \\\n+\t\tSSSNIC_ETHDEV_RX_BCAST)\n+\n+#define SSSNIC_ETHDEV_LRO_BUF_SIZE 1024\n+#define SSSNIC_ETHDEV_LRO_TIMER 16\n+\n struct sssnic_netdev {\n \tvoid *hw;\n \tstruct rte_ether_addr *mcast_addrs;\n@@ -67,6 +86,8 @@ struct sssnic_netdev {\n \tuint16_t max_num_rxq;\n \tuint16_t num_started_rxqs;\n \tuint16_t num_started_txqs;\n+\tuint16_t max_rx_size;\n+\tuint32_t rx_mode;\n };\n \n #define SSSNIC_ETHDEV_PRIVATE(eth_dev)                                         \\\ndiff --git a/drivers/net/sssnic/sssnic_ethdev_rx.c b/drivers/net/sssnic/sssnic_ethdev_rx.c\nindex 9c1b2f20d1..fd4975dfd5 100644\n--- a/drivers/net/sssnic/sssnic_ethdev_rx.c\n+++ b/drivers/net/sssnic/sssnic_ethdev_rx.c\n@@ -185,7 +185,7 @@ sssnic_ethdev_rxq_doorbell_ring(struct sssnic_ethdev_rxq *rxq, uint16_t pi)\n \tdb.qid = rxq->qid;\n \tdb.pi_hi = (hw_pi >> 8) & 0xff;\n \n-\tdb_addr = (uint64_t *)(rxq->doorbell + (hw_pi & 0xff));\n+\tdb_addr = ((uint64_t *)rxq->doorbell) + (hw_pi & 0xff);\n \n \trte_write64(db.u64, db_addr);\n }\n@@ -885,3 +885,271 @@ sssnic_ethdev_rx_intr_shutdown(struct rte_eth_dev *ethdev)\n \trte_intr_efd_disable(intr_handle);\n \trte_intr_vec_list_free(intr_handle);\n }\n+\n+uint16_t\n+sssnic_ethdev_rx_max_size_determine(struct rte_eth_dev *ethdev)\n+{\n+\tstruct sssnic_ethdev_rxq *rxq;\n+\tuint16_t max_size = 0;\n+\tuint16_t i;\n+\n+\tfor (i = 0; i < ethdev->data->nb_rx_queues; i++) {\n+\t\trxq = ethdev->data->rx_queues[i];\n+\t\tif (rxq->rx_buf_size > max_size)\n+\t\t\tmax_size = rxq->rx_buf_size;\n+\t}\n+\n+\treturn max_size;\n+}\n+\n+static void\n+sssnic_ethdev_rxq_ctx_build(struct sssnic_ethdev_rxq *rxq,\n+\tstruct sssnic_rxq_ctx *rxq_ctx)\n+{\n+\tuint16_t hw_ci, hw_pi;\n+\tuint64_t pfn;\n+\n+\thw_ci = sssnic_ethdev_rxq_ci_get(rxq) << 1;\n+\thw_pi = sssnic_ethdev_rxq_pi_get(rxq) << 1;\n+\n+\t/* dw0 */\n+\trxq_ctx->pi = hw_pi;\n+\trxq_ctx->ci = hw_ci;\n+\n+\t/* dw1 */\n+\trxq_ctx->msix_id = rxq->intr.msix_id;\n+\trxq_ctx->intr_dis = !rxq->intr.enable;\n+\n+\t/* workq buf phyaddress PFN, size = 4K */\n+\tpfn = SSSNIC_WORKQ_BUF_PHYADDR(rxq->workq) >> 12;\n+\n+\t/* dw2 */\n+\trxq_ctx->wq_pfn_hi = SSSNIC_UPPER_32_BITS(pfn);\n+\trxq_ctx->wqe_type = 2;\n+\trxq_ctx->wq_owner = 1;\n+\n+\t/* dw3 */\n+\trxq_ctx->wq_pfn_lo = SSSNIC_LOWER_32_BITS(pfn);\n+\n+\t/* dw4, dw5, dw6 are reserved */\n+\n+\t/* dw7 */\n+\trxq_ctx->rxd_len = 1;\n+\n+\t/* dw8 */\n+\trxq_ctx->pre_cache_thd = 256;\n+\trxq_ctx->pre_cache_max = 6;\n+\trxq_ctx->pre_cache_min = 1;\n+\n+\t/* dw9 */\n+\trxq_ctx->pre_ci_hi = (hw_ci >> 12) & 0xf;\n+\trxq_ctx->pre_owner = 1;\n+\n+\t/* dw10 */\n+\trxq_ctx->pre_wq_pfn_hi = SSSNIC_UPPER_32_BITS(pfn);\n+\trxq_ctx->pre_ci_lo = hw_ci & 0xfff;\n+\n+\t/* dw11 */\n+\trxq_ctx->pre_wq_pfn_lo = SSSNIC_LOWER_32_BITS(pfn);\n+\n+\t/* dw12 */\n+\trxq_ctx->pi_addr_hi = SSSNIC_UPPER_32_BITS(rxq->pi_mz->iova);\n+\n+\t/* dw13 */\n+\trxq_ctx->pi_addr_lo = SSSNIC_LOWER_32_BITS(rxq->pi_mz->iova);\n+\n+\t/* workq buf block PFN, size = 512B */\n+\tpfn = SSSNIC_WORKQ_BUF_PHYADDR(rxq->workq) >> 9;\n+\n+\t/* dw14 */\n+\trxq_ctx->wq_blk_pfn_hi = SSSNIC_UPPER_32_BITS(pfn);\n+\n+\t/* dw15 */\n+\trxq_ctx->wq_blk_pfn_lo = SSSNIC_LOWER_32_BITS(pfn);\n+}\n+\n+int\n+sssnic_ethdev_rx_queues_ctx_init(struct rte_eth_dev *ethdev)\n+{\n+\tstruct sssnic_hw *hw = SSSNIC_ETHDEV_TO_HW(ethdev);\n+\tstruct sssnic_ethdev_rxq *rxq;\n+\tstruct sssnic_rxq_ctx *qctx;\n+\tuint16_t qid, numq;\n+\tint ret;\n+\n+\tnumq = ethdev->data->nb_rx_queues;\n+\n+\tqctx = rte_zmalloc(NULL, numq * sizeof(struct sssnic_rxq_ctx), 0);\n+\tif (qctx == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to alloc memory for rxq ctx\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tfor (qid = 0; qid < numq; qid++) {\n+\t\trxq = ethdev->data->rx_queues[qid];\n+\n+\t\t/* reset ci and pi */\n+\t\tsssnic_workq_reset(rxq->workq);\n+\n+\t\tsssnic_ethdev_rxq_ctx_build(rxq, &qctx[qid]);\n+\t}\n+\n+\tret = sssnic_rxq_ctx_set(hw, qctx, 0, numq);\n+\trte_free(qctx);\n+\n+\treturn ret;\n+}\n+\n+int\n+sssnic_ethdev_rx_offload_ctx_reset(struct rte_eth_dev *ethdev)\n+{\n+\treturn sssnic_rx_offload_ctx_reset(SSSNIC_ETHDEV_TO_HW(ethdev));\n+}\n+\n+uint16_t\n+sssnic_ethdev_rx_queue_depth_get(struct rte_eth_dev *ethdev, uint16_t qid)\n+{\n+\tstruct sssnic_ethdev_rxq *rxq;\n+\n+\tif (qid >= ethdev->data->nb_rx_queues)\n+\t\treturn 0;\n+\n+\trxq = ethdev->data->rx_queues[qid];\n+\n+\treturn rxq->depth;\n+};\n+\n+uint32_t\n+sssnic_ethdev_rx_buf_size_index_get(uint16_t rx_buf_size)\n+{\n+\tuint32_t i;\n+\n+\tfor (i = 0; i < SSSNIC_ETHDEV_RX_BUF_SIZE_COUNT; i++) {\n+\t\tif (rx_buf_size == sssnic_ethdev_rx_buf_size_tbl[i])\n+\t\t\treturn i;\n+\t}\n+\n+\treturn SSSNIC_ETHDEV_DEF_RX_BUF_SIZE_IDX;\n+}\n+\n+int\n+sssnic_ethdev_rx_mode_set(struct rte_eth_dev *ethdev, uint32_t mode)\n+{\n+\tstruct sssnic_netdev *netdev = SSSNIC_ETHDEV_PRIVATE(ethdev);\n+\tint ret;\n+\n+\tret = sssnic_port_rx_mode_set(SSSNIC_ETHDEV_TO_HW(ethdev), mode);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tnetdev->rx_mode = mode;\n+\n+\tPMD_DRV_LOG(DEBUG, \"Set rx_mode to %x\", mode);\n+\n+\treturn 0;\n+}\n+\n+static int\n+sssnic_ethdev_lro_setup(struct rte_eth_dev *ethdev)\n+{\n+\tstruct sssnic_hw *hw = SSSNIC_ETHDEV_TO_HW(ethdev);\n+\tstruct rte_eth_conf *dev_conf = &ethdev->data->dev_conf;\n+\tbool enable;\n+\tuint8_t num_lro_bufs;\n+\tuint32_t max_lro_pkt_size;\n+\tuint32_t timer = SSSNIC_ETHDEV_LRO_TIMER;\n+\tint ret;\n+\n+\tif (dev_conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO)\n+\t\tenable = true;\n+\telse\n+\t\tenable = false;\n+\n+\tmax_lro_pkt_size = dev_conf->rxmode.max_lro_pkt_size;\n+\tnum_lro_bufs = max_lro_pkt_size / SSSNIC_ETHDEV_LRO_BUF_SIZE;\n+\n+\tif (num_lro_bufs == 0)\n+\t\tnum_lro_bufs = 1;\n+\n+\tret = sssnic_lro_enable_set(hw, enable, enable, num_lro_bufs);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to %s LRO\",\n+\t\t\tenable ? \"enable\" : \"disable\");\n+\t\treturn ret;\n+\t}\n+\n+\tret = sssnic_lro_timer_set(hw, timer);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to set lro timer to %u\", timer);\n+\t\treturn ret;\n+\t}\n+\n+\tPMD_DRV_LOG(INFO,\n+\t\t\"%s LRO, max_lro_pkt_size: %u, num_lro_bufs: %u, lro_timer: %u\",\n+\t\tenable ? \"Enabled\" : \"Disabled\", max_lro_pkt_size, num_lro_bufs,\n+\t\ttimer);\n+\n+\treturn 0;\n+}\n+\n+static int\n+sssnic_ethdev_rx_vlan_offload_setup(struct rte_eth_dev *ethdev)\n+{\n+\tstruct sssnic_hw *hw = SSSNIC_ETHDEV_TO_HW(ethdev);\n+\tstruct rte_eth_conf *dev_conf = &ethdev->data->dev_conf;\n+\tbool vlan_strip_en;\n+\tuint32_t vlan_filter_en;\n+\tint ret;\n+\n+\tif (dev_conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)\n+\t\tvlan_strip_en = true;\n+\telse\n+\t\tvlan_strip_en = false;\n+\n+\tret = sssnic_vlan_strip_enable_set(hw, vlan_strip_en);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to %s VLAN strip\",\n+\t\t\tvlan_strip_en ? \"enable\" : \"disable\");\n+\t\treturn ret;\n+\t}\n+\n+\tPMD_DRV_LOG(INFO, \"%s VLAN strip\",\n+\t\tvlan_strip_en ? \"Enabled\" : \"Disabled\");\n+\n+\tif (dev_conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER)\n+\t\tvlan_filter_en = true;\n+\telse\n+\t\tvlan_filter_en = false;\n+\n+\tret = sssnic_vlan_filter_enable_set(hw, vlan_filter_en);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to %s VLAN filter\",\n+\t\t\tvlan_filter_en ? \"enable\" : \"disable\");\n+\t\treturn ret;\n+\t}\n+\n+\tPMD_DRV_LOG(ERR, \"%s VLAN filter\",\n+\t\tvlan_filter_en ? \"Enabled\" : \"Disabled\");\n+\n+\treturn 0;\n+}\n+\n+int\n+sssnic_ethdev_rx_offload_setup(struct rte_eth_dev *ethdev)\n+{\n+\tint ret;\n+\n+\tret = sssnic_ethdev_lro_setup(ethdev);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to setup LRO\");\n+\t\treturn ret;\n+\t}\n+\n+\tret = sssnic_ethdev_rx_vlan_offload_setup(ethdev);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to setup rx vlan offload\");\n+\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\ndiff --git a/drivers/net/sssnic/sssnic_ethdev_rx.h b/drivers/net/sssnic/sssnic_ethdev_rx.h\nindex 77a116f4a5..f4b4545944 100644\n--- a/drivers/net/sssnic/sssnic_ethdev_rx.h\n+++ b/drivers/net/sssnic/sssnic_ethdev_rx.h\n@@ -30,5 +30,13 @@ int sssnic_ethdev_rx_queue_intr_disable(struct rte_eth_dev *ethdev,\n \tuint16_t qid);\n int sssnic_ethdev_rx_intr_init(struct rte_eth_dev *ethdev);\n void sssnic_ethdev_rx_intr_shutdown(struct rte_eth_dev *ethdev);\n+uint16_t sssnic_ethdev_rx_max_size_determine(struct rte_eth_dev *ethdev);\n+int sssnic_ethdev_rx_queues_ctx_init(struct rte_eth_dev *ethdev);\n+int sssnic_ethdev_rx_offload_ctx_reset(struct rte_eth_dev *ethdev);\n+uint16_t sssnic_ethdev_rx_queue_depth_get(struct rte_eth_dev *ethdev,\n+\tuint16_t qid);\n+uint32_t sssnic_ethdev_rx_buf_size_index_get(uint16_t rx_buf_size);\n+int sssnic_ethdev_rx_mode_set(struct rte_eth_dev *ethdev, uint32_t mode);\n+int sssnic_ethdev_rx_offload_setup(struct rte_eth_dev *ethdev);\n \n #endif\ndiff --git a/drivers/net/sssnic/sssnic_ethdev_tx.c b/drivers/net/sssnic/sssnic_ethdev_tx.c\nindex 47d7e3f343..b9c4f97cb3 100644\n--- a/drivers/net/sssnic/sssnic_ethdev_tx.c\n+++ b/drivers/net/sssnic/sssnic_ethdev_tx.c\n@@ -179,6 +179,9 @@ enum sssnic_ethdev_txq_entry_type {\n /* Doorbell offset 4096 */\n #define SSSNIC_ETHDEV_TXQ_DB_OFFSET 0x1000\n \n+#define SSSNIC_ETHDEV_TX_CI_DEF_COALESCING_TIME 16\n+#define SSSNIC_ETHDEV_TX_CI_DEF_PENDING_TIME 4\n+\n static inline uint16_t\n sssnic_ethdev_txq_num_used_entries(struct sssnic_ethdev_txq *txq)\n {\n@@ -507,3 +510,163 @@ sssnic_ethdev_tx_queue_all_stop(struct rte_eth_dev *ethdev)\n \tfor (qid = 0; qid < numq; qid++)\n \t\tsssnic_ethdev_tx_queue_stop(ethdev, qid);\n }\n+\n+static void\n+sssnic_ethdev_txq_ctx_build(struct sssnic_ethdev_txq *txq,\n+\tstruct sssnic_txq_ctx *qctx)\n+{\n+\tuint64_t pfn;\n+\n+\t/* dw0 */\n+\tqctx->pi = sssnic_ethdev_txq_pi_get(txq);\n+\tqctx->ci = sssnic_ethdev_txq_ci_get(txq);\n+\n+\t/* dw1 */\n+\tqctx->sp = 0;\n+\tqctx->drop = 0;\n+\n+\t/* workq buf phyaddress PFN */\n+\tpfn = SSSNIC_WORKQ_BUF_PHYADDR(txq->workq) >> 12;\n+\n+\t/* dw2 */\n+\tqctx->wq_pfn_hi = SSSNIC_UPPER_32_BITS(pfn);\n+\tqctx->wq_owner = 1;\n+\n+\t/* dw3 */\n+\tqctx->wq_pfn_lo = SSSNIC_LOWER_32_BITS(pfn);\n+\n+\t/* dw4 reserved */\n+\n+\t/* dw5 */\n+\tqctx->drop_on_thd = 0xffff;\n+\tqctx->drop_off_thd = 0;\n+\n+\t/* dw6 */\n+\tqctx->qid = txq->qid;\n+\n+\t/* dw7 */\n+\tqctx->insert_mode = 1;\n+\n+\t/* dw8 */\n+\tqctx->pre_cache_thd = 256;\n+\tqctx->pre_cache_max = 6;\n+\tqctx->pre_cache_min = 1;\n+\n+\t/* dw9 */\n+\tqctx->pre_ci_hi = sssnic_ethdev_txq_ci_get(txq) >> 12;\n+\tqctx->pre_owner = 1;\n+\n+\t/* dw10 */\n+\tqctx->pre_wq_pfn_hi = SSSNIC_UPPER_32_BITS(pfn);\n+\tqctx->pre_ci_lo = sssnic_ethdev_txq_ci_get(txq);\n+\n+\t/* dw11 */\n+\tqctx->pre_wq_pfn_lo = SSSNIC_LOWER_32_BITS(pfn);\n+\n+\t/* dw12,dw13 are reserved */\n+\n+\t/* workq buf block PFN */\n+\tpfn = SSSNIC_WORKQ_BUF_PHYADDR(txq->workq) >> 9;\n+\n+\t/* dw14 */\n+\tqctx->wq_blk_pfn_hi = SSSNIC_UPPER_32_BITS(pfn);\n+\n+\t/* dw15 */\n+\tqctx->wq_blk_pfn_lo = SSSNIC_LOWER_32_BITS(pfn);\n+}\n+\n+int\n+sssnic_ethdev_tx_queues_ctx_init(struct rte_eth_dev *ethdev)\n+{\n+\tstruct sssnic_hw *hw = SSSNIC_ETHDEV_TO_HW(ethdev);\n+\tstruct sssnic_ethdev_txq *txq;\n+\tstruct sssnic_txq_ctx *qctx;\n+\tuint16_t qid, numq;\n+\tint ret;\n+\n+\tnumq = ethdev->data->nb_tx_queues;\n+\n+\tqctx = rte_zmalloc(NULL, numq * sizeof(struct sssnic_txq_ctx), 0);\n+\tif (qctx == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to alloc memory for txq ctx\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tfor (qid = 0; qid < numq; qid++) {\n+\t\ttxq = ethdev->data->tx_queues[qid];\n+\n+\t\t/* reset ci and pi */\n+\t\tsssnic_workq_reset(txq->workq);\n+\n+\t\t*txq->hw_ci_addr = 0;\n+\t\ttxq->owner = 1;\n+\n+\t\tsssnic_ethdev_txq_ctx_build(txq, &qctx[qid]);\n+\t}\n+\n+\tret = sssnic_txq_ctx_set(hw, qctx, 0, numq);\n+\trte_free(qctx);\n+\n+\treturn ret;\n+}\n+\n+int\n+sssnic_ethdev_tx_offload_ctx_reset(struct rte_eth_dev *ethdev)\n+{\n+\treturn sssnic_tx_offload_ctx_reset(SSSNIC_ETHDEV_TO_HW(ethdev));\n+}\n+\n+uint16_t\n+sssnic_ethdev_tx_queue_depth_get(struct rte_eth_dev *ethdev, uint16_t qid)\n+{\n+\tstruct sssnic_ethdev_txq *txq;\n+\n+\tif (qid >= ethdev->data->nb_tx_queues)\n+\t\treturn 0;\n+\n+\ttxq = ethdev->data->tx_queues[qid];\n+\n+\treturn txq->depth;\n+}\n+\n+int\n+sssnic_ethdev_tx_ci_attr_init(struct rte_eth_dev *ethdev)\n+{\n+\tstruct sssnic_hw *hw = SSSNIC_ETHDEV_TO_HW(ethdev);\n+\tstruct sssnic_ethdev_txq *txq;\n+\tuint16_t i;\n+\tint ret;\n+\n+\tfor (i = 0; i < ethdev->data->nb_tx_queues; i++) {\n+\t\ttxq = ethdev->data->tx_queues[i];\n+\n+\t\tret = sssnic_port_tx_ci_attr_set(hw, i,\n+\t\t\tSSSNIC_ETHDEV_TX_CI_DEF_PENDING_TIME,\n+\t\t\tSSSNIC_ETHDEV_TX_CI_DEF_COALESCING_TIME,\n+\t\t\ttxq->ci_mz->iova);\n+\n+\t\tif (ret != 0) {\n+\t\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\t\"Failed to initialize tx ci attributes of queue %u\",\n+\t\t\t\ti);\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int\n+sssnic_ethdev_tx_max_size_set(struct rte_eth_dev *ethdev, uint16_t size)\n+{\n+\tstruct sssnic_hw *hw = SSSNIC_ETHDEV_TO_HW(ethdev);\n+\tint ret;\n+\n+\tret = sssnic_tx_max_size_set(hw, size);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tPMD_DRV_LOG(INFO, \"Set tx_max_size to %u\", size);\n+\n+\treturn 0;\n+};\ndiff --git a/drivers/net/sssnic/sssnic_ethdev_tx.h b/drivers/net/sssnic/sssnic_ethdev_tx.h\nindex 3de9e899a0..88ad82a055 100644\n--- a/drivers/net/sssnic/sssnic_ethdev_tx.h\n+++ b/drivers/net/sssnic/sssnic_ethdev_tx.h\n@@ -27,5 +27,11 @@ int sssnic_ethdev_tx_queue_start(struct rte_eth_dev *ethdev, uint16_t queue_id);\n int sssnic_ethdev_tx_queue_stop(struct rte_eth_dev *ethdev, uint16_t queue_id);\n int sssnic_ethdev_tx_queue_all_start(struct rte_eth_dev *ethdev);\n void sssnic_ethdev_tx_queue_all_stop(struct rte_eth_dev *ethdev);\n+int sssnic_ethdev_tx_queues_ctx_init(struct rte_eth_dev *ethdev);\n+int sssnic_ethdev_tx_offload_ctx_reset(struct rte_eth_dev *ethdev);\n+uint16_t sssnic_ethdev_tx_queue_depth_get(struct rte_eth_dev *ethdev,\n+\tuint16_t qid);\n+int sssnic_ethdev_tx_ci_attr_init(struct rte_eth_dev *ethdev);\n+int sssnic_ethdev_tx_max_size_set(struct rte_eth_dev *ethdev, uint16_t size);\n \n #endif /* _SSSNIC_ETHDEV_TX_H_ */\n",
    "prefixes": [
        "v4",
        "19/32"
    ]
}