get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 131107,
    "url": "https://patches.dpdk.org/api/patches/131107/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20230904045658.238185-8-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": "<20230904045658.238185-8-wanry@3snic.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20230904045658.238185-8-wanry@3snic.com",
    "date": "2023-09-04T04:56:33",
    "name": "[v5,07/32] net/sssnic/base: add mailbox support",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "32e0d53b074c7cf8c5ee0b84eceb972b9874e34d",
    "submitter": {
        "id": 3119,
        "url": "https://patches.dpdk.org/api/people/3119/?format=api",
        "name": "Renyong Wan",
        "email": "wanry@3snic.com"
    },
    "delegate": {
        "id": 319,
        "url": "https://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20230904045658.238185-8-wanry@3snic.com/mbox/",
    "series": [
        {
            "id": 29409,
            "url": "https://patches.dpdk.org/api/series/29409/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=29409",
            "date": "2023-09-04T04:56:26",
            "name": "Introduce sssnic PMD for 3SNIC's 9x0 serials Ethernet adapters",
            "version": 5,
            "mbox": "https://patches.dpdk.org/series/29409/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/131107/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/131107/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 E914E424E7;\n\tMon,  4 Sep 2023 06:58:27 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id DC5EB402D4;\n\tMon,  4 Sep 2023 06:57:38 +0200 (CEST)",
            "from VLXDG1SPAM1.ramaxel.com (email.ramaxel.com [221.4.138.186])\n by mails.dpdk.org (Postfix) with ESMTP id AAC36402E0\n for <dev@dpdk.org>; Mon,  4 Sep 2023 06:57:35 +0200 (CEST)",
            "from V12DG1MBS03.ramaxel.local ([172.26.18.33])\n by VLXDG1SPAM1.ramaxel.com with ESMTP id 3844vBQG054252;\n Mon, 4 Sep 2023 12:57:11 +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; Mon, 4 Sep 2023 12:57:10 +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 v5 07/32] net/sssnic/base: add mailbox support",
        "Date": "Mon, 4 Sep 2023 12:56:33 +0800",
        "Message-ID": "<20230904045658.238185-8-wanry@3snic.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20230904045658.238185-1-wanry@3snic.com>",
        "References": "<20230904045658.238185-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 3844vBQG054252",
        "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\nMailbox is a message channel used to communicate between PF and\nVF as well as driver and hardware functions.\nMailbox messages are received by driver through event queue, and\nsent by driver through registers of mailbox.\nThere are two transfer modes for sending mailbox message, one is\nDMA mode used to send message to PF, another is inline mode used\nto send message to VF.\n\nSigned-off-by: Steven Song <steven.song@3snic.com>\nSigned-off-by: Renyong Wan <wanry@3snic.com>\n---\nv3:\n* Fixed dereferencing type-punned pointer.\n---\n drivers/net/sssnic/base/meson.build   |   1 +\n drivers/net/sssnic/base/sssnic_hw.c   |  10 +\n drivers/net/sssnic/base/sssnic_hw.h   |   4 +\n drivers/net/sssnic/base/sssnic_mbox.c | 615 ++++++++++++++++++++++++++\n drivers/net/sssnic/base/sssnic_mbox.h |  45 ++\n drivers/net/sssnic/base/sssnic_misc.h |  11 +\n drivers/net/sssnic/base/sssnic_reg.h  |  47 ++\n 7 files changed, 733 insertions(+)\n create mode 100644 drivers/net/sssnic/base/sssnic_mbox.c\n create mode 100644 drivers/net/sssnic/base/sssnic_mbox.h\n create mode 100644 drivers/net/sssnic/base/sssnic_misc.h",
    "diff": "diff --git a/drivers/net/sssnic/base/meson.build b/drivers/net/sssnic/base/meson.build\nindex dd4dd08fc1..4abd1a0daf 100644\n--- a/drivers/net/sssnic/base/meson.build\n+++ b/drivers/net/sssnic/base/meson.build\n@@ -5,6 +5,7 @@ sources = [\n         'sssnic_hw.c',\n         'sssnic_eventq.c',\n         'sssnic_msg.c',\n+        'sssnic_mbox.c',\n ]\n \n c_args = cflags\ndiff --git a/drivers/net/sssnic/base/sssnic_hw.c b/drivers/net/sssnic/base/sssnic_hw.c\nindex 387c823c7e..ff527b2c7f 100644\n--- a/drivers/net/sssnic/base/sssnic_hw.c\n+++ b/drivers/net/sssnic/base/sssnic_hw.c\n@@ -11,6 +11,7 @@\n #include \"sssnic_reg.h\"\n #include \"sssnic_eventq.h\"\n #include \"sssnic_msg.h\"\n+#include \"sssnic_mbox.h\"\n \n static int\n wait_for_sssnic_hw_ready(struct sssnic_hw *hw)\n@@ -210,8 +211,16 @@ sssnic_hw_init(struct sssnic_hw *hw)\n \t\tgoto eventq_init_fail;\n \t}\n \n+\tret = sssnic_mbox_init(hw);\n+\tif (ret) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to initialize mailbox\");\n+\t\tgoto mbox_init_fail;\n+\t}\n+\n \treturn -EINVAL;\n \n+mbox_init_fail:\n+\tsssnic_eventq_all_shutdown(hw);\n eventq_init_fail:\n \tsssnic_msg_inbox_shutdown(hw);\n \treturn ret;\n@@ -222,6 +231,7 @@ sssnic_hw_shutdown(struct sssnic_hw *hw)\n {\n \tPMD_INIT_FUNC_TRACE();\n \n+\tsssnic_mbox_shutdown(hw);\n \tsssnic_eventq_all_shutdown(hw);\n \tsssnic_msg_inbox_shutdown(hw);\n }\ndiff --git a/drivers/net/sssnic/base/sssnic_hw.h b/drivers/net/sssnic/base/sssnic_hw.h\nindex 38fb9ac1ac..41e65f5880 100644\n--- a/drivers/net/sssnic/base/sssnic_hw.h\n+++ b/drivers/net/sssnic/base/sssnic_hw.h\n@@ -53,12 +53,16 @@ struct sssnic_hw {\n \tstruct sssnic_hw_attr attr;\n \tstruct sssnic_eventq *eventqs;\n \tstruct sssnic_msg_inbox *msg_inbox;\n+\tstruct sssnic_mbox *mbox;\n \tuint8_t num_eventqs;\n \tuint16_t eth_port_id;\n };\n \n+#define SSSNIC_FUNC_IDX(hw) ((hw)->attr.func_idx)\n #define SSSNIC_ETH_PORT_ID(hw) ((hw)->eth_port_id)\n #define SSSNIC_MPU_FUNC_IDX 0x1fff\n+#define SSSNIC_FUNC_TYPE(hw) ((hw)->attr.func_type)\n+#define SSSNIC_AF_FUNC_IDX(hw) ((hw)->attr.af_idx)\n \n int sssnic_hw_init(struct sssnic_hw *hw);\n void sssnic_hw_shutdown(struct sssnic_hw *hw);\ndiff --git a/drivers/net/sssnic/base/sssnic_mbox.c b/drivers/net/sssnic/base/sssnic_mbox.c\nnew file mode 100644\nindex 0000000000..02957137ea\n--- /dev/null\n+++ b/drivers/net/sssnic/base/sssnic_mbox.c\n@@ -0,0 +1,615 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2018-2022 Shenzhen 3SNIC Information Technology Co., Ltd.\n+ */\n+\n+#include <rte_byteorder.h>\n+#include <rte_common.h>\n+#include <rte_cycles.h>\n+#include <rte_bus_pci.h>\n+#include <rte_malloc.h>\n+#include <rte_memzone.h>\n+#include <ethdev_pci.h>\n+#include <ethdev_driver.h>\n+\n+#include \"../sssnic_log.h\"\n+#include \"sssnic_hw.h\"\n+#include \"sssnic_reg.h\"\n+#include \"sssnic_misc.h\"\n+#include \"sssnic_eventq.h\"\n+#include \"sssnic_mbox.h\"\n+\n+#define SSSNIC_MBOX_SEND_RESULT_SIZE 16\n+#define SSSNIC_MBOX_SEND_BUF_SIZE 2048UL\n+#define SSSNIC_MBOX_RESP_MSG_EVENTQ 1\n+#define SSSNIC_MBOX_SEND_DONE_TIMEOUT 500000 /* uint is 10us */\n+#define SSSNIC_MBOX_DEF_REQ_TIMEOUT 4000 /* millisecond */\n+#define SSSNIC_MBOX_REQ_ID_MASK 0xf /* request id only 4 bits*/\n+\n+struct sssnic_sendbox {\n+\tstruct sssnic_mbox *mbox;\n+\t/* Send data memory */\n+\tuint8_t *data;\n+\t/* Send result DMA memory zone */\n+\tconst struct rte_memzone *result_mz;\n+\t/* Send result DMA virtual address */\n+\tvolatile uint64_t *result_addr;\n+\t/* DMA buffer mz */\n+\tconst struct rte_memzone *buf_mz;\n+\t/* DMA buffer virtual address */\n+\tuint8_t *buf_addr;\n+\tpthread_mutex_t lock;\n+};\n+\n+struct sssnic_mbox_msg_dma_desc {\n+\t/* 32bit xor checksum for DMA data */\n+\tuint32_t checksum;\n+\t/* dword of high DMA address */\n+\tuint32_t dma_addr_hi;\n+\t/* dword of low DMA address */\n+\tuint32_t dma_addr_lo;\n+\t/* DMA data length */\n+\tuint32_t len;\n+\tuint32_t resvd[2];\n+};\n+#define SSSNIC_MBOX_MSG_DMA_DESC_SIZE 16\n+\n+struct sssnic_mbox_send_result {\n+\tunion {\n+\t\tuint16_t u16;\n+\t\tstruct {\n+\t\t\t/* SSSNIC_MBOX_SEND_STATUS_xx */\n+\t\t\tuint16_t status : 8;\n+\t\t\tuint16_t errcode : 8;\n+\t\t};\n+\t};\n+};\n+\n+#define SSSNIC_MBOX_SEND_STATUS_DONE 0xff\n+#define SSSNIC_MBOX_SEND_STATUS_ERR 0xfe\n+#define SSSNIC_MBOX_SEND_ERR_NONE 0x0\n+\n+static inline uint16_t\n+sssnic_sendbox_result_get(struct sssnic_sendbox *sendbox)\n+{\n+\tuint64_t result = rte_be_to_cpu_64(rte_read64(sendbox->result_addr));\n+\treturn (uint16_t)(result & 0xffff);\n+}\n+\n+static inline void\n+sssnic_sendbox_result_clear(struct sssnic_sendbox *sendbox)\n+{\n+\trte_write64(0, sendbox->result_addr);\n+}\n+\n+/* Wait send status to done */\n+static int\n+sssnic_sendbox_result_wait(struct sssnic_sendbox *sendbox, uint32_t timeout)\n+{\n+\tint ret;\n+\tstruct sssnic_mbox_send_result result;\n+\n+\tdo {\n+\t\tresult.u16 = sssnic_sendbox_result_get(sendbox);\n+\t\tif (result.status == SSSNIC_MBOX_SEND_STATUS_DONE) {\n+\t\t\treturn 0;\n+\t\t} else if (result.status == SSSNIC_MBOX_SEND_STATUS_ERR) {\n+\t\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\t\"Failed to send mbox segment data, error code=%u\",\n+\t\t\t\tresult.errcode);\n+\t\t\tret = -EFAULT;\n+\t\t\tgoto err_return;\n+\t\t}\n+\t\tif (timeout == 0)\n+\t\t\tbreak;\n+\t\trte_delay_us(10);\n+\t} while (--timeout);\n+\n+\tPMD_DRV_LOG(ERR, \"Mbox segment data sent time out\");\n+\tret = -ETIMEDOUT;\n+\n+err_return:\n+\tPMD_DRV_LOG(ERR, \"MBOX_SEND_CTRL0_REG=0x%x, SEND_CTRL1_REG=0x%x\",\n+\t\tsssnic_cfg_reg_read(sendbox->mbox->hw,\n+\t\t\tSSSNIC_MBOX_SEND_CTRL0_REG),\n+\t\tsssnic_cfg_reg_read(sendbox->mbox->hw,\n+\t\t\tSSSNIC_MBOX_SEND_CTRL1_REG));\n+\n+\treturn ret;\n+}\n+\n+static void\n+sssnic_mbox_send_ctrl_set(struct sssnic_mbox *mbox, uint16_t func,\n+\tuint16_t dst_eq, uint16_t len)\n+{\n+\tstruct sssnic_mbox_send_ctrl0_reg ctrl_0;\n+\tstruct sssnic_mbox_send_ctrl1_reg ctrl_1;\n+\n+\tctrl_1.u32 = 0;\n+\tctrl_1.dma_attr = 0;\n+\tctrl_1.ordering = 0;\n+\tctrl_1.dst_eq = dst_eq;\n+\tctrl_1.src_eq = 0;\n+\tctrl_1.tx_size = RTE_ALIGN(len + SSSNIC_MSG_HDR_SIZE, 4) >> 2;\n+\tctrl_1.wb = 1;\n+\tsssnic_cfg_reg_write(mbox->hw, SSSNIC_MBOX_SEND_CTRL1_REG, ctrl_1.u32);\n+\trte_wmb();\n+\n+\tif (SSSNIC_FUNC_TYPE(mbox->hw) == SSSNIC_FUNC_TYPE_VF &&\n+\t\tfunc != SSSNIC_MPU_FUNC_IDX) {\n+\t\tif (func == SSSNIC_AF_FUNC_IDX(mbox->hw))\n+\t\t\tfunc = 1;\n+\t\telse\n+\t\t\tfunc = 0;\n+\t}\n+\n+\tctrl_0.u32 = 0;\n+\tctrl_0.func = func;\n+\tctrl_0.src_eq_en = 0;\n+\tctrl_0.tx_status = SSSNIC_REG_MBOX_TX_READY;\n+\tsssnic_cfg_reg_write(mbox->hw, SSSNIC_MBOX_SEND_CTRL0_REG, ctrl_0.u32);\n+}\n+\n+static void\n+sssnic_mbox_state_set(struct sssnic_mbox *mbox, enum sssnic_mbox_state state)\n+{\n+\trte_spinlock_lock(&mbox->state_lock);\n+\tmbox->state = state;\n+\trte_spinlock_unlock(&mbox->state_lock);\n+}\n+\n+static void\n+sssnic_sendbox_write(struct sssnic_sendbox *sendbox, uint16_t offset,\n+\tuint8_t *data, uint16_t data_len)\n+{\n+\tuint32_t *send_addr;\n+\tuint32_t send_data;\n+\tuint32_t remain_data[3] = { 0 };\n+\tuint16_t remain;\n+\tuint16_t i;\n+\tuint16_t len;\n+\tuint16_t num_dw;\n+\n+\tlen = data_len;\n+\tremain = len & 0x3;\n+\tif (remain > 0) {\n+\t\tlen = len - remain;\n+\t\tfor (i = 0; i < remain; i++)\n+\t\t\tremain_data[i] = data[len + i];\n+\t}\n+\tnum_dw = len / sizeof(uint32_t);\n+\tsend_addr = (uint32_t *)(sendbox->data + offset);\n+\n+\tSSSNIC_DEBUG(\"data_buf=%p, data_len=%u, aligned_len=%u, remain=%u, \"\n+\t\t     \"num_dw=%u send_addr=%p\",\n+\t\tdata, data_len, len, remain, num_dw, send_addr);\n+\n+\tfor (i = 0; i < num_dw; i++) {\n+\t\tsend_data = *(((uint32_t *)data) + i);\n+\t\trte_write32(rte_cpu_to_be_32(send_data), send_addr + i);\n+\t}\n+\tif (remain > 0) {\n+\t\tsend_data = remain_data[0] << 24;\n+\t\tsend_data |= remain_data[1] << 16;\n+\t\tsend_data |= remain_data[2] << 8;\n+\t\trte_write32(send_data, send_addr + i);\n+\t}\n+}\n+\n+static inline void\n+sssnic_mbox_msg_hdr_init(struct sssnic_msg_hdr *msghdr, struct sssnic_msg *msg)\n+{\n+\tmsghdr->u64 = 0;\n+\tif (msg == NULL)\n+\t\treturn;\n+\tif (msg->func == SSSNIC_MPU_FUNC_IDX) {\n+\t\tmsghdr->trans_mode = SSSNIC_MSG_TRANS_MODE_DMA;\n+\t\tmsghdr->length = SSSNIC_MBOX_MSG_DMA_DESC_SIZE;\n+\t\tmsghdr->seg_len = SSSNIC_MBOX_MSG_DMA_DESC_SIZE;\n+\t\tmsghdr->last_seg = 1;\n+\t} else {\n+\t\tmsghdr->trans_mode = SSSNIC_MSG_TRANS_MODE_INLINE;\n+\t\tmsghdr->length = msg->data_len;\n+\t\tif (msg->data_len > SSSNIC_MSG_MAX_SEG_SIZE) {\n+\t\t\tmsghdr->seg_len = SSSNIC_MSG_MAX_SEG_SIZE;\n+\t\t\tmsghdr->last_seg = 0;\n+\t\t} else {\n+\t\t\tmsghdr->seg_len = msg->data_len;\n+\t\t\tmsghdr->last_seg = 1;\n+\t\t}\n+\t}\n+\tmsghdr->module = msg->module;\n+\tmsghdr->no_response = !msg->ack;\n+\tmsghdr->seg_id = SSSNIC_MSG_MIN_SGE_ID;\n+\tmsghdr->type = msg->type;\n+\tmsghdr->command = msg->command;\n+\tmsghdr->id = msg->id;\n+\tmsghdr->eventq = SSSNIC_MBOX_RESP_MSG_EVENTQ;\n+\tmsghdr->channel = SSSNIC_MSG_CHAN_MBOX;\n+\tmsghdr->status = msg->status;\n+}\n+\n+/* Calculate data checksum with XOR */\n+static uint32_t\n+sssnic_mbox_dma_data_csum(uint32_t *data, uint16_t data_len)\n+{\n+\tuint32_t xor = 0x5a5a5a5a;\n+\tuint16_t dw = data_len / sizeof(uint32_t);\n+\tuint16_t i;\n+\n+\tfor (i = 0; i < dw; i++)\n+\t\txor ^= data[i];\n+\treturn xor;\n+}\n+\n+static int\n+sssnic_mbox_dma_send(struct sssnic_mbox *mbox, struct sssnic_msg *msg)\n+{\n+\tint ret;\n+\tstruct sssnic_mbox_msg_dma_desc dma_desc = { 0 };\n+\tstruct sssnic_msg_hdr msghdr;\n+\tstruct sssnic_sendbox *sendbox = mbox->sendbox;\n+\n+\t/* Init DMA description */\n+\tdma_desc.checksum = sssnic_mbox_dma_data_csum((uint32_t *)msg->data_buf,\n+\t\tmsg->data_len);\n+\tdma_desc.dma_addr_hi = (uint32_t)((sendbox->buf_mz->iova >> 16) >> 16);\n+\tdma_desc.dma_addr_lo = (uint32_t)(sendbox->buf_mz->iova);\n+\tdma_desc.len = msg->data_len;\n+\t/* Copy message data to DMA buffer */\n+\trte_memcpy(sendbox->buf_addr, msg->data_buf, msg->data_len);\n+\t/* Init message header */\n+\tsssnic_mbox_msg_hdr_init(&msghdr, msg);\n+\tmsghdr.function = SSSNIC_FUNC_IDX(mbox->hw);\n+\t/* Clear send result */\n+\tsssnic_sendbox_result_clear(sendbox);\n+\t/* write mbox message header */\n+\tsssnic_sendbox_write(sendbox, 0, (uint8_t *)&msghdr,\n+\t\tSSSNIC_MSG_HDR_SIZE);\n+\t/* write DMA description*/\n+\tsssnic_sendbox_write(sendbox, SSSNIC_MSG_HDR_SIZE, (void *)&dma_desc,\n+\t\tsizeof(struct sssnic_mbox_msg_dma_desc));\n+\t/* mbox send control set */\n+\tsssnic_mbox_send_ctrl_set(mbox, msg->func,\n+\t\tmsg->type == SSSNIC_MSG_TYPE_REQ ? 0 :\n+\t\t\t\t\t\t\t SSSNIC_MBOX_RESP_MSG_EVENTQ,\n+\t\tSSSNIC_MBOX_MSG_DMA_DESC_SIZE);\n+\n+\trte_wmb();\n+\t/* Wait for send status becomes done */\n+\tret = sssnic_sendbox_result_wait(sendbox,\n+\t\tSSSNIC_MBOX_SEND_DONE_TIMEOUT);\n+\tif (ret != 0)\n+\t\tPMD_DRV_LOG(ERR, \"Failed to send mbox DMA data\");\n+\n+\treturn ret;\n+}\n+\n+static int\n+sssnic_mbox_inline_send(struct sssnic_mbox *mbox, struct sssnic_msg *msg)\n+{\n+\tint ret;\n+\tuint16_t remain;\n+\tuint16_t send;\n+\tstruct sssnic_msg_hdr msghdr;\n+\tstruct sssnic_sendbox *sendbox = mbox->sendbox;\n+\n+\t/* Init message header */\n+\tsssnic_mbox_msg_hdr_init(&msghdr, msg);\n+\tsend = 0;\n+\tremain = msg->data_len;\n+\tdo {\n+\t\t/* Clear send result */\n+\t\tsssnic_sendbox_result_clear(sendbox);\n+\t\t/* write mbox message header */\n+\t\tsssnic_sendbox_write(sendbox, 0, (uint8_t *)&msghdr,\n+\t\t\tSSSNIC_MSG_HDR_SIZE);\n+\t\t/* write mbox message data */\n+\t\tsssnic_sendbox_write(sendbox, SSSNIC_MSG_HDR_SIZE,\n+\t\t\tmsg->data_buf + send, msghdr.seg_len);\n+\t\t/* mbox send control set */\n+\t\tsssnic_mbox_send_ctrl_set(mbox, msg->func,\n+\t\t\tmsg->type == SSSNIC_MSG_TYPE_REQ ?\n+\t\t\t\t      0 :\n+\t\t\t\t      SSSNIC_MBOX_RESP_MSG_EVENTQ,\n+\t\t\tmsghdr.seg_len);\n+\n+\t\trte_wmb();\n+\t\t/* Wait for send status becomes done */\n+\t\tret = sssnic_sendbox_result_wait(sendbox,\n+\t\t\tSSSNIC_MBOX_SEND_DONE_TIMEOUT);\n+\t\tif (ret != 0) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Failed to send mbox inline data\");\n+\t\t\treturn ret;\n+\t\t}\n+\t\t/*last segment has been sent*/\n+\t\tif (msghdr.last_seg)\n+\t\t\tbreak;\n+\n+\t\tremain -= SSSNIC_MSG_MAX_SEG_SIZE;\n+\t\tsend += SSSNIC_MSG_MAX_SEG_SIZE;\n+\t\tif (remain <= SSSNIC_MSG_MAX_SEG_SIZE) {\n+\t\t\tmsghdr.seg_len = remain;\n+\t\t\tmsghdr.last_seg = 1;\n+\t\t}\n+\t\tmsghdr.seg_id++;\n+\t} while (remain > 0);\n+\n+\treturn 0;\n+}\n+\n+static int\n+sssnic_sendbox_init(struct sssnic_mbox *mbox)\n+{\n+\tint ret;\n+\tstruct sssnic_sendbox *sendbox;\n+\tstruct sssnic_hw *hw;\n+\tchar m_name[RTE_MEMZONE_NAMESIZE];\n+\n+\tPMD_INIT_FUNC_TRACE();\n+\n+\thw = mbox->hw;\n+\n+\tsendbox = rte_zmalloc(NULL, sizeof(struct sssnic_sendbox), 1);\n+\tif (sendbox == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Could not alloc memory for sendbox\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\thw = mbox->hw;\n+\tmbox->sendbox = sendbox;\n+\tsendbox->mbox = mbox;\n+\n+\tsnprintf(m_name, sizeof(m_name), \"sssnic%u_mbox_send_result\",\n+\t\tSSSNIC_ETH_PORT_ID(hw));\n+\tsendbox->result_mz = rte_memzone_reserve_aligned(m_name,\n+\t\tSSSNIC_MBOX_SEND_RESULT_SIZE, SOCKET_ID_ANY,\n+\t\tRTE_MEMZONE_IOVA_CONTIG, RTE_CACHE_LINE_SIZE);\n+\tif (sendbox->result_mz == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Could not alloc memzone for %s\", m_name);\n+\t\tret = -ENOMEM;\n+\t\tgoto alloc_send_result_fail;\n+\t}\n+\tsssnic_cfg_reg_write(hw, SSSNIC_MBOX_SEND_RESULT_ADDR_H_REG,\n+\t\tSSSNIC_UPPER_32_BITS(sendbox->result_mz->iova));\n+\tsssnic_cfg_reg_write(hw, SSSNIC_MBOX_SEND_RESULT_ADDR_L_REG,\n+\t\tSSSNIC_LOWER_32_BITS(sendbox->result_mz->iova));\n+\tsendbox->result_addr = sendbox->result_mz->addr;\n+\n+\tsnprintf(m_name, sizeof(m_name), \"sssnic%u_mbox_sendbuf\",\n+\t\tSSSNIC_ETH_PORT_ID(hw));\n+\tsendbox->buf_mz = rte_memzone_reserve_aligned(m_name,\n+\t\tSSSNIC_MBOX_SEND_BUF_SIZE, SOCKET_ID_ANY,\n+\t\tRTE_MEMZONE_IOVA_CONTIG, SSSNIC_MBOX_SEND_BUF_SIZE);\n+\tif (sendbox->buf_mz == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Could not alloc memzone for %s\", m_name);\n+\t\tret = -ENOMEM;\n+\t\tgoto alloc_send_buf_fail;\n+\t};\n+\tsendbox->buf_addr = sendbox->buf_mz->addr;\n+\n+\tsendbox->data = hw->cfg_base_addr + SSSNIC_MBOX_SEND_DATA_BASE_REG;\n+\n+\tpthread_mutex_init(&sendbox->lock, NULL);\n+\n+\treturn 0;\n+\n+alloc_send_buf_fail:\n+\trte_memzone_free(sendbox->result_mz);\n+alloc_send_result_fail:\n+\trte_free(sendbox);\n+\treturn ret;\n+}\n+\n+static void\n+sssnic_sendbox_shutdown(struct sssnic_mbox *mbox)\n+{\n+\tstruct sssnic_sendbox *sendbox = mbox->sendbox;\n+\n+\tPMD_INIT_FUNC_TRACE();\n+\n+\trte_memzone_free(sendbox->buf_mz);\n+\tsssnic_cfg_reg_write(mbox->hw, SSSNIC_MBOX_SEND_RESULT_ADDR_H_REG, 0);\n+\tsssnic_cfg_reg_write(mbox->hw, SSSNIC_MBOX_SEND_RESULT_ADDR_L_REG, 0);\n+\trte_memzone_free(sendbox->result_mz);\n+\tpthread_mutex_destroy(&sendbox->lock);\n+\trte_free(sendbox);\n+}\n+\n+static int\n+sssnic_mbox_response_handle(struct sssnic_msg *msg,\n+\t__rte_unused enum sssnic_msg_chann_id chan_id, void *priv)\n+{\n+\tint ret;\n+\tstruct sssnic_mbox *mbox = priv;\n+\t;\n+\n+\trte_spinlock_lock(&mbox->state_lock);\n+\tif (msg->id == mbox->req_id &&\n+\t\tmbox->state == SSSNIC_MBOX_STATE_RUNNING) {\n+\t\tmbox->state = SSSNIC_MBOX_STATE_READY;\n+\t\tret = SSSNIC_MSG_DONE;\n+\t} else {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Failed to handle mbox response message, msg_id=%u, \"\n+\t\t\t\"req_id=%u, msg_status=%u, mbox_state=%u\",\n+\t\t\tmsg->id, mbox->req_id, msg->status, mbox->state);\n+\t\tret = SSSNIC_MSG_REJECT;\n+\t}\n+\trte_spinlock_unlock(&mbox->state_lock);\n+\n+\treturn ret;\n+}\n+\n+static int\n+sssnic_mbox_msg_tx(struct sssnic_mbox *mbox, struct sssnic_msg *msg)\n+{\n+\tint ret;\n+\n+\tif (mbox == NULL || msg == NULL || msg->data_buf == NULL ||\n+\t\tmsg->data_len == 0 ||\n+\t\tmsg->data_len > SSSNIC_MSG_MAX_DATA_SIZE) {\n+\t\tPMD_DRV_LOG(ERR, \"Bad parameter for mbox message tx\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tSSSNIC_DEBUG(\"command=%u, func=%u module=%u, type=%u, ack=%u, seq=%u, \"\n+\t\t     \"status=%u, id=%u data_buf=%p, data_len=%u\",\n+\t\tmsg->command, msg->func, msg->module, msg->type, msg->ack,\n+\t\tmsg->seg, msg->status, msg->id, msg->data_buf, msg->data_len);\n+\n+\tpthread_mutex_lock(&mbox->sendbox->lock);\n+\tif (msg->func == SSSNIC_MPU_FUNC_IDX)\n+\t\tret = sssnic_mbox_dma_send(mbox, msg);\n+\telse\n+\t\tret = sssnic_mbox_inline_send(mbox, msg);\n+\tpthread_mutex_unlock(&mbox->sendbox->lock);\n+\n+\treturn ret;\n+}\n+\n+static int\n+sssnic_mbox_send_internal(struct sssnic_mbox *mbox, struct sssnic_msg *msg,\n+\tuint8_t *resp_data, uint32_t *resp_data_len, uint32_t timeout_ms)\n+{\n+\tint ret;\n+\tstruct sssnic_msg *resp_msg = NULL;\n+\n+\tif (resp_data != NULL) {\n+\t\t/* the function of request message equls to response message */\n+\t\tresp_msg = SSSNIC_MSG_LOCATE(mbox->hw, SSSNIC_MSG_CHAN_MBOX,\n+\t\t\tSSSNIC_MSG_TYPE_RESP, SSSNIC_MSG_SRC(msg->func));\n+\t\tmbox->req_id++;\n+\t\tmbox->req_id &= SSSNIC_MBOX_REQ_ID_MASK;\n+\t\tmsg->id = mbox->req_id;\n+\t\tmsg->ack = 1;\n+\t\tsssnic_mbox_state_set(mbox, SSSNIC_MBOX_STATE_RUNNING);\n+\t}\n+\tret = sssnic_mbox_msg_tx(mbox, msg);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to transmit mbox message, ret=%d\",\n+\t\t\tret);\n+\t\tif (resp_data != NULL)\n+\t\t\tsssnic_mbox_state_set(mbox, SSSNIC_MBOX_STATE_FAILED);\n+\t\treturn ret;\n+\t}\n+\n+\tif (resp_data == NULL)\n+\t\treturn 0;\n+\n+\tret = sssnic_eventq_flush(mbox->hw, SSSNIC_MBOX_RESP_MSG_EVENTQ,\n+\t\ttimeout_ms ? timeout_ms : SSSNIC_MBOX_DEF_REQ_TIMEOUT);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"No response message, ret=%d\", ret);\n+\t\tsssnic_mbox_state_set(mbox, SSSNIC_MBOX_STATE_TIMEOUT);\n+\t\treturn ret;\n+\t}\n+\tif (resp_msg->module != msg->module ||\n+\t\tresp_msg->command != msg->command) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Received invalid response message, module=%x, command=%x, expected message module=%x, command=%x\",\n+\t\t\tresp_msg->module, resp_msg->command, msg->module,\n+\t\t\tmsg->command);\n+\t\tsssnic_mbox_state_set(mbox, SSSNIC_MBOX_STATE_FAILED);\n+\t\treturn ret;\n+\t}\n+\tsssnic_mbox_state_set(mbox, SSSNIC_MBOX_STATE_READY);\n+\n+\tif (resp_msg->status != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Bad response status\");\n+\t\treturn -EFAULT;\n+\t}\n+\n+\tif (*resp_data_len < resp_msg->data_len) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Invalid response data size %u, expected less than %u for module %x command %x\",\n+\t\t\tresp_msg->data_len, *resp_data_len, msg->module,\n+\t\t\tmsg->command);\n+\t\treturn -EFAULT;\n+\t}\n+\n+\trte_memcpy(resp_data, resp_msg->data_buf, resp_msg->data_len);\n+\t*resp_data_len = resp_msg->data_len;\n+\treturn 0;\n+}\n+\n+int\n+sssnic_mbox_send(struct sssnic_hw *hw, struct sssnic_msg *msg,\n+\tuint8_t *resp_data, uint32_t *resp_data_len, uint32_t timeout_ms)\n+{\n+\tint ret;\n+\tstruct sssnic_mbox *mbox;\n+\n+\tif (hw == NULL || msg == NULL ||\n+\t\t(resp_data != NULL && resp_data_len == NULL)) {\n+\t\tPMD_DRV_LOG(ERR, \"Bad parameter for mbox request\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tmbox = hw->mbox;\n+\n+\tif (resp_data != NULL) {\n+\t\tret = pthread_mutex_lock(&mbox->req_lock);\n+\t\tif (ret != 0) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Failed to lock mbox request lock\");\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\tret = sssnic_mbox_send_internal(mbox, msg, resp_data, resp_data_len,\n+\t\ttimeout_ms);\n+\n+\tif (resp_data != NULL)\n+\t\tpthread_mutex_unlock(&mbox->req_lock);\n+\n+\treturn ret;\n+}\n+\n+int\n+sssnic_mbox_init(struct sssnic_hw *hw)\n+{\n+\tint ret;\n+\tstruct sssnic_mbox *mbox;\n+\n+\tPMD_INIT_FUNC_TRACE();\n+\n+\tmbox = rte_zmalloc(NULL, sizeof(struct sssnic_mbox), 1);\n+\tif (mbox == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Could not alloc memory for mailbox struct\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tpthread_mutex_init(&mbox->req_lock, NULL);\n+\trte_spinlock_init(&mbox->state_lock);\n+\n+\tmbox->hw = hw;\n+\thw->mbox = mbox;\n+\tret = sssnic_sendbox_init(mbox);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to initialize sendbox!\");\n+\t\tgoto sendbox_init_fail;\n+\t}\n+\n+\tsssnic_msg_rx_handler_register(hw, SSSNIC_MSG_CHAN_MBOX,\n+\t\tSSSNIC_MSG_TYPE_RESP, sssnic_mbox_response_handle, mbox);\n+\n+\treturn 0;\n+\n+sendbox_init_fail:\n+\tpthread_mutex_destroy(&mbox->req_lock);\n+\trte_free(mbox);\n+\treturn ret;\n+}\n+\n+void\n+sssnic_mbox_shutdown(struct sssnic_hw *hw)\n+{\n+\tstruct sssnic_mbox *mbox = hw->mbox;\n+\n+\tPMD_INIT_FUNC_TRACE();\n+\n+\tif (mbox == NULL)\n+\t\treturn;\n+\n+\tsssnic_sendbox_shutdown(mbox);\n+\tpthread_mutex_destroy(&mbox->req_lock);\n+\trte_free(mbox);\n+}\ndiff --git a/drivers/net/sssnic/base/sssnic_mbox.h b/drivers/net/sssnic/base/sssnic_mbox.h\nnew file mode 100644\nindex 0000000000..00fa02ea78\n--- /dev/null\n+++ b/drivers/net/sssnic/base/sssnic_mbox.h\n@@ -0,0 +1,45 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2018-2022 Shenzhen 3SNIC Information Technology Co., Ltd.\n+ */\n+\n+#ifndef _SSSNIC_MBOX_H_\n+#define _SSSNIC_MBOX_H_\n+\n+#include <rte_spinlock.h>\n+\n+#include \"sssnic_msg.h\"\n+\n+enum sssnic_mbox_state {\n+\t/* Mbox is sending message or waiting for response */\n+\tSSSNIC_MBOX_STATE_RUNNING,\n+\t/* Waiting for response timed out*/\n+\tSSSNIC_MBOX_STATE_TIMEOUT,\n+\t/* Mbox failed to send message */\n+\tSSSNIC_MBOX_STATE_FAILED,\n+\t/* Response is ready */\n+\tSSSNIC_MBOX_STATE_READY,\n+\t/* Mbox is idle, it can send message */\n+\tSSSNIC_MBOX_STATE_IDLE,\n+};\n+\n+struct sssnic_sendbox;\n+\n+struct sssnic_mbox {\n+\tstruct sssnic_hw *hw;\n+\t/* just be used for sending request msg*/\n+\tpthread_mutex_t req_lock;\n+\t/* request msg id*/\n+\tuint8_t req_id;\n+\tstruct sssnic_sendbox *sendbox;\n+\t/*current state*/\n+\tenum sssnic_mbox_state state;\n+\trte_spinlock_t state_lock;\n+};\n+\n+int sssnic_mbox_send(struct sssnic_hw *hw, struct sssnic_msg *msg,\n+\tuint8_t *resp_data, uint32_t *resp_data_len, uint32_t timeout_ms);\n+\n+int sssnic_mbox_init(struct sssnic_hw *hw);\n+void sssnic_mbox_shutdown(struct sssnic_hw *hw);\n+\n+#endif /* _SSSNIC_MBOX_H_ */\ndiff --git a/drivers/net/sssnic/base/sssnic_misc.h b/drivers/net/sssnic/base/sssnic_misc.h\nnew file mode 100644\nindex 0000000000..ac1bbd9c73\n--- /dev/null\n+++ b/drivers/net/sssnic/base/sssnic_misc.h\n@@ -0,0 +1,11 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2018-2022 Shenzhen 3SNIC Information Technology Co., Ltd.\n+ */\n+\n+#ifndef _SSSNIC_MISC_H_\n+#define _SSSNIC_MISC_H_\n+\n+#define SSSNIC_LOWER_32_BITS(x) ((uint32_t)(x))\n+#define SSSNIC_UPPER_32_BITS(x) ((uint32_t)(((x) >> 16) >> 16))\n+\n+#endif /* _SSSNIC_MISC_H_ */\ndiff --git a/drivers/net/sssnic/base/sssnic_reg.h b/drivers/net/sssnic/base/sssnic_reg.h\nindex e38d39a691..859654087d 100644\n--- a/drivers/net/sssnic/base/sssnic_reg.h\n+++ b/drivers/net/sssnic/base/sssnic_reg.h\n@@ -26,6 +26,12 @@\n #define SSSNIC_EVENTQ_PROD_IDX_REG 0x20c\n #define SSSNIC_EVENTQ_PAGE_ADDR_REG 0x240\n \n+#define SSSNIC_MBOX_SEND_DATA_BASE_REG 0x80\n+#define SSSNIC_MBOX_SEND_CTRL0_REG 0x100\n+#define SSSNIC_MBOX_SEND_CTRL1_REG 0x104\n+#define SSSNIC_MBOX_SEND_RESULT_ADDR_H_REG 0x108\n+#define SSSNIC_MBOX_SEND_RESULT_ADDR_L_REG 0x10c\n+\n /* registers of mgmt */\n #define SSSNIC_AF_ELECTION_REG 0x6000\n #define SSSNIC_MF_ELECTION_REG 0x6020\n@@ -193,6 +199,47 @@ struct sssnic_eventq_ci_ctrl_reg {\n \t};\n };\n \n+#define SSSNIC_REG_MBOX_TX_DONE 0 /* Mailbox transmission is done */\n+#define SSSNIC_REG_MBOX_TX_READY 1 /* Mailbox is ready to transmit */\n+struct sssnic_mbox_send_ctrl0_reg {\n+\tunion {\n+\t\tuint32_t u32;\n+\t\tstruct {\n+\t\t\t/* enable to inform source eventq if tx done */\n+\t\t\tuint32_t src_eq_en : 1;\n+\t\t\t/* mailbox tx result, see SSSNIC_REG_MBOX_TX_XX */\n+\t\t\tuint32_t tx_status : 1;\n+\t\t\tuint32_t resvd0 : 14;\n+\t\t\t/* destination function where the mbox send to */\n+\t\t\tuint32_t func : 13;\n+\t\t\tuint32_t resvd1 : 3;\n+\t\t};\n+\t};\n+};\n+\n+struct sssnic_mbox_send_ctrl1_reg {\n+\tunion {\n+\t\tuint32_t u32;\n+\t\tstruct {\n+\t\t\tuint32_t resvd0 : 10;\n+\t\t\t/* Destination eventq in the mgmt cpu */\n+\t\t\tuint32_t dst_eq : 2;\n+\t\t\t/* eventq that will be informed if tx done */\n+\t\t\tuint32_t src_eq : 2;\n+\t\t\tuint32_t dma_attr : 6;\n+\t\t\t/* mailbox message size include header and body\n+\t\t\t * must 4byte align and unit is 4byte\n+\t\t\t */\n+\t\t\tuint32_t tx_size : 5;\n+\t\t\tuint32_t ordering : 2;\n+\t\t\tuint32_t resvd1 : 1;\n+\t\t\t/*write result back to DMA address of sending result  */\n+\t\t\tuint32_t wb : 1;\n+\t\t\tuint32_t resvd2 : 3;\n+\t\t};\n+\t};\n+};\n+\n static inline uint32_t\n sssnic_cfg_reg_read(struct sssnic_hw *hw, uint32_t reg)\n {\n",
    "prefixes": [
        "v5",
        "07/32"
    ]
}