v1: open the npsdk lib<br />    msg chan:<br />    support pf/vf send msg to backend<br />        support pf to vf and vf to pf send msg<br /> <br />Signed-off-by: Junlong Wang <wang.junlong1@zte.com.cn> <br />---<br /> doc/guides/nics/features/zxdh.ini |   38 +<br /> doc/guides/nics/index.rst         |    1 +<br /> doc/guides/nics/zxdh.rst          |   61 ++<br /> drivers/net/meson.build           |    1 +<br /> drivers/net/zxdh/meson.build      |   14 +<br /> drivers/net/zxdh/zxdh_ethdev.c    |   22 +<br /> drivers/net/zxdh/zxdh_logs.h      |   38 +<br /> drivers/net/zxdh/zxdh_msg.c       | 1188 +++++++++++++++++++++++++++++<br /> drivers/net/zxdh/zxdh_msg.h       |  408 ++++++++++<br /> drivers/net/zxdh/zxdh_npsdk.c     |  158 ++++<br /> drivers/net/zxdh/zxdh_npsdk.h     |  216 ++++++<br /> 11 files changed, 2145 insertions(+)<br /> create mode 100644 doc/guides/nics/features/zxdh.ini<br /> create mode 100644 doc/guides/nics/zxdh.rst<br /> create mode 100644 drivers/net/zxdh/meson.build<br /> create mode 100644 drivers/net/zxdh/zxdh_ethdev.c<br /> create mode 100644 drivers/net/zxdh/zxdh_logs.h<br /> create mode 100644 drivers/net/zxdh/zxdh_msg.c<br /> create mode 100644 drivers/net/zxdh/zxdh_msg.h<br /> create mode 100644 drivers/net/zxdh/zxdh_npsdk.c<br /> create mode 100644 drivers/net/zxdh/zxdh_npsdk.h<br /> <br />diff --git a/doc/guides/nics/features/zxdh.ini b/doc/guides/nics/features/zxdh.ini<br />new file mode 100644<br />index 0000000000..fc41426077<br />--- /dev/null<br />+++ b/doc/guides/nics/features/zxdh.ini<br />@@ -0,0 +1,38 @@<br />+;<br />+; Supported features of the 'zxdh' network poll mode driver.<br />+;<br />+; Refer to default.ini for the full list of available PMD features.<br />+;<br />+[Features]<br />+Speed capabilities   = Y<br />+Link status          = Y<br />+Link status event    = Y<br />+MTU update           = Y<br />+Scattered Rx         = Y<br />+TSO                  = Y<br />+LRO                  = Y<br />+Promiscuous mode     = Y<br />+Allmulticast mode    = Y<br />+Unicast MAC filter   = Y<br />+Multicast MAC filter = Y<br />+RSS hash             = Y<br />+RSS key update       = Y<br />+RSS reta update      = Y<br />+Inner RSS            = Y<br />+SR-IOV               = Y<br />+VLAN filter          = Y<br />+VLAN offload         = Y<br />+L3 checksum offload  = Y<br />+L4 checksum offload  = Y<br />+Inner L3 checksum    = Y<br />+Inner L4 checksum    = Y<br />+Basic stats          = Y<br />+Extended stats       = Y<br />+Stats per queue      = Y<br />+Flow control         = Y<br />+FW version           = Y<br />+Multiprocess aware   = Y<br />+Linux                = Y<br />+x86-64               = Y<br />+ARMv8                = Y<br />+<br />diff --git a/doc/guides/nics/index.rst b/doc/guides/nics/index.rst<br />index c14bc7988a..8e371ac4a5 100644<br />--- a/doc/guides/nics/index.rst<br />+++ b/doc/guides/nics/index.rst<br />@@ -69,3 +69,4 @@ Network Interface Controller Drivers<br />     vhost<br />     virtio<br />     vmxnet3<br />+    zxdh<br />diff --git a/doc/guides/nics/zxdh.rst b/doc/guides/nics/zxdh.rst<br />new file mode 100644<br />index 0000000000..f7cbc5755b<br />--- /dev/null<br />+++ b/doc/guides/nics/zxdh.rst<br />@@ -0,0 +1,61 @@<br />+..  SPDX-License-Identifier: BSD-3-Clause<br />+    Copyright(c) 2023 ZTE Corporation.<br />+<br />+<br />+ZXDH Poll Mode Driver<br />+======================<br />+<br />+The ZXDH PMD (**librte_net_zxdh**) provides poll mode driver support<br />+for 25/100 Gbps ZXDH NX Series Ethernet Controller based on<br />+the ZTE Ethernet Controller E310/E312.<br />+<br />+<br />+Features<br />+--------<br />+<br />+Features of the zxdh PMD are:<br />+<br />+- Multi arch support: x86_64, ARMv8.<br />+- Multiple queues for TX and RX<br />+- Receiver Side Scaling (RSS)<br />+- MAC/VLAN filtering<br />+- Checksum offload<br />+- TSO offload<br />+- VLAN/QinQ stripping and inserting<br />+- Promiscuous mode<br />+- Port hardware statistics<br />+- Link state information<br />+- Link flow control<br />+- Scattered and gather for TX and RX<br />+- SR-IOV VF<br />+- VLAN filter and VLAN offload<br />+- Allmulticast mode<br />+- MTU update<br />+- Jumbo frames<br />+- Unicast MAC filter<br />+- Multicast MAC filter<br />+- Flow API<br />+- Set Link down or up<br />+- FW version<br />+- LRO<br />+<br />+Prerequisites<br />+-------------<br />+<br />+This PMD driver need NPSDK library for system initialization and allocation of resources.<br />+Communication between PMD and kernel modules is mediated by zxdh Kernel modules.<br />+The NPSDK library and zxdh Kernel modules are not part of DPDK and must be installed<br />+separately:<br />+<br />+- Getting the latest NPSDK library and software supports using<br />+  ``_.<br />+<br />+Driver compilation and testing<br />+------------------------------<br />+<br />+Refer to the document :ref:`compiling and testing a PMD for a NIC <pmd_build_and_test>`<br />+for details.<br />+<br />+Limitations or Known issues<br />+---------------------------<br />+X86-32, Power8, ARMv7 and BSD are not supported yet.<br />diff --git a/drivers/net/meson.build b/drivers/net/meson.build<br />index fb6d34b782..1a3db8a04d 100644<br />--- a/drivers/net/meson.build<br />+++ b/drivers/net/meson.build<br />@@ -62,6 +62,7 @@ drivers = [<br />         'vhost',<br />         'virtio',<br />         'vmxnet3',<br />+    'zxdh',<br /> ]<br /> std_deps = ['ethdev', 'kvargs'] # 'ethdev' also pulls in mbuf, net, eal etc<br /> std_deps += ['bus_pci']         # very many PMDs depend on PCI, so make std<br />diff --git a/drivers/net/zxdh/meson.build b/drivers/net/zxdh/meson.build<br />new file mode 100644<br />index 0000000000..217d8920cd<br />--- /dev/null<br />+++ b/drivers/net/zxdh/meson.build<br />@@ -0,0 +1,14 @@<br />+# SPDX-License-Identifier: BSD-3-Clause<br />+# Copyright(c) 2024 ZTE Corporation<br />+<br />+if not is_linux<br />+    build = false<br />+    reason = 'only supported on Linux' <br />+    subdir_done()<br />+endif<br />+<br />+sources = files(<br />+    'zxdh_ethdev.c',<br />+    'zxdh_msg.c',<br />+    'zxdh_npsdk.c',<br />+    )<br />diff --git a/drivers/net/zxdh/zxdh_ethdev.c b/drivers/net/zxdh/zxdh_ethdev.c<br />new file mode 100644<br />index 0000000000..a3c05f9809<br />--- /dev/null<br />+++ b/drivers/net/zxdh/zxdh_ethdev.c<br />@@ -0,0 +1,22 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#include <rte_memcpy.h> <br />+#include <rte_malloc.h> <br />+#include <rte_interrupts.h> <br />+#include <eal_interrupts.h> <br />+#include <ethdev_pci.h> <br />+#include <rte_kvargs.h> <br />+#include <rte_hexdump.h> <br />+<br />+RTE_PMD_REGISTER_KMOD_DEP(net_zxdh, "* vfio-pci");<br />+RTE_LOG_REGISTER_SUFFIX(zxdh_logtype_init, init, NOTICE);<br />+RTE_LOG_REGISTER_SUFFIX(zxdh_logtype_driver, driver, NOTICE);<br />+RTE_LOG_REGISTER_SUFFIX(zxdh_logtype_rx, rx, DEBUG);<br />+RTE_LOG_REGISTER_SUFFIX(zxdh_logtype_tx, tx, DEBUG);<br />+<br />+RTE_LOG_REGISTER_SUFFIX(zxdh_logtype_msg, msg, NOTICE);<br />+RTE_PMD_REGISTER_PARAM_STRING(net_zxdh,<br />+    "q_depth=<int>");<br />+<br />diff --git a/drivers/net/zxdh/zxdh_logs.h b/drivers/net/zxdh/zxdh_logs.h<br />new file mode 100644<br />index 0000000000..fb9b2d452f<br />--- /dev/null<br />+++ b/drivers/net/zxdh/zxdh_logs.h<br />@@ -0,0 +1,38 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#ifndef _ZXDH_LOGS_H_<br />+#define _ZXDH_LOGS_H_<br />+<br />+#include <rte_log.h> <br />+<br />+#define PMD_INIT_FUNC_TRACE() PMD_INIT_LOG(DEBUG, " >>")<br />+<br />+extern int32_t zxdh_logtype_init;<br />+#define PMD_INIT_LOG(level, fmt, args...) \<br />+    rte_log(RTE_LOG_ ## level, zxdh_logtype_init, \<br />+    "offload_zxdh %s(): " fmt "\n", __func__, ## args)<br />+<br />+extern int32_t zxdh_logtype_driver;<br />+#define PMD_DRV_LOG(level, fmt, args...) \<br />+    rte_log(RTE_LOG_ ## level, zxdh_logtype_driver, \<br />+    "offload_zxdh %s(): " fmt "\n", __func__, ## args)<br />+<br />+extern int zxdh_logtype_rx;<br />+#define PMD_RX_LOG(level, fmt, args...) \<br />+    rte_log(RTE_LOG_ ## level, zxdh_logtype_rx, \<br />+    "offload_zxdh %s(): " fmt "\n", __func__, ## args)<br />+<br />+extern int zxdh_logtype_tx;<br />+#define PMD_TX_LOG(level, fmt, args...) \<br />+    rte_log(RTE_LOG_ ## level, zxdh_logtype_tx, \<br />+    "offload_zxdh %s(): " fmt "\n", __func__, ## args)<br />+<br />+extern int32_t zxdh_logtype_msg;<br />+#define PMD_MSG_LOG(level, fmt, args...) \<br />+    rte_log(RTE_LOG_ ## level, zxdh_logtype_msg, \<br />+    "offload_zxdh %s(): " fmt "\n", __func__, ## args)<br />+<br />+#endif /* _ZXDH_LOGS_H_ */<br />+<br />diff --git a/drivers/net/zxdh/zxdh_msg.c b/drivers/net/zxdh/zxdh_msg.c<br />new file mode 100644<br />index 0000000000..e71b18a25a<br />--- /dev/null<br />+++ b/drivers/net/zxdh/zxdh_msg.c<br />@@ -0,0 +1,1188 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2023 ZTE Corporation<br />+ */<br />+<br />+#include <stdbool.h> <br />+#include <rte_common.h> <br />+#include <rte_memcpy.h> <br />+#include <pthread.h> <br />+#include <rte_cycles.h> <br />+<br />+#include "zxdh_logs.h" <br />+#include "zxdh_msg.h" <br />+<br />+#define REPS_INFO_FLAG_USABLE  0x00<br />+#define REPS_INFO_FLAG_USED    0xa0<br />+<br />+#define BDF_ECAM(bus, devid, func)   (((bus & 0xff) << 8) | (func & 0x07) | ((devid & 0x1f) << 3))<br />+<br />+/**<br />+ * common.ko will work in 5 scenarios<br />+ * 1: SCENE_HOST_IN_DPU  : host in DPU card<br />+ * 2: SCENE_ZF_IN_DPU    : zf   in DPU card<br />+ * 3: SCENE_NIC_WITH_DDR : inic with DDR<br />+ * 4: SCENE_NIC_NO_DDR   : inic without DDR<br />+ * 5: SCENE_STD_NIC      : std card<br />+ */<br />+#ifdef SCENE_HOST_IN_DPU<br />+#define BAR_PF_NUM             31<br />+#define BAR_VF_NUM             1024<br />+#define BAR_INDEX_PF_TO_VF     1<br />+#define BAR_INDEX_MPF_TO_MPF   1<br />+#define BAR_INDEX_MPF_TO_PFVF  0xff<br />+#define BAR_INDEX_PFVF_TO_MPF  0xff<br />+#endif<br />+<br />+#ifdef SCENE_ZF_IN_DPU<br />+#define BAR_PF_NUM             7<br />+#define BAR_VF_NUM             128<br />+#define BAR_INDEX_PF_TO_VF     0xff<br />+#define BAR_INDEX_MPF_TO_MPF   1<br />+#define BAR_INDEX_MPF_TO_PFVF  0xff<br />+#define BAR_INDEX_PFVF_TO_MPF  0xff<br />+#endif<br />+<br />+#ifdef SCENE_NIC_WITH_DDR<br />+#define BAR_PF_NUM             31<br />+#define BAR_VF_NUM             1024<br />+#define BAR_INDEX_PF_TO_VF     1<br />+#define BAR_INDEX_MPF_TO_MPF   0xff<br />+#define BAR_INDEX_MPF_TO_PFVF  0xff<br />+#define BAR_INDEX_PFVF_TO_MPF  0xff<br />+#endif<br />+<br />+#ifdef SCENE_NIC_NO_DDR<br />+#define BAR_PF_NUM             31<br />+#define BAR_VF_NUM             1024<br />+#define BAR_INDEX_PF_TO_VF     1<br />+#define BAR_INDEX_MPF_TO_MPF   0xff<br />+#define BAR_INDEX_MPF_TO_PFVF  1<br />+#define BAR_INDEX_PFVF_TO_MPF  2<br />+#endif<br />+<br />+#ifdef SCENE_STD_NIC<br />+#define BAR_PF_NUM             7<br />+#define BAR_VF_NUM             256<br />+#define BAR_INDEX_PF_TO_VF     1<br />+#define BAR_INDEX_MPF_TO_MPF   0xff<br />+#define BAR_INDEX_MPF_TO_PFVF  1<br />+#define BAR_INDEX_PFVF_TO_MPF  2<br />+#endif<br />+<br />+#define SCENE_TEST<br />+#ifdef SCENE_TEST<br />+#define BAR_PF_NUM             7<br />+#define BAR_VF_NUM             256<br />+#define BAR_INDEX_PF_TO_VF     0<br />+#define BAR_INDEX_MPF_TO_MPF   0xff<br />+#define BAR_INDEX_MPF_TO_PFVF  0<br />+#define BAR_INDEX_PFVF_TO_MPF  0<br />+#endif<br />+<br />+/**<br />+ * 0: left 2K,    1: right 2K<br />+ * src/dst: TO_RISC, TO_PFVF, TO_MPF<br />+ * MPF:       0         0       0<br />+ * PF:        0         0       1<br />+ * VF:        0         1       1<br />+ **/<br />+#define BAR_MSG_SRC_NUM   3<br />+#define BAR_MSG_SRC_MPF   0<br />+#define BAR_MSG_SRC_PF    1<br />+#define BAR_MSG_SRC_VF    2<br />+#define BAR_MSG_SRC_ERR   0xff<br />+<br />+#define BAR_MSG_DST_NUM   3<br />+#define BAR_MSG_DST_RISC  0<br />+#define BAR_MSG_DST_MPF   2<br />+#define BAR_MSG_DST_PFVF  1<br />+#define BAR_MSG_DST_ERR   0xff<br />+<br />+#define BAR_SUBCHAN_INDEX_SEND  0<br />+#define BAR_SUBCHAN_INDEX_RECV  1<br />+#define BAR_SEQID_NUM_MAX  256<br />+<br />+#define BAR_ALIGN_WORD_MASK  0xfffffffc<br />+#define BAR_MSG_VALID_MASK    1<br />+#define BAR_MSG_VALID_OFFSET  0<br />+<br />+#define BAR_MSG_CHAN_USABLE  0<br />+#define BAR_MSG_CHAN_USED    1<br />+<br />+#define LOCK_TYPE_HARD  (1)<br />+#define LOCK_TYPE_SOFT  (0)<br />+#define BAR_INDEX_TO_RISC  0<br />+<br />+#define BAR_MSG_POL_MASK    (0x10)<br />+#define BAR_MSG_POL_OFFSET  (4)<br />+<br />+#define REPS_HEADER_LEN_OFFSET      1<br />+#define REPS_HEADER_PAYLOAD_OFFSET  4<br />+#define REPS_HEADER_REPLYED         0xff<br />+<br />+#define READ_CHECK  1<br />+<br />+uint8_t subchan_id_tbl[BAR_MSG_SRC_NUM][BAR_MSG_DST_NUM] = {<br />+    {BAR_SUBCHAN_INDEX_SEND, BAR_SUBCHAN_INDEX_SEND, BAR_SUBCHAN_INDEX_SEND},<br />+    {BAR_SUBCHAN_INDEX_SEND, BAR_SUBCHAN_INDEX_SEND, BAR_SUBCHAN_INDEX_RECV},<br />+    {BAR_SUBCHAN_INDEX_SEND, BAR_SUBCHAN_INDEX_RECV, BAR_SUBCHAN_INDEX_RECV}<br />+};<br />+<br />+uint8_t chan_id_tbl[BAR_MSG_SRC_NUM][BAR_MSG_DST_NUM] = {<br />+    {BAR_INDEX_TO_RISC, BAR_INDEX_MPF_TO_PFVF, BAR_INDEX_MPF_TO_MPF},<br />+    {BAR_INDEX_TO_RISC, BAR_INDEX_PF_TO_VF,    BAR_INDEX_PFVF_TO_MPF},<br />+    {BAR_INDEX_TO_RISC, BAR_INDEX_PF_TO_VF,    BAR_INDEX_PFVF_TO_MPF}<br />+};<br />+<br />+uint8_t lock_type_tbl[BAR_MSG_SRC_NUM][BAR_MSG_DST_NUM] = {<br />+    {LOCK_TYPE_HARD, LOCK_TYPE_HARD, LOCK_TYPE_HARD},<br />+    {LOCK_TYPE_SOFT, LOCK_TYPE_SOFT, LOCK_TYPE_HARD},<br />+    {LOCK_TYPE_HARD, LOCK_TYPE_HARD, LOCK_TYPE_HARD}<br />+};<br />+<br />+#define PCIEID_IS_PF_MASK   (0x0800)<br />+#define PCIEID_PF_IDX_MASK  (0x0700)<br />+#define PCIEID_VF_IDX_MASK  (0x00ff)<br />+#define PCIEID_EP_IDX_MASK  (0x7000)<br />+/* PCIEID bit field offset */<br />+#define PCIEID_PF_IDX_OFFSET  (8)<br />+#define PCIEID_EP_IDX_OFFSET  (12)<br />+<br />+#define MAX_EP_NUM     (4)<br />+#define PF_NUM_PER_EP  (8)<br />+#define VF_NUM_PER_PF  (32)<br />+<br />+#define MULTIPLY_BY_8(x)    ((x) << 3)<br />+#define MULTIPLY_BY_32(x)   ((x) << 5)<br />+#define MULTIPLY_BY_256(x)  ((x) << 8)<br />+<br />+#define MAX_HARD_SPINLOCK_NUM        (511)<br />+#define MAX_HARD_SPINLOCK_ASK_TIMES  (1000)<br />+#define SPINLOCK_POLLING_SPAN_US     (100)<br />+<br />+#define LOCK_MASTER_ID_MASK                (0x8000)<br />+/* bar offset */<br />+#define BAR0_CHAN_RISC_OFFSET              (0x2000)<br />+#define BAR0_CHAN_PFVF_OFFSET              (0x3000)<br />+#define BAR0_SPINLOCK_OFFSET               (0x4000)<br />+#define FW_SHRD_OFFSET                     (0x5000)<br />+#define FW_SHRD_INNER_HW_LABEL_PAT         (0x800)<br />+#define HW_LABEL_OFFSET                    (FW_SHRD_OFFSET + FW_SHRD_INNER_HW_LABEL_PAT)<br />+<br />+#define CHAN_RISC_SPINLOCK_OFFSET          (BAR0_SPINLOCK_OFFSET - BAR0_CHAN_RISC_OFFSET)<br />+#define CHAN_PFVF_SPINLOCK_OFFSET          (BAR0_SPINLOCK_OFFSET - BAR0_CHAN_PFVF_OFFSET)<br />+#define CHAN_RISC_LABEL_OFFSET             (HW_LABEL_OFFSET - BAR0_CHAN_RISC_OFFSET)<br />+#define CHAN_PFVF_LABEL_OFFSET             (HW_LABEL_OFFSET - BAR0_CHAN_PFVF_OFFSET)<br />+<br />+#define RSC_TBL_CONTENT_LEN_MAX  (257 * 2)<br />+#define TBL_MSG_PRO_SUCCESS  0xaa<br />+<br />+zxdh_bar_chan_msg_recv_callback msg_recv_func_tbl[BAR_MSG_MODULE_NUM];<br />+<br />+struct dev_stat {<br />+    bool is_mpf_scanned;<br />+    bool is_res_init;<br />+    int16_t dev_cnt; /* probe cnt */<br />+};<br />+struct dev_stat g_dev_stat = {0};<br />+<br />+static uint8_t __bar_msg_src_index_trans(uint8_t src)<br />+{<br />+    uint8_t src_index = 0;<br />+<br />+    switch (src) {<br />+    case MSG_CHAN_END_MPF:<br />+        src_index = BAR_MSG_SRC_MPF;<br />+        break;<br />+    case MSG_CHAN_END_PF:<br />+        src_index = BAR_MSG_SRC_PF;<br />+        break;<br />+    case MSG_CHAN_END_VF:<br />+        src_index = BAR_MSG_SRC_VF;<br />+        break;<br />+    default:<br />+        src_index = BAR_MSG_SRC_ERR;<br />+        break;<br />+    }<br />+    return src_index;<br />+}<br />+<br />+static uint8_t __bar_msg_dst_index_trans(uint8_t dst)<br />+{<br />+    uint8_t dst_index = 0;<br />+<br />+    switch (dst) {<br />+    case MSG_CHAN_END_MPF:<br />+        dst_index = BAR_MSG_DST_MPF;<br />+        break;<br />+    case MSG_CHAN_END_PF:<br />+        dst_index = BAR_MSG_DST_PFVF;<br />+        break;<br />+    case MSG_CHAN_END_VF:<br />+        dst_index = BAR_MSG_DST_PFVF;<br />+        break;<br />+    case MSG_CHAN_END_RISC:<br />+        dst_index = BAR_MSG_DST_RISC;<br />+        break;<br />+    default:<br />+        dst_index = BAR_MSG_SRC_ERR;<br />+        break;<br />+    }<br />+    return dst_index;<br />+}<br />+<br />+struct seqid_item {<br />+    void *reps_addr;<br />+    uint16_t id;<br />+    uint16_t buffer_len;<br />+    uint16_t flag;<br />+};<br />+<br />+struct seqid_ring {<br />+    uint16_t cur_id;<br />+    pthread_spinlock_t lock;<br />+    struct seqid_item reps_info_tbl[BAR_SEQID_NUM_MAX];<br />+};<br />+struct seqid_ring g_seqid_ring = {0};<br />+<br />+static int __bar_chan_msgid_allocate(uint16_t *msgid)<br />+{<br />+    struct seqid_item *seqid_reps_info = NULL;<br />+<br />+    pthread_spin_lock(&g_seqid_ring.lock);<br />+    uint16_t g_id = g_seqid_ring.cur_id;<br />+    uint16_t count = 0;<br />+<br />+    do {<br />+        count++;<br />+        ++g_id;<br />+        g_id %= BAR_SEQID_NUM_MAX;<br />+        seqid_reps_info = &g_seqid_ring.reps_info_tbl[g_id];<br />+    } while ((seqid_reps_info->flag != REPS_INFO_FLAG_USABLE) && (count < BAR_SEQID_NUM_MAX));<br />+    int rc;<br />+<br />+    if (count >= BAR_SEQID_NUM_MAX) {<br />+        rc = -1;<br />+        goto out;<br />+    }<br />+    seqid_reps_info->flag = REPS_INFO_FLAG_USED;<br />+    g_seqid_ring.cur_id = g_id;<br />+    *msgid = g_id;<br />+    rc = BAR_MSG_OK;<br />+<br />+out:<br />+    pthread_spin_unlock(&g_seqid_ring.lock);<br />+    return rc;<br />+}<br />+<br />+static uint16_t __bar_chan_save_recv_info(struct zxdh_msg_recviver_mem *result, uint16_t *msg_id)<br />+{<br />+    int ret = __bar_chan_msgid_allocate(msg_id);<br />+<br />+    if (ret != BAR_MSG_OK)<br />+        return BAR_MSG_ERR_MSGID;<br />+<br />+    PMD_MSG_LOG(DEBUG, "allocate msg_id: %u", *msg_id);<br />+    struct seqid_item *reps_info = &g_seqid_ring.reps_info_tbl[*msg_id];<br />+<br />+    reps_info->reps_addr = result->recv_buffer;<br />+    reps_info->buffer_len = result->buffer_len;<br />+    return BAR_MSG_OK;<br />+}<br />+<br />+static void __bar_chan_msgid_free(uint16_t msg_id)<br />+{<br />+    struct seqid_item *seqid_reps_info = &g_seqid_ring.reps_info_tbl[msg_id];<br />+<br />+    pthread_spin_lock(&g_seqid_ring.lock);<br />+    seqid_reps_info->flag = REPS_INFO_FLAG_USABLE;<br />+    PMD_MSG_LOG(DEBUG, "free msg_id: %u", msg_id);<br />+    pthread_spin_unlock(&g_seqid_ring.lock);<br />+}<br />+<br />+static uint64_t subchan_addr_cal(uint64_t virt_addr, uint8_t chan_id, uint8_t subchan_id)<br />+{<br />+    return virt_addr + (2 * chan_id + subchan_id) * BAR_MSG_ADDR_CHAN_INTERVAL;<br />+}<br />+<br />+static uint16_t __bar_chan_subchan_addr_get(struct zxdh_pci_bar_msg *in, uint64_t *subchan_addr)<br />+{<br />+    uint8_t src_index = __bar_msg_src_index_trans(in->src);<br />+    uint8_t dst_index = __bar_msg_dst_index_trans(in->dst);<br />+    uint16_t chan_id = chan_id_tbl[src_index][dst_index];<br />+    uint16_t subchan_id = subchan_id_tbl[src_index][dst_index];<br />+<br />+    *subchan_addr = subchan_addr_cal(in->virt_addr, chan_id, subchan_id);<br />+    return BAR_MSG_OK;<br />+}<br />+<br />+static int __bar_chan_reg_write(uint64_t subchan_addr, uint32_t offset, uint32_t data)<br />+{<br />+    uint32_t algin_offset = (offset & BAR_ALIGN_WORD_MASK);<br />+<br />+    if (unlikely(algin_offset >= BAR_MSG_ADDR_CHAN_INTERVAL)) {<br />+        PMD_MSG_LOG(ERR, "write addr: 0x%" PRIu64 " + %" PRIu64 "",<br />+            subchan_addr, algin_offset);<br />+        return -1;<br />+    }<br />+    *(uint32_t *)(subchan_addr + algin_offset) = data;<br />+    return 0;<br />+}<br />+static int __bar_chan_reg_read(uint64_t subchan_addr, uint32_t offset, uint32_t *pdata)<br />+{<br />+    uint32_t algin_offset = (offset & BAR_ALIGN_WORD_MASK);<br />+<br />+    if (unlikely(algin_offset >= BAR_MSG_ADDR_CHAN_INTERVAL)) {<br />+        PMD_MSG_LOG(ERR, "read addr: 0x%" PRIu64 " + 0x%" PRIu64 "",<br />+            subchan_addr, algin_offset);<br />+        return -1;<br />+    }<br />+    *pdata = *(uint32_t *)(subchan_addr + algin_offset);<br />+    return 0;<br />+}<br />+<br />+static uint16_t __bar_chan_msg_header_set(uint64_t subchan_addr, struct bar_msg_header *msg_header)<br />+{<br />+    uint32_t *data = (uint32_t *)msg_header;<br />+    uint16_t idx;<br />+<br />+    for (idx = 0; idx < (BAR_MSG_PLAYLOAD_OFFSET >> 2); idx++)<br />+        __bar_chan_reg_write(subchan_addr, idx * 4, *(data + idx));<br />+<br />+    return BAR_MSG_OK;<br />+}<br />+<br />+static uint16_t __bar_chan_msg_header_get(uint64_t subchan_addr, struct bar_msg_header *msg_header)<br />+{<br />+    uint32_t *data = (uint32_t *)msg_header;<br />+    uint16_t idx;<br />+<br />+    for (idx = 0; idx < (BAR_MSG_PLAYLOAD_OFFSET >> 2); idx++)<br />+        __bar_chan_reg_read(subchan_addr, idx * 4, data + idx);<br />+<br />+    return BAR_MSG_OK;<br />+}<br />+<br />+static uint16_t __bar_chan_msg_payload_set(uint64_t subchan_addr, uint8_t *msg, uint16_t len)<br />+{<br />+    uint32_t *data = (uint32_t *)msg;<br />+    uint32_t count = (len >> 2); /* 4B unit */<br />+    uint32_t ix;<br />+<br />+    for (ix = 0; ix < count; ix++)<br />+        __bar_chan_reg_write(subchan_addr, 4 * ix + BAR_MSG_PLAYLOAD_OFFSET, *(data + ix));<br />+<br />+    /* not 4B align part */<br />+    uint32_t remain = (len & 0x3);<br />+<br />+    if (remain) {<br />+        uint32_t remain_data = 0;<br />+<br />+        for (ix = 0; ix < remain; ix++)<br />+            remain_data |= *((uint8_t *)(msg + len - remain + ix)) << (8 * ix);<br />+<br />+        __bar_chan_reg_write(subchan_addr, 4 * count +<br />+                BAR_MSG_PLAYLOAD_OFFSET, remain_data);<br />+    }<br />+    return BAR_MSG_OK;<br />+}<br />+<br />+static uint16_t __bar_chan_msg_payload_get(uint64_t subchan_addr, uint8_t *msg, uint16_t len)<br />+{<br />+    uint32_t *data = (uint32_t *)msg;<br />+    uint32_t count = (len >> 2);<br />+    uint32_t ix;<br />+<br />+    for (ix = 0; ix < count; ix++)<br />+        __bar_chan_reg_read(subchan_addr, 4 * ix + BAR_MSG_PLAYLOAD_OFFSET, (data + ix));<br />+<br />+    uint32_t remain = (len & 0x3);<br />+<br />+    if (remain) {<br />+        uint32_t remain_data = 0;<br />+<br />+        __bar_chan_reg_read(subchan_addr, 4 * count +<br />+                BAR_MSG_PLAYLOAD_OFFSET, &remain_data);<br />+        for (ix = 0; ix < remain; ix++)<br />+            *((uint8_t *)(msg + (len - remain + ix))) = remain_data >> (8 * ix);<br />+    }<br />+    return BAR_MSG_OK;<br />+}<br />+<br />+static uint16_t __bar_chan_msg_valid_set(uint64_t subchan_addr, uint8_t valid_label)<br />+{<br />+    uint32_t data;<br />+<br />+    __bar_chan_reg_read(subchan_addr, BAR_MSG_VALID_OFFSET, &data);<br />+    data &= (~BAR_MSG_VALID_MASK);<br />+    data |= (uint32_t)valid_label;<br />+    __bar_chan_reg_write(subchan_addr, BAR_MSG_VALID_OFFSET, data);<br />+    return BAR_MSG_OK;<br />+}<br />+<br />+static uint16_t __bar_msg_valid_stat_get(uint64_t subchan_addr)<br />+{<br />+    uint32_t data;<br />+<br />+    __bar_chan_reg_read(subchan_addr, BAR_MSG_VALID_OFFSET, &data);<br />+    if (BAR_MSG_CHAN_USABLE == (data & BAR_MSG_VALID_MASK))<br />+        return BAR_MSG_CHAN_USABLE;<br />+<br />+    return BAR_MSG_CHAN_USED;<br />+}<br />+<br />+#if READ_CHECK<br />+static uint8_t temp_msg[BAR_MSG_ADDR_CHAN_INTERVAL];<br />+#endif<br />+static uint16_t __bar_chan_msg_send(uint64_t subchan_addr, void *payload_addr,<br />+                    uint16_t payload_len, struct bar_msg_header *msg_header)<br />+{<br />+    __bar_chan_msg_header_set(subchan_addr, msg_header);<br />+#if READ_CHECK<br />+    __bar_chan_msg_header_get(subchan_addr, (struct bar_msg_header *)temp_msg);<br />+#endif<br />+    __bar_chan_msg_payload_set(subchan_addr, (uint8_t *)(payload_addr), payload_len);<br />+#if READ_CHECK<br />+    __bar_chan_msg_payload_get(subchan_addr, temp_msg, payload_len);<br />+#endif<br />+    __bar_chan_msg_valid_set(subchan_addr, BAR_MSG_CHAN_USED);<br />+    return BAR_MSG_OK;<br />+}<br />+<br />+static uint16_t __bar_chan_msg_poltag_set(uint64_t subchan_addr, uint8_t label)<br />+{<br />+    uint32_t data;<br />+<br />+    __bar_chan_reg_read(subchan_addr, BAR_MSG_VALID_OFFSET, &data);<br />+    data &= (~(uint32_t)BAR_MSG_POL_MASK);<br />+    data |= ((uint32_t)label << BAR_MSG_POL_OFFSET);<br />+    __bar_chan_reg_write(subchan_addr, BAR_MSG_VALID_OFFSET, data);<br />+    return BAR_MSG_OK;<br />+}<br />+<br />+static uint16_t __bar_chan_sync_msg_reps_get(uint64_t subchan_addr,<br />+                    uint64_t recv_buffer, uint16_t buffer_len)<br />+{<br />+    struct bar_msg_header msg_header;<br />+<br />+    __bar_chan_msg_header_get(subchan_addr, &msg_header);<br />+    uint16_t msg_id = msg_header.msg_id;<br />+    struct seqid_item *reps_info = &g_seqid_ring.reps_info_tbl[msg_id];<br />+<br />+    if (reps_info->flag != REPS_INFO_FLAG_USED) {<br />+        PMD_MSG_LOG(ERR, "msg_id %u unused", msg_id);<br />+        return BAR_MSG_ERR_REPLY;<br />+    }<br />+    uint16_t msg_len = msg_header.len;<br />+<br />+    if (msg_len > buffer_len - 4) {<br />+        PMD_MSG_LOG(ERR, "recv buffer len is: %u, but reply msg len is: %u",<br />+                buffer_len, msg_len + 4);<br />+        return BAR_MSG_ERR_REPSBUFF_LEN;<br />+    }<br />+    uint8_t *recv_msg = (uint8_t *)recv_buffer;<br />+<br />+    __bar_chan_msg_payload_get(subchan_addr, recv_msg + REPS_HEADER_PAYLOAD_OFFSET, msg_len);<br />+    *(uint16_t *)(recv_msg + REPS_HEADER_LEN_OFFSET) = msg_len;<br />+    *recv_msg = REPS_HEADER_REPLYED; /* set reps's valid */<br />+    return BAR_MSG_OK;<br />+}<br />+<br />+static int __bar_chan_send_para_check(struct zxdh_pci_bar_msg *in,<br />+                    struct zxdh_msg_recviver_mem *result)<br />+{<br />+    if (in == NULL || result == NULL) {<br />+        PMD_MSG_LOG(ERR, "send para ERR: null para.");<br />+        return BAR_MSG_ERR_NULL_PARA;<br />+    }<br />+    uint8_t src_index = __bar_msg_src_index_trans(in->src);<br />+    uint8_t dst_index = __bar_msg_dst_index_trans(in->dst);<br />+<br />+    if (src_index == BAR_MSG_SRC_ERR || dst_index == BAR_MSG_DST_ERR) {<br />+        PMD_MSG_LOG(ERR, "send para ERR: chan doesn't exist.");<br />+        return BAR_MSG_ERR_TYPE;<br />+    }<br />+    if (in->module_id >= BAR_MSG_MODULE_NUM) {<br />+        PMD_MSG_LOG(ERR, "send para ERR: invalid module_id: %d.", in->module_id);<br />+        return BAR_MSG_ERR_MODULE;<br />+    }<br />+    if (in->payload_addr == NULL) {<br />+        PMD_MSG_LOG(ERR, "send para ERR: null message.");<br />+        return BAR_MSG_ERR_BODY_NULL;<br />+    }<br />+    if (in->payload_len > BAR_MSG_PAYLOAD_MAX_LEN) {<br />+        PMD_MSG_LOG(ERR, "send para ERR: len %d is too long.", in->payload_len);<br />+        return BAR_MSG_ERR_LEN;<br />+    }<br />+    if (in->virt_addr == 0 || result->recv_buffer == NULL) {<br />+        PMD_MSG_LOG(ERR, "send para ERR: virt_addr or recv_buffer is NULL.");<br />+        return BAR_MSG_ERR_VIRTADDR_NULL;<br />+    }<br />+    if (result->buffer_len < REPS_HEADER_PAYLOAD_OFFSET)<br />+        PMD_MSG_LOG(ERR,<br />+            "recv buffer's len: %" PRIu64 " is short than mininal 4 bytes\n",<br />+            result->buffer_len);<br />+<br />+    return BAR_MSG_OK;<br />+}<br />+<br />+static uint16_t pcie_id_to_hard_lock(uint16_t src_pcieid, uint8_t dst)<br />+{<br />+    uint16_t lock_id = 0;<br />+    uint16_t pf_idx = (src_pcieid & PCIEID_PF_IDX_MASK) >> PCIEID_PF_IDX_OFFSET;<br />+    uint16_t ep_idx = (src_pcieid & PCIEID_EP_IDX_MASK) >> PCIEID_EP_IDX_OFFSET;<br />+<br />+    switch (dst) {<br />+    /* msg to risc */<br />+    case MSG_CHAN_END_RISC:<br />+        lock_id = MULTIPLY_BY_8(ep_idx) + pf_idx;<br />+        break;<br />+    /* msg to pf/vf */<br />+    case MSG_CHAN_END_VF:<br />+    case MSG_CHAN_END_PF:<br />+        lock_id = MULTIPLY_BY_8(ep_idx) + pf_idx + MULTIPLY_BY_8(1 + MAX_EP_NUM);<br />+        break;<br />+    default:<br />+        lock_id = 0;<br />+        break;<br />+    }<br />+    if (lock_id >= MAX_HARD_SPINLOCK_NUM)<br />+        lock_id = 0;<br />+<br />+    return lock_id;<br />+}<br />+<br />+static uint8_t spinklock_read(uint64_t virt_lock_addr, uint32_t lock_id)<br />+{<br />+    return *(volatile uint8_t *)((uint64_t)virt_lock_addr + (uint64_t)lock_id);<br />+}<br />+<br />+static void spinlock_write(uint64_t virt_lock_addr, uint32_t lock_id, uint8_t data)<br />+{<br />+    *(volatile uint8_t *)((uint64_t)virt_lock_addr + (uint64_t)lock_id) = data;<br />+}<br />+<br />+static void label_write(uint64_t label_lock_addr, uint32_t lock_id, uint16_t value)<br />+{<br />+    *(volatile uint16_t *)(label_lock_addr + lock_id * 2) = value;<br />+}<br />+<br />+static int32_t zxdh_spinlock_lock(uint32_t virt_lock_id, uint64_t virt_addr,<br />+                    uint64_t label_addr, uint16_t master_id)<br />+{<br />+    uint32_t lock_rd_cnt = 0;<br />+<br />+    do {<br />+        /* read to lock */<br />+        uint8_t spl_val = spinklock_read(virt_addr, virt_lock_id);<br />+<br />+        if (spl_val == 0) {<br />+            label_write((uint64_t)label_addr, virt_lock_id, master_id);<br />+            break;<br />+        }<br />+        rte_delay_us_block(SPINLOCK_POLLING_SPAN_US);<br />+        lock_rd_cnt++;<br />+    } while (lock_rd_cnt < MAX_HARD_SPINLOCK_ASK_TIMES);<br />+    if (lock_rd_cnt >= MAX_HARD_SPINLOCK_ASK_TIMES)<br />+        return -1;<br />+<br />+    return 0;<br />+}<br />+<br />+static int32_t zxdh_spinlock_unlock(uint32_t virt_lock_id, uint64_t virt_addr, uint64_t label_addr)<br />+{<br />+    label_write((uint64_t)label_addr, virt_lock_id, 0);<br />+    spinlock_write(virt_addr, virt_lock_id, 0);<br />+    return 0;<br />+}<br />+<br />+int pf_recv_bar_msg(void *pay_load __rte_unused,<br />+                    uint16_t len __rte_unused,<br />+                    void *reps_buffer __rte_unused,<br />+                    uint16_t *reps_len __rte_unused,<br />+                    void *eth_dev __rte_unused)<br />+{<br />+    /* todo later provided*/<br />+    return 0;<br />+}<br />+<br />+int vf_recv_bar_msg(void *pay_load __rte_unused,<br />+                    uint16_t len __rte_unused,<br />+                    void *reps_buffer __rte_unused,<br />+                    uint16_t *reps_len __rte_unused,<br />+                    void *eth_dev __rte_unused)<br />+{<br />+    /* todo later provided*/<br />+    return 0;<br />+}<br />+<br />+static int bar_hard_lock(uint16_t src_pcieid, uint8_t dst, uint64_t virt_addr)<br />+{<br />+    int ret = 0;<br />+    uint16_t lockid = pcie_id_to_hard_lock(src_pcieid, dst);<br />+<br />+    PMD_MSG_LOG(DEBUG, "dev pcieid: 0x%x lock, get hardlockid: %u\n", src_pcieid, lockid);<br />+    if (dst == MSG_CHAN_END_RISC)<br />+        ret = zxdh_spinlock_lock(lockid, virt_addr + CHAN_RISC_SPINLOCK_OFFSET,<br />+                    virt_addr + CHAN_RISC_LABEL_OFFSET,<br />+                    src_pcieid | LOCK_MASTER_ID_MASK);<br />+    else<br />+        ret = zxdh_spinlock_lock(lockid, virt_addr + CHAN_PFVF_SPINLOCK_OFFSET,<br />+                    virt_addr + CHAN_PFVF_LABEL_OFFSET,<br />+                    src_pcieid | LOCK_MASTER_ID_MASK);<br />+<br />+    return ret;<br />+}<br />+<br />+static void bar_hard_unlock(uint16_t src_pcieid, uint8_t dst, uint64_t virt_addr)<br />+{<br />+    uint16_t lockid = pcie_id_to_hard_lock(src_pcieid, dst);<br />+<br />+    PMD_MSG_LOG(DEBUG, "dev pcieid: 0x%x unlock, get hardlockid: %u\n", src_pcieid, lockid);<br />+    if (dst == MSG_CHAN_END_RISC)<br />+        zxdh_spinlock_unlock(lockid, virt_addr + CHAN_RISC_SPINLOCK_OFFSET,<br />+                virt_addr + CHAN_RISC_LABEL_OFFSET);<br />+    else<br />+        zxdh_spinlock_unlock(lockid, virt_addr + CHAN_PFVF_SPINLOCK_OFFSET,<br />+                virt_addr + CHAN_PFVF_LABEL_OFFSET);<br />+}<br />+/**<br />+ * Fun: PF init hard_spinlock addr<br />+ * @pcie_id: pf's pcie_id<br />+ * @bar_base_addr:<br />+ */<br />+int bar_chan_pf_init_spinlock(uint16_t pcie_id, uint64_t bar_base_addr)<br />+{<br />+    int lock_id = pcie_id_to_hard_lock(pcie_id, MSG_CHAN_END_RISC);<br />+<br />+    zxdh_spinlock_unlock(lock_id, bar_base_addr + BAR0_SPINLOCK_OFFSET,<br />+            bar_base_addr + HW_LABEL_OFFSET);<br />+    lock_id = pcie_id_to_hard_lock(pcie_id, MSG_CHAN_END_VF);<br />+    zxdh_spinlock_unlock(lock_id, bar_base_addr + BAR0_SPINLOCK_OFFSET,<br />+            bar_base_addr + HW_LABEL_OFFSET);<br />+    return 0;<br />+}<br />+<br />+/**<br />+ * Fun: lock the channel<br />+ */<br />+pthread_spinlock_t chan_lock;<br />+static int bar_chan_lock(uint8_t src, uint8_t dst, uint16_t src_pcieid, uint64_t virt_addr)<br />+{<br />+    int ret = 0;<br />+    uint8_t src_index = __bar_msg_src_index_trans(src);<br />+    uint8_t dst_index = __bar_msg_dst_index_trans(dst);<br />+<br />+    if (src_index == BAR_MSG_SRC_ERR || dst_index == BAR_MSG_DST_ERR) {<br />+        PMD_MSG_LOG(ERR, "lock ERR: chan doesn't exist.\n");<br />+        return BAR_MSG_ERR_TYPE;<br />+    }<br />+    uint16_t idx = lock_type_tbl[src_index][dst_index];<br />+<br />+    if (idx == LOCK_TYPE_SOFT)<br />+        pthread_spin_lock(&chan_lock);<br />+    else<br />+        ret = bar_hard_lock(src_pcieid, dst, virt_addr);<br />+<br />+    if (ret != 0)<br />+        PMD_MSG_LOG(ERR, "dev: 0x%x failed to lock.\n", src_pcieid);<br />+<br />+    return ret;<br />+}<br />+/**<br />+ * Fun: unlock the channel<br />+ */<br />+static int bar_chan_unlock(uint8_t src, uint8_t dst, uint16_t src_pcieid, uint64_t virt_addr)<br />+{<br />+    uint8_t src_index = __bar_msg_src_index_trans(src);<br />+    uint8_t dst_index = __bar_msg_dst_index_trans(dst);<br />+<br />+    if (src_index == BAR_MSG_SRC_ERR || dst_index == BAR_MSG_DST_ERR) {<br />+        PMD_MSG_LOG(ERR, "unlock ERR: chan doesn't exist.\n");<br />+        return BAR_MSG_ERR_TYPE;<br />+    }<br />+    uint16_t idx = lock_type_tbl[src_index][dst_index];<br />+<br />+    if (idx == LOCK_TYPE_SOFT)<br />+        pthread_spin_unlock(&chan_lock);<br />+    else<br />+        bar_hard_unlock(src_pcieid, dst, virt_addr);<br />+<br />+    return BAR_MSG_OK;<br />+}<br />+<br />+static void __bar_chan_msg_header_pr(uint64_t addr)<br />+{<br />+    struct bar_msg_header *hdr = (struct bar_msg_header *)addr;<br />+    PMD_MSG_LOG(DEBUG,<br />+        "valid:%u, msg_id:%u, mod_id:%u, ack:%u s_pcie:0x%x, d_pcie:0x%x.\n",<br />+        hdr->valid, hdr->msg_id, hdr->module_id, hdr->ack,<br />+        hdr->src_pcieid, hdr->dst_pcieid);<br />+}<br />+<br />+int zxdh_bar_chan_sync_msg_send(struct zxdh_pci_bar_msg *in, struct zxdh_msg_recviver_mem *result)<br />+{<br />+    uint16_t ret = __bar_chan_send_para_check(in, result);<br />+<br />+    if (ret != BAR_MSG_OK)<br />+        goto exit;<br />+<br />+    uint16_t seq_id;<br />+<br />+    ret = __bar_chan_save_recv_info(result, &seq_id);<br />+    if (ret != BAR_MSG_OK)<br />+        goto exit;<br />+<br />+    uint64_t subchan_addr;<br />+<br />+    __bar_chan_subchan_addr_get(in, &subchan_addr);<br />+    struct bar_msg_header msg_header = {0};<br />+<br />+    msg_header.sync = BAR_CHAN_MSG_SYNC;<br />+    msg_header.emec = in->emec;<br />+    msg_header.usr  = 0;<br />+    msg_header.rsv  = 0;<br />+    msg_header.module_id  = in->module_id;<br />+    msg_header.len        = in->payload_len;<br />+    msg_header.msg_id     = seq_id;<br />+    msg_header.src_pcieid = in->src_pcieid;<br />+    msg_header.dst_pcieid = in->dst_pcieid;<br />+<br />+    ret = bar_chan_lock(in->src, in->dst, in->src_pcieid, in->virt_addr);<br />+    if (ret != BAR_MSG_OK) {<br />+        __bar_chan_msgid_free(seq_id);<br />+        goto exit;<br />+    }<br />+    __bar_chan_msg_send(subchan_addr, in->payload_addr, in->payload_len, &msg_header);<br />+    /* wait unset valid */<br />+    uint32_t time_out_cnt = 0;<br />+    uint16_t valid;<br />+<br />+    do {<br />+        rte_delay_us_block(BAR_MSG_POLLING_SPAN);<br />+        valid = __bar_msg_valid_stat_get(subchan_addr);<br />+        ++time_out_cnt;<br />+        if ((time_out_cnt % BAR_MSG_POLL_CNT_PER_S) == 0) /* 1s/per_line */<br />+            PMD_MSG_LOG(DEBUG, "waiting %u ms", time_out_cnt / BAR_MSG_POLL_CNT_PER_MS);<br />+    } while ((time_out_cnt < BAR_MSG_TIMEOUT_TH) && (valid == BAR_MSG_CHAN_USED));<br />+    if (time_out_cnt / BAR_MSG_POLL_CNT_PER_MS > 10) /* 10ms */<br />+        PMD_MSG_LOG(DEBUG, "module_id: %s(%u) total waiting %u ms",<br />+            module_id_name(msg_header.module_id), msg_header.module_id,<br />+                time_out_cnt / BAR_MSG_POLL_CNT_PER_MS);<br />+    else<br />+        PMD_MSG_LOG(DEBUG, "module_id: %s(%u) total waiting %u ms",<br />+            module_id_name(msg_header.module_id), msg_header.module_id,<br />+                time_out_cnt / BAR_MSG_POLL_CNT_PER_MS);<br />+<br />+    if ((time_out_cnt == BAR_MSG_TIMEOUT_TH) && (valid != BAR_MSG_CHAN_USABLE)) {<br />+        __bar_chan_msg_valid_set(subchan_addr, BAR_MSG_CHAN_USABLE);<br />+        __bar_chan_msg_poltag_set(subchan_addr, 0);<br />+        PMD_MSG_LOG(ERR, "BAR MSG ERR: chan type time out.");<br />+        __bar_chan_msg_header_pr(subchan_addr);<br />+        ret = BAR_MSG_ERR_TIME_OUT;<br />+    } else {<br />+        ret = __bar_chan_sync_msg_reps_get(subchan_addr,<br />+                    (uint64_t)result->recv_buffer, result->buffer_len);<br />+    }<br />+    __bar_chan_msgid_free(seq_id);<br />+    bar_chan_unlock(in->src, in->dst, in->src_pcieid, in->virt_addr);<br />+<br />+exit:<br />+    return ret;<br />+}<br />+<br />+static uint64_t recv_addr_get(uint8_t src_type, uint8_t dst_type, uint64_t virt_addr)<br />+{<br />+    uint8_t src = __bar_msg_dst_index_trans(src_type);<br />+    uint8_t dst = __bar_msg_src_index_trans(dst_type);<br />+<br />+    if (src == BAR_MSG_SRC_ERR || dst == BAR_MSG_DST_ERR)<br />+        return 0;<br />+<br />+    uint8_t chan_id = chan_id_tbl[dst][src];<br />+    uint8_t subchan_id = 1 - subchan_id_tbl[dst][src];<br />+<br />+    return subchan_addr_cal(virt_addr, chan_id, subchan_id);<br />+}<br />+<br />+static uint64_t reply_addr_get(uint8_t sync, uint8_t src_type, uint8_t dst_type, uint64_t virt_addr)<br />+{<br />+    uint8_t src = __bar_msg_dst_index_trans(src_type);<br />+    uint8_t dst = __bar_msg_src_index_trans(dst_type);<br />+<br />+    if (src == BAR_MSG_SRC_ERR || dst == BAR_MSG_DST_ERR)<br />+        return 0;<br />+<br />+    uint8_t chan_id = chan_id_tbl[dst][src];<br />+    uint8_t subchan_id = 1 - subchan_id_tbl[dst][src];<br />+    uint64_t recv_rep_addr;<br />+<br />+    if (sync == BAR_CHAN_MSG_SYNC)<br />+        recv_rep_addr = subchan_addr_cal(virt_addr, chan_id, subchan_id);<br />+    else<br />+        recv_rep_addr = subchan_addr_cal(virt_addr, chan_id, 1 - subchan_id);<br />+<br />+    return recv_rep_addr;<br />+}<br />+<br />+static uint16_t __bar_chan_msg_header_check(struct bar_msg_header *msg_header)<br />+{<br />+    if (msg_header->valid != BAR_MSG_CHAN_USED) {<br />+        PMD_MSG_LOG(ERR, "recv header ERR: valid label is not used.");<br />+        return BAR_MSG_ERR_MODULE;<br />+    }<br />+    uint8_t module_id = msg_header->module_id;<br />+<br />+    if (module_id >= (uint8_t)BAR_MSG_MODULE_NUM) {<br />+        PMD_MSG_LOG(ERR, "recv header ERR: invalid module_id: %u.", module_id);<br />+        return BAR_MSG_ERR_MODULE;<br />+    }<br />+    uint16_t len = msg_header->len;<br />+<br />+    if (len > BAR_MSG_PAYLOAD_MAX_LEN) {<br />+        PMD_MSG_LOG(ERR, "recv header ERR: invalid mesg len: %u.", len);<br />+        return BAR_MSG_ERR_LEN;<br />+    }<br />+    if (msg_recv_func_tbl[msg_header->module_id] == NULL) {<br />+        PMD_MSG_LOG(ERR, "recv header ERR: module:%s(%u) doesn't register",<br />+                module_id_name(module_id), module_id);<br />+        return BAR_MSG_ERR_MODULE_NOEXIST;<br />+    }<br />+    return BAR_MSG_OK;<br />+}<br />+<br />+static void __bar_msg_sync_msg_proc(uint64_t reply_addr, struct bar_msg_header *msg_header,<br />+                    uint8_t *reciver_buff, void *dev)<br />+{<br />+    uint8_t *reps_buffer = malloc(BAR_MSG_PAYLOAD_MAX_LEN);<br />+<br />+    if (reps_buffer == NULL)<br />+        return;<br />+<br />+    zxdh_bar_chan_msg_recv_callback recv_func = msg_recv_func_tbl[msg_header->module_id];<br />+    uint16_t reps_len = 0;<br />+<br />+    recv_func(reciver_buff, msg_header->len, reps_buffer, &reps_len, dev);<br />+    msg_header->ack = BAR_CHAN_MSG_ACK;<br />+    msg_header->len = reps_len;<br />+    __bar_chan_msg_header_set(reply_addr, msg_header);<br />+    __bar_chan_msg_payload_set(reply_addr, reps_buffer, reps_len);<br />+    __bar_chan_msg_valid_set(reply_addr, BAR_MSG_CHAN_USABLE);<br />+    free(reps_buffer);<br />+}<br />+<br />+static void __bar_msg_ack_async_msg_proc(struct bar_msg_header *msg_header, uint8_t *reciver_buff)<br />+{<br />+    struct seqid_item *reps_info = &g_seqid_ring.reps_info_tbl[msg_header->msg_id];<br />+<br />+    if (reps_info->flag != REPS_INFO_FLAG_USED) {<br />+        PMD_MSG_LOG(ERR, "msg_id: %u is released", msg_header->msg_id);<br />+        return;<br />+    }<br />+    if (msg_header->len > reps_info->buffer_len - 4) {<br />+        PMD_MSG_LOG(ERR, "reps_buf_len is %u, but reps_msg_len is %u",<br />+                reps_info->buffer_len, msg_header->len + 4);<br />+        goto free_id;<br />+    }<br />+    uint8_t *reps_buffer = (uint8_t *)reps_info->reps_addr;<br />+<br />+    memcpy(reps_buffer + 4, reciver_buff, msg_header->len);<br />+    *(uint16_t *)(reps_buffer + 1) = msg_header->len;<br />+    *(uint8_t *)(reps_info->reps_addr) = REPS_HEADER_REPLYED;<br />+<br />+free_id:<br />+    __bar_chan_msgid_free(msg_header->msg_id);<br />+}<br />+<br />+int zxdh_bar_irq_recv(uint8_t src, uint8_t dst, uint64_t virt_addr, void *dev)<br />+{<br />+    uint64_t recv_addr = recv_addr_get(src, dst, virt_addr);<br />+<br />+    if (recv_addr == 0) {<br />+        PMD_MSG_LOG(ERR, "invalid driver type(src:%u, dst:%u).", src, dst);<br />+        return -1;<br />+    }<br />+<br />+    struct bar_msg_header msg_header;<br />+<br />+    __bar_chan_msg_header_get(recv_addr, &msg_header);<br />+    uint16_t ret = __bar_chan_msg_header_check(&msg_header);<br />+<br />+    if (ret != BAR_MSG_OK) {<br />+        PMD_MSG_LOG(ERR, "recv msg_head err, ret: %u.", ret);<br />+        return -1;<br />+    }<br />+    uint8_t *recved_msg = malloc(msg_header.len);<br />+<br />+    if (recved_msg == NULL) {<br />+        PMD_MSG_LOG(ERR, "malloc temp buff failed.");<br />+        return -1;<br />+    }<br />+    __bar_chan_msg_payload_get(recv_addr, recved_msg, msg_header.len);<br />+<br />+    uint64_t reps_addr = reply_addr_get(msg_header.sync, src, dst, virt_addr);<br />+<br />+    if (msg_header.sync == BAR_CHAN_MSG_SYNC) {<br />+        __bar_msg_sync_msg_proc(reps_addr, &msg_header, recved_msg, dev);<br />+        goto exit;<br />+    }<br />+    __bar_chan_msg_valid_set(recv_addr, BAR_MSG_CHAN_USABLE);<br />+    if (msg_header.ack == BAR_CHAN_MSG_ACK) {<br />+        __bar_msg_ack_async_msg_proc(&msg_header, recved_msg);<br />+        goto exit;<br />+    }<br />+<br />+exit:<br />+    free(recved_msg);<br />+    return BAR_MSG_OK;<br />+}<br />+<br />+int zxdh_bar_chan_msg_recv_register(uint8_t module_id, zxdh_bar_chan_msg_recv_callback callback)<br />+{<br />+    if (module_id >= (uint16_t)BAR_MSG_MODULE_NUM) {<br />+        PMD_MSG_LOG(ERR, "register ERR: invalid module_id: %u.", module_id);<br />+        return BAR_MSG_ERR_MODULE;<br />+    }<br />+    if (callback == NULL) {<br />+        PMD_MSG_LOG(ERR, "register %s(%u) error: null callback.",<br />+            module_id_name(module_id), module_id);<br />+        return BAR_MEG_ERR_NULL_FUNC;<br />+    }<br />+    if (msg_recv_func_tbl[module_id] != NULL) {<br />+        PMD_MSG_LOG(ERR, "register warning, event:%s(%u) already be registered.",<br />+            module_id_name(module_id), module_id);<br />+        return BAR_MSG_ERR_REPEAT_REGISTER;<br />+    }<br />+    msg_recv_func_tbl[module_id] = callback;<br />+    PMD_MSG_LOG(DEBUG, "register module: %s(%u) success.",<br />+            module_id_name(module_id), module_id);<br />+    return BAR_MSG_OK;<br />+}<br />+<br />+int zxdh_bar_chan_msg_recv_unregister(uint8_t module_id)<br />+{<br />+    if (module_id >= (uint16_t)BAR_MSG_MODULE_NUM) {<br />+        PMD_MSG_LOG(ERR, "unregister ERR: invalid module_id :%u.", module_id);<br />+        return BAR_MSG_ERR_MODULE;<br />+    }<br />+    if (msg_recv_func_tbl[module_id] == NULL) {<br />+        PMD_MSG_LOG(ERR, "unregister wanning, event: %s(%d) has already be unregistered.",<br />+            module_id_name(module_id), module_id);<br />+        return BAR_MSG_ERR_UNGISTER;<br />+    }<br />+    msg_recv_func_tbl[module_id] = NULL;<br />+    PMD_MSG_LOG(DEBUG, "unregister module %s(%d) success.",<br />+        module_id_name(module_id), module_id);<br />+    return BAR_MSG_OK;<br />+}<br />+<br />+static int bar_get_sum(uint8_t *ptr, uint8_t len)<br />+{<br />+    uint64_t sum = 0;<br />+    int idx;<br />+<br />+    for (idx = 0; idx < len; idx++)<br />+        sum += *(ptr + idx);<br />+<br />+    return (uint16_t)sum;<br />+}<br />+<br />+static int zxdh_get_res_info(struct zxdh_res_para *dev, uint8_t field, uint8_t *res, uint16_t *len)<br />+{<br />+    if (!res || !dev)<br />+        return BAR_MSG_ERR_NULL;<br />+<br />+    struct tbl_msg_header tbl_msg = {<br />+        .type = TBL_TYPE_READ,<br />+        .field = field,<br />+        .pcieid = dev->pcie_id,<br />+        .slen = 0,<br />+        .rsv = 0,<br />+    };<br />+<br />+    struct zxdh_pci_bar_msg in = {0};<br />+<br />+    in.virt_addr = dev->virt_addr;<br />+    in.payload_addr = &tbl_msg;<br />+    in.payload_len = sizeof(tbl_msg);<br />+    in.src = dev->src_type;<br />+    in.dst = MSG_CHAN_END_RISC;<br />+    in.module_id = BAR_MODULE_TBL;<br />+    in.src_pcieid = dev->pcie_id;<br />+<br />+    uint8_t recv_buf[RSC_TBL_CONTENT_LEN_MAX + 8] = {0};<br />+    struct zxdh_msg_recviver_mem result = {<br />+        .recv_buffer = recv_buf,<br />+        .buffer_len = sizeof(recv_buf),<br />+    };<br />+    int ret = zxdh_bar_chan_sync_msg_send(&in, &result);<br />+<br />+    if (ret != BAR_MSG_OK) {<br />+        PMD_MSG_LOG(ERR,<br />+            "send sync_msg failed. pcieid: 0x%x, ret: %d.\n", dev->pcie_id, ret);<br />+        return ret;<br />+    }<br />+    struct tbl_msg_reps_header *tbl_reps =<br />+        (struct tbl_msg_reps_header *)(recv_buf + REPS_HEADER_PAYLOAD_OFFSET);<br />+<br />+    if (tbl_reps->check != TBL_MSG_PRO_SUCCESS) {<br />+        PMD_MSG_LOG(ERR,<br />+            "get resource_field failed. pcieid: 0x%x, ret: %d.\n", dev->pcie_id, ret);<br />+        return ret;<br />+    }<br />+    *len = tbl_reps->len;<br />+    memcpy(res,<br />+        (recv_buf + REPS_HEADER_PAYLOAD_OFFSET + sizeof(struct tbl_msg_reps_header)), *len);<br />+    return ret;<br />+}<br />+<br />+int zxdh_get_res_panel_id(struct zxdh_res_para *in, uint8_t *panel_id)<br />+{<br />+    uint8_t reps = 0;<br />+    uint16_t reps_len = 0;<br />+<br />+    if (zxdh_get_res_info(in, TBL_FIELD_PNLID, &reps, &reps_len) != BAR_MSG_OK)<br />+        return -1;<br />+<br />+    *panel_id = reps;<br />+    return BAR_MSG_OK;<br />+}<br />+int zxdh_get_res_hash_id(struct zxdh_res_para *in, uint8_t *hash_id)<br />+{<br />+    uint8_t reps = 0;<br />+    uint16_t reps_len = 0;<br />+<br />+    if (zxdh_get_res_info(in, TBL_FIELD_HASHID, &reps, &reps_len) != BAR_MSG_OK)<br />+        return -1;<br />+<br />+    *hash_id = reps;<br />+    return BAR_MSG_OK;<br />+}<br />+<br />+int zxdh_bar_chan_enable(struct msix_para *_msix_para, uint16_t *vport)<br />+{<br />+    int ret = 0;<br />+    uint16_t check_token = 0;<br />+    uint16_t sum_res = 0;<br />+<br />+    recv_addr_get(MSG_CHAN_END_RISC, MSG_CHAN_END_PF, 0x0);<br />+<br />+    if (!_msix_para)<br />+        return BAR_MSG_ERR_NULL;<br />+<br />+    struct msix_msg msix_msg = {<br />+        .pcie_id = _msix_para->pcie_id,<br />+        .vector_risc = _msix_para->vector_risc,<br />+        .vector_pfvf = _msix_para->vector_pfvf,<br />+        .vector_mpf = _msix_para->vector_mpf,<br />+    };<br />+    struct zxdh_pci_bar_msg in = {<br />+        .virt_addr = _msix_para->virt_addr,<br />+        .payload_addr = &msix_msg,<br />+        .payload_len = sizeof(msix_msg),<br />+        .emec = 0,<br />+        .src = _msix_para->driver_type,<br />+        .dst = MSG_CHAN_END_RISC,<br />+        .module_id = BAR_MODULE_MISX,<br />+        .src_pcieid = _msix_para->pcie_id,<br />+        .dst_pcieid = 0,<br />+        .usr = 0,<br />+    };<br />+<br />+    struct bar_recv_msg recv_msg = {0};<br />+    struct zxdh_msg_recviver_mem result = {<br />+        .recv_buffer = &recv_msg,<br />+        .buffer_len = sizeof(recv_msg),<br />+    };<br />+<br />+    ret = zxdh_bar_chan_sync_msg_send(&in, &result);<br />+<br />+    if (ret != BAR_MSG_OK)<br />+        return -ret;<br />+<br />+    check_token = recv_msg.msix_reps.check;<br />+    sum_res = bar_get_sum((uint8_t *)&msix_msg, sizeof(msix_msg));<br />+<br />+    if (check_token != sum_res) {<br />+        PMD_MSG_LOG(ERR, "expect token: 0x%x, get token: 0x%x.\n", sum_res, check_token);<br />+        return BAR_MSG_ERR_REPLY;<br />+    }<br />+    *vport = recv_msg.msix_reps.vport;<br />+<br />+    return BAR_MSG_OK;<br />+}<br />+<br />+int zxdh_get_bar_offset(struct bar_offset_params *paras, struct bar_offset_res *res)<br />+{<br />+    uint16_t check_token = 0;<br />+    uint16_t sum_res = 0;<br />+    int ret = 0;<br />+<br />+    if (!paras)<br />+        return BAR_MSG_ERR_NULL;<br />+<br />+    struct offset_get_msg send_msg = {<br />+        .pcie_id = paras->pcie_id,<br />+        .type = paras->type,<br />+    };<br />+    struct zxdh_pci_bar_msg in = {0};<br />+<br />+    in.payload_addr = &send_msg;<br />+    in.payload_len = sizeof(send_msg);<br />+    in.virt_addr = paras->virt_addr;<br />+    in.src = MSG_CHAN_END_PF;<br />+    in.dst = MSG_CHAN_END_RISC;<br />+    in.module_id = BAR_MODULE_OFFSET_GET;<br />+    in.src_pcieid = paras->pcie_id;<br />+<br />+    struct bar_recv_msg recv_msg = {0};<br />+    struct zxdh_msg_recviver_mem result = {<br />+        .recv_buffer = &recv_msg,<br />+        .buffer_len = sizeof(recv_msg),<br />+    };<br />+    ret = zxdh_bar_chan_sync_msg_send(&in, &result);<br />+    if (ret != BAR_MSG_OK)<br />+        return -ret;<br />+<br />+    check_token = recv_msg.offset_reps.check;<br />+    sum_res = bar_get_sum((uint8_t *)&send_msg, sizeof(send_msg));<br />+<br />+    if (check_token != sum_res) {<br />+        PMD_MSG_LOG(ERR, "expect token: 0x%x, get token: 0x%x.\n", sum_res, check_token);<br />+        return BAR_MSG_ERR_REPLY;<br />+    }<br />+    res->bar_offset = recv_msg.offset_reps.offset;<br />+    res->bar_length = recv_msg.offset_reps.length;<br />+    return BAR_MSG_OK;<br />+}<br />+<br />+int zxdh_msg_chan_init(void)<br />+{<br />+    g_dev_stat.dev_cnt++;<br />+    if (g_dev_stat.is_res_init)<br />+        return BAR_MSG_OK;<br />+<br />+    pthread_spin_init(&chan_lock, 0);<br />+    g_seqid_ring.cur_id = 0;<br />+    pthread_spin_init(&g_seqid_ring.lock, 0);<br />+    uint16_t seq_id;<br />+<br />+    for (seq_id = 0; seq_id < BAR_SEQID_NUM_MAX; seq_id++) {<br />+        struct seqid_item *reps_info = &(g_seqid_ring.reps_info_tbl[seq_id]);<br />+<br />+        reps_info->id = seq_id;<br />+        reps_info->flag = REPS_INFO_FLAG_USABLE;<br />+    }<br />+    g_dev_stat.is_res_init = true;<br />+    return BAR_MSG_OK;<br />+}<br />+<br />+int zxdh_bar_msg_chan_exit(void)<br />+{<br />+    if (!g_dev_stat.is_res_init || (--g_dev_stat.dev_cnt > 0))<br />+        return BAR_MSG_OK;<br />+<br />+    g_dev_stat.is_res_init = false;<br />+    PMD_MSG_LOG(DEBUG, "%s exit success!", __func__);<br />+    return BAR_MSG_OK;<br />+}<br />diff --git a/drivers/net/zxdh/zxdh_msg.h b/drivers/net/zxdh/zxdh_msg.h<br />new file mode 100644<br />index 0000000000..b74e7f05ea<br />--- /dev/null<br />+++ b/drivers/net/zxdh/zxdh_msg.h<br />@@ -0,0 +1,408 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2023 ZTE Corporation<br />+ */<br />+<br />+#ifndef _ZXDH_MSG_CHAN_H_<br />+#define _ZXDH_MSG_CHAN_H_<br />+<br />+#ifdef __cplusplus<br />+extern "C" {<br />+#endif<br />+<br />+#include <stdint.h> <br />+<br />+#define ZXDH_MSG_CHAN_PFVFSHARE_OFFSET  (ZXDH_CTRLCH_OFFSET + 0x1000)<br />+#define ZXDH_MSIX_INTR_MSG_VEC_BASE  1<br />+#define ZXDH_MSIX_INTR_MSG_VEC_NUM   3<br />+<br />+#define BAR_MSG_POLLING_SPAN     100 /* sleep us */<br />+#define BAR_MSG_POLL_CNT_PER_MS  (1 * 1000 / BAR_MSG_POLLING_SPAN)<br />+#define BAR_MSG_POLL_CNT_PER_S   (1 * 1000 * 1000 / BAR_MSG_POLLING_SPAN)<br />+#define BAR_MSG_TIMEOUT_TH       (10 * 1000 * 1000 / BAR_MSG_POLLING_SPAN) /* 10s */<br />+<br />+#define BAR_CHAN_MSG_SYNC     0<br />+#define BAR_CHAN_MSG_ASYNC    1<br />+#define BAR_CHAN_MSG_NO_EMEC  0<br />+#define BAR_CHAN_MSG_EMEC     1<br />+#define BAR_CHAN_MSG_NO_ACK   0<br />+#define BAR_CHAN_MSG_ACK      1<br />+<br />+#define ZXDH_MSIX_INTR_DTB_VEC      (ZXDH_MSIX_INTR_MSG_VEC_BASE + ZXDH_MSIX_INTR_MSG_VEC_NUM)<br />+#define ZXDH_MSIX_INTR_DTB_VEC_NUM  1<br />+#define ZXDH_INTR_NONQUE_NUM        (ZXDH_MSIX_INTR_MSG_VEC_NUM + ZXDH_MSIX_INTR_DTB_VEC_NUM + 1)<br />+#define ZXDH_QUE_INTR_VEC_BASE      (ZXDH_MSIX_INTR_DTB_VEC + ZXDH_MSIX_INTR_DTB_VEC_NUM) /* 5 */<br />+#define ZXDH_QUE_INTR_VEC_NUM       256<br />+<br />+#define BAR_MSG_ADDR_CHAN_INTERVAL  (2 * 1024) /* channel size */<br />+#define BAR_MSG_PLAYLOAD_OFFSET     (sizeof(struct bar_msg_header))<br />+#define BAR_MSG_PAYLOAD_MAX_LEN     (BAR_MSG_ADDR_CHAN_INTERVAL - sizeof(struct bar_msg_header))<br />+<br />+#define MSG_CHAN_RET_ERR_RECV_FAIL              (-11)<br />+#define ZXDH_INDIR_RQT_SIZE 256<br />+#define MODULE_EEPROM_DATA_LEN 128<br />+<br />+enum BAR_MSG_RTN {<br />+    BAR_MSG_OK = 0,<br />+    BAR_MSG_ERR_MSGID,<br />+    BAR_MSG_ERR_NULL,<br />+    BAR_MSG_ERR_TYPE, /* Message type exception */<br />+    BAR_MSG_ERR_MODULE, /* Module ID exception */<br />+    BAR_MSG_ERR_BODY_NULL, /* Message body exception */<br />+    BAR_MSG_ERR_LEN, /* Message length exception */<br />+    BAR_MSG_ERR_TIME_OUT, /* Message sending length too long */<br />+    BAR_MSG_ERR_NOT_READY, /* Abnormal message sending conditions*/<br />+    BAR_MEG_ERR_NULL_FUNC, /* Empty receive processing function pointer*/<br />+    BAR_MSG_ERR_REPEAT_REGISTER, /* Module duplicate registration*/<br />+    BAR_MSG_ERR_UNGISTER, /* Repeated deregistration*/<br />+    /**<br />+     * The sending interface parameter boundary structure pointer is empty<br />+     */<br />+    BAR_MSG_ERR_NULL_PARA,<br />+    BAR_MSG_ERR_REPSBUFF_LEN, /* The length of reps_buff is too short*/<br />+    /**<br />+     * Unable to find the corresponding message processing function for this module<br />+     */<br />+    BAR_MSG_ERR_MODULE_NOEXIST,<br />+    /**<br />+     * The virtual address in the parameters passed in by the sending interface is empty<br />+     */<br />+    BAR_MSG_ERR_VIRTADDR_NULL,<br />+    BAR_MSG_ERR_REPLY, /* sync msg resp_error */<br />+    BAR_MSG_ERR_MPF_NOT_SCANNED,<br />+    BAR_MSG_ERR_KERNEL_READY,<br />+    BAR_MSG_ERR_USR_RET_ERR,<br />+    BAR_MSG_ERR_ERR_PCIEID,<br />+    BAR_MSG_ERR_SOCKET, /* netlink sockte err */<br />+};<br />+<br />+enum bar_module_id {<br />+    BAR_MODULE_DBG = 0, /* 0:  debug */<br />+    BAR_MODULE_TBL,     /* 1:  resource table */<br />+    BAR_MODULE_MISX,    /* 2:  config msix */<br />+    BAR_MODULE_SDA,     /* 3: */<br />+    BAR_MODULE_RDMA,    /* 4: */<br />+    BAR_MODULE_DEMO,    /* 5:  channel test */<br />+    BAR_MODULE_SMMU,    /* 6: */<br />+    BAR_MODULE_MAC,     /* 7:  mac rx/tx stats */<br />+    BAR_MODULE_VDPA,    /* 8:  vdpa live migration */<br />+    BAR_MODULE_VQM,     /* 9:  vqm live migration */<br />+    BAR_MODULE_NP,      /* 10: vf msg callback np */<br />+    BAR_MODULE_VPORT,   /* 11: get vport */<br />+    BAR_MODULE_BDF,     /* 12: get bdf */<br />+    BAR_MODULE_RISC_READY, /* 13: */<br />+    BAR_MODULE_REVERSE,    /* 14: byte stream reverse */<br />+    BAR_MDOULE_NVME,       /* 15: */<br />+    BAR_MDOULE_NPSDK,      /* 16: */<br />+    BAR_MODULE_NP_TODO,    /* 17: */<br />+    MODULE_BAR_MSG_TO_PF,  /* 18: */<br />+    MODULE_BAR_MSG_TO_VF,  /* 19: */<br />+<br />+    MODULE_FLASH = 32,<br />+    BAR_MODULE_OFFSET_GET = 33,<br />+    BAR_EVENT_OVS_WITH_VCB = 36, /* ovs<-->vcb */<br />+<br />+    BAR_MSG_MODULE_NUM = 100,<br />+};<br />+<br />+static inline const char *module_id_name(int val)<br />+{<br />+    switch (val) {<br />+    case BAR_MODULE_DBG:        return "BAR_MODULE_DBG";<br />+    case BAR_MODULE_TBL:        return "BAR_MODULE_TBL";<br />+    case BAR_MODULE_MISX:       return "BAR_MODULE_MISX";<br />+    case BAR_MODULE_SDA:        return "BAR_MODULE_SDA";<br />+    case BAR_MODULE_RDMA:       return "BAR_MODULE_RDMA";<br />+    case BAR_MODULE_DEMO:       return "BAR_MODULE_DEMO";<br />+    case BAR_MODULE_SMMU:       return "BAR_MODULE_SMMU";<br />+    case BAR_MODULE_MAC:        return "BAR_MODULE_MAC";<br />+    case BAR_MODULE_VDPA:       return "BAR_MODULE_VDPA";<br />+    case BAR_MODULE_VQM:        return "BAR_MODULE_VQM";<br />+    case BAR_MODULE_NP:         return "BAR_MODULE_NP";<br />+    case BAR_MODULE_VPORT:      return "BAR_MODULE_VPORT";<br />+    case BAR_MODULE_BDF:        return "BAR_MODULE_BDF";<br />+    case BAR_MODULE_RISC_READY: return "BAR_MODULE_RISC_READY";<br />+    case BAR_MODULE_REVERSE:    return "BAR_MODULE_REVERSE";<br />+    case BAR_MDOULE_NVME:       return "BAR_MDOULE_NVME";<br />+    case BAR_MDOULE_NPSDK:      return "BAR_MDOULE_NPSDK";<br />+    case BAR_MODULE_NP_TODO:    return "BAR_MODULE_NP_TODO";<br />+    case MODULE_BAR_MSG_TO_PF:  return "MODULE_BAR_MSG_TO_PF";<br />+    case MODULE_BAR_MSG_TO_VF:  return "MODULE_BAR_MSG_TO_VF";<br />+    case MODULE_FLASH:          return "MODULE_FLASH";<br />+    case BAR_MODULE_OFFSET_GET: return "BAR_MODULE_OFFSET_GET";<br />+    case BAR_EVENT_OVS_WITH_VCB: return "BAR_EVENT_OVS_WITH_VCB";<br />+    default: return "NA";<br />+    }<br />+}<br />+<br />+struct bar_msg_header {<br />+    uint8_t valid : 1; /* used by __bar_chan_msg_valid_set/get */<br />+    uint8_t sync  : 1;<br />+    uint8_t emec  : 1; /* emergency? */<br />+    uint8_t ack   : 1; /* ack msg? */<br />+    uint8_t poll  : 1;<br />+    uint8_t usr   : 1;<br />+    uint8_t rsv;<br />+    uint16_t module_id;<br />+    uint16_t len;<br />+    uint16_t msg_id;<br />+    uint16_t src_pcieid;<br />+    uint16_t dst_pcieid; /* used in PF-->VF */<br />+}; /* 12B */<br />+<br />+struct zxdh_pci_bar_msg {<br />+    uint64_t virt_addr; /* bar addr */<br />+    void    *payload_addr;<br />+    uint16_t payload_len;<br />+    uint16_t emec;<br />+    uint16_t src; /* refer to BAR_DRIVER_TYPE */<br />+    uint16_t dst; /* refer to BAR_DRIVER_TYPE */<br />+    uint16_t module_id;<br />+    uint16_t src_pcieid;<br />+    uint16_t dst_pcieid;<br />+    uint16_t usr;<br />+}; /* 32B */<br />+<br />+struct zxdh_msg_recviver_mem {<br />+    void    *recv_buffer; /* first 4B is head, followed by payload */<br />+    uint64_t buffer_len;<br />+}; /* 16B */<br />+<br />+struct msix_msg {<br />+    uint16_t pcie_id;<br />+    uint16_t vector_risc;<br />+    uint16_t vector_pfvf;<br />+    uint16_t vector_mpf;<br />+};<br />+/* private reps struct */<br />+struct bar_msix_reps {<br />+    uint16_t pcie_id;<br />+    uint16_t check;<br />+    uint16_t vport;<br />+    uint16_t rsv;<br />+} __rte_packed; /* 8B */<br />+<br />+struct bar_offset_reps {<br />+    uint16_t check;<br />+    uint16_t rsv;<br />+    uint32_t offset;<br />+    uint32_t length;<br />+} __rte_packed; /* 12B */<br />+<br />+struct bar_recv_msg {<br />+    /* fix 4B */<br />+    uint8_t  reps_ok;<br />+    uint16_t reps_len;<br />+    uint8_t  rsv;<br />+    union {<br />+        struct bar_msix_reps   msix_reps;   /* 8B */<br />+        struct bar_offset_reps offset_reps; /* 12B */<br />+    } __rte_packed;<br />+} __rte_packed;<br />+<br />+enum pciebar_layout_type {<br />+    URI_VQM      = 0,<br />+    URI_SPINLOCK = 1,<br />+    URI_FWCAP    = 2,<br />+    URI_FWSHR    = 3,<br />+    URI_DRS_SEC  = 4,<br />+    URI_RSV      = 5,<br />+    URI_CTRLCH   = 6,<br />+    URI_1588     = 7,<br />+    URI_QBV      = 8,<br />+    URI_MACPCS   = 9,<br />+    URI_RDMA     = 10,<br />+/* DEBUG PF */<br />+    URI_MNP      = 11,<br />+    URI_MSPM     = 12,<br />+    URI_MVQM     = 13,<br />+    URI_MDPI     = 14,<br />+    URI_NP       = 15,<br />+/* END DEBUG PF */<br />+    URI_MAX,<br />+};<br />+<br />+enum RES_TBL_FILED {<br />+    TBL_FIELD_PCIEID     = 0,<br />+    TBL_FIELD_BDF        = 1,<br />+    TBL_FIELD_MSGCH      = 2,<br />+    TBL_FIELD_DATACH     = 3,<br />+    TBL_FIELD_VPORT      = 4,<br />+    TBL_FIELD_PNLID      = 5,<br />+    TBL_FIELD_PHYPORT    = 6,<br />+    TBL_FIELD_SERDES_NUM = 7,<br />+    TBL_FIELD_NP_PORT    = 8,<br />+    TBL_FIELD_SPEED      = 9,<br />+    TBL_FIELD_HASHID     = 10,<br />+    TBL_FIELD_NON,<br />+};<br />+<br />+struct tbl_msg_header {<br />+    uint8_t  type;  /* r/w */<br />+    uint8_t  field; /* which table? */<br />+    uint16_t pcieid;<br />+    uint16_t slen;<br />+    uint16_t rsv;<br />+}; /* 8B */<br />+struct tbl_msg_reps_header {<br />+    uint8_t  check;<br />+    uint8_t  rsv;<br />+    uint16_t len;<br />+}; /* 4B */<br />+<br />+enum TBL_MSG_TYPE {<br />+    TBL_TYPE_READ,<br />+    TBL_TYPE_WRITE,<br />+    TBL_TYPE_NON,<br />+};<br />+<br />+struct bar_offset_params {<br />+    uint64_t virt_addr;  /* Bar space control space virtual address */<br />+    uint16_t pcie_id;<br />+    uint16_t type;  /* Module types corresponding to PCIBAR planning */<br />+};<br />+struct bar_offset_res {<br />+    uint32_t bar_offset;<br />+    uint32_t bar_length;<br />+};<br />+<br />+/* vec0  : dev  interrupt<br />+ * vec1~3: risc interrupt<br />+ * vec4  : dtb  interrupt<br />+ */<br />+enum {<br />+    MSIX_FROM_PFVF = ZXDH_MSIX_INTR_MSG_VEC_BASE, /* 1 */<br />+    MSIX_FROM_MPF,   /* 2 */<br />+    MSIX_FROM_RISCV, /* 3 */<br />+    MSG_VEC_NUM      /* 4 */<br />+} MSG_VEC;<br />+<br />+enum DRIVER_TYPE {<br />+    MSG_CHAN_END_MPF = 0,<br />+    MSG_CHAN_END_PF,<br />+    MSG_CHAN_END_VF,<br />+    MSG_CHAN_END_RISC,<br />+};<br />+<br />+enum MSG_TYPE {<br />+    /* loopback test type */<br />+    TYPE_DEBUG = 0,<br />+    DST_RISCV,<br />+    DST_MPF,<br />+    DST_PF_OR_VF,<br />+    DST_ZF,<br />+    MSG_TYPE_NUM,<br />+};<br />+<br />+struct msg_header {<br />+    bool is_async;<br />+    enum MSG_TYPE msg_type;<br />+    enum bar_module_id msg_module_id;<br />+    uint8_t msg_priority;<br />+    uint16_t vport_dst;<br />+    uint16_t qid_dst;<br />+};<br />+<br />+struct zxdh_res_para {<br />+    uint64_t virt_addr;<br />+    uint16_t pcie_id;<br />+    uint16_t src_type; /* refer to BAR_DRIVER_TYPE */<br />+};<br />+<br />+struct msix_para {<br />+    uint16_t pcie_id;<br />+    uint16_t vector_risc;<br />+    uint16_t vector_pfvf;<br />+    uint16_t vector_mpf;<br />+    uint64_t virt_addr;<br />+    uint16_t driver_type; /* refer to DRIVER_TYPE */<br />+};<br />+<br />+struct offset_get_msg {<br />+    uint16_t pcie_id;<br />+    uint16_t type;<br />+}; /* 4B */<br />+<br />+typedef int (*zxdh_bar_chan_msg_recv_callback)(void *pay_load, uint16_t len, void *reps_buffer,<br />+                    uint16_t *reps_len, void *dev);<br />+<br />+/**<br />+ * Init msg_chan_pkt in probe()<br />+ * @return zero for success, negative for failure<br />+ */<br />+int16_t zxdh_msg_chan_pkt_init(void);<br />+void zxdh_msg_chan_pkt_remove(void); /* Remove msg_chan_pkt in probe() */<br />+<br />+/**<br />+ * Get the offset value of the specified module<br />+ * @bar_offset_params:  input parameter<br />+ * @bar_offset_res: Module offset and length<br />+ */<br />+int zxdh_get_bar_offset(struct bar_offset_params *paras, struct bar_offset_res *res);<br />+<br />+typedef int (*zxdh_bar_chan_msg_recv_callback)(void *pay_load, uint16_t len, void *reps_buffer,<br />+                    uint16_t *reps_len, void *dev);<br />+<br />+/**<br />+ * Send synchronization messages through PCIE BAR space<br />+ * @in: Message sending information<br />+ * @result: Message result feedback<br />+ * @return: 0 successful, other failures<br />+ */<br />+int zxdh_bar_chan_sync_msg_send(struct zxdh_pci_bar_msg *in, struct zxdh_msg_recviver_mem *result);<br />+<br />+/**<br />+ * PCIE BAR spatial message method, registering message reception callback<br />+ * @module_id: Registration module ID<br />+ * @callback: Pointer to the receive processing function implemented by the module<br />+ * @return: 0 successful, other failures<br />+ * Usually called during driver initialization<br />+ */<br />+int zxdh_bar_chan_msg_recv_register(uint8_t module_id, zxdh_bar_chan_msg_recv_callback callback);<br />+<br />+/**<br />+ * PCIE BAR spatial message method, unregistered message receiving callback<br />+ * @module_id: Kernel PCIE device address<br />+ * @return: 0 successful, other failures<br />+ * Called during driver uninstallation<br />+ */<br />+int zxdh_bar_chan_msg_recv_unregister(uint8_t module_id);<br />+<br />+/**<br />+ * Provide a message receiving interface for device driver interrupt handling functions<br />+ * @src:  Driver type for sending interrupts<br />+ * @dst:  Device driver's own driver type<br />+ * @virt_addr: The communication bar address of the device<br />+ * @return: 0 successful, other failures<br />+ */<br />+int zxdh_bar_irq_recv(uint8_t src, uint8_t dst, uint64_t virt_addr, void *dev);<br />+<br />+/**<br />+ * Initialize spilock and clear the hardware lock address it belongs to<br />+ * @pcie_id: PCIE_id of PF device<br />+ * @bar_base_addr: Bar0 initial base address<br />+ */<br />+int bar_chan_pf_init_spinlock(uint16_t pcie_id, uint64_t bar_base_addr);<br />+<br />+int zxdh_bar_chan_enable(struct msix_para *_msix_para, uint16_t *vport);<br />+int zxdh_msg_chan_init(void);<br />+int zxdh_bar_msg_chan_exit(void);<br />+<br />+int zxdh_get_res_panel_id(struct zxdh_res_para *in, uint8_t *panel_id);<br />+int zxdh_get_res_hash_id(struct zxdh_res_para *in, uint8_t *hash_id);<br />+<br />+int pf_recv_bar_msg(void *pay_load __rte_unused,<br />+                    uint16_t len __rte_unused,<br />+                    void *reps_buffer __rte_unused,<br />+                    uint16_t *reps_len __rte_unused,<br />+                    void *eth_dev __rte_unused);<br />+int vf_recv_bar_msg(void *pay_load __rte_unused,<br />+                    uint16_t len __rte_unused,<br />+                    void *reps_buffer __rte_unused,<br />+                    uint16_t *reps_len __rte_unused,<br />+                    void *eth_dev __rte_unused);<br />+<br />+#ifdef __cplusplus<br />+}<br />+#endif<br />+<br />+#endif /* _ZXDH_MSG_CHAN_H_  */<br />diff --git a/drivers/net/zxdh/zxdh_npsdk.c b/drivers/net/zxdh/zxdh_npsdk.c<br />new file mode 100644<br />index 0000000000..eec644b01e<br />--- /dev/null<br />+++ b/drivers/net/zxdh/zxdh_npsdk.c<br />@@ -0,0 +1,158 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2023 ZTE Corporation<br />+ */<br />+<br />+#include <rte_common.h> <br />+#include "zxdh_npsdk.h" <br />+<br />+int dpp_dtb_hash_offline_delete(uint32_t dev_id __rte_unused,<br />+                                uint32_t queue_id __rte_unused,<br />+                                uint32_t sdt_no __rte_unused,<br />+                                uint32_t flush_mode __rte_unused)<br />+{<br />+    /* todo provided later */<br />+    return 0;<br />+}<br />+<br />+int dpp_dtb_hash_online_delete(uint32_t dev_id __rte_unused,<br />+                               uint32_t queue_id __rte_unused,<br />+                               uint32_t sdt_no __rte_unused)<br />+{<br />+    /* todo provided later */<br />+    return 0;<br />+}<br />+<br />+int dpp_apt_hash_res_get(uint32_t type __rte_unused,<br />+                DPP_APT_HASH_RES_INIT_T *HashResInit __rte_unused)<br />+{<br />+    /* todo provided later */<br />+    return 0;<br />+}<br />+<br />+int dpp_apt_eram_res_get(uint32_t type __rte_unused,<br />+                DPP_APT_ERAM_RES_INIT_T *EramResInit __rte_unused)<br />+{<br />+    /* todo provided later */<br />+    return 0;<br />+}<br />+<br />+int dpp_apt_stat_res_get(uint32_t type __rte_unused,<br />+                DPP_APT_STAT_RES_INIT_T *StatResInit __rte_unused)<br />+{<br />+    /* todo provided later */<br />+    return 0;<br />+}<br />+<br />+int dpp_apt_hash_global_res_init(uint32_t dev_id __rte_unused)<br />+{<br />+    /* todo provided later */<br />+    return 0;<br />+}<br />+<br />+int dpp_apt_hash_func_res_init(uint32_t dev_id __rte_unused,<br />+                    uint32_t func_num __rte_unused,<br />+                    DPP_APT_HASH_FUNC_RES_T *HashFuncRes __rte_unused)<br />+{<br />+    /* todo provided later */<br />+    return 0;<br />+}<br />+<br />+int dpp_apt_hash_bulk_res_init(uint32_t dev_id __rte_unused,<br />+                    uint32_t bulk_num __rte_unused,<br />+                    DPP_APT_HASH_BULK_RES_T *BulkRes __rte_unused)<br />+{<br />+    /* todo provided later */<br />+    return 0;<br />+}<br />+<br />+int dpp_apt_hash_tbl_res_init(uint32_t dev_id __rte_unused,<br />+                    uint32_t tbl_num __rte_unused,<br />+                    DPP_APT_HASH_TABLE_T *HashTbl __rte_unused)<br />+{<br />+    /* todo provided later */<br />+    return 0;<br />+}<br />+<br />+int dpp_apt_eram_res_init(uint32_t dev_id __rte_unused,<br />+                uint32_t tbl_num __rte_unused,<br />+                DPP_APT_ERAM_TABLE_T *EramTbl __rte_unused)<br />+{<br />+    /* todo provided later */<br />+    return 0;<br />+}<br />+<br />+int dpp_stat_ppu_eram_baddr_set(uint32_t dev_id __rte_unused,<br />+                    uint32_t ppu_eram_baddr __rte_unused)<br />+{<br />+    /* todo provided later */<br />+    return 0;<br />+}<br />+int dpp_stat_ppu_eram_depth_set(uint32_t dev_id __rte_unused,<br />+                    uint32_t ppu_eram_depth __rte_unused)<br />+{<br />+    /* todo provided later */<br />+    return 0;<br />+}<br />+int dpp_se_cmmu_smmu1_cfg_set(uint32_t dev_id __rte_unused,<br />+                    uint32_t base_addr __rte_unused)<br />+{<br />+    /* todo provided later */<br />+    return 0;<br />+}<br />+int dpp_stat_ppu_ddr_baddr_set(uint32_t dev_id __rte_unused,<br />+                    uint32_t ppu_ddr_baddr __rte_unused)<br />+{<br />+    /* todo provided later */<br />+    return 0;<br />+}<br />+<br />+int dpp_host_np_init(uint32_t dev_id __rte_unused,<br />+            DPP_DEV_INIT_CTRL_T *p_dev_init_ctrl __rte_unused)<br />+{<br />+    /* todo provided later */<br />+    return 0;<br />+}<br />+int dpp_np_online_uninstall(uint32_t dev_id __rte_unused,<br />+            char *port_name __rte_unused,<br />+            uint32_t queue_id __rte_unused)<br />+{<br />+    /* todo provided later */<br />+    return 0;<br />+}<br />+<br />+int dpp_dtb_stat_ppu_cnt_get(uint32_t dev_id __rte_unused,<br />+             uint32_t queue_id __rte_unused,<br />+             STAT_CNT_MODE_E rd_mode __rte_unused,<br />+             uint32_t index __rte_unused,<br />+             uint32_t *p_data __rte_unused)<br />+{<br />+    /* todo provided later */<br />+    return 0;<br />+}<br />+<br />+int dpp_dtb_entry_get(uint32_t dev_id __rte_unused,<br />+         uint32_t queue_id __rte_unused,<br />+         DPP_DTB_USER_ENTRY_T *GetEntry __rte_unused,<br />+         uint32_t srh_mode __rte_unused)<br />+{<br />+    /* todo provided later */<br />+    return 0;<br />+}<br />+int dpp_dtb_table_entry_write(uint32_t dev_id __rte_unused,<br />+            uint32_t queue_id __rte_unused,<br />+            uint32_t entryNum __rte_unused,<br />+            DPP_DTB_USER_ENTRY_T *DownEntrys __rte_unused)<br />+{<br />+    /* todo provided later */<br />+    return 0;<br />+}<br />+int dpp_dtb_table_entry_delete(uint32_t dev_id __rte_unused,<br />+             uint32_t queue_id __rte_unused,<br />+             uint32_t entryNum __rte_unused,<br />+             DPP_DTB_USER_ENTRY_T *DeleteEntrys __rte_unused)<br />+{<br />+    /* todo provided later */<br />+    return 0;<br />+}<br />+<br />+<br />diff --git a/drivers/net/zxdh/zxdh_npsdk.h b/drivers/net/zxdh/zxdh_npsdk.h<br />new file mode 100644<br />index 0000000000..265f79d132<br />--- /dev/null<br />+++ b/drivers/net/zxdh/zxdh_npsdk.h<br />@@ -0,0 +1,216 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2023 ZTE Corporation<br />+ */<br />+<br />+#include <stdint.h> <br />+<br />+#define DPP_PORT_NAME_MAX                   (32)<br />+#define DPP_SMMU1_READ_REG_MAX_NUM          (16)<br />+#define DPP_DIR_TBL_BUF_MAX_NUM             (DPP_SMMU1_READ_REG_MAX_NUM)<br />+#define DPP_ETCAM_BLOCK_NUM                 (8)<br />+#define DPP_SMMU0_LPM_AS_TBL_ID_NUM         (8)<br />+#define SE_NIC_RES_TYPE                      0<br />+<br />+#define ZXDH_SDT_VPORT_ATT_TABLE            ((uint32_t)(1))<br />+#define ZXDH_SDT_PANEL_ATT_TABLE            ((uint32_t)(2))<br />+#define ZXDH_SDT_RSS_ATT_TABLE              ((uint32_t)(3))<br />+#define ZXDH_SDT_VLAN_ATT_TABLE             ((uint32_t)(4))<br />+#define ZXDH_SDT_BROCAST_ATT_TABLE          ((uint32_t)(6))<br />+#define ZXDH_SDT_UNICAST_ATT_TABLE          ((uint32_t)(10))<br />+#define ZXDH_SDT_MULTICAST_ATT_TABLE        ((uint32_t)(11))<br />+<br />+#define ZXDH_SDT_L2_ENTRY_TABLE0            ((uint32_t)(64))<br />+#define ZXDH_SDT_L2_ENTRY_TABLE1            ((uint32_t)(65))<br />+#define ZXDH_SDT_L2_ENTRY_TABLE2            ((uint32_t)(66))<br />+#define ZXDH_SDT_L2_ENTRY_TABLE3            ((uint32_t)(67))<br />+#define ZXDH_SDT_L2_ENTRY_TABLE4            ((uint32_t)(68))<br />+#define ZXDH_SDT_L2_ENTRY_TABLE5            ((uint32_t)(69))<br />+<br />+#define ZXDH_SDT_MC_TABLE0                  ((uint32_t)(76))<br />+#define ZXDH_SDT_MC_TABLE1                  ((uint32_t)(77))<br />+#define ZXDH_SDT_MC_TABLE2                  ((uint32_t)(78))<br />+#define ZXDH_SDT_MC_TABLE3                  ((uint32_t)(79))<br />+#define ZXDH_SDT_MC_TABLE4                  ((uint32_t)(80))<br />+#define ZXDH_SDT_MC_TABLE5                  ((uint32_t)(81))<br />+<br />+#define MK_SDT_NO(table, hash_idx) \<br />+    (ZXDH_SDT_##table##_TABLE0 + hash_idx)<br />+<br />+typedef struct dpp_dtb_addr_info_t {<br />+    uint32_t sdt_no;<br />+    uint32_t size;<br />+    uint32_t phy_addr;<br />+    uint32_t vir_addr;<br />+} DPP_DTB_ADDR_INFO_T;<br />+<br />+typedef struct dpp_dev_init_ctrl_t {<br />+    uint32_t vport;<br />+    char  port_name[DPP_PORT_NAME_MAX];<br />+    uint32_t vector;<br />+    uint32_t queue_id;<br />+    uint32_t np_bar_offset;<br />+    uint32_t np_bar_len;<br />+    uint32_t pcie_vir_addr;<br />+    uint32_t down_phy_addr;<br />+    uint32_t down_vir_addr;<br />+    uint32_t dump_phy_addr;<br />+    uint32_t dump_vir_addr;<br />+    uint32_t dump_sdt_num;<br />+    DPP_DTB_ADDR_INFO_T dump_addr_info[];<br />+} DPP_DEV_INIT_CTRL_T;<br />+<br />+typedef struct dpp_apt_hash_func_res_t {<br />+    uint32_t func_id;<br />+    uint32_t zblk_num;<br />+    uint32_t zblk_bitmap;<br />+    uint32_t ddr_dis;<br />+} DPP_APT_HASH_FUNC_RES_T;<br />+<br />+typedef enum dpp_hash_ddr_width_mode {<br />+    DDR_WIDTH_INVALID = 0,<br />+    DDR_WIDTH_256b,<br />+    DDR_WIDTH_512b,<br />+} DPP_HASH_DDR_WIDTH_MODE;<br />+<br />+typedef struct dpp_apt_hash_bulk_res_t {<br />+    uint32_t func_id;<br />+    uint32_t bulk_id;<br />+    uint32_t zcell_num;<br />+    uint32_t zreg_num;<br />+    uint32_t ddr_baddr;<br />+    uint32_t ddr_item_num;<br />+    DPP_HASH_DDR_WIDTH_MODE ddr_width_mode;<br />+    uint32_t ddr_crc_sel;<br />+    uint32_t ddr_ecc_en;<br />+} DPP_APT_HASH_BULK_RES_T;<br />+<br />+<br />+typedef struct dpp_sdt_tbl_hash_t {<br />+    uint32_t table_type;<br />+    uint32_t hash_id;<br />+    uint32_t hash_table_width;<br />+    uint32_t key_size;<br />+    uint32_t hash_table_id;<br />+    uint32_t learn_en;<br />+    uint32_t keep_alive;<br />+    uint32_t keep_alive_baddr;<br />+    uint32_t rsp_mode;<br />+    uint32_t hash_clutch_en;<br />+} DPP_SDTTBL_HASH_T;<br />+<br />+typedef struct dpp_hash_entry {<br />+    uint8_t *p_key;<br />+    uint8_t *p_rst;<br />+} DPP_HASH_ENTRY;<br />+<br />+<br />+typedef uint32_t (*DPP_APT_HASH_ENTRY_SET_FUNC)(void *Data, DPP_HASH_ENTRY *Entry);<br />+typedef uint32_t (*DPP_APT_HASH_ENTRY_GET_FUNC)(void *Data, DPP_HASH_ENTRY *Entry);<br />+<br />+typedef struct dpp_apt_hash_table_t {<br />+    uint32_t sdtNo;<br />+    uint32_t sdt_partner;<br />+    DPP_SDTTBL_HASH_T hashSdt;<br />+    uint32_t tbl_flag;<br />+    DPP_APT_HASH_ENTRY_SET_FUNC hash_set_func;<br />+    DPP_APT_HASH_ENTRY_GET_FUNC hash_get_func;<br />+} DPP_APT_HASH_TABLE_T;<br />+<br />+typedef struct dpp_apt_hash_res_init_t {<br />+    uint32_t func_num;<br />+    uint32_t bulk_num;<br />+    uint32_t tbl_num;<br />+    DPP_APT_HASH_FUNC_RES_T *func_res;<br />+    DPP_APT_HASH_BULK_RES_T *bulk_res;<br />+    DPP_APT_HASH_TABLE_T  *tbl_res;<br />+} DPP_APT_HASH_RES_INIT_T;<br />+<br />+typedef struct dpp_sdt_tbl_eram_t {<br />+    uint32_t table_type;<br />+    uint32_t eram_mode;<br />+    uint32_t eram_base_addr;<br />+    uint32_t eram_table_depth;<br />+    uint32_t eram_clutch_en;<br />+} DPP_SDTTBL_ERAM_T;<br />+<br />+typedef uint32_t (*DPP_APT_ERAM_SET_FUNC)(void *Data, uint32_t buf[4]);<br />+typedef uint32_t (*DPP_APT_ERAM_GET_FUNC)(void *Data, uint32_t buf[4]);<br />+<br />+typedef struct dpp_apt_eram_table_t {<br />+    uint32_t sdtNo;<br />+    DPP_SDTTBL_ERAM_T ERamSdt;<br />+    uint32_t opr_mode;<br />+    uint32_t rd_mode;<br />+    DPP_APT_ERAM_SET_FUNC  eram_set_func;<br />+    DPP_APT_ERAM_GET_FUNC  eram_get_func;<br />+} DPP_APT_ERAM_TABLE_T;<br />+<br />+<br />+typedef struct dpp_apt_eram_res_init_t {<br />+    uint32_t tbl_num;<br />+    DPP_APT_ERAM_TABLE_T *eram_res;<br />+} DPP_APT_ERAM_RES_INIT_T;<br />+<br />+typedef struct dpp_apt_stat_res_init_t {<br />+    uint32_t eram_baddr;<br />+    uint32_t eram_depth;<br />+    uint32_t ddr_baddr;<br />+    uint32_t ppu_ddr_offset;<br />+} DPP_APT_STAT_RES_INIT_T;<br />+<br />+typedef enum stat_cnt_mode_e {<br />+    STAT_64_MODE  = 0,<br />+    STAT_128_MODE = 1,<br />+    STAT_MAX_MODE,<br />+} STAT_CNT_MODE_E;<br />+<br />+typedef struct dpp_dtb_user_entry_t {<br />+    uint32_t sdt_no;<br />+    void *p_entry_data;<br />+} DPP_DTB_USER_ENTRY_T;<br />+<br />+<br />+int dpp_dtb_hash_offline_delete(uint32_t dev_id, uint32_t queue_id,<br />+                        uint32_t sdt_no, uint32_t flush_mode);<br />+int dpp_dtb_hash_online_delete(uint32_t dev_id, uint32_t queue_id, uint32_t sdt_no);<br />+int dpp_apt_hash_res_get(uint32_t type, DPP_APT_HASH_RES_INIT_T *HashResInit);<br />+int dpp_apt_eram_res_get(uint32_t type, DPP_APT_ERAM_RES_INIT_T *EramResInit);<br />+<br />+int dpp_apt_stat_res_get(uint32_t type, DPP_APT_STAT_RES_INIT_T *StatResInit);<br />+int dpp_apt_hash_global_res_init(uint32_t dev_id);<br />+int dpp_apt_hash_func_res_init(uint32_t dev_id, uint32_t func_num,<br />+                               DPP_APT_HASH_FUNC_RES_T *HashFuncRes);<br />+int dpp_apt_hash_bulk_res_init(uint32_t dev_id, uint32_t bulk_num,<br />+                               DPP_APT_HASH_BULK_RES_T *BulkRes);<br />+int dpp_apt_hash_tbl_res_init(uint32_t dev_id, uint32_t tbl_num,<br />+                               DPP_APT_HASH_TABLE_T *HashTbl);<br />+int dpp_apt_eram_res_init(uint32_t dev_id, uint32_t tbl_num,<br />+                          DPP_APT_ERAM_TABLE_T *EramTbl);<br />+int dpp_stat_ppu_eram_baddr_set(uint32_t dev_id, uint32_t ppu_eram_baddr);<br />+int dpp_stat_ppu_eram_depth_set(uint32_t dev_id, uint32_t ppu_eram_depth);<br />+int dpp_se_cmmu_smmu1_cfg_set(uint32_t dev_id, uint32_t base_addr);<br />+int dpp_stat_ppu_ddr_baddr_set(uint32_t dev_id, uint32_t ppu_ddr_baddr);<br />+<br />+int dpp_host_np_init(uint32_t dev_id, DPP_DEV_INIT_CTRL_T *p_dev_init_ctrl);<br />+int dpp_np_online_uninstall(uint32_t dev_id,<br />+                            char *port_name,<br />+                            uint32_t queue_id);<br />+<br />+int dpp_dtb_stat_ppu_cnt_get(uint32_t dev_id,<br />+                            uint32_t queue_id,<br />+                            STAT_CNT_MODE_E rd_mode,<br />+                            uint32_t index,<br />+                            uint32_t *p_data);<br />+<br />+int dpp_dtb_entry_get(uint32_t dev_id,<br />+                    uint32_t queue_id,<br />+                    DPP_DTB_USER_ENTRY_T *GetEntry,<br />+                    uint32_t srh_mode);<br />+int dpp_dtb_table_entry_write(uint32_t dev_id,<br />+                            uint32_t queue_id,<br />+                            uint32_t entryNum,<br />+                            DPP_DTB_USER_ENTRY_T *DownEntrys);<br />+int dpp_dtb_table_entry_delete(uint32_t dev_id,<br />+                            uint32_t queue_id,<br />+                            uint32_t entryNum,<br />+                            DPP_DTB_USER_ENTRY_T *DeleteEntrys);<br />--  <br />2.43.0<br />