get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 59744,
    "url": "http://patches.dpdk.org/api/patches/59744/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/adf174d66c00eea5c103e3ab179c0e75b8cecd7f.1569421287.git.cloud.wangxiaoyun@huawei.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<adf174d66c00eea5c103e3ab179c0e75b8cecd7f.1569421287.git.cloud.wangxiaoyun@huawei.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/adf174d66c00eea5c103e3ab179c0e75b8cecd7f.1569421287.git.cloud.wangxiaoyun@huawei.com",
    "date": "2019-09-25T14:30:29",
    "name": "[v2,01/17] net/hinic/base: add mbox command channel for SRIOV",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "20e18953b4459f87561bc990a80a54078d2ca99a",
    "submitter": {
        "id": 1446,
        "url": "http://patches.dpdk.org/api/people/1446/?format=api",
        "name": "Wangxiaoyun (Cloud)",
        "email": "cloud.wangxiaoyun@huawei.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/adf174d66c00eea5c103e3ab179c0e75b8cecd7f.1569421287.git.cloud.wangxiaoyun@huawei.com/mbox/",
    "series": [
        {
            "id": 6529,
            "url": "http://patches.dpdk.org/api/series/6529/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=6529",
            "date": "2019-09-25T14:26:40",
            "name": "Add advanced features for Huawei hinic pmd",
            "version": 2,
            "mbox": "http://patches.dpdk.org/series/6529/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/59744/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/59744/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 1E2CD1BE82;\n\tWed, 25 Sep 2019 16:15:18 +0200 (CEST)",
            "from huawei.com (szxga06-in.huawei.com [45.249.212.32])\n\tby dpdk.org (Postfix) with ESMTP id 05F871BE51\n\tfor <dev@dpdk.org>; Wed, 25 Sep 2019 16:15:17 +0200 (CEST)",
            "from DGGEMS402-HUB.china.huawei.com (unknown [172.30.72.60])\n\tby Forcepoint Email with ESMTP id B84B19E8F1E60F9726D4\n\tfor <dev@dpdk.org>; Wed, 25 Sep 2019 22:15:15 +0800 (CST)",
            "from tester.localdomain (10.175.119.39) by\n\tDGGEMS402-HUB.china.huawei.com (10.3.19.202) with Microsoft SMTP\n\tServer id 14.3.439.0; Wed, 25 Sep 2019 22:15:09 +0800"
        ],
        "From": "Xiaoyun wang <cloud.wangxiaoyun@huawei.com>",
        "To": "<ferruh.yigit@intel.com>",
        "CC": "<dev@dpdk.org>, <xuanziyang2@huawei.com>, <shahar.belkar@huawei.com>,\n\t<luoxianjun@huawei.com>, <tanya.brokhman@huawei.com>,\n\t<zhouguoyang@huawei.com>, <wulike1@huawei.com>, Xiaoyun wang\n\t<cloud.wangxiaoyun@huawei.com>",
        "Date": "Wed, 25 Sep 2019 22:30:29 +0800",
        "Message-ID": "<adf174d66c00eea5c103e3ab179c0e75b8cecd7f.1569421287.git.cloud.wangxiaoyun@huawei.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<cover.1569421286.git.cloud.wangxiaoyun@huawei.com>",
        "References": "<cover.1569421286.git.cloud.wangxiaoyun@huawei.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[10.175.119.39]",
        "X-CFilter-Loop": "Reflected",
        "Subject": "[dpdk-dev] [PATCH v2 01/17] net/hinic/base: add mbox command\n\tchannel for SRIOV",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n\t<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\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Add mbox command channel for SRIOV, which is used to\ncommunicate between VF and VF, VF and PF. This patch\nintroduces data structures, initialization, interfaces\nand commands of mbox channel.\n\nSigned-off-by: Xiaoyun wang <cloud.wangxiaoyun@huawei.com>\n---\n drivers/net/hinic/Makefile               |   1 +\n drivers/net/hinic/base/hinic_compat.h    |  34 +-\n drivers/net/hinic/base/hinic_pmd_hwdev.h |   5 +-\n drivers/net/hinic/base/hinic_pmd_mbox.c  | 938 +++++++++++++++++++++++++++++++\n drivers/net/hinic/base/hinic_pmd_mbox.h  |  93 +++\n drivers/net/hinic/base/meson.build       |   1 +\n 6 files changed, 1069 insertions(+), 3 deletions(-)\n create mode 100644 drivers/net/hinic/base/hinic_pmd_mbox.c\n create mode 100644 drivers/net/hinic/base/hinic_pmd_mbox.h",
    "diff": "diff --git a/drivers/net/hinic/Makefile b/drivers/net/hinic/Makefile\nindex 42b4a78..20a338e 100644\n--- a/drivers/net/hinic/Makefile\n+++ b/drivers/net/hinic/Makefile\n@@ -59,6 +59,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_HINIC_PMD) += hinic_pmd_mgmt.c\n SRCS-$(CONFIG_RTE_LIBRTE_HINIC_PMD) += hinic_pmd_niccfg.c\n SRCS-$(CONFIG_RTE_LIBRTE_HINIC_PMD) += hinic_pmd_nicio.c\n SRCS-$(CONFIG_RTE_LIBRTE_HINIC_PMD) += hinic_pmd_wq.c\n+SRCS-$(CONFIG_RTE_LIBRTE_HINIC_PMD) += hinic_pmd_mbox.c\n \n SRCS-$(CONFIG_RTE_LIBRTE_HINIC_PMD) += hinic_pmd_ethdev.c\n SRCS-$(CONFIG_RTE_LIBRTE_HINIC_PMD) += hinic_pmd_rx.c\ndiff --git a/drivers/net/hinic/base/hinic_compat.h b/drivers/net/hinic/base/hinic_compat.h\nindex f599947..db60a51 100644\n--- a/drivers/net/hinic/base/hinic_compat.h\n+++ b/drivers/net/hinic/base/hinic_compat.h\n@@ -227,7 +227,7 @@ static inline u16 ilog2(u32 n)\n  * hinic_cpu_to_be32 - convert data to big endian 32 bit format\n  * @data: the data to convert\n  * @len: length of data to convert, must be Multiple of 4B\n- **/\n+ */\n static inline void hinic_cpu_to_be32(void *data, u32 len)\n {\n \tu32 i;\n@@ -243,7 +243,7 @@ static inline void hinic_cpu_to_be32(void *data, u32 len)\n  * hinic_be32_to_cpu - convert data from big endian 32 bit format\n  * @data: the data to convert\n  * @len: length of data to convert, must be Multiple of 4B\n- **/\n+ */\n static inline void hinic_be32_to_cpu(void *data, u32 len)\n {\n \tu32 i;\n@@ -278,4 +278,34 @@ static inline int hinic_mutex_destroy(pthread_mutex_t *pthreadmutex)\n \treturn err;\n }\n \n+static inline int hinic_mutex_lock(pthread_mutex_t *pthreadmutex)\n+{\n+\tint err;\n+\n+\terr = pthread_mutex_lock(pthreadmutex);\n+\tif (!err) {\n+\t\treturn err;\n+\t} else if (err == EOWNERDEAD) {\n+\t\tPMD_DRV_LOG(ERR, \"Mutex lock failed. (ErrorNo=%d)\", errno);\n+#if defined(__GLIBC__)\n+#if __GLIBC_PREREQ(2, 12)\n+\t\t(void)pthread_mutex_consistent(pthreadmutex);\n+#else\n+\t\t(void)pthread_mutex_consistent_np(pthreadmutex);\n+#endif\n+#else\n+\t\t(void)pthread_mutex_consistent(pthreadmutex);\n+#endif\n+\t} else {\n+\t\tPMD_DRV_LOG(ERR, \"Mutex lock failed. (ErrorNo=%d)\", errno);\n+\t}\n+\n+\treturn err;\n+}\n+\n+static inline int hinic_mutex_unlock(pthread_mutex_t *pthreadmutex)\n+{\n+\treturn pthread_mutex_unlock(pthreadmutex);\n+}\n+\n #endif /* _HINIC_COMPAT_H_ */\ndiff --git a/drivers/net/hinic/base/hinic_pmd_hwdev.h b/drivers/net/hinic/base/hinic_pmd_hwdev.h\nindex 6c21c47..fc5bdf9 100644\n--- a/drivers/net/hinic/base/hinic_pmd_hwdev.h\n+++ b/drivers/net/hinic/base/hinic_pmd_hwdev.h\n@@ -7,13 +7,15 @@\n \n #include \"hinic_pmd_cmd.h\"\n \n-#define HINIC_PAGE_SIZE_MAX\t20\n+#define HINIC_PAGE_SIZE_MAX\t\t20\n \n #define HINIC_MGMT_CMD_UNSUPPORTED\t0xFF\n #define HINIC_PF_SET_VF_ALREADY\t\t0x4\n \n #define MAX_PCIE_DFX_BUF_SIZE\t\t1024\n \n+#define HINIC_DEV_BUSY_ACTIVE_FW\t0xFE\n+\n /* dma pool */\n struct dma_pool {\n \tu32 inuse;\n@@ -436,6 +438,7 @@ struct hinic_hwdev {\n \tstruct hinic_hwif *hwif;\n \tstruct cfg_mgmt_info *cfg_mgmt;\n \tstruct hinic_aeqs *aeqs;\n+\tstruct hinic_mbox_func_to_func *func_to_func;\n \tstruct hinic_msg_pf_to_mgmt *pf_to_mgmt;\n \tstruct hinic_cmdqs *cmdqs;\n \tstruct hinic_nic_io *nic_io;\ndiff --git a/drivers/net/hinic/base/hinic_pmd_mbox.c b/drivers/net/hinic/base/hinic_pmd_mbox.c\nnew file mode 100644\nindex 0000000..7ae8fd0\n--- /dev/null\n+++ b/drivers/net/hinic/base/hinic_pmd_mbox.c\n@@ -0,0 +1,938 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2017 Huawei Technologies Co., Ltd\n+ */\n+\n+#include \"hinic_compat.h\"\n+#include \"hinic_csr.h\"\n+#include \"hinic_pmd_hwdev.h\"\n+#include \"hinic_pmd_hwif.h\"\n+#include \"hinic_pmd_eqs.h\"\n+#include \"hinic_pmd_mgmt.h\"\n+#include \"hinic_pmd_mbox.h\"\n+\n+#define HINIC_MBOX_INT_DST_FUNC_SHIFT\t\t\t\t0\n+#define HINIC_MBOX_INT_DST_AEQN_SHIFT\t\t\t\t10\n+#define HINIC_MBOX_INT_SRC_RESP_AEQN_SHIFT\t\t\t12\n+#define HINIC_MBOX_INT_STAT_DMA_SHIFT\t\t\t\t14\n+/* The size of data to be send (unit of 4 bytes) */\n+#define HINIC_MBOX_INT_TX_SIZE_SHIFT\t\t\t\t20\n+/* SO_RO(strong order, relax order)  */\n+#define HINIC_MBOX_INT_STAT_DMA_SO_RO_SHIFT\t\t\t25\n+#define HINIC_MBOX_INT_WB_EN_SHIFT\t\t\t\t28\n+\n+\n+#define HINIC_MBOX_INT_DST_FUNC_MASK\t\t\t\t0x3FF\n+#define HINIC_MBOX_INT_DST_AEQN_MASK\t\t\t\t0x3\n+#define HINIC_MBOX_INT_SRC_RESP_AEQN_MASK\t\t\t0x3\n+#define HINIC_MBOX_INT_STAT_DMA_MASK\t\t\t\t0x3F\n+#define HINIC_MBOX_INT_TX_SIZE_MASK\t\t\t\t0x1F\n+#define HINIC_MBOX_INT_STAT_DMA_SO_RO_MASK\t\t\t0x3\n+#define HINIC_MBOX_INT_WB_EN_MASK\t\t\t\t0x1\n+\n+#define HINIC_MBOX_INT_SET(val, field)\t\\\n+\t\t\t(((val) & HINIC_MBOX_INT_##field##_MASK) << \\\n+\t\t\tHINIC_MBOX_INT_##field##_SHIFT)\n+\n+enum hinic_mbox_tx_status {\n+\tTX_DONE = 0,\n+\tTX_IN_PROGRESS,\n+};\n+\n+#define HINIC_MBOX_CTRL_TRIGGER_AEQE_SHIFT\t\t\t0\n+/* specifies the issue request for the message data.\n+ * 0 - Tx request is done;\n+ * 1 - Tx request is in process.\n+ */\n+#define HINIC_MBOX_CTRL_TX_STATUS_SHIFT\t\t\t\t1\n+\n+#define HINIC_MBOX_CTRL_TRIGGER_AEQE_MASK\t\t\t0x1\n+#define HINIC_MBOX_CTRL_TX_STATUS_MASK\t\t\t\t0x1\n+\n+#define HINIC_MBOX_CTRL_SET(val, field)\t\\\n+\t\t\t(((val) & HINIC_MBOX_CTRL_##field##_MASK) << \\\n+\t\t\tHINIC_MBOX_CTRL_##field##_SHIFT)\n+\n+#define HINIC_MBOX_HEADER_MSG_LEN_SHIFT\t\t\t\t0\n+#define HINIC_MBOX_HEADER_MODULE_SHIFT\t\t\t\t11\n+#define HINIC_MBOX_HEADER_SEG_LEN_SHIFT\t\t\t\t16\n+#define HINIC_MBOX_HEADER_NO_ACK_SHIFT\t\t\t\t22\n+#define HINIC_MBOX_HEADER_SEQID_SHIFT\t\t\t\t24\n+#define HINIC_MBOX_HEADER_LAST_SHIFT\t\t\t\t30\n+\n+#define HINIC_MBOX_HEADER_DIRECTION_SHIFT\t\t\t31\n+#define HINIC_MBOX_HEADER_CMD_SHIFT\t\t\t\t32\n+#define HINIC_MBOX_HEADER_MSG_ID_SHIFT\t\t\t\t40\n+#define HINIC_MBOX_HEADER_STATUS_SHIFT\t\t\t\t48\n+#define HINIC_MBOX_HEADER_SRC_GLB_FUNC_IDX_SHIFT\t\t54\n+\n+#define HINIC_MBOX_HEADER_MSG_LEN_MASK\t\t\t\t0x7FF\n+#define HINIC_MBOX_HEADER_MODULE_MASK\t\t\t\t0x1F\n+#define HINIC_MBOX_HEADER_SEG_LEN_MASK\t\t\t\t0x3F\n+#define HINIC_MBOX_HEADER_NO_ACK_MASK\t\t\t\t0x1\n+#define HINIC_MBOX_HEADER_SEQID_MASK\t\t\t\t0x3F\n+#define HINIC_MBOX_HEADER_LAST_MASK\t\t\t\t0x1\n+#define HINIC_MBOX_HEADER_DIRECTION_MASK\t\t\t0x1\n+#define HINIC_MBOX_HEADER_CMD_MASK\t\t\t\t0xFF\n+#define HINIC_MBOX_HEADER_MSG_ID_MASK\t\t\t\t0xFF\n+#define HINIC_MBOX_HEADER_STATUS_MASK\t\t\t\t0x3F\n+#define HINIC_MBOX_HEADER_SRC_GLB_FUNC_IDX_MASK\t\t\t0x3FF\n+\n+#define HINIC_MBOX_HEADER_GET(val, field)\t\\\n+\t\t\t(((val) >> HINIC_MBOX_HEADER_##field##_SHIFT) & \\\n+\t\t\tHINIC_MBOX_HEADER_##field##_MASK)\n+#define HINIC_MBOX_HEADER_SET(val, field)\t\\\n+\t\t\t((u64)((val) & HINIC_MBOX_HEADER_##field##_MASK) << \\\n+\t\t\tHINIC_MBOX_HEADER_##field##_SHIFT)\n+\n+#define HINIC_MBOX_COMP_TIME_MS\t\t\t8000U\n+#define MBOX_MSG_POLLING_TIMEOUT_MS\t\t5000\n+\n+/* The size unit is Bytes */\n+#define HINIC_MBOX_DATA_SIZE\t\t\t2040\n+#define MBOX_MAX_BUF_SZ\t\t\t\t2048UL\n+#define MBOX_HEADER_SZ\t\t\t\t8\n+\n+/* MBOX size is 64B, 8B for mbox_header, 4B reserved */\n+#define MBOX_SEG_LEN\t\t\t\t48\n+#define MBOX_SEG_LEN_ALIGN\t\t\t4\n+#define MBOX_WB_STATUS_LEN\t\t\t16UL\n+#define MBOX_SIZE\t\t\t\t64\n+\n+/* mbox write back status is 16B, only first 4B is used */\n+#define MBOX_WB_STATUS_ERRCODE_MASK\t\t0xFFFF\n+#define MBOX_WB_STATUS_MASK\t\t\t0xFF\n+#define MBOX_WB_ERROR_CODE_MASK\t\t\t0xFF00\n+#define MBOX_WB_STATUS_FINISHED_SUCCESS\t\t0xFF\n+#define MBOX_WB_STATUS_FINISHED_WITH_ERR\t0xFE\n+#define MBOX_WB_STATUS_NOT_FINISHED\t\t0x00\n+\n+#define MBOX_STATUS_FINISHED(wb)\t\\\n+\t(((wb) & MBOX_WB_STATUS_MASK) != MBOX_WB_STATUS_NOT_FINISHED)\n+#define MBOX_STATUS_SUCCESS(wb)\t\t\\\n+\t(((wb) & MBOX_WB_STATUS_MASK) == MBOX_WB_STATUS_FINISHED_SUCCESS)\n+#define MBOX_STATUS_ERRCODE(wb)\t\t\\\n+\t((wb) & MBOX_WB_ERROR_CODE_MASK)\n+\n+#define SEQ_ID_START_VAL\t\t\t0\n+\n+#define DST_AEQ_IDX_DEFAULT_VAL\t\t\t0\n+#define SRC_AEQ_IDX_DEFAULT_VAL\t\t\t0\n+#define NO_DMA_ATTRIBUTE_VAL\t\t\t0\n+\n+#define MBOX_MSG_NO_DATA_LEN\t\t\t1\n+\n+#define FUNC_ID_OFF_SET_8B\t\t8\n+#define FUNC_ID_OFF_SET_10B\t\t10\n+\n+#define MBOX_BODY_FROM_HDR(header)\t((u8 *)(header) + MBOX_HEADER_SZ)\n+#define MBOX_AREA(hwif)\t\t\t\\\n+\t\t((hwif)->cfg_regs_base + HINIC_FUNC_CSR_MAILBOX_DATA_OFF)\n+\n+#define MBOX_RESPONSE_ERROR\t\t0x1\n+#define MBOX_MSG_ID_MASK\t\t0xFF\n+#define MBOX_MSG_ID(func_to_func)\t((func_to_func)->send_msg_id)\n+#define MBOX_MSG_ID_INC(func_to_func)\t(MBOX_MSG_ID(func_to_func) =\t\\\n+\t\t\t(MBOX_MSG_ID(func_to_func) + 1) & MBOX_MSG_ID_MASK)\n+\n+enum hinic_hwif_direction_type {\n+\t/* driver send msg to up or up send msg to drier*/\n+\tHINIC_HWIF_DIRECT_SEND = 0,\n+\t/* after driver/up send msg to each other, then up/driver ack the msg */\n+\tHINIC_HWIF_RESPONSE,\n+};\n+\n+enum mbox_send_mod {\n+\tMBOX_SEND_MSG_POLL = 1\n+};\n+\n+enum mbox_seg_type {\n+\tNOT_LAST_SEG,\n+\tLAST_SEG,\n+};\n+\n+enum mbox_ordering_type {\n+\tSTRONG_ORDER,\n+\tRELAX_ORDER,\n+};\n+\n+enum mbox_write_back_type {\n+\tNOT_WRITE_BACK = 0,\n+\tWRITE_BACK,\n+};\n+\n+enum mbox_aeq_trig_type {\n+\tNOT_TRIGGER,\n+\tTRIGGER,\n+};\n+\n+static int send_mbox_to_func(struct hinic_mbox_func_to_func *func_to_func,\n+\t\t\t\tenum hinic_mod_type mod, u16 cmd, void *msg,\n+\t\t\t\tu16 msg_len, u16 dst_func,\n+\t\t\t\tenum hinic_hwif_direction_type direction,\n+\t\t\t\tenum hinic_mbox_ack_type ack_type,\n+\t\t\t\tstruct mbox_msg_info *msg_info);\n+\n+static int recv_vf_mbox_handler(struct hinic_mbox_func_to_func *func_to_func,\n+\t\t\t\tstruct hinic_recv_mbox *recv_mbox,\n+\t\t\t\tvoid *buf_out, u16 *out_size, void *param)\n+{\n+\tint rc = 0;\n+\t*out_size = 0;\n+\n+\tswitch (recv_mbox->mod) {\n+\tcase HINIC_MOD_COMM:\n+\t\thinic_comm_async_event_handle(func_to_func->hwdev,\n+\t\t\t\t\t\trecv_mbox->cmd, recv_mbox->mbox,\n+\t\t\t\t\t\trecv_mbox->mbox_len,\n+\t\t\t\t\t\tbuf_out, out_size);\n+\t\tbreak;\n+\tcase HINIC_MOD_L2NIC:\n+\t\thinic_l2nic_async_event_handle(func_to_func->hwdev, param,\n+\t\t\t\t\t\trecv_mbox->cmd, recv_mbox->mbox,\n+\t\t\t\t\t\trecv_mbox->mbox_len,\n+\t\t\t\t\t\tbuf_out, out_size);\n+\t\tbreak;\n+\tdefault:\n+\t\tPMD_DRV_LOG(ERR, \"No handler, mod = %d\",\n+\t\t\t\trecv_mbox->mod);\n+\t\trc = HINIC_MBOX_VF_CMD_ERROR;\n+\t\tbreak;\n+\t}\n+\n+\treturn rc;\n+}\n+\n+static void set_mbx_msg_status(struct mbox_msg_info *msg_info, int status)\n+{\n+\tif (status == HINIC_DEV_BUSY_ACTIVE_FW)\n+\t\tmsg_info->status = HINIC_MBOX_PF_BUSY_ACTIVE_FW;\n+\telse if (status == HINIC_MBOX_VF_CMD_ERROR)\n+\t\tmsg_info->status = HINIC_MBOX_VF_CMD_ERROR;\n+\telse if (status)\n+\t\tmsg_info->status = HINIC_MBOX_PF_SEND_ERR;\n+}\n+\n+static void recv_func_mbox_handler(struct hinic_mbox_func_to_func *func_to_func,\n+\t\t\t\tstruct hinic_recv_mbox *recv_mbox,\n+\t\t\t\tu16 src_func_idx, void *param)\n+{\n+\tstruct hinic_hwdev *dev = func_to_func->hwdev;\n+\tstruct mbox_msg_info msg_info = { 0 };\n+\tu16 out_size = MBOX_MAX_BUF_SZ;\n+\tvoid *buf_out = recv_mbox->buf_out;\n+\tint err = 0;\n+\n+\tif (HINIC_IS_VF(dev)) {\n+\t\terr = recv_vf_mbox_handler(func_to_func, recv_mbox, buf_out,\n+\t\t\t\t\t\t&out_size, param);\n+\t} else {\n+\t\terr = -EINVAL;\n+\t\tPMD_DRV_LOG(ERR, \"PMD doesn't support non-VF handle mailbox message\");\n+\t}\n+\n+\tif (!out_size || err)\n+\t\tout_size = MBOX_MSG_NO_DATA_LEN;\n+\n+\tif (recv_mbox->ack_type == MBOX_ACK) {\n+\t\tmsg_info.msg_id = recv_mbox->msg_info.msg_id;\n+\t\tset_mbx_msg_status(&msg_info, err);\n+\t\tsend_mbox_to_func(func_to_func, recv_mbox->mod, recv_mbox->cmd,\n+\t\t\t\tbuf_out, out_size, src_func_idx,\n+\t\t\t\tHINIC_HWIF_RESPONSE, MBOX_ACK, &msg_info);\n+\t}\n+}\n+\n+static bool check_mbox_seq_id_and_seg_len(struct hinic_recv_mbox *recv_mbox,\n+\t\t\t\t\t  u8 seq_id, u8 seg_len)\n+{\n+\tif (seq_id > HINIC_SEQ_ID_MAX_VAL || seg_len > HINIC_MSG_SEG_LEN)\n+\t\treturn false;\n+\n+\tif (seq_id == 0) {\n+\t\trecv_mbox->sed_id = seq_id;\n+\t} else {\n+\t\tif (seq_id != recv_mbox->sed_id + 1) {\n+\t\t\trecv_mbox->sed_id = 0;\n+\t\t\treturn false;\n+\t\t}\n+\n+\t\trecv_mbox->sed_id = seq_id;\n+\t}\n+\n+\treturn true;\n+}\n+\n+static void clear_mbox_status(struct hinic_send_mbox *mbox)\n+{\n+\t/* clear mailbox write back status */\n+\t*mbox->wb_status = 0;\n+\trte_wmb();\n+}\n+\n+static void mbox_copy_header(struct hinic_send_mbox *mbox, u64 *header)\n+{\n+\tu32 *data = (u32 *)header;\n+\tu32 i, idx_max = MBOX_HEADER_SZ / sizeof(u32);\n+\n+\tfor (i = 0; i < idx_max; i++)\n+\t\t__raw_writel(*(data + i), mbox->data + i * sizeof(u32));\n+}\n+\n+static void\n+mbox_copy_send_data(struct hinic_send_mbox *mbox, void *seg, u16 seg_len)\n+{\n+\tu32 *data = (u32 *)seg;\n+\tu32 data_len, chk_sz = sizeof(u32);\n+\tu32 i, idx_max;\n+\tu8 mbox_max_buf[MBOX_SEG_LEN] = {0};\n+\n+\t/* The mbox message should be aligned in 4 bytes. */\n+\tif (seg_len % chk_sz) {\n+\t\tmemcpy(mbox_max_buf, seg, seg_len);\n+\t\tdata = (u32 *)mbox_max_buf;\n+\t}\n+\n+\tdata_len = seg_len;\n+\tidx_max = ALIGN(data_len, chk_sz) / chk_sz;\n+\n+\tfor (i = 0; i < idx_max; i++)\n+\t\t__raw_writel(*(data + i),\n+\t\t\t\tmbox->data + MBOX_HEADER_SZ + i * sizeof(u32));\n+}\n+\n+static void write_mbox_msg_attr(struct hinic_mbox_func_to_func *func_to_func,\n+\t\t\tu16 dst_func, u16 dst_aeqn,\n+\t\t\t__rte_unused u16 seg_len, int poll)\n+{\n+\tu32 mbox_int, mbox_ctrl;\n+\n+\tmbox_int = HINIC_MBOX_INT_SET(dst_func, DST_FUNC) |\n+\t\tHINIC_MBOX_INT_SET(dst_aeqn, DST_AEQN) |\n+\t\tHINIC_MBOX_INT_SET(HINIC_MBOX_RSP_AEQN, SRC_RESP_AEQN) |\n+\t\tHINIC_MBOX_INT_SET(NO_DMA_ATTRIBUTE_VAL, STAT_DMA) |\n+\t\tHINIC_MBOX_INT_SET(ALIGN(MBOX_SIZE, MBOX_SEG_LEN_ALIGN) >> 2,\n+\t\t\t\t\tTX_SIZE) |\n+\t\tHINIC_MBOX_INT_SET(STRONG_ORDER, STAT_DMA_SO_RO) |\n+\t\tHINIC_MBOX_INT_SET(WRITE_BACK, WB_EN);\n+\n+\thinic_hwif_write_reg(func_to_func->hwdev->hwif,\n+\t\t\tHINIC_FUNC_CSR_MAILBOX_INT_OFFSET_OFF, mbox_int);\n+\n+\trte_wmb();\n+\tmbox_ctrl = HINIC_MBOX_CTRL_SET(TX_IN_PROGRESS, TX_STATUS);\n+\n+\tif (poll)\n+\t\tmbox_ctrl |= HINIC_MBOX_CTRL_SET(NOT_TRIGGER, TRIGGER_AEQE);\n+\telse\n+\t\tmbox_ctrl |= HINIC_MBOX_CTRL_SET(TRIGGER, TRIGGER_AEQE);\n+\n+\thinic_hwif_write_reg(func_to_func->hwdev->hwif,\n+\t\t\t\tHINIC_FUNC_CSR_MAILBOX_CONTROL_OFF, mbox_ctrl);\n+}\n+\n+static int init_mbox_info(struct hinic_recv_mbox *mbox_info)\n+{\n+\tint err;\n+\n+\tmbox_info->mbox = kzalloc(MBOX_MAX_BUF_SZ, GFP_KERNEL);\n+\tif (!mbox_info->mbox) {\n+\t\tPMD_DRV_LOG(ERR, \"Alloc mbox buf_in mem failed\\n\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tmbox_info->buf_out = kzalloc(MBOX_MAX_BUF_SZ, GFP_KERNEL);\n+\tif (!mbox_info->buf_out) {\n+\t\tPMD_DRV_LOG(ERR, \"Alloc mbox buf_out mem failed\\n\");\n+\t\terr = -ENOMEM;\n+\t\tgoto alloc_buf_out_err;\n+\t}\n+\n+\treturn 0;\n+\n+alloc_buf_out_err:\n+\tkfree(mbox_info->mbox);\n+\n+\treturn err;\n+}\n+\n+static void clean_mbox_info(struct hinic_recv_mbox *mbox_info)\n+{\n+\tkfree(mbox_info->buf_out);\n+\tkfree(mbox_info->mbox);\n+}\n+\n+static int alloc_mbox_info(struct hinic_recv_mbox *mbox_info)\n+{\n+\tu16 func_idx, i;\n+\tint err;\n+\n+\tfor (func_idx = 0; func_idx < HINIC_MAX_FUNCTIONS; func_idx++) {\n+\t\terr = init_mbox_info(&mbox_info[func_idx]);\n+\t\tif (err) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Initialize function[%d] mailbox information failed, err: %d\",\n+\t\t\t\t    func_idx, err);\n+\t\t\tgoto init_mbox_info_err;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+\n+init_mbox_info_err:\n+\tfor (i = 0; i < func_idx; i++)\n+\t\tclean_mbox_info(&mbox_info[i]);\n+\n+\treturn err;\n+}\n+\n+static void free_mbox_info(struct hinic_recv_mbox *mbox_info)\n+{\n+\tu16 func_idx;\n+\n+\tfor (func_idx = 0; func_idx < HINIC_MAX_FUNCTIONS; func_idx++)\n+\t\tclean_mbox_info(&mbox_info[func_idx]);\n+}\n+\n+static void prepare_send_mbox(struct hinic_mbox_func_to_func *func_to_func)\n+{\n+\tstruct hinic_send_mbox *send_mbox = &func_to_func->send_mbox;\n+\n+\tsend_mbox->data = MBOX_AREA(func_to_func->hwdev->hwif);\n+}\n+\n+static int alloc_mbox_wb_status(struct hinic_mbox_func_to_func *func_to_func)\n+{\n+\tstruct hinic_send_mbox *send_mbox = &func_to_func->send_mbox;\n+\tstruct hinic_hwdev *hwdev = func_to_func->hwdev;\n+\tstruct hinic_hwif *hwif = hwdev->hwif;\n+\tu32 addr_h, addr_l;\n+\n+\tsend_mbox->wb_vaddr = dma_zalloc_coherent(hwdev,\n+\t\t\t\t  MBOX_WB_STATUS_LEN,\n+\t\t\t\t  &send_mbox->wb_paddr,\n+\t\t\t\t  GFP_KERNEL);\n+\tif (!send_mbox->wb_vaddr) {\n+\t\tPMD_DRV_LOG(ERR, \"Allocating memory for mailbox wb status failed\");\n+\t\treturn -ENOMEM;\n+\t}\n+\tsend_mbox->wb_status = (volatile u64 *)send_mbox->wb_vaddr;\n+\n+\taddr_h = upper_32_bits(send_mbox->wb_paddr);\n+\taddr_l = lower_32_bits(send_mbox->wb_paddr);\n+\thinic_hwif_write_reg(hwif, HINIC_FUNC_CSR_MAILBOX_RESULT_H_OFF, addr_h);\n+\thinic_hwif_write_reg(hwif, HINIC_FUNC_CSR_MAILBOX_RESULT_L_OFF, addr_l);\n+\n+\treturn 0;\n+}\n+\n+static void free_mbox_wb_status(struct hinic_mbox_func_to_func *func_to_func)\n+{\n+\tstruct hinic_send_mbox *send_mbox = &func_to_func->send_mbox;\n+\tstruct hinic_hwdev *hwdev = func_to_func->hwdev;\n+\tstruct hinic_hwif *hwif = hwdev->hwif;\n+\n+\thinic_hwif_write_reg(hwif, HINIC_FUNC_CSR_MAILBOX_RESULT_H_OFF, 0);\n+\thinic_hwif_write_reg(hwif, HINIC_FUNC_CSR_MAILBOX_RESULT_L_OFF, 0);\n+\n+\tdma_free_coherent(hwdev, MBOX_WB_STATUS_LEN,\n+\t\t\t\tsend_mbox->wb_vaddr, send_mbox->wb_paddr);\n+}\n+\n+static int recv_mbox_handler(struct hinic_mbox_func_to_func *func_to_func,\n+\t\tvoid *header, struct hinic_recv_mbox *recv_mbox, void *param)\n+{\n+\tu64 mbox_header = *((u64 *)header);\n+\tvoid *mbox_body = MBOX_BODY_FROM_HDR(header);\n+\tu16 src_func_idx;\n+\tenum hinic_hwif_direction_type direction;\n+\tu8 seq_id, seg_len;\n+\n+\tseq_id = HINIC_MBOX_HEADER_GET(mbox_header, SEQID);\n+\tseg_len = HINIC_MBOX_HEADER_GET(mbox_header, SEG_LEN);\n+\tdirection = HINIC_MBOX_HEADER_GET(mbox_header, DIRECTION);\n+\tsrc_func_idx = HINIC_MBOX_HEADER_GET(mbox_header, SRC_GLB_FUNC_IDX);\n+\n+\tif (!check_mbox_seq_id_and_seg_len(recv_mbox, seq_id, seg_len)) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Mailbox sequence and segment check failed, src func id: 0x%x, front id: 0x%x, current id: 0x%x, seg len: 0x%x\\n\",\n+\t\t\tsrc_func_idx, recv_mbox->sed_id, seq_id, seg_len);\n+\t\treturn HINIC_ERROR;\n+\t}\n+\n+\tmemcpy((u8 *)recv_mbox->mbox + seq_id * HINIC_MSG_SEG_LEN,\n+\t\tmbox_body, seg_len);\n+\n+\tif (!HINIC_MBOX_HEADER_GET(mbox_header, LAST))\n+\t\treturn HINIC_ERROR;\n+\n+\trecv_mbox->sed_id = 0;\n+\trecv_mbox->cmd = HINIC_MBOX_HEADER_GET(mbox_header, CMD);\n+\trecv_mbox->mod = HINIC_MBOX_HEADER_GET(mbox_header, MODULE);\n+\trecv_mbox->mbox_len = HINIC_MBOX_HEADER_GET(mbox_header, MSG_LEN);\n+\trecv_mbox->ack_type = HINIC_MBOX_HEADER_GET(mbox_header, NO_ACK);\n+\trecv_mbox->msg_info.msg_id = HINIC_MBOX_HEADER_GET(mbox_header, MSG_ID);\n+\trecv_mbox->msg_info.status = HINIC_MBOX_HEADER_GET(mbox_header, STATUS);\n+\n+\tif (direction == HINIC_HWIF_RESPONSE) {\n+\t\tif (recv_mbox->msg_info.msg_id == func_to_func->send_msg_id &&\n+\t\t\tfunc_to_func->event_flag == EVENT_START) {\n+\t\t\treturn HINIC_OK;\n+\t\t}\n+\n+\t\tPMD_DRV_LOG(ERR, \"Mbox response timeout, current send msg id(0x%x), recv msg id(0x%x), status(0x%x)\",\n+\t\t\tfunc_to_func->send_msg_id, recv_mbox->msg_info.msg_id,\n+\t\t\trecv_mbox->msg_info.status);\n+\t\treturn HINIC_ERROR;\n+\t}\n+\n+\trecv_func_mbox_handler(func_to_func, recv_mbox, src_func_idx, param);\n+\n+\treturn HINIC_ERROR;\n+}\n+\n+/**\n+ * hinic_mbox_func_aeqe_handler - Process mbox info from func which is\n+ * sent by aeqe.\n+ *\n+ * @param handle\n+ *   Pointer to hradware nic device.\n+ * @param header\n+ *   Mbox header info.\n+ * @param size\n+ *   The size of aeqe descriptor.\n+ * @param param\n+ *   customized parameter.\n+ *\n+ * @return\n+ *   0 on success, negative error value otherwise.\n+ */\n+int hinic_mbox_func_aeqe_handler(void *handle, u8 *header,\n+\t\t\t\t\t__rte_unused u8 size, void *param)\n+{\n+\tstruct hinic_mbox_func_to_func *func_to_func =\n+\t\t\t\t((struct hinic_hwdev *)handle)->func_to_func;\n+\tstruct hinic_recv_mbox *recv_mbox;\n+\tu64 mbox_header = *((u64 *)header);\n+\tu16 src = HINIC_MBOX_HEADER_GET(mbox_header, SRC_GLB_FUNC_IDX);\n+\n+\tif (src >= HINIC_MAX_FUNCTIONS) {\n+\t\tPMD_DRV_LOG(ERR, \"Mailbox source function id: %d is invalid\",\n+\t\t\t\tsrc);\n+\t\treturn HINIC_ERROR;\n+\t}\n+\n+\trecv_mbox = (HINIC_MBOX_HEADER_GET(mbox_header, DIRECTION) ==\n+\t\t\tHINIC_HWIF_DIRECT_SEND) ?\n+\t\t\t&func_to_func->mbox_send[src] :\n+\t\t\t&func_to_func->mbox_resp[src];\n+\n+\treturn recv_mbox_handler(func_to_func, (u64 *)header, recv_mbox, param);\n+}\n+\n+static u16 get_mbox_status(struct hinic_send_mbox *mbox)\n+{\n+\t/* write back is 16B, but only use first 4B */\n+\tu64 wb_val = be64_to_cpu(*mbox->wb_status);\n+\n+\trte_rmb(); /* verify reading before check */\n+\n+\treturn (u16)(wb_val & MBOX_WB_STATUS_ERRCODE_MASK);\n+}\n+\n+static void dump_mox_reg(struct hinic_hwdev *hwdev)\n+{\n+\tu32 val;\n+\n+\tval = hinic_hwif_read_reg(hwdev->hwif,\n+\t\t\t\t\tHINIC_FUNC_CSR_MAILBOX_CONTROL_OFF);\n+\tPMD_DRV_LOG(WARNING, \"Mailbox control reg: 0x%x\", val);\n+\tval = hinic_hwif_read_reg(hwdev->hwif,\n+\t\t\t\t\tHINIC_FUNC_CSR_MAILBOX_INT_OFFSET_OFF);\n+\tPMD_DRV_LOG(WARNING, \"Mailbox interrupt offset: 0x%x\", val);\n+}\n+\n+static int send_mbox_seg(struct hinic_mbox_func_to_func *func_to_func,\n+\t\t\t u64 header, u16 dst_func, void *seg, u16 seg_len)\n+{\n+\tstruct hinic_send_mbox *send_mbox = &func_to_func->send_mbox;\n+\tstruct hinic_hwdev *hwdev = func_to_func->hwdev;\n+\tu16 seq_dir = HINIC_MBOX_HEADER_GET(header, DIRECTION);\n+\tu16 dst_aeqn = (seq_dir == HINIC_HWIF_DIRECT_SEND) ?\n+\t\t\t\tHINIC_MBOX_RECV_AEQN : HINIC_MBOX_RSP_AEQN;\n+\tu16 err_code, wb_status = 0;\n+\tu32 cnt = 0;\n+\n+\tclear_mbox_status(send_mbox);\n+\n+\tmbox_copy_header(send_mbox, &header);\n+\n+\tmbox_copy_send_data(send_mbox, seg, seg_len);\n+\n+\twrite_mbox_msg_attr(func_to_func, dst_func, dst_aeqn, seg_len,\n+\t\t\t    MBOX_SEND_MSG_POLL);\n+\n+\trte_wmb();\n+\n+\twhile (cnt < MBOX_MSG_POLLING_TIMEOUT_MS) {\n+\t\twb_status = get_mbox_status(send_mbox);\n+\t\tif (MBOX_STATUS_FINISHED(wb_status))\n+\t\t\tbreak;\n+\n+\t\trte_delay_ms(1); /* loop every ms */\n+\t\tcnt++;\n+\t}\n+\n+\tif (cnt == MBOX_MSG_POLLING_TIMEOUT_MS) {\n+\t\tPMD_DRV_LOG(ERR, \"Send mailbox segment timeout, wb status: 0x%x\",\n+\t\t\t\twb_status);\n+\t\tdump_mox_reg(hwdev);\n+\t\treturn -ETIMEDOUT;\n+\t}\n+\n+\tif (!MBOX_STATUS_SUCCESS(wb_status)) {\n+\t\tPMD_DRV_LOG(ERR, \"Send mailbox segment to function %d error, wb status: 0x%x\",\n+\t\t\t\tdst_func, wb_status);\n+\t\t/*\n+\t\t * err_code: 0 responses no errors, other values can\n+\t\t * refer to FS doc.\n+\t\t */\n+\t\terr_code = MBOX_STATUS_ERRCODE(wb_status);\n+\t\treturn err_code ? err_code : -EFAULT;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static void set_mbox_to_func_event(struct hinic_mbox_func_to_func *func_to_func,\n+\t\t\t\t   enum mbox_event_state event_flag)\n+{\n+\tspin_lock(&func_to_func->mbox_lock);\n+\tfunc_to_func->event_flag = event_flag;\n+\tspin_unlock(&func_to_func->mbox_lock);\n+}\n+\n+static int send_mbox_to_func(struct hinic_mbox_func_to_func *func_to_func,\n+\t\t\t\tenum hinic_mod_type mod, u16 cmd, void *msg,\n+\t\t\t\tu16 msg_len, u16 dst_func,\n+\t\t\t\tenum hinic_hwif_direction_type direction,\n+\t\t\t\tenum hinic_mbox_ack_type ack_type,\n+\t\t\t\tstruct mbox_msg_info *msg_info)\n+{\n+\tstruct hinic_hwdev *hwdev = func_to_func->hwdev;\n+\tint err = 0;\n+\tu32 seq_id = 0;\n+\tu16 seg_len = HINIC_MSG_SEG_LEN;\n+\tu16 left = msg_len;\n+\tu8 *msg_seg = (u8 *)msg;\n+\tu64 header = 0;\n+\n+\terr = hinic_mutex_lock(&func_to_func->msg_send_mutex);\n+\tif (err)\n+\t\treturn err;\n+\n+\theader = HINIC_MBOX_HEADER_SET(msg_len, MSG_LEN) |\n+\t\tHINIC_MBOX_HEADER_SET(mod, MODULE) |\n+\t\tHINIC_MBOX_HEADER_SET(seg_len, SEG_LEN) |\n+\t\tHINIC_MBOX_HEADER_SET(ack_type, NO_ACK) |\n+\t\tHINIC_MBOX_HEADER_SET(SEQ_ID_START_VAL, SEQID) |\n+\t\tHINIC_MBOX_HEADER_SET(NOT_LAST_SEG, LAST) |\n+\t\tHINIC_MBOX_HEADER_SET(direction, DIRECTION) |\n+\t\tHINIC_MBOX_HEADER_SET(cmd, CMD) |\n+\t\tHINIC_MBOX_HEADER_SET(msg_info->msg_id, MSG_ID) |\n+\t\tHINIC_MBOX_HEADER_SET(msg_info->status, STATUS) |\n+\t\tHINIC_MBOX_HEADER_SET(hinic_global_func_id(hwdev),\n+\t\t\t\t\tSRC_GLB_FUNC_IDX);\n+\n+\twhile (!(HINIC_MBOX_HEADER_GET(header, LAST))) {\n+\t\tif (left <= HINIC_MSG_SEG_LEN) {\n+\t\t\theader &=\n+\t\t\t~(HINIC_MBOX_HEADER_SET(HINIC_MBOX_HEADER_SEG_LEN_MASK,\n+\t\t\t\t\t\tSEG_LEN));\n+\t\t\theader |= HINIC_MBOX_HEADER_SET(left, SEG_LEN);\n+\t\t\theader |= HINIC_MBOX_HEADER_SET(LAST_SEG, LAST);\n+\n+\t\t\tseg_len = left;\n+\t\t}\n+\n+\t\terr = send_mbox_seg(func_to_func, header, dst_func, msg_seg,\n+\t\t\t\t    seg_len);\n+\t\tif (err) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Fail to send mbox seg, seq_id: 0x%lx, err: %d\",\n+\t\t\t\tHINIC_MBOX_HEADER_GET(header, SEQID), err);\n+\t\t\tgoto send_err;\n+\t\t}\n+\n+\t\tleft -= HINIC_MSG_SEG_LEN;\n+\t\tmsg_seg += HINIC_MSG_SEG_LEN;\n+\n+\t\tseq_id++;\n+\t\theader &= ~(HINIC_MBOX_HEADER_SET(HINIC_MBOX_HEADER_SEQID_MASK,\n+\t\t\t\t\t\t\tSEQID));\n+\t\theader |= HINIC_MBOX_HEADER_SET(seq_id, SEQID);\n+\t}\n+\n+send_err:\n+\t(void)hinic_mutex_unlock(&func_to_func->msg_send_mutex);\n+\n+\treturn err;\n+}\n+\n+static int hinic_mbox_to_func(struct hinic_mbox_func_to_func *func_to_func,\n+\t\t\tenum hinic_mod_type mod, u16 cmd, u16 dst_func,\n+\t\t\tvoid *buf_in, u16 in_size, void *buf_out, u16 *out_size,\n+\t\t\tu32 timeout)\n+{\n+\tstruct hinic_recv_mbox *mbox_for_resp =\n+\t\t\t\t\t&func_to_func->mbox_resp[dst_func];\n+\tstruct mbox_msg_info msg_info = {0};\n+\tu32 time;\n+\tint err;\n+\n+\terr = hinic_mutex_lock(&func_to_func->mbox_send_mutex);\n+\tif (err)\n+\t\treturn err;\n+\n+\tmsg_info.msg_id = MBOX_MSG_ID_INC(func_to_func);\n+\n+\tset_mbox_to_func_event(func_to_func, EVENT_START);\n+\n+\terr = send_mbox_to_func(func_to_func, mod, cmd, buf_in, in_size,\n+\t\t\t\tdst_func, HINIC_HWIF_DIRECT_SEND,\n+\t\t\t\tMBOX_ACK, &msg_info);\n+\tif (err)\n+\t\tgoto send_err;\n+\n+\ttime = msecs_to_jiffies(timeout ? timeout : HINIC_MBOX_COMP_TIME_MS);\n+\terr = hinic_aeq_poll_msg(func_to_func->rsp_aeq, time, NULL);\n+\tif (err) {\n+\t\tset_mbox_to_func_event(func_to_func, EVENT_TIMEOUT);\n+\t\tPMD_DRV_LOG(ERR, \"Send mailbox message time out\");\n+\t\terr = -ETIMEDOUT;\n+\t\tgoto send_err;\n+\t}\n+\n+\tset_mbox_to_func_event(func_to_func, EVENT_END);\n+\n+\tif (mbox_for_resp->msg_info.status) {\n+\t\terr = mbox_for_resp->msg_info.status;\n+\t\tif (err != HINIC_MBOX_PF_BUSY_ACTIVE_FW)\n+\t\t\tPMD_DRV_LOG(ERR, \"Mailbox response error: 0x%x\",\n+\t\t\t\t\tmbox_for_resp->msg_info.status);\n+\t\telse\n+\t\t\tPMD_DRV_LOG(ERR, \"Chip is in active, PF can't process VF message\");\n+\t\tgoto send_err;\n+\t}\n+\n+\trte_rmb();\n+\n+\tif (mbox_for_resp->mbox_len && buf_out && out_size) {\n+\t\tif (mbox_for_resp->mbox_len <= *out_size) {\n+\t\t\tmemcpy(buf_out, mbox_for_resp->mbox,\n+\t\t\t\tmbox_for_resp->mbox_len);\n+\t\t\t*out_size = mbox_for_resp->mbox_len;\n+\t\t} else {\n+\t\t\tPMD_DRV_LOG(ERR, \"Mailbox response message len[%u] overflow\",\n+\t\t\t\t\tmbox_for_resp->mbox_len);\n+\t\t\terr = -ERANGE;\n+\t\t}\n+\t}\n+\n+send_err:\n+\tif (err && out_size)\n+\t\t*out_size = 0;\n+\t(void)hinic_mutex_unlock(&func_to_func->mbox_send_mutex);\n+\n+\treturn err;\n+}\n+\n+static int\n+mbox_func_params_valid(__rte_unused struct hinic_mbox_func_to_func *mbox_obj,\n+\t\t\tvoid *buf_in, u16 in_size)\n+{\n+\tif (!buf_in || !in_size)\n+\t\treturn -EINVAL;\n+\n+\tif (in_size > HINIC_MBOX_DATA_SIZE) {\n+\t\tPMD_DRV_LOG(ERR, \"Mailbox message len(%d) exceed limit(%d)\",\n+\t\t\t\tin_size, HINIC_MBOX_DATA_SIZE);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static u8 hinic_pf_id_of_vf(void *hwdev)\n+{\n+\tstruct hinic_hwif *hwif = ((struct hinic_hwdev *)hwdev)->hwif;\n+\treturn hwif->attr.port_to_port_idx;\n+}\n+\n+/**\n+ * hinic_mbox_to_pf - Send mbox info to pf and need pf to response.\n+ *\n+ * @param hwdev\n+ *   Pointer to hardware nic device.\n+ * @param mod\n+ *   Mode type of hardware.\n+ * @param cmd\n+ *   The command sent to pf.\n+ * @param buf_in\n+ *   Input parameter.\n+ * @param in_size\n+ *   Input parameter size.\n+ * @param buf_out\n+ *   Output parameter.\n+ * @param out_size\n+ *   Output parameter size.\n+ * @param timeout\n+ *   Timeout.\n+ *\n+ * @return\n+ *   0 on success, negative error value otherwise.\n+ */\n+int hinic_mbox_to_pf(struct hinic_hwdev *hwdev,\n+\t\t      enum hinic_mod_type mod, u8 cmd, void *buf_in,\n+\t\t      u16 in_size, void *buf_out, u16 *out_size, u32 timeout)\n+{\n+\tstruct hinic_mbox_func_to_func *func_to_func = hwdev->func_to_func;\n+\tint err;\n+\n+\terr = mbox_func_params_valid(func_to_func, buf_in, in_size);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Mailbox parameters check failed: %d\", err);\n+\t\treturn err;\n+\t}\n+\n+\tif (!HINIC_IS_VF(hwdev)) {\n+\t\tPMD_DRV_LOG(ERR, \"Input function type error, func_type: %d\",\n+\t\t\t\thinic_func_type(hwdev));\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn hinic_mbox_to_func(func_to_func, mod, cmd,\n+\t\t\t\t   hinic_pf_id_of_vf(hwdev), buf_in, in_size,\n+\t\t\t\t   buf_out, out_size, timeout);\n+}\n+\n+/**\n+ * hinic_mbox_to_pf_no_ack - Send mbox info to pf and do not need pf to response\n+ *\n+ * @param hwdev\n+ *   Pointer to hardware nic device.\n+ * @param mod\n+ *   Mode type of hardware.\n+ * @param cmd\n+ *   The command sent to pf.\n+ * @param buf_in\n+ *   Input parameter.\n+ * @param in_size\n+ *   Input parameter size.\n+ *\n+ * @return\n+ *   0 on success, negative error value otherwise.\n+ */\n+int hinic_mbox_to_pf_no_ack(struct hinic_hwdev *hwdev, enum hinic_mod_type mod,\n+\t\t\tu8 cmd, void *buf_in, u16 in_size)\n+{\n+\tint err;\n+\tstruct mbox_msg_info msg_info = {0};\n+\n+\terr = hinic_mutex_lock(&hwdev->func_to_func->mbox_send_mutex);\n+\tif (err)\n+\t\treturn err;\n+\n+\terr = send_mbox_to_func(hwdev->func_to_func, mod, cmd, buf_in, in_size,\n+\t\t\thinic_pf_id_of_vf(hwdev), HINIC_HWIF_DIRECT_SEND,\n+\t\t\tMBOX_NO_ACK, &msg_info);\n+\tif (err)\n+\t\tPMD_DRV_LOG(ERR, \"Send mailbox no ack failed, err: %d\", err);\n+\n+\t(void)hinic_mutex_unlock(&hwdev->func_to_func->mbox_send_mutex);\n+\n+\treturn err;\n+}\n+\n+static int hinic_func_to_func_init(struct hinic_hwdev *hwdev)\n+{\n+\tstruct hinic_mbox_func_to_func *func_to_func;\n+\tint err;\n+\n+\tfunc_to_func = kzalloc(sizeof(*func_to_func), GFP_KERNEL);\n+\tif (!func_to_func) {\n+\t\tPMD_DRV_LOG(ERR, \"Allocating memory for func_to_func object failed\");\n+\t\treturn -ENOMEM;\n+\t}\n+\thwdev->func_to_func = func_to_func;\n+\tfunc_to_func->hwdev = hwdev;\n+\t(void)hinic_mutex_init(&func_to_func->mbox_send_mutex, NULL);\n+\t(void)hinic_mutex_init(&func_to_func->msg_send_mutex, NULL);\n+\n+\terr = alloc_mbox_info(func_to_func->mbox_send);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Allocating memory for mailbox sending failed\");\n+\t\tgoto alloc_mbox_for_send_err;\n+\t}\n+\n+\terr = alloc_mbox_info(func_to_func->mbox_resp);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Allocating memory for mailbox responsing failed\");\n+\t\tgoto alloc_mbox_for_resp_err;\n+\t}\n+\n+\terr = alloc_mbox_wb_status(func_to_func);\n+\tif (err)\n+\t\tgoto alloc_wb_status_err;\n+\n+\tprepare_send_mbox(func_to_func);\n+\n+\treturn 0;\n+\n+alloc_wb_status_err:\n+\tfree_mbox_info(func_to_func->mbox_resp);\n+\n+alloc_mbox_for_resp_err:\n+\tfree_mbox_info(func_to_func->mbox_send);\n+\n+alloc_mbox_for_send_err:\n+\tkfree(func_to_func);\n+\n+\treturn err;\n+}\n+\n+/**\n+ * hinic_comm_func_to_func_free - Uninitialize func to func resource.\n+ *\n+ * @param hwdev\n+ *   Pointer to hardware nic device.\n+ */\n+void hinic_comm_func_to_func_free(struct hinic_hwdev *hwdev)\n+{\n+\tstruct hinic_mbox_func_to_func *func_to_func = hwdev->func_to_func;\n+\n+\tfree_mbox_wb_status(func_to_func);\n+\tfree_mbox_info(func_to_func->mbox_resp);\n+\tfree_mbox_info(func_to_func->mbox_send);\n+\t(void)hinic_mutex_destroy(&func_to_func->mbox_send_mutex);\n+\t(void)hinic_mutex_destroy(&func_to_func->msg_send_mutex);\n+\tkfree(func_to_func);\n+}\n+\n+/**\n+ * hinic_comm_func_to_func_init - Initialize func to func resource.\n+ *\n+ * @param hwdev\n+ *   Pointer to hardware nic device.\n+ */\n+int hinic_comm_func_to_func_init(struct hinic_hwdev *hwdev)\n+{\n+\tint rc;\n+\n+\trc = hinic_func_to_func_init(hwdev);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\thwdev->func_to_func->rsp_aeq = &hwdev->aeqs->aeq[HINIC_MBOX_RSP_AEQN];\n+\thwdev->func_to_func->recv_aeq = &hwdev->aeqs->aeq[HINIC_MBOX_RECV_AEQN];\n+\n+\treturn 0;\n+}\n+\ndiff --git a/drivers/net/hinic/base/hinic_pmd_mbox.h b/drivers/net/hinic/base/hinic_pmd_mbox.h\nnew file mode 100644\nindex 0000000..bf7b490\n--- /dev/null\n+++ b/drivers/net/hinic/base/hinic_pmd_mbox.h\n@@ -0,0 +1,93 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2017 Huawei Technologies Co., Ltd\n+ */\n+\n+#ifndef _HINIC_PMD_MBOX_H_\n+#define _HINIC_PMD_MBOX_H_\n+\n+#define HINIC_MBOX_RECV_AEQN\t\t0\n+#define HINIC_MBOX_RSP_AEQN\t\t2\n+\n+#define HINIC_MBOX_PF_SEND_ERR\t\t0x1\n+#define HINIC_MBOX_PF_BUSY_ACTIVE_FW\t0x2\n+#define HINIC_MBOX_VF_CMD_ERROR\t\t0x3\n+\n+/* PFs do not support enable SR-IOV cap when PFs use PMD, VFs just receive\n+ * mailbox message from PFs. The max number of PFs is 16, so the max number\n+ * of mailbox buffer for functions is also 16.\n+ */\n+#define HINIC_MAX_FUNCTIONS\t\t16\n+#define HINIC_MAX_PF_FUNCS\t\t16\n+\n+#define HINIC_MGMT_CMD_UNSUPPORTED\t0xFF\n+\n+#define HINIC_SEQ_ID_MAX_VAL\t\t42\n+#define HINIC_MSG_SEG_LEN\t\t48\n+\n+enum hinic_mbox_ack_type {\n+\tMBOX_ACK,\n+\tMBOX_NO_ACK,\n+};\n+\n+struct mbox_msg_info {\n+\tu8 msg_id;\n+\tu8 status; /*can only use 6 bit*/\n+};\n+\n+struct hinic_recv_mbox {\n+\tvoid *mbox;\n+\tu8 cmd;\n+\tenum hinic_mod_type mod;\n+\tu16 mbox_len;\n+\tvoid *buf_out;\n+\tenum hinic_mbox_ack_type ack_type;\n+\tstruct mbox_msg_info msg_info;\n+\tu8 sed_id;\n+};\n+\n+struct hinic_send_mbox {\n+\tu8 *data;\n+\tvolatile u64 *wb_status;\n+\tvoid *wb_vaddr;\n+\tdma_addr_t wb_paddr;\n+};\n+\n+enum mbox_event_state {\n+\tEVENT_START = 0,\n+\tEVENT_TIMEOUT,\n+\tEVENT_END,\n+};\n+\n+struct hinic_mbox_func_to_func {\n+\tstruct hinic_hwdev *hwdev;\n+\n+\tpthread_mutex_t     mbox_send_mutex;\n+\tpthread_mutex_t     msg_send_mutex;\n+\n+\tstruct hinic_send_mbox send_mbox;\n+\n+\tstruct hinic_recv_mbox mbox_resp[HINIC_MAX_FUNCTIONS];\n+\tstruct hinic_recv_mbox mbox_send[HINIC_MAX_FUNCTIONS];\n+\n+\tstruct hinic_eq *rsp_aeq;\n+\tstruct hinic_eq *recv_aeq;\n+\n+\tu8 send_msg_id;\n+\tenum mbox_event_state event_flag;\n+\tspinlock_t mbox_lock; /* lock for mbox event flag */\n+};\n+\n+/*\n+ * mbox function prototypes\n+ */\n+int hinic_comm_func_to_func_init(struct hinic_hwdev *hwdev);\n+void hinic_comm_func_to_func_free(struct hinic_hwdev *hwdev);\n+int hinic_mbox_func_aeqe_handler(void *handle, u8 *header,\n+\t\t\t\t\tu8 size, void *param);\n+int hinic_mbox_to_pf(struct hinic_hwdev *hwdev, enum hinic_mod_type mod, u8 cmd,\n+\t\t\tvoid *buf_in, u16 in_size,\n+\t\t\tvoid *buf_out, u16 *out_size, u32 timeout);\n+int hinic_mbox_to_pf_no_ack(struct hinic_hwdev *hwdev, enum hinic_mod_type mod,\n+\t\t\t\tu8 cmd, void *buf_in, u16 in_size);\n+\n+#endif /* _HINIC_PMD_MBOX_H_ */\ndiff --git a/drivers/net/hinic/base/meson.build b/drivers/net/hinic/base/meson.build\nindex cde394a..6cf947f 100644\n--- a/drivers/net/hinic/base/meson.build\n+++ b/drivers/net/hinic/base/meson.build\n@@ -12,6 +12,7 @@ sources = [\n \t'hinic_pmd_niccfg.c',\n \t'hinic_pmd_nicio.c',\n \t'hinic_pmd_wq.c',\n+ \t'hinic_pmd_mbox.c',\n ]\n \n extra_flags = []\n",
    "prefixes": [
        "v2",
        "01/17"
    ]
}