get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 105242,
    "url": "http://patches.dpdk.org/api/patches/105242/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/6451d119ff8b1c838ae5041f1d35a616a04fbd74.1639636621.git.songyl@ramaxel.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": "<6451d119ff8b1c838ae5041f1d35a616a04fbd74.1639636621.git.songyl@ramaxel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/6451d119ff8b1c838ae5041f1d35a616a04fbd74.1639636621.git.songyl@ramaxel.com",
    "date": "2021-12-18T02:51:32",
    "name": "[v1,05/25] net/spnic: add mgmt module",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "782c1bfd625249679b08f3fe342107881b8fe241",
    "submitter": {
        "id": 2455,
        "url": "http://patches.dpdk.org/api/people/2455/?format=api",
        "name": "Yanling Song",
        "email": "songyl@ramaxel.com"
    },
    "delegate": null,
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/6451d119ff8b1c838ae5041f1d35a616a04fbd74.1639636621.git.songyl@ramaxel.com/mbox/",
    "series": [
        {
            "id": 20973,
            "url": "http://patches.dpdk.org/api/series/20973/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=20973",
            "date": "2021-12-18T02:51:28",
            "name": "Net/SPNIC: support SPNIC into DPDK 22.03",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/20973/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/105242/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/105242/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 0B114A04A4;\n\tSat, 18 Dec 2021 03:52:31 +0100 (CET)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 2A62541148;\n\tSat, 18 Dec 2021 03:52:20 +0100 (CET)",
            "from VLXDG1SPAM1.ramaxel.com (email.ramaxel.com [221.4.138.186])\n by mails.dpdk.org (Postfix) with ESMTP id 0478341152\n for <dev@dpdk.org>; Sat, 18 Dec 2021 03:52:18 +0100 (CET)",
            "from V12DG1MBS01.ramaxel.local (v12dg1mbs01.ramaxel.local\n [172.26.18.31])\n by VLXDG1SPAM1.ramaxel.com with ESMTPS id 1BI2pxKP010303\n (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL);\n Sat, 18 Dec 2021 10:51:59 +0800 (GMT-8)\n (envelope-from songyl@ramaxel.com)",
            "from localhost.localdomain (10.64.9.47) by V12DG1MBS01.ramaxel.local\n (172.26.18.31) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2308.14; Sat, 18\n Dec 2021 10:51:58 +0800"
        ],
        "From": "Yanling Song <songyl@ramaxel.com>",
        "To": "<dev@dpdk.org>",
        "CC": "<songyl@ramaxel.com>, <yanling.song@linux.dev>, <yanggan@ramaxel.com>,\n <ferruh.yigit@intel.com>",
        "Subject": "[PATCH v1 05/25] net/spnic: add mgmt module",
        "Date": "Sat, 18 Dec 2021 10:51:32 +0800",
        "Message-ID": "\n <6451d119ff8b1c838ae5041f1d35a616a04fbd74.1639636621.git.songyl@ramaxel.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<cover.1639636621.git.songyl@ramaxel.com>",
        "References": "<cover.1639636621.git.songyl@ramaxel.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[10.64.9.47]",
        "X-ClientProxiedBy": "V12DG1MBS01.ramaxel.local (172.26.18.31) To\n V12DG1MBS01.ramaxel.local (172.26.18.31)",
        "X-DNSRBL": "",
        "X-MAIL": "VLXDG1SPAM1.ramaxel.com 1BI2pxKP010303",
        "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": "Mgmt module manage the message gerenated from the hardware.\nThis patch implements mgmt module initialization, related event\nprocessing and message command definition.\n\nSigned-off-by: Yanling Song <songyl@ramaxel.com>\n---\n drivers/net/spnic/base/meson.build       |   4 +-\n drivers/net/spnic/base/spnic_cmd.h       | 222 ++++++++++++++\n drivers/net/spnic/base/spnic_eqs.c       |  46 ++-\n drivers/net/spnic/base/spnic_hwdev.c     |  91 +++++-\n drivers/net/spnic/base/spnic_hwdev.h     |  66 +++-\n drivers/net/spnic/base/spnic_mbox.c      |  17 ++\n drivers/net/spnic/base/spnic_mgmt.c      | 367 +++++++++++++++++++++++\n drivers/net/spnic/base/spnic_mgmt.h      |  74 +++++\n drivers/net/spnic/base/spnic_nic_event.c | 171 +++++++++++\n drivers/net/spnic/base/spnic_nic_event.h |  34 +++\n 10 files changed, 1081 insertions(+), 11 deletions(-)\n create mode 100644 drivers/net/spnic/base/spnic_cmd.h\n create mode 100644 drivers/net/spnic/base/spnic_mgmt.c\n create mode 100644 drivers/net/spnic/base/spnic_nic_event.c\n create mode 100644 drivers/net/spnic/base/spnic_nic_event.h",
    "diff": "diff --git a/drivers/net/spnic/base/meson.build b/drivers/net/spnic/base/meson.build\nindex ce7457f400..3f6a060b37 100644\n--- a/drivers/net/spnic/base/meson.build\n+++ b/drivers/net/spnic/base/meson.build\n@@ -5,7 +5,9 @@ sources = [\n \t'spnic_eqs.c',\n \t'spnic_hwdev.c',\n \t'spnic_hwif.c',\n-\t'spnic_mbox.c'\n+\t'spnic_mbox.c',\n+\t'spnic_mgmt.c',\n+\t'spnic_nic_event.c'\n ]\n \n extra_flags = []\ndiff --git a/drivers/net/spnic/base/spnic_cmd.h b/drivers/net/spnic/base/spnic_cmd.h\nnew file mode 100644\nindex 0000000000..8900489eef\n--- /dev/null\n+++ b/drivers/net/spnic/base/spnic_cmd.h\n@@ -0,0 +1,222 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2021 Ramaxel Memory Technology, Ltd\n+ */\n+\n+#ifndef _SPNIC_CMD_H_\n+#define _SPNIC_CMD_H_\n+\n+#define NIC_RSS_TEMP_ID_TO_CTX_LT_IDX(tmp_id)\ttmp_id\n+/* Begin of one temp tbl */\n+#define NIC_RSS_TEMP_ID_TO_INDIR_LT_IDX(tmp_id)\t((tmp_id) << 4)\n+/* 4 ctx in one entry */\n+#define NIC_RSS_CTX_TBL_ENTRY_SIZE\t\t0x10\n+/* Entry size = 16B, 16 entry/template */\n+#define NIC_RSS_INDIR_TBL_ENTRY_SIZE\t\t0x10\n+/* Entry size = 16B, so entry_num = 256B/16B */\n+#define NIC_RSS_INDIR_TBL_ENTRY_NUM\t\t0x10\n+\n+#define NIC_UP_RSS_INVALID_TEMP_ID\t\t0xFF\n+#define NIC_UP_RSS_INVALID_FUNC_ID\t\t0xFFFF\n+#define NIC_UP_RSS_INVALID\t\t\t0x00\n+#define NIC_UP_RSS_EN\t\t\t\t0x01\n+#define NIC_UP_RSS_INVALID_GROUP_ID\t\t0x7F\n+\n+#define NIC_RSS_CMD_TEMP_ALLOC\t\t\t0x01\n+#define NIC_RSS_CMD_TEMP_FREE\t\t\t0x02\n+\n+#define SPNIC_RSS_TYPE_VALID_SHIFT\t\t23\n+#define SPNIC_RSS_TYPE_TCP_IPV6_EXT_SHIFT\t24\n+#define SPNIC_RSS_TYPE_IPV6_EXT_SHIFT\t\t25\n+#define SPNIC_RSS_TYPE_TCP_IPV6_SHIFT\t\t26\n+#define SPNIC_RSS_TYPE_IPV6_SHIFT\t\t27\n+#define SPNIC_RSS_TYPE_TCP_IPV4_SHIFT\t\t28\n+#define SPNIC_RSS_TYPE_IPV4_SHIFT\t\t29\n+#define SPNIC_RSS_TYPE_UDP_IPV6_SHIFT\t\t30\n+#define SPNIC_RSS_TYPE_UDP_IPV4_SHIFT\t\t31\n+#define SPNIC_RSS_TYPE_SET(val, member)\t\\\n+\t(((u32)(val) & 0x1) << SPNIC_RSS_TYPE_##member##_SHIFT)\n+\n+#define SPNIC_RSS_TYPE_GET(val, member)\t\\\n+\t(((u32)(val) >> SPNIC_RSS_TYPE_##member##_SHIFT) & 0x1)\n+\n+/* NIC CMDQ MODE */\n+typedef enum spnic_ucode_cmd {\n+\tSPNIC_UCODE_CMD_MODIFY_QUEUE_CTX = 0,\n+\tSPNIC_UCODE_CMD_CLEAN_QUEUE_CONTEXT,\n+\tSPNIC_UCODE_CMD_ARM_SQ,\n+\tSPNIC_UCODE_CMD_ARM_RQ,\n+\tSPNIC_UCODE_CMD_SET_RSS_INDIR_TABLE,\n+\tSPNIC_UCODE_CMD_SET_RSS_CONTEXT_TABLE,\n+\tSPNIC_UCODE_CMD_GET_RSS_INDIR_TABLE,\n+\tSPNIC_UCODE_CMD_GET_RSS_CONTEXT_TABLE,\n+\tSPNIC_UCODE_CMD_SET_IQ_ENABLE,\n+\tSPNIC_UCODE_CMD_SET_RQ_FLUSH = 10,\n+\tSPNIC_UCODE_CMD_MODIFY_VLAN_CTX,\n+\tSPNIC_UCODE_CMD_DPI_FLOW\n+} cmdq_nic_subtype_e;\n+\n+/*\n+ * Commands between NIC and MPU\n+ */\n+enum spnic_cmd {\n+\tSPNIC_CMD_VF_REGISTER = 0, /* only for PFD and VFD */\n+\n+\t/* FUNC CFG */\n+\tSPNIC_CMD_SET_FUNC_TBL = 5,\n+\tSPNIC_CMD_SET_VPORT_ENABLE,\n+\tSPNIC_CMD_SET_RX_MODE,\n+\tSPNIC_CMD_SQ_CI_ATTR_SET,\n+\tSPNIC_CMD_GET_VPORT_STAT,\n+\tSPNIC_CMD_CLEAN_VPORT_STAT,\n+\tSPNIC_CMD_CLEAR_QP_RESOURCE,\n+\tSPNIC_CMD_CFG_FLEX_QUEUE,\n+\t/* LRO CFG */\n+\tSPNIC_CMD_CFG_RX_LRO,\n+\tSPNIC_CMD_CFG_LRO_TIMER,\n+\tSPNIC_CMD_FEATURE_NEGO,\n+\n+\t/* MAC & VLAN CFG */\n+\tSPNIC_CMD_GET_MAC = 20,\n+\tSPNIC_CMD_SET_MAC,\n+\tSPNIC_CMD_DEL_MAC,\n+\tSPNIC_CMD_UPDATE_MAC,\n+\tSPNIC_CMD_GET_ALL_DEFAULT_MAC,\n+\n+\tSPNIC_CMD_CFG_FUNC_VLAN,\n+\tSPNIC_CMD_SET_VLAN_FILTER_EN,\n+\tSPNIC_CMD_SET_RX_VLAN_OFFLOAD,\n+\n+\t/* SR-IOV */\n+\tSPNIC_CMD_CFG_VF_VLAN = 40,\n+\tSPNIC_CMD_SET_SPOOPCHK_STATE,\n+\t/* RATE LIMIT */\n+\tSPNIC_CMD_SET_MAX_MIN_RATE,\n+\n+\t/* RSS CFG */\n+\tSPNIC_CMD_RSS_CFG = 60,\n+\tSPNIC_CMD_RSS_TEMP_MGR,\n+\tSPNIC_CMD_GET_RSS_CTX_TBL,\n+\tSPNIC_CMD_CFG_RSS_HASH_KEY,\n+\tSPNIC_CMD_CFG_RSS_HASH_ENGINE,\n+\tSPNIC_CMD_GET_INDIR_TBL,\n+\n+\t/* DPI/FDIR */\n+\tSPNIC_CMD_ADD_TC_FLOW = 80,\n+\tSPNIC_CMD_DEL_TC_FLOW,\n+\tSPNIC_CMD_GET_TC_FLOW,\n+\tSPNIC_CMD_FLUSH_TCAM,\n+\tSPNIC_CMD_CFG_TCAM_BLOCK,\n+\tSPNIC_CMD_ENABLE_TCAM,\n+\tSPNIC_CMD_GET_TCAM_BLOCK,\n+\n+\t/* PORT CFG */\n+\tSPNIC_CMD_SET_PORT_ENABLE = 100,\n+\tSPNIC_CMD_CFG_PAUSE_INFO,\n+\n+\tSPNIC_CMD_SET_PORT_CAR,\n+\tSPNIC_CMD_SET_ER_DROP_PKT,\n+\n+\tSPNIC_CMD_VF_COS,\n+\tSPNIC_CMD_SETUP_COS_MAPPING,\n+\tSPNIC_CMD_SET_ETS,\n+\tSPNIC_CMD_SET_PFC,\n+\n+\t/* MISC */\n+\tSPNIC_CMD_BIOS_CFG = 120,\n+\tSPNIC_CMD_SET_FIRMWARE_CUSTOM_PACKETS_MSG,\n+\n+\t/* DFX */\n+\tSPNIC_CMD_GET_SM_TABLE = 140,\n+\tSPNIC_CMD_RD_LINE_TBL,\n+\n+\tSPNIC_CMD_MAX = 256\n+};\n+\n+/* COMM commands between driver to MPU */\n+enum spnic_mgmt_cmd {\n+\tMGMT_CMD_FUNC_RESET = 0,\n+\tMGMT_CMD_FEATURE_NEGO,\n+\tMGMT_CMD_FLUSH_DOORBELL,\n+\tMGMT_CMD_START_FLUSH,\n+\tMGMT_CMD_SET_FUNC_FLR,\n+\n+\tMGMT_CMD_SET_CMDQ_CTXT = 20,\n+\tMGMT_CMD_SET_VAT,\n+\tMGMT_CMD_CFG_PAGESIZE,\n+\tMGMT_CMD_CFG_MSIX_CTRL_REG,\n+\tMGMT_CMD_SET_CEQ_CTRL_REG,\n+\tMGMT_CMD_SET_DMA_ATTR,\n+\n+\tMGMT_CMD_GET_MQM_FIX_INFO = 40,\n+\tMGMT_CMD_SET_MQM_CFG_INFO,\n+\tMGMT_CMD_SET_MQM_SRCH_GPA,\n+\tMGMT_CMD_SET_PPF_TMR,\n+\tMGMT_CMD_SET_PPF_HT_GPA,\n+\tMGMT_CMD_SET_FUNC_TMR_BITMAT,\n+\n+\tMGMT_CMD_GET_FW_VERSION = 60,\n+\tMGMT_CMD_GET_BOARD_INFO,\n+\tMGMT_CMD_SYNC_TIME,\n+\tMGMT_CMD_GET_HW_PF_INFOS,\n+\tMGMT_CMD_SEND_BDF_INFO,\n+\n+\tMGMT_CMD_UPDATE_FW = 80,\n+\tMGMT_CMD_ACTIVE_FW,\n+\tMGMT_CMD_HOT_ACTIVE_FW,\n+\tMGMT_CMD_HOT_ACTIVE_DONE_NOTICE,\n+\tMGMT_CMD_SWITCH_CFG,\n+\tMGMT_CMD_CHECK_FLASH,\n+\tMGMT_CMD_CHECK_FLASH_RW,\n+\tMGMT_CMD_RESOURCE_CFG,\n+\tMGMT_CMD_UPDATE_BIOS,\n+\n+\tMGMT_CMD_FAULT_REPORT = 100,\n+\tMGMT_CMD_WATCHDOG_INFO,\n+\tMGMT_CMD_MGMT_RESET,\n+\tMGMT_CMD_FFM_SET,\n+\n+\tMGMT_CMD_GET_LOG = 120,\n+\tMGMT_CMD_TEMP_OP,\n+\tMGMT_CMD_EN_AUTO_RST_CHIP,\n+\tMGMT_CMD_CFG_REG,\n+\tMGMT_CMD_GET_CHIP_ID,\n+\tMGMT_CMD_SYSINFO_DFX,\n+\tMGMT_CMD_PCIE_DFX_NTC,\n+};\n+\n+enum mag_cmd {\n+\tSERDES_CMD_PROCESS = 0,\n+\n+\tMAG_CMD_SET_PORT_CFG      = 1,\n+\tMAG_CMD_SET_PORT_ADAPT    = 2,\n+\tMAG_CMD_CFG_LOOPBACK_MODE = 3,\n+\n+\tMAG_CMD_GET_PORT_ENABLE   = 5,\n+\tMAG_CMD_SET_PORT_ENABLE   = 6,\n+\tMAG_CMD_GET_LINK_STATUS   = 7,\n+\tMAG_CMD_SET_LINK_FOLLOW   = 8,\n+\tMAG_CMD_SET_PMA_ENABLE    = 9,\n+\tMAG_CMD_CFG_FEC_MODE      = 10,\n+\n+\t/* PHY */\n+\tMAG_CMD_GET_XSFP_INFO        = 60,\n+\tMAG_CMD_SET_XSFP_ENABLE      = 61,\n+\tMAG_CMD_GET_XSFP_PRESENT     = 62,\n+\tMAG_CMD_SET_XSFP_RW          = 63,\n+\tMAG_CMD_CFG_XSFP_TEMPERATURE = 64,\n+\n+\tMAG_CMD_WIRE_EVENT        = 100,\n+\tMAG_CMD_LINK_ERR_EVENT    = 101,\n+\n+\tMAG_CMD_EVENT_PORT_INFO   = 150,\n+\tMAG_CMD_GET_PORT_STAT     = 151,\n+\tMAG_CMD_CLR_PORT_STAT     = 152,\n+\tMAG_CMD_GET_PORT_INFO     = 153,\n+\tMAG_CMD_GET_PCS_ERR_CNT   = 154,\n+\tMAG_CMD_GET_MAG_CNT       = 155,\n+\tMAG_CMD_DUMP_ANTRAIN_INFO = 156,\n+\n+\tMAG_CMD_MAX = 0xFF\n+};\n+\n+#endif /* _SPNIC_CMD_H_ */\ndiff --git a/drivers/net/spnic/base/spnic_eqs.c b/drivers/net/spnic/base/spnic_eqs.c\nindex 7953976441..ee52252ecc 100644\n--- a/drivers/net/spnic/base/spnic_eqs.c\n+++ b/drivers/net/spnic/base/spnic_eqs.c\n@@ -12,6 +12,7 @@\n #include \"spnic_eqs.h\"\n #include \"spnic_mgmt.h\"\n #include \"spnic_mbox.h\"\n+#include \"spnic_nic_event.h\"\n \n #define AEQ_CTRL_0_INTR_IDX_SHIFT\t\t0\n #define AEQ_CTRL_0_DMA_ATTR_SHIFT\t\t12\n@@ -510,6 +511,39 @@ void spnic_aeqs_free(struct spnic_hwdev *hwdev)\n \trte_free(aeqs);\n }\n \n+void spnic_dump_aeq_info(struct spnic_hwdev *hwdev)\n+{\n+\tstruct spnic_aeq_elem *aeqe_pos = NULL;\n+\tstruct spnic_eq *eq = NULL;\n+\tu32 addr, ci, pi, ctrl0, idx;\n+\tint q_id;\n+\n+\tfor (q_id = 0; q_id < hwdev->aeqs->num_aeqs; q_id++) {\n+\t\teq = &hwdev->aeqs->aeq[q_id];\n+\t\t/* Indirect access should set q_id first */\n+\t\tspnic_hwif_write_reg(eq->hwdev->hwif, SPNIC_AEQ_INDIR_IDX_ADDR,\n+\t\t\t\t     eq->q_id);\n+\t\trte_wmb(); /* Write index before config */\n+\n+\t\taddr = SPNIC_CSR_AEQ_CTRL_0_ADDR;\n+\n+\t\tctrl0 = spnic_hwif_read_reg(hwdev->hwif, addr);\n+\n+\t\tidx = spnic_hwif_read_reg(hwdev->hwif,\n+\t\t\t\t\t  SPNIC_AEQ_INDIR_IDX_ADDR);\n+\n+\t\taddr = SPNIC_CSR_AEQ_CONS_IDX_ADDR;\n+\t\tci = spnic_hwif_read_reg(hwdev->hwif, addr);\n+\t\taddr = SPNIC_CSR_AEQ_PROD_IDX_ADDR;\n+\t\tpi = spnic_hwif_read_reg(hwdev->hwif, addr);\n+\t\taeqe_pos = GET_CURR_AEQ_ELEM(eq);\n+\t\tPMD_DRV_LOG(ERR, \"Aeq id: %d, idx: %u, ctrl0: 0x%08x, wrap: %d,\"\n+\t\t\t    \" pi: 0x%x, ci: 0x%08x,  desc: 0x%x\", q_id, idx,\n+\t\t\t    ctrl0, eq->wrapped, pi, ci,\n+\t\t\t    be32_to_cpu(aeqe_pos->desc));\n+\t}\n+}\n+\n static int aeq_elem_handler(struct spnic_eq *eq, u32 aeqe_desc,\n \t\t\t    struct spnic_aeq_elem *aeqe_pos, void *param)\n {\n@@ -518,12 +552,22 @@ static int aeq_elem_handler(struct spnic_eq *eq, u32 aeqe_desc,\n \tu8 size;\n \n \tevent = EQ_ELEM_DESC_GET(aeqe_desc, TYPE);\n+\tif (EQ_ELEM_DESC_GET(aeqe_desc, SRC)) {\n+\t\t/* SW event uses only the first 8B */\n+\t\tmemcpy(data, aeqe_pos->aeqe_data, SPNIC_AEQE_DATA_SIZE);\n+\t\tspnic_be32_to_cpu(data, SPNIC_AEQE_DATA_SIZE);\n+\t\t/* Just support SPNIC_STATELESS_EVENT */\n+\t\treturn spnic_nic_sw_aeqe_handler(eq->hwdev, event, data);\n+\t}\n \n \tmemcpy(data, aeqe_pos->aeqe_data, SPNIC_AEQE_DATA_SIZE);\n \tspnic_be32_to_cpu(data, SPNIC_AEQE_DATA_SIZE);\n \tsize = EQ_ELEM_DESC_GET(aeqe_desc, SIZE);\n \n-\tif (event == SPNIC_MBX_FROM_FUNC) {\n+\tif (event == SPNIC_MSG_FROM_MGMT_CPU) {\n+\t\treturn spnic_mgmt_msg_aeqe_handler(eq->hwdev, data, size,\n+\t\t\t\t\t\t   param);\n+\t} else if (event == SPNIC_MBX_FROM_FUNC) {\n \t\treturn spnic_mbox_func_aeqe_handler(eq->hwdev, data, size,\n \t\t\t\t\t\t    param);\n \t} else {\ndiff --git a/drivers/net/spnic/base/spnic_hwdev.c b/drivers/net/spnic/base/spnic_hwdev.c\nindex e45058423c..2b5154f8a4 100644\n--- a/drivers/net/spnic/base/spnic_hwdev.c\n+++ b/drivers/net/spnic/base/spnic_hwdev.c\n@@ -7,6 +7,7 @@\n #include \"spnic_hwif.h\"\n #include \"spnic_eqs.h\"\n #include \"spnic_mgmt.h\"\n+#include \"spnic_cmd.h\"\n #include \"spnic_mbox.h\"\n #include \"spnic_hwdev.h\"\n \n@@ -18,7 +19,62 @@ struct mgmt_event_handle {\n \tmgmt_event_cb proc;\n };\n \n+int vf_handle_pf_comm_mbox(void *handle, __rte_unused void *pri_handle,\n+\t\t\t   __rte_unused u16 cmd, __rte_unused void *buf_in,\n+\t\t\t   __rte_unused u16 in_size, __rte_unused void *buf_out,\n+\t\t\t   __rte_unused u16 *out_size)\n+{\n+\tstruct spnic_hwdev *hwdev = handle;\n+\n+\tif (!hwdev)\n+\t\treturn -EINVAL;\n+\n+\tPMD_DRV_LOG(WARNING, \"Unsupported pf mbox event %d to process\", cmd);\n+\n+\treturn 0;\n+}\n+\n+static void fault_event_handler(__rte_unused void *hwdev,\n+\t\t\t\t__rte_unused void *buf_in,\n+\t\t\t\t__rte_unused u16 in_size,\n+\t\t\t\t__rte_unused void *buf_out,\n+\t\t\t\t__rte_unused u16 *out_size)\n+{\n+\tPMD_DRV_LOG(WARNING, \"Unsupported fault event handler\");\n+}\n+\n+static void ffm_event_msg_handler(__rte_unused void *hwdev,\n+\t\t\t\t  void *buf_in, u16 in_size,\n+\t\t\t\t  __rte_unused void *buf_out, u16 *out_size)\n+{\n+\tstruct ffm_intr_info *intr = NULL;\n+\n+\tif (in_size != sizeof(*intr)) {\n+\t\tPMD_DRV_LOG(ERR, \"Invalid fault event report, length: %d, should be %\"PRIu64\" \",\n+\t\t\t    in_size, sizeof(*intr));\n+\t\treturn;\n+\t}\n+\n+\tintr = buf_in;\n+\n+\tPMD_DRV_LOG(ERR, \"node_id: 0x%x, err_type: 0x%x, err_level: %d, \"\n+\t\t    \"err_csr_addr: 0x%08x, err_csr_value: 0x%08x\",\n+\t\t    intr->node_id, intr->err_type, intr->err_level,\n+\t\t    intr->err_csr_addr, intr->err_csr_value);\n+\n+\t*out_size = sizeof(*intr);\n+}\n+\n const struct mgmt_event_handle mgmt_event_proc[] = {\n+\t{\n+\t\t.cmd\t= MGMT_CMD_FAULT_REPORT,\n+\t\t.proc\t= fault_event_handler,\n+\t},\n+\n+\t{\n+\t\t.cmd\t= MGMT_CMD_FFM_SET,\n+\t\t.proc\t= ffm_event_msg_handler,\n+\t},\n };\n \n void pf_handle_mgmt_comm_event(void *handle, __rte_unused void *pri_handle,\n@@ -44,21 +100,30 @@ void pf_handle_mgmt_comm_event(void *handle, __rte_unused void *pri_handle,\n \tPMD_DRV_LOG(WARNING, \"Unsupported mgmt cpu event %d to process\", cmd);\n }\n \n-int vf_handle_pf_comm_mbox(void *handle, __rte_unused void *pri_handle,\n-\t\t\t   __rte_unused u16 cmd, __rte_unused void *buf_in,\n-\t\t\t   __rte_unused u16 in_size, __rte_unused void *buf_out,\n-\t\t\t   __rte_unused u16 *out_size)\n+static int spnic_comm_pf_to_mgmt_init(struct spnic_hwdev *hwdev)\n {\n-\tstruct spnic_hwdev *hwdev = handle;\n+\tint err;\n \n-\tif (!hwdev)\n-\t\treturn -EINVAL;\n+\t/* VF does not support send msg to mgmt directly */\n+\tif (spnic_func_type(hwdev) == TYPE_VF)\n+\t\treturn 0;\n \n-\tPMD_DRV_LOG(WARNING, \"Unsupported pf mbox event %d to process\", cmd);\n+\terr = spnic_pf_to_mgmt_init(hwdev);\n+\tif (err)\n+\t\treturn err;\n \n \treturn 0;\n }\n \n+static void spnic_comm_pf_to_mgmt_free(struct spnic_hwdev *hwdev)\n+{\n+\t/* VF does not support send msg to mgmt directly */\n+\tif (spnic_func_type(hwdev) == TYPE_VF)\n+\t\treturn;\n+\n+\tspnic_pf_to_mgmt_free(hwdev);\n+}\n+\n static int init_mgmt_channel(struct spnic_hwdev *hwdev)\n {\n \tint err;\n@@ -69,6 +134,12 @@ static int init_mgmt_channel(struct spnic_hwdev *hwdev)\n \t\treturn err;\n \t}\n \n+\terr = spnic_comm_pf_to_mgmt_init(hwdev);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Init mgmt channel failed\");\n+\t\tgoto msg_init_err;\n+\t}\n+\n \terr = spnic_func_to_func_init(hwdev);\n \tif (err) {\n \t\tPMD_DRV_LOG(ERR, \"Init mailbox channel failed\");\n@@ -78,6 +149,9 @@ static int init_mgmt_channel(struct spnic_hwdev *hwdev)\n \treturn 0;\n \n func_to_func_init_err:\n+\tspnic_comm_pf_to_mgmt_free(hwdev);\n+\n+msg_init_err:\n \tspnic_aeqs_free(hwdev);\n \n \treturn err;\n@@ -86,6 +160,7 @@ static int init_mgmt_channel(struct spnic_hwdev *hwdev)\n static void free_mgmt_channel(struct spnic_hwdev *hwdev)\n {\n \tspnic_func_to_func_free(hwdev);\n+\tspnic_comm_pf_to_mgmt_free(hwdev);\n \tspnic_aeqs_free(hwdev);\n }\n \ndiff --git a/drivers/net/spnic/base/spnic_hwdev.h b/drivers/net/spnic/base/spnic_hwdev.h\nindex a0691eed2e..4e77d776ee 100644\n--- a/drivers/net/spnic/base/spnic_hwdev.h\n+++ b/drivers/net/spnic/base/spnic_hwdev.h\n@@ -7,7 +7,6 @@\n \n #include <rte_ether.h>\n \n-#define SPNIC_CHIP_FAULT_SIZE\t\t(110 * 1024)\n struct cfg_mgmt_info;\n struct spnic_hwif;\n struct spnic_aeqs;\n@@ -24,6 +23,70 @@ struct ffm_intr_info {\n \tu32 err_csr_value;\n };\n \n+struct link_event_stats {\n+\tu32 link_down_stats;\n+\tu32 link_up_stats;\n+};\n+\n+enum spnic_fault_err_level {\n+\tFAULT_LEVEL_FATAL,\n+\tFAULT_LEVEL_SERIOUS_RESET,\n+\tFAULT_LEVEL_SERIOUS_FLR,\n+\tFAULT_LEVEL_GENERAL,\n+\tFAULT_LEVEL_SUGGESTION,\n+\tFAULT_LEVEL_MAX\n+};\n+\n+enum spnic_fault_type {\n+\tFAULT_TYPE_CHIP,\n+\tFAULT_TYPE_UCODE,\n+\tFAULT_TYPE_MEM_RD_TIMEOUT,\n+\tFAULT_TYPE_MEM_WR_TIMEOUT,\n+\tFAULT_TYPE_REG_RD_TIMEOUT,\n+\tFAULT_TYPE_REG_WR_TIMEOUT,\n+\tFAULT_TYPE_PHY_FAULT,\n+\tFAULT_TYPE_MAX\n+};\n+\n+struct fault_event_stats {\n+\trte_atomic32_t chip_fault_stats[22][FAULT_LEVEL_MAX];\n+\trte_atomic32_t fault_type_stat[FAULT_TYPE_MAX];\n+\trte_atomic32_t pcie_fault_stats;\n+};\n+\n+struct spnic_hw_stats {\n+\trte_atomic32_t heart_lost_stats;\n+\tstruct link_event_stats link_event_stats;\n+\tstruct fault_event_stats fault_event_stats;\n+};\n+\n+#define SPNIC_CHIP_FAULT_SIZE\t\t(110 * 1024)\n+#define MAX_DRV_BUF_SIZE\t\t4096\n+\n+struct nic_cmd_chip_fault_stats {\n+\tu32 offset;\n+\tu8 chip_fault_stats[MAX_DRV_BUF_SIZE];\n+};\n+\n+struct spnic_board_info {\n+\tu8 board_type;\n+\tu8 port_num;\n+\tu8 port_speed;\n+\tu8 pcie_width;\n+\tu8 host_num;\n+\tu8 pf_num;\n+\tu16 vf_total_num;\n+\tu8 tile_num;\n+\tu8 qcm_num;\n+\tu8 core_num;\n+\tu8 work_mode;\n+\tu8 service_mode;\n+\tu8 pcie_mode;\n+\tu8 boot_sel;\n+\tu8 board_id;\n+\tu32 cfg_addr;\n+};\n+\n struct spnic_hwdev {\n \tvoid *dev_handle; /* Pointer to spnic_nic_dev */\n \tvoid *pci_dev; /* Pointer to rte_pci_device */\n@@ -37,6 +100,7 @@ struct spnic_hwdev {\n \tstruct spnic_aeqs *aeqs;\n \tstruct spnic_msg_pf_to_mgmt *pf_to_mgmt;\n \tu8 *chip_fault_stats;\n+\tstruct spnic_hw_stats hw_stats;\n \n \tu16 max_vfs;\n \tu16 link_status;\ndiff --git a/drivers/net/spnic/base/spnic_mbox.c b/drivers/net/spnic/base/spnic_mbox.c\nindex 1677bd7404..5c39e307be 100644\n--- a/drivers/net/spnic/base/spnic_mbox.c\n+++ b/drivers/net/spnic/base/spnic_mbox.c\n@@ -6,10 +6,12 @@\n #include \"spnic_compat.h\"\n #include \"spnic_hwdev.h\"\n #include \"spnic_csr.h\"\n+#include \"spnic_cmd.h\"\n #include \"spnic_mgmt.h\"\n #include \"spnic_hwif.h\"\n #include \"spnic_eqs.h\"\n #include \"spnic_mbox.h\"\n+#include \"spnic_nic_event.h\"\n \n #define SPNIC_MBOX_INT_DST_FUNC_SHIFT\t\t\t\t0\n #define SPNIC_MBOX_INT_DST_AEQN_SHIFT\t\t\t\t10\n@@ -148,6 +150,21 @@ static int recv_vf_mbox_handler(struct spnic_mbox *func_to_func,\n \t\t\t\t\t     recv_mbox->mbox_len,\n \t\t\t\t\t     buf_out, out_size);\n \t\tbreak;\n+\tcase SPNIC_MOD_L2NIC:\n+\t\terr = spnic_vf_event_handler(func_to_func->hwdev,\n+\t\t\t\t\t     func_to_func->hwdev->cfg_mgmt,\n+\t\t\t\t\t     recv_mbox->cmd, recv_mbox->mbox,\n+\t\t\t\t\t     recv_mbox->mbox_len,\n+\t\t\t\t\t     buf_out, out_size);\n+\t\tbreak;\n+\tcase SPNIC_MOD_HILINK:\n+\t\terr = spnic_vf_mag_event_handler(func_to_func->hwdev,\n+\t\t\t\t\t\t func_to_func->hwdev->cfg_mgmt,\n+\t\t\t\t\t\t recv_mbox->cmd,\n+\t\t\t\t\t\t recv_mbox->mbox,\n+\t\t\t\t\t\t recv_mbox->mbox_len,\n+\t\t\t\t\t\t buf_out, out_size);\n+\t\tbreak;\n \tdefault:\n \t\tPMD_DRV_LOG(ERR, \"No handler, mod: %d\", recv_mbox->mod);\n \t\terr = SPNIC_MBOX_VF_CMD_ERROR;\ndiff --git a/drivers/net/spnic/base/spnic_mgmt.c b/drivers/net/spnic/base/spnic_mgmt.c\nnew file mode 100644\nindex 0000000000..e202780411\n--- /dev/null\n+++ b/drivers/net/spnic/base/spnic_mgmt.c\n@@ -0,0 +1,367 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2021 Ramaxel Memory Technology, Ltd\n+ */\n+\n+#include <rte_ethdev.h>\n+\n+#include \"spnic_compat.h\"\n+#include \"spnic_hwdev.h\"\n+#include \"spnic_eqs.h\"\n+#include \"spnic_mgmt.h\"\n+#include \"spnic_mbox.h\"\n+#include \"spnic_nic_event.h\"\n+\n+#define SPNIC_MSG_TO_MGMT_MAX_LEN\t\t2016\n+\n+#define MAX_PF_MGMT_BUF_SIZE\t\t\t2048UL\n+#define SEGMENT_LEN\t\t\t\t48\n+#define ASYNC_MSG_FLAG\t\t\t\t0x20\n+#define MGMT_MSG_MAX_SEQ_ID\t(RTE_ALIGN(SPNIC_MSG_TO_MGMT_MAX_LEN, \\\n+\t\t\t\t\t   SEGMENT_LEN) / SEGMENT_LEN)\n+\n+#define BUF_OUT_DEFAULT_SIZE\t\t\t1\n+\n+#define MGMT_MSG_SIZE_MIN\t\t\t20\n+#define MGMT_MSG_SIZE_STEP\t\t\t16\n+#define\tMGMT_MSG_RSVD_FOR_DEV\t\t\t8\n+\n+#define SYNC_MSG_ID_MASK\t\t\t0x1F\n+#define ASYNC_MSG_ID_MASK\t\t\t0x1F\n+\n+#define SYNC_FLAG\t\t\t\t0\n+#define ASYNC_FLAG\t\t\t\t1\n+\n+#define MSG_NO_RESP\t\t\t\t0xFFFF\n+\n+#define MGMT_MSG_TIMEOUT\t\t\t300000 /* Millisecond */\n+\n+int spnic_msg_to_mgmt_sync(void *hwdev, enum spnic_mod_type mod, u16 cmd,\n+\t\t\t   void *buf_in, u16 in_size, void *buf_out,\n+\t\t\t   u16 *out_size, u32 timeout)\n+{\n+\tint err;\n+\n+\tif (!hwdev)\n+\t\treturn -EINVAL;\n+\n+\terr = spnic_send_mbox_to_mgmt(hwdev, mod, cmd, buf_in, in_size,\n+\t\t\t\t      buf_out, out_size, timeout);\n+\treturn err;\n+}\n+\n+static void send_mgmt_ack(struct spnic_msg_pf_to_mgmt *pf_to_mgmt,\n+\t\t\t  enum spnic_mod_type mod, u16 cmd, void *buf_in,\n+\t\t\t  u16 in_size, u16 msg_id)\n+{\n+\tu16 buf_size;\n+\n+\tif (!in_size)\n+\t\tbuf_size = BUF_OUT_DEFAULT_SIZE;\n+\telse\n+\t\tbuf_size = in_size;\n+\n+\tspnic_response_mbox_to_mgmt(pf_to_mgmt->hwdev, mod, cmd, buf_in,\n+\t\t\t\t    buf_size, msg_id);\n+}\n+\n+static bool check_mgmt_seq_id_and_seg_len(struct spnic_recv_msg *recv_msg,\n+\t\t\t\t\t  u8 seq_id, u8 seg_len, u16 msg_id)\n+{\n+\tif (seq_id > MGMT_MSG_MAX_SEQ_ID || seg_len > SEGMENT_LEN)\n+\t\treturn false;\n+\n+\tif (seq_id == 0) {\n+\t\trecv_msg->seq_id = seq_id;\n+\t\trecv_msg->msg_id = msg_id;\n+\t} else {\n+\t\tif ((seq_id != recv_msg->seq_id + 1) ||\n+\t\t    msg_id != recv_msg->msg_id) {\n+\t\t\trecv_msg->seq_id = 0;\n+\t\t\treturn false;\n+\t\t}\n+\n+\t\trecv_msg->seq_id = seq_id;\n+\t}\n+\n+\treturn true;\n+}\n+\n+static void spnic_mgmt_recv_msg_handler(struct spnic_msg_pf_to_mgmt *pf_to_mgmt,\n+\t\t\t\t\tstruct spnic_recv_msg *recv_msg,\n+\t\t\t\t\t__rte_unused void *param)\n+{\n+\tvoid *buf_out = pf_to_mgmt->mgmt_ack_buf;\n+\tbool ack_first = false;\n+\tu16 out_size = 0;\n+\n+\tmemset(buf_out, 0, MAX_PF_MGMT_BUF_SIZE);\n+\n+\tswitch (recv_msg->mod) {\n+\tcase SPNIC_MOD_COMM:\n+\t\tpf_handle_mgmt_comm_event(pf_to_mgmt->hwdev, pf_to_mgmt,\n+\t\t\t\t\t  recv_msg->cmd, recv_msg->msg,\n+\t\t\t\t\t  recv_msg->msg_len,\n+\t\t\t\t\t  buf_out, &out_size);\n+\t\tbreak;\n+\tcase SPNIC_MOD_L2NIC:\n+\t\tspnic_pf_event_handler(pf_to_mgmt->hwdev, pf_to_mgmt,\n+\t\t\t\t       recv_msg->cmd, recv_msg->msg,\n+\t\t\t\t       recv_msg->msg_len, buf_out, &out_size);\n+\t\tbreak;\n+\tdefault:\n+\t\tPMD_DRV_LOG(ERR, \"Not support mod, maybe need to response, mod: %d\",\n+\t\t\t    recv_msg->mod);\n+\t\tbreak;\n+\t}\n+\n+\tif (!ack_first && !recv_msg->async_mgmt_to_pf)\n+\t\t/* Mgmt sends async msg, sends the response */\n+\t\tsend_mgmt_ack(pf_to_mgmt, recv_msg->mod, recv_msg->cmd, buf_out,\n+\t\t\t      out_size, recv_msg->msg_id);\n+}\n+\n+/**\n+ * Handler a message from mgmt cpu\n+ *\n+ * @param[in] pf_to_mgmt\n+ *   PF to mgmt channel\n+ * @param[in] recv_msg\n+ *   Received message details\n+ * @param[in] param\n+ *   Customized parameter (unused_)\n+ *\n+ * @retval 0 : When aeqe is response message\n+ * @retval -1 : Default result, when wrong message or not last message.\n+ */\n+static int recv_mgmt_msg_handler(struct spnic_msg_pf_to_mgmt *pf_to_mgmt,\n+\t\t\t\t u8 *header, struct spnic_recv_msg *recv_msg,\n+\t\t\t\t void *param)\n+{\n+\tu64 mbox_header = *((u64 *)header);\n+\tvoid *msg_body = header + sizeof(mbox_header);\n+\tu8 seq_id, seq_len;\n+\tu32 offset;\n+\tu8 front_id;\n+\tu16 msg_id;\n+\n+\t/* Don't need to get anything from hw when cmd is async */\n+\tif (SPNIC_MSG_HEADER_GET(mbox_header, DIRECTION) == SPNIC_MSG_RESPONSE)\n+\t\treturn 0;\n+\n+\tseq_len = SPNIC_MSG_HEADER_GET(mbox_header, SEG_LEN);\n+\tseq_id  = SPNIC_MSG_HEADER_GET(mbox_header, SEQID);\n+\tmsg_id = SPNIC_MSG_HEADER_GET(mbox_header, MSG_ID);\n+\tfront_id = recv_msg->seq_id;\n+\n+\tif (!check_mgmt_seq_id_and_seg_len(recv_msg, seq_id, seq_len, msg_id)) {\n+\t\tPMD_DRV_LOG(ERR, \"Mgmt msg sequence id and segment length check failed, \"\n+\t\t\t    \"front seq_id: 0x%x, current seq_id: 0x%x, seg len: 0x%x \"\n+\t\t\t    \"front msg_id: %d, cur msg_id: %d\",\n+\t\t\t    front_id, seq_id, seq_len,\n+\t\t\t    recv_msg->msg_id, msg_id);\n+\t\t/* Set seq_id to invalid seq_id */\n+\t\trecv_msg->seq_id = MGMT_MSG_MAX_SEQ_ID;\n+\t\treturn SPNIC_MSG_HANDLER_RES;\n+\t}\n+\n+\toffset  = seq_id * SEGMENT_LEN;\n+\tmemcpy((u8 *)recv_msg->msg + offset, msg_body, seq_len);\n+\n+\tif (!SPNIC_MSG_HEADER_GET(mbox_header, LAST))\n+\t\treturn SPNIC_MSG_HANDLER_RES;\n+\n+\trecv_msg->cmd = SPNIC_MSG_HEADER_GET(mbox_header, CMD);\n+\trecv_msg->mod = SPNIC_MSG_HEADER_GET(mbox_header, MODULE);\n+\trecv_msg->async_mgmt_to_pf = SPNIC_MSG_HEADER_GET(mbox_header, NO_ACK);\n+\trecv_msg->msg_len = SPNIC_MSG_HEADER_GET(mbox_header, MSG_LEN);\n+\trecv_msg->msg_id = SPNIC_MSG_HEADER_GET(mbox_header, MSG_ID);\n+\trecv_msg->seq_id = MGMT_MSG_MAX_SEQ_ID;\n+\n+\tspnic_mgmt_recv_msg_handler(pf_to_mgmt, recv_msg, param);\n+\n+\treturn SPNIC_MSG_HANDLER_RES;\n+}\n+\n+/**\n+ * Handler for a mgmt message event\n+ *\n+ * @param[in] hwdev\n+ *   The pointer to the private hardware device object\n+ * @param[in] header\n+ *   The header of the message\n+ * @param[in] size\n+ *   Size (unused_)\n+ * @param[in] param\n+ *   Customized parameter\n+ *\n+ * @retval zero : When aeqe is response message\n+ * @retval negative : When wrong message or not last message.\n+ */\n+int spnic_mgmt_msg_aeqe_handler(void *hwdev, u8 *header, u8 size, void *param)\n+{\n+\tstruct spnic_hwdev *dev = (struct spnic_hwdev *)hwdev;\n+\tstruct spnic_msg_pf_to_mgmt *pf_to_mgmt = NULL;\n+\tstruct spnic_recv_msg *recv_msg = NULL;\n+\tbool is_send_dir = false;\n+\n+\tif ((SPNIC_MSG_HEADER_GET(*(u64 *)header, SOURCE) ==\n+\t     SPNIC_MSG_FROM_MBOX)) {\n+\t\treturn spnic_mbox_func_aeqe_handler(hwdev, header, size, param);\n+\t}\n+\n+\tpf_to_mgmt = dev->pf_to_mgmt;\n+\n+\tis_send_dir = (SPNIC_MSG_HEADER_GET(*(u64 *)header, DIRECTION) ==\n+\t\t       SPNIC_MSG_DIRECT_SEND) ? true : false;\n+\n+\trecv_msg = is_send_dir ? &pf_to_mgmt->recv_msg_from_mgmt :\n+\t\t   &pf_to_mgmt->recv_resp_msg_from_mgmt;\n+\n+\treturn recv_mgmt_msg_handler(pf_to_mgmt, header, recv_msg, param);\n+}\n+\n+/**\n+ * Allocate received message memory\n+ *\n+ * @param[in] recv_msg\n+ *   Pointer that will hold the allocated data\n+ *\n+ * @retval zero : Success\n+ * @retval negative : Failure.\n+ */\n+static int alloc_recv_msg(struct spnic_recv_msg *recv_msg)\n+{\n+\trecv_msg->seq_id = MGMT_MSG_MAX_SEQ_ID;\n+\n+\trecv_msg->msg = rte_zmalloc(\"recv_msg\", MAX_PF_MGMT_BUF_SIZE,\n+\t\t\t\t    SPNIC_MEM_ALLOC_ALIGN_MIN);\n+\tif (!recv_msg->msg)\n+\t\treturn -ENOMEM;\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * Free received message memory\n+ *\n+ * @param[in] recv_msg\n+ *   Pointer that will hold the allocated data\n+ */\n+static void free_recv_msg(struct spnic_recv_msg *recv_msg)\n+{\n+\trte_free(recv_msg->msg);\n+}\n+\n+/**\n+ * Allocate all the message buffers of PF to mgmt channel\n+ *\n+ * @param[in] pf_to_mgmt\n+ *   PF to mgmt channel\n+ *\n+ * @retval zero : Success\n+ * @retval negative : Failure.\n+ */\n+static int alloc_msg_buf(struct spnic_msg_pf_to_mgmt *pf_to_mgmt)\n+{\n+\tint err;\n+\n+\terr = alloc_recv_msg(&pf_to_mgmt->recv_msg_from_mgmt);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Allocate recv msg failed\");\n+\t\treturn err;\n+\t}\n+\n+\terr = alloc_recv_msg(&pf_to_mgmt->recv_resp_msg_from_mgmt);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Allocate resp recv msg failed\");\n+\t\tgoto alloc_msg_for_resp_err;\n+\t}\n+\n+\tpf_to_mgmt->mgmt_ack_buf = rte_zmalloc(\"mgmt_ack_buf\",\n+\t\t\t\t\t       MAX_PF_MGMT_BUF_SIZE,\n+\t\t\t\t\t       SPNIC_MEM_ALLOC_ALIGN_MIN);\n+\tif (!pf_to_mgmt->mgmt_ack_buf) {\n+\t\terr = -ENOMEM;\n+\t\tgoto ack_msg_buf_err;\n+\t}\n+\n+\treturn 0;\n+\n+ack_msg_buf_err:\n+\tfree_recv_msg(&pf_to_mgmt->recv_resp_msg_from_mgmt);\n+\n+alloc_msg_for_resp_err:\n+\tfree_recv_msg(&pf_to_mgmt->recv_msg_from_mgmt);\n+\treturn err;\n+}\n+\n+/**\n+ * Free all the message buffers of PF to mgmt channel\n+ *\n+ * @param[in] pf_to_mgmt\n+ *   PF to mgmt channel\n+ */\n+static void free_msg_buf(struct spnic_msg_pf_to_mgmt *pf_to_mgmt)\n+{\n+\trte_free(pf_to_mgmt->mgmt_ack_buf);\n+\tfree_recv_msg(&pf_to_mgmt->recv_resp_msg_from_mgmt);\n+\tfree_recv_msg(&pf_to_mgmt->recv_msg_from_mgmt);\n+}\n+\n+/**\n+ * Initialize PF to mgmt channel\n+ *\n+ * @param[in] hwdev\n+ *   The pointer to the private hardware device object\n+ *\n+ * @retval zero : Success\n+ * @retval negative : Failure.\n+ */\n+int spnic_pf_to_mgmt_init(struct spnic_hwdev *hwdev)\n+{\n+\tstruct spnic_msg_pf_to_mgmt *pf_to_mgmt;\n+\tint err;\n+\n+\tpf_to_mgmt = rte_zmalloc(\"pf_to_mgmt\", sizeof(*pf_to_mgmt),\n+\t\t\t\t SPNIC_MEM_ALLOC_ALIGN_MIN);\n+\tif (!pf_to_mgmt)\n+\t\treturn -ENOMEM;\n+\n+\thwdev->pf_to_mgmt = pf_to_mgmt;\n+\tpf_to_mgmt->hwdev = hwdev;\n+\n+\terr = spnic_mutex_init(&pf_to_mgmt->sync_msg_mutex, NULL);\n+\tif (err)\n+\t\tgoto mutex_init_err;\n+\n+\terr = alloc_msg_buf(pf_to_mgmt);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Allocate msg buffers failed\");\n+\t\tgoto alloc_msg_buf_err;\n+\t}\n+\n+\treturn 0;\n+\n+alloc_msg_buf_err:\n+\tspnic_mutex_destroy(&pf_to_mgmt->sync_msg_mutex);\n+\n+mutex_init_err:\n+\trte_free(pf_to_mgmt);\n+\n+\treturn err;\n+}\n+\n+/**\n+ * Free PF to mgmt channel\n+ *\n+ * @param[in] hwdev\n+ *   The pointer to the private hardware device object\n+ */\n+void spnic_pf_to_mgmt_free(struct spnic_hwdev *hwdev)\n+{\n+\tstruct spnic_msg_pf_to_mgmt *pf_to_mgmt = hwdev->pf_to_mgmt;\n+\n+\tfree_msg_buf(pf_to_mgmt);\n+\tspnic_mutex_destroy(&pf_to_mgmt->sync_msg_mutex);\n+\trte_free(pf_to_mgmt);\n+}\ndiff --git a/drivers/net/spnic/base/spnic_mgmt.h b/drivers/net/spnic/base/spnic_mgmt.h\nindex 37d0410473..ca820828d2 100644\n--- a/drivers/net/spnic/base/spnic_mgmt.h\n+++ b/drivers/net/spnic/base/spnic_mgmt.h\n@@ -7,6 +7,13 @@\n \n #define SPNIC_MSG_HANDLER_RES\t(-1)\n \n+/* Structures for l2nic and mag msg to mgmt sync interface */\n+struct mgmt_msg_head {\n+\tu8 status;\n+\tu8 version;\n+\tu8 rsvd0[6];\n+};\n+\n /* Cmdq module type */\n enum spnic_mod_type {\n \tSPNIC_MOD_COMM = 0, /* HW communication module */\n@@ -33,4 +40,71 @@ enum spnic_mod_type {\n \tSPNIC_MOD_MAX\n };\n \n+typedef enum {\n+\tRES_TYPE_FLUSH_BIT = 0,\n+\tRES_TYPE_MQM,\n+\tRES_TYPE_SMF,\n+\n+\tRES_TYPE_COMM = 10,\n+\t/* clear mbox and aeq, The RES_TYPE_COMM bit must be set */\n+\tRES_TYPE_COMM_MGMT_CH,\n+\t/* clear cmdq, The RES_TYPE_COMM bit must be set */\n+\tRES_TYPE_COMM_CMD_CH,\n+\tRES_TYPE_NIC,\n+\tRES_TYPE_OVS,\n+\tRES_TYPE_MAX = 20,\n+} func_reset_flag_e;\n+\n+#define SPNIC_COMM_RES\t\t((1 << RES_TYPE_COMM) | \\\n+\t\t\t\t(1 << RES_TYPE_FLUSH_BIT) | \\\n+\t\t\t\t(1 << RES_TYPE_MQM) | \\\n+\t\t\t\t(1 << RES_TYPE_SMF) | \\\n+\t\t\t\t(1 << RES_TYPE_COMM_CMD_CH))\n+#define SPNIC_NIC_RES\t\t(1 << RES_TYPE_NIC)\n+#define SPNIC_OVS_RES\t\t(1 << RES_TYPE_OVS)\n+\n+struct spnic_recv_msg {\n+\tvoid *msg;\n+\n+\tu16 msg_len;\n+\tenum spnic_mod_type mod;\n+\tu16 cmd;\n+\tu8 seq_id;\n+\tu16 msg_id;\n+\tint async_mgmt_to_pf;\n+};\n+\n+enum comm_pf_to_mgmt_event_state {\n+\tSEND_EVENT_UNINIT = 0,\n+\tSEND_EVENT_START,\n+\tSEND_EVENT_SUCCESS,\n+\tSEND_EVENT_FAIL,\n+\tSEND_EVENT_TIMEOUT,\n+\tSEND_EVENT_END\n+};\n+\n+struct spnic_msg_pf_to_mgmt {\n+\tstruct spnic_hwdev *hwdev;\n+\n+\t/* Mutex for sync message */\n+\tpthread_mutex_t sync_msg_mutex;\n+\n+\tvoid *mgmt_ack_buf;\n+\n+\tstruct spnic_recv_msg recv_msg_from_mgmt;\n+\tstruct spnic_recv_msg recv_resp_msg_from_mgmt;\n+\n+\tu16 sync_msg_id;\n+};\n+\n+int spnic_mgmt_msg_aeqe_handler(void *hwdev, u8 *header, u8 size, void *param);\n+\n+int spnic_pf_to_mgmt_init(struct spnic_hwdev *hwdev);\n+\n+void spnic_pf_to_mgmt_free(struct spnic_hwdev *hwdev);\n+\n+int spnic_msg_to_mgmt_sync(void *hwdev, enum spnic_mod_type mod, u16 cmd,\n+\t\t\t   void *buf_in, u16 in_size, void *buf_out,\n+\t\t\t   u16 *out_size, u32 timeout);\n+\n #endif /* _SPNIC_MGMT_H_ */\ndiff --git a/drivers/net/spnic/base/spnic_nic_event.c b/drivers/net/spnic/base/spnic_nic_event.c\nnew file mode 100644\nindex 0000000000..07ea036d84\n--- /dev/null\n+++ b/drivers/net/spnic/base/spnic_nic_event.c\n@@ -0,0 +1,171 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2021 Ramaxel Memory Technology, Ltd\n+ */\n+\n+#include <ethdev_driver.h>\n+\n+#include \"spnic_compat.h\"\n+#include \"spnic_cmd.h\"\n+#include \"spnic_hwif.h\"\n+#include \"spnic_hwdev.h\"\n+#include \"spnic_mgmt.h\"\n+#include \"spnic_hwdev.h\"\n+#include \"spnic_nic_event.h\"\n+\n+static void get_port_info(u8 link_state, struct rte_eth_link *link)\n+{\n+\tif (!link_state) {\n+\t\tlink->link_status = ETH_LINK_DOWN;\n+\t\tlink->link_speed = ETH_SPEED_NUM_NONE;\n+\t\tlink->link_duplex = ETH_LINK_HALF_DUPLEX;\n+\t\tlink->link_autoneg = ETH_LINK_FIXED;\n+\t}\n+}\n+\n+static void spnic_link_event_stats(void *dev, u8 link)\n+{\n+\tstruct spnic_hwdev *hwdev = dev;\n+\tstruct link_event_stats *stats = &hwdev->hw_stats.link_event_stats;\n+\n+\tif (link)\n+\t\t__atomic_fetch_add(&stats->link_up_stats, 1, __ATOMIC_RELAXED);\n+\telse\n+\t\t__atomic_fetch_add(&stats->link_down_stats, 1, __ATOMIC_RELAXED);\n+}\n+\n+static void link_status_event_handler(void *hwdev, void *buf_in,\n+\t\t\t\t      __rte_unused u16 in_size,\n+\t\t\t\t      __rte_unused void *buf_out,\n+\t\t\t\t      __rte_unused u16 *out_size)\n+{\n+\tstruct spnic_cmd_link_state *link_status = NULL;\n+\tstruct rte_eth_link link;\n+\tstruct spnic_hwdev *dev = hwdev;\n+\tint err;\n+\n+\tlink_status = buf_in;\n+\tPMD_DRV_LOG(INFO, \"Link status report received, func_id: %d, status: %d(%s)\",\n+\t\t    spnic_global_func_id(hwdev), link_status->state,\n+\t\t    link_status->state ? \"UP\" : \"DOWN\");\n+\n+\tspnic_link_event_stats(hwdev, link_status->state);\n+\n+\t/* Link event reported only after set vport enable */\n+\tget_port_info(link_status->state, &link);\n+\terr = rte_eth_linkstatus_set((struct rte_eth_dev *)(dev->eth_dev),\n+\t\t\t\t     &link);\n+\tif (!err)\n+\t\trte_eth_dev_callback_process(dev->eth_dev,\n+\t\t\t\t\t      RTE_ETH_EVENT_INTR_LSC, NULL);\n+}\n+\n+struct nic_event_handler {\n+\tu16 cmd;\n+\tvoid (*handler)(void *hwdev, void *buf_in, u16 in_size,\n+\t\t\tvoid *buf_out, u16 *out_size);\n+};\n+\n+struct nic_event_handler nic_cmd_handler[] = {\n+};\n+\n+static void nic_event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,\n+\t\t\t      void *buf_out, u16 *out_size)\n+{\n+\tu32 i, size = ARRAY_LEN(nic_cmd_handler);\n+\n+\tif (!hwdev)\n+\t\treturn;\n+\n+\t*out_size = 0;\n+\n+\tfor (i = 0; i < size; i++) {\n+\t\tif (cmd == nic_cmd_handler[i].cmd) {\n+\t\t\tnic_cmd_handler[i].handler(hwdev, buf_in, in_size,\n+\t\t\t\t\t\t   buf_out, out_size);\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\tif (i == size)\n+\t\tPMD_DRV_LOG(WARNING,\n+\t\t\t    \"Unsupported nic event cmd(%d) to process\", cmd);\n+}\n+\n+/*\n+ * VF handler mbox msg from ppf/pf\n+ * VF link change event\n+ * VF fault report event\n+ */\n+int spnic_vf_event_handler(void *hwdev, __rte_unused void *pri_handle,\n+\t\t\t   u16 cmd, void *buf_in, u16 in_size,\n+\t\t\t   void *buf_out, u16 *out_size)\n+{\n+\tnic_event_handler(hwdev, cmd, buf_in, in_size, buf_out, out_size);\n+\treturn 0;\n+}\n+\n+/*  NIC event of PF/PPF handler reported by mgmt cpu */\n+void spnic_pf_event_handler(void *hwdev, __rte_unused void *pri_handle,\n+\t\t\t    u16 cmd, void *buf_in, u16 in_size,\n+\t\t\t    void *buf_out, u16 *out_size)\n+{\n+\tnic_event_handler(hwdev, cmd, buf_in, in_size, buf_out, out_size);\n+}\n+\n+static struct nic_event_handler mag_cmd_handler[] = {\n+\t{\n+\t\t.cmd = MAG_CMD_GET_LINK_STATUS,\n+\t\t.handler = link_status_event_handler,\n+\t},\n+};\n+\n+static int spnic_mag_event_handler(void *hwdev, u16 cmd, void *buf_in,\n+\t\t\t\t   u16 in_size, void *buf_out,\n+\t\t\t\t   u16 *out_size)\n+{\n+\tu32 size = ARRAY_LEN(mag_cmd_handler);\n+\tu32 i;\n+\n+\tif (!hwdev)\n+\t\treturn -EINVAL;\n+\n+\t*out_size = 0;\n+\tfor (i = 0; i < size; i++) {\n+\t\tif (cmd == mag_cmd_handler[i].cmd) {\n+\t\t\tmag_cmd_handler[i].handler(hwdev, buf_in, in_size,\n+\t\t\t\t\t\t   buf_out, out_size);\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\t/* can't find this event cmd */\n+\tif (i == size)\n+\t\tPMD_DRV_LOG(ERR, \"Unsupported mag event, cmd: %u\\n\", cmd);\n+\n+\treturn 0;\n+}\n+\n+int spnic_vf_mag_event_handler(void *hwdev, void *pri_handle, u16 cmd,\n+\t\t\t       void *buf_in, u16 in_size, void *buf_out,\n+\t\t\t       u16 *out_size)\n+{\n+\treturn spnic_mag_event_handler(hwdev, cmd, buf_in, in_size, buf_out,\n+\t\t\t\t       out_size);\n+}\n+\n+/* pf/ppf handler mgmt cpu report hilink event*/\n+void spnic_pf_mag_event_handler(void *hwdev, void *pri_handle, u16 cmd,\n+\t\t\t\tvoid *buf_in, u16 in_size, void *buf_out,\n+\t\t\t\tu16 *out_size)\n+{\n+\tspnic_mag_event_handler(hwdev, cmd, buf_in, in_size, buf_out, out_size);\n+}\n+\n+u8 spnic_nic_sw_aeqe_handler(__rte_unused void *hwdev, u8 event, u8 *data)\n+{\n+\tPMD_DRV_LOG(ERR,\n+\t\t    \"Received nic ucode aeq event type: 0x%x, data: %\"PRIu64\"\",\n+\t\t    event, *((u64 *)data));\n+\n+\treturn 0;\n+}\ndiff --git a/drivers/net/spnic/base/spnic_nic_event.h b/drivers/net/spnic/base/spnic_nic_event.h\nnew file mode 100644\nindex 0000000000..eb41d76a7d\n--- /dev/null\n+++ b/drivers/net/spnic/base/spnic_nic_event.h\n@@ -0,0 +1,34 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2021 Ramaxel Memory Technology, Ltd\n+ */\n+\n+#ifndef _SPNIC_NIC_EVENT_H_\n+#define _SPNIC_NIC_EVENT_H_\n+\n+struct spnic_cmd_link_state {\n+\tstruct mgmt_msg_head msg_head;\n+\n+\tu8 port_id;\n+\tu8 state;\n+\tu16 rsvd1;\n+};\n+\n+void spnic_pf_event_handler(void *hwdev, __rte_unused void *pri_handle,\n+\t\t\t    u16 cmd, void *buf_in, u16 in_size,\n+\t\t\t    void *buf_out, u16 *out_size);\n+\n+int spnic_vf_event_handler(void *hwdev, __rte_unused void *pri_handle,\n+\t\t\t   u16 cmd, void *buf_in, u16 in_size,\n+\t\t\t   void *buf_out, u16 *out_size);\n+\n+void spnic_pf_mag_event_handler(void *hwdev, void *pri_handle, u16 cmd,\n+\t\t\t\tvoid *buf_in, u16 in_size, void *buf_out,\n+\t\t\t\tu16 *out_size);\n+\n+int spnic_vf_mag_event_handler(void *hwdev, void *pri_handle, u16 cmd,\n+\t\t\t       void *buf_in, u16 in_size, void *buf_out,\n+\t\t\t       u16 *out_size);\n+\n+u8 spnic_nic_sw_aeqe_handler(__rte_unused void *hwdev, u8 event, u8 *data);\n+\n+#endif /* _SPNIC_NIC_EVENT_H_ */\n",
    "prefixes": [
        "v1",
        "05/25"
    ]
}