insert port tables in host.

Signed-off-by: Junlong Wang <wang.junlong1@zte.com.cn>
---
 drivers/net/zxdh/meson.build   |   1 +
 drivers/net/zxdh/zxdh_ethdev.c |  24 ++
 drivers/net/zxdh/zxdh_msg.c    |  65 ++++
 drivers/net/zxdh/zxdh_msg.h    |  72 ++++
 drivers/net/zxdh/zxdh_np.c     | 648 ++++++++++++++++++++++++++++++++-
 drivers/net/zxdh/zxdh_np.h     | 210 +++++++++++
 drivers/net/zxdh/zxdh_pci.h    |   2 +
 drivers/net/zxdh/zxdh_tables.c | 105 ++++++
 drivers/net/zxdh/zxdh_tables.h | 148 ++++++++
 9 files changed, 1274 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/zxdh/zxdh_tables.c
 create mode 100644 drivers/net/zxdh/zxdh_tables.h

diff --git a/drivers/net/zxdh/meson.build b/drivers/net/zxdh/meson.build
index ab24a3145c..5b3af87c5b 100644
--- a/drivers/net/zxdh/meson.build
+++ b/drivers/net/zxdh/meson.build
@@ -20,4 +20,5 @@ sources = files(
         'zxdh_pci.c',
         'zxdh_queue.c',
         'zxdh_np.c',
+        'zxdh_tables.c',
 )
diff --git a/drivers/net/zxdh/zxdh_ethdev.c b/drivers/net/zxdh/zxdh_ethdev.c
index 4e114d95da..ff44816384 100644
--- a/drivers/net/zxdh/zxdh_ethdev.c
+++ b/drivers/net/zxdh/zxdh_ethdev.c
@@ -14,6 +14,7 @@
 #include "zxdh_common.h"
 #include "zxdh_queue.h"
 #include "zxdh_np.h"
+#include "zxdh_tables.h"
 
 struct zxdh_hw_internal zxdh_hw_internal[RTE_MAX_ETHPORTS];
 struct zxdh_shared_data *zxdh_shared_data;
@@ -1144,6 +1145,25 @@ zxdh_np_init(struct rte_eth_dev *eth_dev)
     return 0;
 }
 
+static int
+zxdh_tables_init(struct rte_eth_dev *dev)
+{
+    int ret = 0;
+
+    ret = zxdh_port_attr_init(dev);
+    if (ret) {
+        PMD_DRV_LOG(ERR, "zxdh_port_attr_init failed");
+        return ret;
+    }
+
+    ret = zxdh_panel_table_init(dev);
+    if (ret) {
+        PMD_DRV_LOG(ERR, " panel table init failed");
+        return ret;
+    }
+    return ret;
+}
+
 static int
 zxdh_eth_dev_init(struct rte_eth_dev *eth_dev)
 {
@@ -1220,6 +1240,10 @@ zxdh_eth_dev_init(struct rte_eth_dev *eth_dev)
     if (ret != 0)
         goto err_zxdh_init;
 
+    ret = zxdh_tables_init(eth_dev);
+    if (ret != 0)
+        goto err_zxdh_init;
+
     return ret;
 
 err_zxdh_init:
diff --git a/drivers/net/zxdh/zxdh_msg.c b/drivers/net/zxdh/zxdh_msg.c
index dd7a518a51..aa2e10fd45 100644
--- a/drivers/net/zxdh/zxdh_msg.c
+++ b/drivers/net/zxdh/zxdh_msg.c
@@ -14,6 +14,7 @@
 #include "zxdh_ethdev.h"
 #include "zxdh_logs.h"
 #include "zxdh_msg.h"
+#include "zxdh_pci.h"
 
 #define ZXDH_REPS_INFO_FLAG_USABLE  0x00
 #define ZXDH_BAR_SEQID_NUM_MAX      256
@@ -100,6 +101,7 @@
 #define ZXDH_BAR_CHAN_MSG_EMEC     1
 #define ZXDH_BAR_CHAN_MSG_NO_ACK   0
 #define ZXDH_BAR_CHAN_MSG_ACK      1
+#define ZXDH_MSG_REPS_OK           0xff
 
 uint8_t subchan_id_tbl[ZXDH_BAR_MSG_SRC_NUM][ZXDH_BAR_MSG_DST_NUM] = {
     {ZXDH_BAR_CHAN_INDEX_SEND, ZXDH_BAR_CHAN_INDEX_SEND, ZXDH_BAR_CHAN_INDEX_SEND},
@@ -1079,3 +1081,66 @@ int zxdh_get_bar_offset(struct zxdh_bar_offset_params *paras,
     res->bar_length = recv_msg.offset_reps.length;
     return ZXDH_BAR_MSG_OK;
 }
+
+int zxdh_vf_send_msg_to_pf(struct rte_eth_dev *dev,  void *msg_req,
+            uint16_t msg_req_len, void *reply, uint16_t reply_len)
+{
+    struct zxdh_hw *hw  = dev->data->dev_private;
+    struct zxdh_msg_recviver_mem result = {0};
+    struct zxdh_msg_reply_info reply_info = {0};
+    int ret = 0;
+
+    if (reply) {
+        RTE_ASSERT(reply_len < sizeof(zxdh_msg_reply_info));
+        result.recv_buffer  = reply;
+        result.buffer_len = reply_len;
+    } else {
+        result.recv_buffer = &reply_info;
+        result.buffer_len = sizeof(reply_info);
+    }
+
+    struct zxdh_msg_reply_head *reply_head =
+                &(((struct zxdh_msg_reply_info *)result.recv_buffer)->reply_head);
+    struct zxdh_msg_reply_body *reply_body =
+                &(((struct zxdh_msg_reply_info *)result.recv_buffer)->reply_body);
+
+    struct zxdh_pci_bar_msg in = {
+        .virt_addr = (uint64_t)(hw->bar_addr[ZXDH_BAR0_INDEX] +
+                ZXDH_MSG_CHAN_PFVFSHARE_OFFSET),
+        .payload_addr = msg_req,
+        .payload_len = msg_req_len,
+        .src = ZXDH_MSG_CHAN_END_VF,
+        .dst = ZXDH_MSG_CHAN_END_PF,
+        .module_id = ZXDH_MODULE_BAR_MSG_TO_PF,
+        .src_pcieid = hw->pcie_id,
+        .dst_pcieid = ZXDH_PF_PCIE_ID(hw->pcie_id),
+    };
+
+    ret = zxdh_bar_chan_sync_msg_send(&in, &result);
+    if (ret != ZXDH_BAR_MSG_OK) {
+        PMD_MSG_LOG(ERR,
+            "vf[%d] send bar msg to pf failed.ret %d", hw->vport.vfid, ret);
+        return -1;
+    }
+    if (reply_head->flag != ZXDH_MSG_REPS_OK) {
+        PMD_MSG_LOG(ERR, "vf[%d] get pf reply failed: reply_head flag : 0x%x(0xff is OK).replylen %d",
+                hw->vport.vfid, reply_head->flag, reply_head->reps_len);
+        return -1;
+    }
+    if (reply_body->flag != ZXDH_REPS_SUCC) {
+        PMD_MSG_LOG(ERR, "vf[%d] msg processing failed", hw->vfid);
+        return -1;
+    }
+    return 0;
+}
+
+void zxdh_msg_head_build(struct zxdh_hw *hw, enum zxdh_msg_type type,
+        struct zxdh_msg_info *msg_info)
+{
+    struct zxdh_msg_head *msghead = &msg_info->msg_head;
+
+    msghead->msg_type = type;
+    msghead->vport    = hw->vport.vport;
+    msghead->vf_id    = hw->vport.vfid;
+    msghead->pcieid   = hw->pcie_id;
+}
diff --git a/drivers/net/zxdh/zxdh_msg.h b/drivers/net/zxdh/zxdh_msg.h
index fbc79e8f9d..b7b17b8696 100644
--- a/drivers/net/zxdh/zxdh_msg.h
+++ b/drivers/net/zxdh/zxdh_msg.h
@@ -33,6 +33,19 @@
 #define ZXDH_BAR_MSG_PAYLOAD_MAX_LEN     \
     (ZXDH_BAR_MSG_ADDR_CHAN_INTERVAL - sizeof(struct zxdh_bar_msg_header))
 
+#define ZXDH_MSG_ADDR_CHAN_INTERVAL       (2 * 1024) /* channel size */
+#define ZXDH_MSG_PAYLOAD_MAX_LEN \
+        (ZXDH_MSG_ADDR_CHAN_INTERVAL - sizeof(struct zxdh_bar_msg_header))
+
+#define ZXDH_MSG_REPLYBODY_HEAD    sizeof(enum zxdh_reps_flag)
+#define ZXDH_MSG_HEADER_SIZE       4
+#define ZXDH_MSG_REPLY_BODY_MAX_LEN  \
+        (ZXDH_MSG_PAYLOAD_MAX_LEN - sizeof(struct zxdh_msg_reply_head))
+
+#define ZXDH_MSG_HEAD_LEN 8
+#define ZXDH_MSG_REQ_BODY_MAX_LEN  \
+        (ZXDH_MSG_PAYLOAD_MAX_LEN - ZXDH_MSG_HEAD_LEN)
+
 enum ZXDH_DRIVER_TYPE {
     ZXDH_MSG_CHAN_END_MPF = 0,
     ZXDH_MSG_CHAN_END_PF,
@@ -151,6 +164,13 @@ enum pciebar_layout_type {
     ZXDH_URI_MAX,
 };
 
+enum zxdh_msg_type {
+    ZXDH_NULL = 0,
+    ZXDH_VF_PORT_INIT = 1,
+
+    ZXDH_MSG_TYPE_END,
+};
+
 struct zxdh_msix_para {
     uint16_t pcie_id;
     uint16_t vector_risc;
@@ -240,6 +260,54 @@ struct zxdh_offset_get_msg {
     uint16_t type;
 };
 
+struct zxdh_msg_reply_head {
+    uint8_t flag;
+    uint16_t reps_len;
+    uint8_t resvd;
+} __rte_packed;
+
+enum zxdh_reps_flag {
+    ZXDH_REPS_FAIL,
+    ZXDH_REPS_SUCC = 0xaa,
+} __rte_packed;
+
+struct zxdh_msg_reply_body {
+    enum zxdh_reps_flag flag;
+    union {
+        uint8_t reply_data[ZXDH_MSG_REPLY_BODY_MAX_LEN - sizeof(enum zxdh_reps_flag)];
+    } __rte_packed;
+} __rte_packed;
+
+struct zxdh_msg_reply_info {
+    struct zxdh_msg_reply_head reply_head;
+    struct zxdh_msg_reply_body reply_body;
+} __rte_packed;
+
+struct zxdh_vf_init_msg {
+    uint8_t link_up;
+    uint8_t rsv;
+    uint16_t base_qid;
+    uint8_t rss_enable;
+} __rte_packed;
+
+struct zxdh_msg_head {
+    enum zxdh_msg_type msg_type;
+    uint16_t  vport;
+    uint16_t  vf_id;
+    uint16_t pcieid;
+} __rte_packed;
+
+struct zxdh_msg_info {
+    union {
+        uint8_t head_len[ZXDH_MSG_HEAD_LEN];
+        struct zxdh_msg_head msg_head;
+    };
+    union {
+        uint8_t datainfo[ZXDH_MSG_REQ_BODY_MAX_LEN];
+        struct zxdh_vf_init_msg vf_init_msg;
+    } __rte_packed data;
+} __rte_packed;
+
 typedef int (*zxdh_bar_chan_msg_recv_callback)(void *pay_load, uint16_t len,
         void *reps_buffer, uint16_t *reps_len, void *dev);
 
@@ -253,5 +321,9 @@ int zxdh_bar_chan_sync_msg_send(struct zxdh_pci_bar_msg *in,
         struct zxdh_msg_recviver_mem *result);
 
 int zxdh_bar_irq_recv(uint8_t src, uint8_t dst, uint64_t virt_addr, void *dev);
+void zxdh_msg_head_build(struct zxdh_hw *hw, enum zxdh_msg_type type,
+        struct zxdh_msg_info *msg_info);
+int zxdh_vf_send_msg_to_pf(struct rte_eth_dev *dev,  void *msg_req,
+            uint16_t msg_req_len, void *reply, uint16_t reply_len);
 
 #endif /* ZXDH_MSG_H */
diff --git a/drivers/net/zxdh/zxdh_np.c b/drivers/net/zxdh/zxdh_np.c
index 28728b0c68..db536d96e3 100644
--- a/drivers/net/zxdh/zxdh_np.c
+++ b/drivers/net/zxdh/zxdh_np.c
@@ -9,6 +9,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_malloc.h>
+#include <rte_memcpy.h>
 
 #include "zxdh_np.h"
 #include "zxdh_logs.h"
@@ -16,11 +17,14 @@
 static uint64_t g_np_bar_offset;
 static ZXDH_DEV_MGR_T g_dev_mgr;
 static ZXDH_SDT_MGR_T g_sdt_mgr;
+static uint32_t g_dpp_dtb_int_enable;
+static uint32_t g_table_type[ZXDH_DEV_CHANNEL_MAX][ZXDH_DEV_SDT_ID_MAX];
 ZXDH_PPU_CLS_BITMAP_T g_ppu_cls_bit_map[ZXDH_DEV_CHANNEL_MAX];
 ZXDH_DTB_MGR_T *p_dpp_dtb_mgr[ZXDH_DEV_CHANNEL_MAX];
 ZXDH_RISCV_DTB_MGR *p_riscv_dtb_queue_mgr[ZXDH_DEV_CHANNEL_MAX];
 ZXDH_TLB_MGR_T *g_p_dpp_tlb_mgr[ZXDH_DEV_CHANNEL_MAX];
 ZXDH_REG_T g_dpp_reg_info[4];
+ZXDH_DTB_TABLE_T g_dpp_dtb_table_info[4];
 
 #define ZXDH_SDT_MGR_PTR_GET()    (&g_sdt_mgr)
 #define ZXDH_SDT_SOFT_TBL_GET(id) (g_sdt_mgr.sdt_tbl_array[id])
@@ -76,6 +80,92 @@ do {\
     } \
 } while (0)
 
+#define ZXDH_COMM_CHECK_POINT(point)\
+do {\
+    if ((point) == NULL) {\
+        PMD_DRV_LOG(ERR, "ZXIC %s:%d[Error:POINT NULL] ! FUNCTION : %s!",\
+        __FILE__, __LINE__, __func__);\
+        RTE_ASSERT(0);\
+    } \
+} while (0)
+
+
+#define ZXDH_COMM_CHECK_POINT_MEMORY_FREE(point, ptr)\
+do {\
+    if ((point) == NULL) {\
+        PMD_DRV_LOG(ERR, "ZXIC %s:%d[Error:POINT NULL] !"\
+        "FUNCTION : %s!", __FILE__, __LINE__, __func__);\
+        rte_free(ptr);\
+        RTE_ASSERT(0);\
+    } \
+} while (0)
+
+#define ZXDH_COMM_CHECK_RC_MEMORY_FREE_NO_ASSERT(rc, becall, ptr)\
+do {\
+    if ((rc) != 0) {\
+        PMD_DRV_LOG(ERR, "ZXICP  %s:%d, %s Call"\
+        " %s Fail!", __FILE__, __LINE__, __func__, becall);\
+        rte_free(ptr);\
+    } \
+} while (0)
+
+#define ZXDH_COMM_CONVERT16(w_data) \
+            (((w_data) & 0xff) << 8)
+
+#define ZXDH_DTB_TAB_UP_VIR_ADDR_GET(DEV_ID, QUEUE_ID, INDEX)     \
+        ((INDEX) * p_dpp_dtb_mgr[(DEV_ID)]->queue_info[(QUEUE_ID)].tab_up.item_size)
+
+#define ZXDH_DTB_TAB_DOWN_VIR_ADDR_GET(DEV_ID, QUEUE_ID, INDEX)   \
+        ((INDEX) * p_dpp_dtb_mgr[(DEV_ID)]->queue_info[(QUEUE_ID)].tab_down.item_size)
+
+#define ZXDH_DTB_TAB_DOWN_WR_INDEX_GET(DEV_ID, QUEUE_ID)       \
+        (p_dpp_dtb_mgr[(DEV_ID)]->queue_info[(QUEUE_ID)].tab_down.wr_index)
+
+#define ZXDH_DTB_QUEUE_INIT_FLAG_GET(DEV_ID, QUEUE_ID)       \
+        (p_dpp_dtb_mgr[(DEV_ID)]->queue_info[(QUEUE_ID)].init_flag)
+
+static uint32_t
+zxdh_np_comm_is_big_endian(void)
+{
+    ZXDH_ENDIAN_U c_data;
+
+    c_data.a = 1;
+
+    if (c_data.b == 1)
+        return 0;
+    else
+        return 1;
+}
+
+static void
+zxdh_np_comm_swap(uint8_t *p_uc_data, uint32_t dw_byte_len)
+{
+    uint16_t *p_w_tmp = NULL;
+    uint32_t *p_dw_tmp = NULL;
+    uint32_t dw_byte_num;
+    uint8_t uc_byte_mode;
+    uint32_t uc_is_big_flag;
+    uint32_t i;
+
+    p_dw_tmp = (uint32_t *)(p_uc_data);
+    uc_is_big_flag = zxdh_np_comm_is_big_endian();
+    if (uc_is_big_flag)
+        return;
+
+    dw_byte_num  = dw_byte_len >> 2;
+    uc_byte_mode = dw_byte_len % 4 & 0xff;
+
+    for (i = 0; i < dw_byte_num; i++) {
+        (*p_dw_tmp) = ZXDH_COMM_CONVERT16(*p_dw_tmp);
+        p_dw_tmp++;
+    }
+
+    if (uc_byte_mode > 1) {
+        p_w_tmp = (uint16_t *)(p_dw_tmp);
+        (*p_w_tmp) = ZXDH_COMM_CONVERT16(*p_w_tmp);
+    }
+}
+
 static uint32_t
 zxdh_np_dev_init(void)
 {
@@ -503,7 +593,7 @@ zxdh_np_dtb_queue_vm_info_get(uint32_t dev_id,
     p_vm_info->func_num = vm_info.cfg_func_num;
     p_vm_info->vfunc_active = vm_info.cfg_vfunc_active;
 
-    return 0;
+    return rc;
 }
 
 static uint32_t
@@ -808,3 +898,559 @@ zxdh_np_online_uninit(uint32_t dev_id,
 
     return 0;
 }
+
+static uint32_t
+zxdh_np_sdt_tbl_type_get(uint32_t dev_id, uint32_t sdt_no)
+{
+    return g_table_type[dev_id][sdt_no];
+}
+
+
+static ZXDH_DTB_TABLE_T *
+zxdh_np_table_info_get(uint32_t table_type)
+{
+    return &g_dpp_dtb_table_info[table_type];
+}
+
+static uint32_t
+zxdh_np_dtb_write_table_cmd(uint32_t dev_id,
+            ZXDH_DTB_TABLE_INFO_E table_type,
+            void *p_cmd_data,
+            void *p_cmd_buff)
+{
+    uint32_t         field_cnt;
+    ZXDH_DTB_TABLE_T     *p_table_info = NULL;
+    ZXDH_DTB_FIELD_T     *p_field_info = NULL;
+    uint32_t         temp_data;
+    uint32_t         rc;
+
+    ZXDH_COMM_CHECK_POINT(p_cmd_data);
+    ZXDH_COMM_CHECK_POINT(p_cmd_buff);
+    p_table_info = zxdh_np_table_info_get(table_type);
+    p_field_info = p_table_info->p_fields;
+    ZXDH_COMM_CHECK_DEV_POINT(dev_id, p_table_info);
+
+    for (field_cnt = 0; field_cnt < p_table_info->field_num; field_cnt++) {
+        temp_data = *((uint32_t *)p_cmd_data + field_cnt) & ZXDH_COMM_GET_BIT_MASK(uint32_t,
+            p_field_info[field_cnt].len);
+
+        rc = zxdh_np_comm_write_bits_ex((uint8_t *)p_cmd_buff,
+                    ZXDH_DTB_TABLE_CMD_SIZE_BIT,
+                    temp_data,
+                    p_field_info[field_cnt].lsb_pos,
+                    p_field_info[field_cnt].len);
+
+        ZXDH_COMM_CHECK_RC_NO_ASSERT(rc, "zxic_comm_write_bits");
+    }
+
+    return rc;
+}
+
+static uint32_t
+zxdh_np_dtb_smmu0_write_entry_data(uint32_t dev_id,
+        uint32_t mode,
+        uint32_t addr,
+        uint32_t *p_data,
+        ZXDH_DTB_ENTRY_T *p_entry)
+{
+    ZXDH_DTB_ERAM_TABLE_FORM_T dtb_eram_form_info = {0};
+    uint32_t  rc = 0;
+
+    dtb_eram_form_info.valid = ZXDH_DTB_TABLE_VALID;
+    dtb_eram_form_info.type_mode = ZXDH_DTB_TABLE_MODE_ERAM;
+    dtb_eram_form_info.data_mode = mode;
+    dtb_eram_form_info.cpu_wr = 1;
+    dtb_eram_form_info.addr = addr;
+    dtb_eram_form_info.cpu_rd = 0;
+    dtb_eram_form_info.cpu_rd_mode = 0;
+
+    if (ZXDH_ERAM128_OPR_128b == mode) {
+        p_entry->data_in_cmd_flag = 0;
+        p_entry->data_size = 128 / 8;
+
+        rc = zxdh_np_dtb_write_table_cmd(dev_id, ZXDH_DTB_TABLE_ERAM_128,
+            &dtb_eram_form_info, p_entry->cmd);
+        ZXDH_COMM_CHECK_RC_NO_ASSERT(rc, "dpp_dtb_write_table_cmd");
+
+        memcpy(p_entry->data, p_data, 128 / 8);
+    } else if (ZXDH_ERAM128_OPR_64b == mode) {
+        p_entry->data_in_cmd_flag = 1;
+        p_entry->data_size  = 64 / 8;
+        dtb_eram_form_info.data_l = *(p_data + 1);
+        dtb_eram_form_info.data_h = *(p_data);
+
+        rc = zxdh_np_dtb_write_table_cmd(dev_id, ZXDH_DTB_TABLE_ERAM_64,
+            &dtb_eram_form_info, p_entry->cmd);
+        ZXDH_COMM_CHECK_RC_NO_ASSERT(rc, "dpp_dtb_write_table_cmd");
+
+    } else if (ZXDH_ERAM128_OPR_1b == mode) {
+        p_entry->data_in_cmd_flag = 1;
+        p_entry->data_size  = 1;
+        dtb_eram_form_info.data_h = *(p_data);
+
+        rc = zxdh_np_dtb_write_table_cmd(dev_id, ZXDH_DTB_TABLE_ERAM_1,
+            &dtb_eram_form_info, p_entry->cmd);
+        ZXDH_COMM_CHECK_RC_NO_ASSERT(rc, "dpp_dtb_write_table_cmd");
+    }
+
+    return rc;
+}
+
+static uint32_t
+zxdh_np_dtb_se_smmu0_ind_write(uint32_t dev_id,
+        uint32_t base_addr,
+        uint32_t index,
+        uint32_t wrt_mode,
+        uint32_t *p_data,
+        ZXDH_DTB_ENTRY_T *p_entry)
+{
+    uint32_t temp_idx;
+    uint32_t dtb_ind_addr;
+    uint32_t rc;
+
+    switch (wrt_mode) {
+    case ZXDH_ERAM128_OPR_128b:
+    {
+        if ((0xFFFFFFFF - (base_addr)) < (index)) {
+            PMD_DRV_LOG(ERR,  "ICM %s:%d[Error:VALUE[val0=0x%x]"
+                "INVALID] [val1=0x%x] ! FUNCTION :%s !", __FILE__, __LINE__,
+                base_addr, index, __func__);
+
+            return ZXDH_PAR_CHK_INVALID_INDEX;
+        }
+        if (base_addr + index > ZXDH_SE_SMMU0_ERAM_ADDR_NUM_TOTAL - 1) {
+            PMD_DRV_LOG(ERR, "dpp_se_smmu0_ind_write : index out of range !");
+            return 1;
+        }
+        temp_idx = index << 7;
+        break;
+    }
+
+    case ZXDH_ERAM128_OPR_64b:
+    {
+        if ((base_addr + (index >> 1)) > ZXDH_SE_SMMU0_ERAM_ADDR_NUM_TOTAL - 1) {
+            PMD_DRV_LOG(ERR, "dpp_se_smmu0_ind_write : index out of range !");
+            return 1;
+        }
+        temp_idx = index << 6;
+        break;
+    }
+
+    case ZXDH_ERAM128_OPR_1b:
+    {
+        if ((base_addr + (index >> 7)) > ZXDH_SE_SMMU0_ERAM_ADDR_NUM_TOTAL - 1) {
+            PMD_DRV_LOG(ERR, "dpp_se_smmu0_ind_write : index out of range !");
+            return 1;
+        }
+
+        temp_idx = index;
+    }
+    }
+
+    dtb_ind_addr = ((base_addr << 7) & ZXDH_ERAM128_BADDR_MASK) + temp_idx;
+
+    PMD_DRV_LOG(INFO, " dtb eram item 1bit addr: 0x%x", dtb_ind_addr);
+
+    rc = zxdh_np_dtb_smmu0_write_entry_data(dev_id,
+                          wrt_mode,
+                          dtb_ind_addr,
+                          p_data,
+                          p_entry);
+    ZXDH_COMM_CHECK_RC_NO_ASSERT(rc, "dpp_dtb_smmu0_write_entry_data");
+
+    return rc;
+}
+
+static uint32_t
+zxdh_np_eram_dtb_len_get(uint32_t mode)
+{
+    uint32_t dtb_len = 0;
+
+    switch (mode) {
+    case ZXDH_ERAM128_OPR_128b:
+    {
+        dtb_len += 2;
+        break;
+    }
+    case ZXDH_ERAM128_OPR_64b:
+    case ZXDH_ERAM128_OPR_1b:
+    {
+        dtb_len += 1;
+        break;
+    }
+    default:
+        break;
+    }
+
+    return dtb_len;
+}
+
+static uint32_t
+zxdh_np_dtb_eram_one_entry(uint32_t dev_id,
+        uint32_t sdt_no,
+        uint32_t del_en,
+        void *pdata,
+        uint32_t *p_dtb_len,
+        ZXDH_DTB_ENTRY_T *p_dtb_one_entry)
+{
+    uint32_t buff[ZXDH_SMMU0_READ_REG_MAX_NUM]      = {0};
+    ZXDH_SDTTBL_ERAM_T sdt_eram           = {0};
+    ZXDH_DTB_ERAM_ENTRY_INFO_T *peramdata = NULL;
+    uint32_t base_addr;
+    uint32_t index;
+    uint32_t opr_mode;
+    uint32_t rc;
+
+    ZXDH_COMM_CHECK_POINT(pdata);
+    ZXDH_COMM_CHECK_POINT(p_dtb_one_entry);
+    ZXDH_COMM_CHECK_POINT(p_dtb_len);
+
+    peramdata = (ZXDH_DTB_ERAM_ENTRY_INFO_T *)pdata;
+    index = peramdata->index;
+    base_addr = sdt_eram.eram_base_addr;
+    opr_mode = sdt_eram.eram_mode;
+
+    switch (opr_mode) {
+    case ZXDH_ERAM128_TBL_128b:
+    {
+        opr_mode = ZXDH_ERAM128_OPR_128b;
+        break;
+    }
+    case ZXDH_ERAM128_TBL_64b:
+    {
+        opr_mode = ZXDH_ERAM128_OPR_64b;
+        break;
+    }
+
+    case ZXDH_ERAM128_TBL_1b:
+    {
+        opr_mode = ZXDH_ERAM128_OPR_1b;
+        break;
+    }
+    }
+
+    if (del_en) {
+        memset((uint8_t *)buff, 0, sizeof(buff));
+        rc = zxdh_np_dtb_se_smmu0_ind_write(dev_id,
+                        base_addr,
+                        index,
+                        opr_mode,
+                        buff,
+                        p_dtb_one_entry);
+        ZXDH_COMM_CHECK_DEV_RC(sdt_no, rc, "zxdh_dtb_se_smmu0_ind_write");
+    } else {
+        rc = zxdh_np_dtb_se_smmu0_ind_write(dev_id,
+                                   base_addr,
+                                   index,
+                                   opr_mode,
+                                   peramdata->p_data,
+                                   p_dtb_one_entry);
+        ZXDH_COMM_CHECK_DEV_RC(dev_id, rc, "zxdh_dtb_se_smmu0_ind_write");
+    }
+    *p_dtb_len = zxdh_np_eram_dtb_len_get(opr_mode);
+
+    return rc;
+}
+
+static uint32_t
+zxdh_np_dtb_data_write(uint8_t *p_data_buff,
+            uint32_t addr_offset,
+            ZXDH_DTB_ENTRY_T *entry)
+{
+    ZXDH_COMM_CHECK_POINT(p_data_buff);
+    ZXDH_COMM_CHECK_POINT(entry);
+
+    uint8_t *p_cmd = p_data_buff + addr_offset;
+    uint32_t cmd_size = ZXDH_DTB_TABLE_CMD_SIZE_BIT / 8;
+
+    uint8_t *p_data = p_cmd + cmd_size;
+    uint32_t data_size = entry->data_size;
+
+    uint8_t *cmd = (uint8_t *)entry->cmd;
+    uint8_t *data = (uint8_t *)entry->data;
+
+    rte_memcpy(p_cmd, cmd, cmd_size);
+
+    if (!entry->data_in_cmd_flag) {
+        zxdh_np_comm_swap(data, data_size);
+        rte_memcpy(p_data, data, data_size);
+    }
+
+    return 0;
+}
+
+static uint32_t
+zxdh_np_dtb_queue_enable_get(uint32_t dev_id,
+        uint32_t queue_id,
+        uint32_t *enable)
+{
+    uint32_t rc = 0;
+    ZXDH_DTB_QUEUE_VM_INFO_T vm_info = {0};
+
+    rc = zxdh_np_dtb_queue_vm_info_get(dev_id, queue_id, &vm_info);
+    ZXDH_COMM_CHECK_RC_NO_ASSERT(rc, "zxdh_dtb_queue_vm_info_get");
+
+    *enable = vm_info.queue_en;
+    return rc;
+}
+
+static uint32_t
+zxdh_np_dtb_item_buff_wr(uint32_t dev_id,
+        uint32_t queue_id,
+        uint32_t dir_flag,
+        uint32_t index,
+        uint32_t pos,
+        uint32_t len,
+        uint32_t *p_data)
+{
+    uint64_t addr;
+
+    if (dir_flag == 1)
+        addr = ZXDH_DTB_TAB_UP_VIR_ADDR_GET(dev_id, queue_id, index) +
+            ZXDH_DTB_ITEM_ACK_SIZE + pos * 4;
+    else
+        addr = ZXDH_DTB_TAB_DOWN_VIR_ADDR_GET(dev_id, queue_id, index) +
+            ZXDH_DTB_ITEM_ACK_SIZE + pos * 4;
+
+    memcpy((uint8_t *)(addr), p_data, len * 4);
+
+    return 0;
+}
+
+static uint32_t
+zxdh_np_dtb_item_ack_rd(uint32_t dev_id,
+        uint32_t queue_id,
+        uint32_t dir_flag,
+        uint32_t index,
+        uint32_t pos,
+        uint32_t *p_data)
+{
+    uint64_t addr;
+    uint32_t val;
+
+    if (dir_flag == 1)
+        addr = ZXDH_DTB_TAB_UP_VIR_ADDR_GET(dev_id, queue_id, index) + pos * 4;
+    else
+        addr = ZXDH_DTB_TAB_DOWN_VIR_ADDR_GET(dev_id, queue_id, index) + pos * 4;
+
+    val = *((volatile uint32_t *)(addr));
+
+    *p_data = val;
+
+    return 0;
+}
+
+static uint32_t
+zxdh_np_dtb_item_ack_wr(uint32_t dev_id,
+        uint32_t queue_id,
+        uint32_t dir_flag,
+        uint32_t index,
+        uint32_t pos,
+        uint32_t data)
+{
+    uint64_t addr;
+
+    if (dir_flag == 1)
+        addr = ZXDH_DTB_TAB_UP_VIR_ADDR_GET(dev_id, queue_id, index) + pos * 4;
+    else
+        addr = ZXDH_DTB_TAB_DOWN_VIR_ADDR_GET(dev_id, queue_id, index) + pos * 4;
+
+    *((volatile uint32_t *)(addr)) = data;
+
+    return 0;
+}
+
+static uint32_t
+zxdh_np_dtb_queue_item_info_set(uint32_t dev_id,
+        uint32_t queue_id,
+        ZXDH_DTB_QUEUE_ITEM_INFO_T *p_item_info)
+{
+    ZXDH_DTB_QUEUE_LEN_T dtb_len = {0};
+    uint32_t rc;
+
+    dtb_len.cfg_dtb_cmd_type = p_item_info->cmd_type;
+    dtb_len.cfg_dtb_cmd_int_en = p_item_info->int_en;
+    dtb_len.cfg_queue_dtb_len = p_item_info->data_len;
+
+    rc = zxdh_np_reg_write(dev_id, ZXDH_DTB_CFG_QUEUE_DTB_LEN,
+                        0, queue_id, (void *)&dtb_len);
+    ZXDH_COMM_CHECK_DEV_RC(dev_id, rc, "dpp_reg_write");
+    return rc;
+}
+
+static uint32_t
+zxdh_np_dtb_tab_down_info_set(uint32_t dev_id,
+        uint32_t queue_id,
+        uint32_t int_flag,
+        uint32_t data_len,
+        uint32_t *p_data,
+        uint32_t *p_item_index)
+{
+    ZXDH_DTB_QUEUE_ITEM_INFO_T item_info = {0};
+    uint32_t unused_item_num = 0;
+    uint32_t queue_en = 0;
+    uint32_t ack_vale = 0;
+    uint64_t phy_addr;
+    uint32_t item_index;
+    uint32_t i;
+    uint32_t rc;
+
+    if (ZXDH_DTB_QUEUE_INIT_FLAG_GET(dev_id, queue_id) == 0) {
+        PMD_DRV_LOG(ERR, "dtb queue %d is not init.", queue_id);
+        return ZXDH_RC_DTB_QUEUE_IS_NOT_INIT;
+    }
+
+    if (data_len % 4 != 0)
+        return ZXDH_RC_DTB_PARA_INVALID;
+
+    rc = zxdh_np_dtb_queue_enable_get(dev_id, queue_id, &queue_en);
+    if (!queue_en) {
+        PMD_DRV_LOG(ERR, "the queue %d is not enable!,rc=%d", queue_id, rc);
+        return ZXDH_RC_DTB_QUEUE_NOT_ENABLE;
+    }
+
+    rc = zxdh_np_dtb_queue_unused_item_num_get(dev_id, queue_id, &unused_item_num);
+    if (unused_item_num == 0)
+        return ZXDH_RC_DTB_QUEUE_ITEM_HW_EMPTY;
+
+    for (i = 0; i < ZXDH_DTB_QUEUE_ITEM_NUM_MAX; i++) {
+        item_index = ZXDH_DTB_TAB_DOWN_WR_INDEX_GET(dev_id, queue_id) %
+            ZXDH_DTB_QUEUE_ITEM_NUM_MAX;
+
+        rc = zxdh_np_dtb_item_ack_rd(dev_id, queue_id, 0,
+            item_index, 0, &ack_vale);
+
+        ZXDH_DTB_TAB_DOWN_WR_INDEX_GET(dev_id, queue_id)++;
+
+        if ((ack_vale >> 8) == ZXDH_DTB_TAB_ACK_UNUSED_MASK)
+            break;
+    }
+
+    if (i == ZXDH_DTB_QUEUE_ITEM_NUM_MAX)
+        return ZXDH_RC_DTB_QUEUE_ITEM_SW_EMPTY;
+
+    rc = zxdh_np_dtb_item_buff_wr(dev_id, queue_id, 0,
+        item_index, 0, data_len, p_data);
+
+    rc = zxdh_np_dtb_item_ack_wr(dev_id, queue_id, 0,
+        item_index, 0, ZXDH_DTB_TAB_ACK_IS_USING_MASK);
+
+    item_info.cmd_vld = 1;
+    item_info.cmd_type = 0;
+    item_info.int_en = int_flag;
+    item_info.data_len = data_len / 4;
+    phy_addr = p_dpp_dtb_mgr[dev_id]->queue_info[queue_id].tab_down.start_phy_addr +
+        item_index * p_dpp_dtb_mgr[dev_id]->queue_info[queue_id].tab_down.item_size;
+    item_info.data_hddr = ((phy_addr >> 4) >> 32) & 0xffffffff;
+    item_info.data_laddr = (phy_addr >> 4) & 0xffffffff;
+
+    rc = zxdh_np_dtb_queue_item_info_set(dev_id, queue_id, &item_info);
+    *p_item_index = item_index;
+
+    return rc;
+}
+
+static uint32_t
+zxdh_np_dtb_write_down_table_data(uint32_t dev_id,
+        uint32_t queue_id,
+        uint32_t down_table_len,
+        uint8_t *p_down_table_buff,
+        uint32_t *p_element_id)
+{
+    uint32_t  rc = 0;
+    uint32_t dtb_interrupt_status = 0;
+
+    dtb_interrupt_status = g_dpp_dtb_int_enable;
+
+    rc = zxdh_np_dtb_tab_down_info_set(dev_id,
+                    queue_id,
+                    dtb_interrupt_status,
+                    down_table_len / 4,
+                    (uint32_t *)p_down_table_buff,
+                    p_element_id);
+    return rc;
+}
+
+int
+zxdh_np_dtb_table_entry_write(uint32_t dev_id,
+            uint32_t queue_id,
+            uint32_t entrynum,
+            ZXDH_DTB_USER_ENTRY_T *down_entries)
+{
+    ZXDH_DTB_USER_ENTRY_T *pentry = NULL;
+    ZXDH_DTB_ENTRY_T   dtb_one_entry = {0};
+    uint8_t entry_cmd[ZXDH_DTB_TABLE_CMD_SIZE_BIT] = {0};
+    uint8_t entry_data[ZXDH_ETCAM_WIDTH_MAX] = {0};
+    uint8_t *p_data_buff = NULL;
+    uint8_t *p_data_buff_ex = NULL;
+    uint32_t element_id = 0xff;
+    uint32_t one_dtb_len = 0;
+    uint32_t dtb_len = 0;
+    uint32_t entry_index;
+    uint32_t sdt_no;
+    uint32_t tbl_type;
+    uint32_t addr_offset;
+    uint32_t max_size;
+    uint32_t rc;
+
+    p_data_buff = rte_zmalloc(NULL, ZXDH_DTB_TABLE_DATA_BUFF_SIZE, 0);
+    ZXDH_COMM_CHECK_POINT(p_data_buff);
+
+    p_data_buff_ex = rte_zmalloc(NULL, ZXDH_DTB_TABLE_DATA_BUFF_SIZE, 0);
+    ZXDH_COMM_CHECK_POINT_MEMORY_FREE(p_data_buff_ex, p_data_buff);
+
+    dtb_one_entry.cmd = entry_cmd;
+    dtb_one_entry.data = entry_data;
+
+    max_size = (ZXDH_DTB_TABLE_DATA_BUFF_SIZE / 16) - 1;
+
+    for (entry_index = 0; entry_index < entrynum; entry_index++) {
+        pentry = down_entries + entry_index;
+        sdt_no = pentry->sdt_no;
+        tbl_type = zxdh_np_sdt_tbl_type_get(dev_id, sdt_no);
+        switch (tbl_type) {
+        case ZXDH_SDT_TBLT_ERAM:
+        {
+            rc = zxdh_np_dtb_eram_one_entry(dev_id, sdt_no, ZXDH_DTB_ITEM_ADD_OR_UPDATE,
+                pentry->p_entry_data, &one_dtb_len, &dtb_one_entry);
+            break;
+        }
+        default:
+        {
+            PMD_DRV_LOG(ERR, "SDT table_type[ %d ] is invalid!", tbl_type);
+            rte_free(p_data_buff);
+            rte_free(p_data_buff_ex);
+            return 1;
+        }
+        }
+
+        addr_offset = dtb_len * ZXDH_DTB_LEN_POS_SETP;
+        dtb_len += one_dtb_len;
+        if (dtb_len > max_size) {
+            rte_free(p_data_buff);
+            rte_free(p_data_buff_ex);
+            PMD_DRV_LOG(ERR, " %s error dtb_len>%u!", __func__,
+                max_size);
+            return ZXDH_RC_DTB_DOWN_LEN_INVALID;
+        }
+        rc = zxdh_np_dtb_data_write(p_data_buff, addr_offset, &dtb_one_entry);
+        memset(entry_cmd, 0x0, sizeof(entry_cmd));
+        memset(entry_data, 0x0, sizeof(entry_data));
+    }
+
+    if (dtb_len == 0) {
+        rte_free(p_data_buff);
+        rte_free(p_data_buff_ex);
+        return ZXDH_RC_DTB_DOWN_LEN_INVALID;
+    }
+
+    rc = zxdh_np_dtb_write_down_table_data(dev_id,
+                    queue_id,
+                    dtb_len * 16,
+                    p_data_buff,
+                    &element_id);
+    rte_free(p_data_buff);
+    rte_free(p_data_buff_ex);
+
+    return rc;
+}
diff --git a/drivers/net/zxdh/zxdh_np.h b/drivers/net/zxdh/zxdh_np.h
index dc0e867827..40961c02a2 100644
--- a/drivers/net/zxdh/zxdh_np.h
+++ b/drivers/net/zxdh/zxdh_np.h
@@ -7,6 +7,8 @@
 
 #include <stdint.h>
 
+#define ZXDH_DISABLE                          (0)
+#define ZXDH_ENABLE                           (1)
 #define ZXDH_PORT_NAME_MAX                    (32)
 #define ZXDH_DEV_CHANNEL_MAX                  (2)
 #define ZXDH_DEV_SDT_ID_MAX                   (256U)
@@ -52,6 +54,94 @@
 #define ZXDH_ACL_TBL_ID_NUM             (8U)
 #define ZXDH_ACL_BLOCK_NUM              (8U)
 
+#define ZXDH_SMMU0_READ_REG_MAX_NUM              (4)
+
+#define ZXDH_DTB_ITEM_ACK_SIZE                   (16)
+#define ZXDH_DTB_ITEM_BUFF_SIZE                  (16 * 1024)
+#define ZXDH_DTB_ITEM_SIZE                       (16 + 16 * 1024)
+#define ZXDH_DTB_TAB_UP_SIZE                     ((16 + 16 * 1024) * 32)
+#define ZXDH_DTB_TAB_DOWN_SIZE                   ((16 + 16 * 1024) * 32)
+
+#define ZXDH_DTB_TAB_UP_ACK_VLD_MASK             (0x555555)
+#define ZXDH_DTB_TAB_DOWN_ACK_VLD_MASK           (0x5a5a5a)
+#define ZXDH_DTB_TAB_ACK_IS_USING_MASK           (0x11111100)
+#define ZXDH_DTB_TAB_ACK_UNUSED_MASK             (0x0)
+#define ZXDH_DTB_TAB_ACK_SUCCESS_MASK            (0xff)
+#define ZXDH_DTB_TAB_ACK_FAILED_MASK             (0x1)
+#define ZXDH_DTB_TAB_ACK_CHECK_VALUE             (0x12345678)
+
+#define ZXDH_DTB_TAB_ACK_VLD_SHIFT               (104)
+#define ZXDH_DTB_TAB_ACK_STATUS_SHIFT            (96)
+#define ZXDH_DTB_LEN_POS_SETP                    (16)
+#define ZXDH_DTB_ITEM_ADD_OR_UPDATE              (0)
+#define ZXDH_DTB_ITEM_DELETE                     (1)
+
+#define ZXDH_ETCAM_LEN_SIZE            (6)
+#define ZXDH_ETCAM_BLOCK_NUM           (8)
+#define ZXDH_ETCAM_TBLID_NUM           (8)
+#define ZXDH_ETCAM_RAM_NUM             (8)
+#define ZXDH_ETCAM_RAM_WIDTH           (80U)
+#define ZXDH_ETCAM_WR_MASK_MAX         (((uint32_t)1 << ZXDH_ETCAM_RAM_NUM) - 1)
+#define ZXDH_ETCAM_WIDTH_MIN           (ZXDH_ETCAM_RAM_WIDTH)
+#define ZXDH_ETCAM_WIDTH_MAX           (ZXDH_ETCAM_RAM_NUM * ZXDH_ETCAM_RAM_WIDTH)
+
+#define ZXDH_DTB_TABLE_DATA_BUFF_SIZE           (16384)
+#define ZXDH_DTB_TABLE_CMD_SIZE_BIT             (128)
+
+#define ZXDH_SE_SMMU0_ERAM_BLOCK_NUM            (32)
+#define ZXDH_SE_SMMU0_ERAM_ADDR_NUM_PER_BLOCK   (0x4000)
+#define ZXDH_SE_SMMU0_ERAM_ADDR_NUM_TOTAL  \
+        (ZXDH_SE_SMMU0_ERAM_BLOCK_NUM * ZXDH_SE_SMMU0_ERAM_ADDR_NUM_PER_BLOCK)
+
+/**errco code */
+#define ZXDH_RC_BASE                            (0x1000U)
+#define ZXDH_PARAMETER_CHK_BASE                 (ZXDH_RC_BASE            | 0x200)
+#define ZXDH_PAR_CHK_POINT_NULL                 (ZXDH_PARAMETER_CHK_BASE | 0x001)
+#define ZXDH_PAR_CHK_ARGIN_ZERO                 (ZXDH_PARAMETER_CHK_BASE | 0x002)
+#define ZXDH_PAR_CHK_ARGIN_OVERFLOW             (ZXDH_PARAMETER_CHK_BASE | 0x003)
+#define ZXDH_PAR_CHK_ARGIN_ERROR                (ZXDH_PARAMETER_CHK_BASE | 0x004)
+#define ZXDH_PAR_CHK_INVALID_INDEX              (ZXDH_PARAMETER_CHK_BASE | 0x005)
+#define ZXDH_PAR_CHK_INVALID_RANGE              (ZXDH_PARAMETER_CHK_BASE | 0x006)
+#define ZXDH_PAR_CHK_INVALID_DEV_ID             (ZXDH_PARAMETER_CHK_BASE | 0x007)
+#define ZXDH_PAR_CHK_INVALID_PARA               (ZXDH_PARAMETER_CHK_BASE | 0x008)
+
+#define ZXDH_ERAM128_BADDR_MASK                 (0x3FFFF80)
+
+#define ZXDH_DTB_TABLE_MODE_ERAM                (0)
+#define ZXDH_DTB_TABLE_MODE_DDR                 (1)
+#define ZXDH_DTB_TABLE_MODE_ZCAM                (2)
+#define ZXDH_DTB_TABLE_MODE_ETCAM               (3)
+#define ZXDH_DTB_TABLE_MODE_MC_HASH             (4)
+#define ZXDH_DTB_TABLE_VALID                    (1)
+
+/* DTB module error code */
+#define ZXDH_RC_DTB_BASE                        (0xd00)
+#define ZXDH_RC_DTB_MGR_EXIST                   (ZXDH_RC_DTB_BASE | 0x0)
+#define ZXDH_RC_DTB_MGR_NOT_EXIST               (ZXDH_RC_DTB_BASE | 0x1)
+#define ZXDH_RC_DTB_QUEUE_RES_EMPTY             (ZXDH_RC_DTB_BASE | 0x2)
+#define ZXDH_RC_DTB_QUEUE_BUFF_SIZE_ERR         (ZXDH_RC_DTB_BASE | 0x3)
+#define ZXDH_RC_DTB_QUEUE_ITEM_HW_EMPTY         (ZXDH_RC_DTB_BASE | 0x4)
+#define ZXDH_RC_DTB_QUEUE_ITEM_SW_EMPTY         (ZXDH_RC_DTB_BASE | 0x5)
+#define ZXDH_RC_DTB_TAB_UP_BUFF_EMPTY           (ZXDH_RC_DTB_BASE | 0x6)
+#define ZXDH_RC_DTB_TAB_DOWN_BUFF_EMPTY         (ZXDH_RC_DTB_BASE | 0x7)
+#define ZXDH_RC_DTB_TAB_UP_TRANS_ERR            (ZXDH_RC_DTB_BASE | 0x8)
+#define ZXDH_RC_DTB_TAB_DOWN_TRANS_ERR          (ZXDH_RC_DTB_BASE | 0x9)
+#define ZXDH_RC_DTB_QUEUE_IS_WORKING            (ZXDH_RC_DTB_BASE | 0xa)
+#define ZXDH_RC_DTB_QUEUE_IS_NOT_INIT           (ZXDH_RC_DTB_BASE | 0xb)
+#define ZXDH_RC_DTB_MEMORY_ALLOC_ERR            (ZXDH_RC_DTB_BASE | 0xc)
+#define ZXDH_RC_DTB_PARA_INVALID                (ZXDH_RC_DTB_BASE | 0xd)
+#define ZXDH_RC_DMA_RANGE_INVALID               (ZXDH_RC_DTB_BASE | 0xe)
+#define ZXDH_RC_DMA_RCV_DATA_EMPTY              (ZXDH_RC_DTB_BASE | 0xf)
+#define ZXDH_RC_DTB_LPM_INSERT_FAIL             (ZXDH_RC_DTB_BASE | 0x10)
+#define ZXDH_RC_DTB_LPM_DELETE_FAIL             (ZXDH_RC_DTB_BASE | 0x11)
+#define ZXDH_RC_DTB_DOWN_LEN_INVALID            (ZXDH_RC_DTB_BASE | 0x12)
+#define ZXDH_RC_DTB_DOWN_HASH_CONFLICT          (ZXDH_RC_DTB_BASE | 0x13)
+#define ZXDH_RC_DTB_QUEUE_NOT_ALLOC             (ZXDH_RC_DTB_BASE | 0x14)
+#define ZXDH_RC_DTB_QUEUE_NAME_ERROR            (ZXDH_RC_DTB_BASE | 0x15)
+#define ZXDH_RC_DTB_DUMP_SIZE_SMALL             (ZXDH_RC_DTB_BASE | 0x16)
+#define ZXDH_RC_DTB_SEARCH_VPORT_QUEUE_ZERO     (ZXDH_RC_DTB_BASE | 0x17)
+#define ZXDH_RC_DTB_QUEUE_NOT_ENABLE            (ZXDH_RC_DTB_BASE | 0x18)
+
 typedef enum zxdh_module_init_e {
     ZXDH_MODULE_INIT_NPPU = 0,
     ZXDH_MODULE_INIT_PPU,
@@ -299,7 +389,127 @@ typedef struct zxdh_tlb_mgr_t {
     uint32_t pa_width;
 } ZXDH_TLB_MGR_T;
 
+typedef enum zxdh_eram128_tbl_mode_e {
+    ZXDH_ERAM128_TBL_1b   = 0,
+    ZXDH_ERAM128_TBL_32b  = 1,
+    ZXDH_ERAM128_TBL_64b  = 2,
+    ZXDH_ERAM128_TBL_128b = 3,
+    ZXDH_ERAM128_TBL_2b   = 4,
+    ZXDH_ERAM128_TBL_4b   = 5,
+    ZXDH_ERAM128_TBL_8b   = 6,
+    ZXDH_ERAM128_TBL_16b  = 7
+} ZXDH_ERAM128_TBL_MODE_E;
+
+typedef enum zxdh_eram128_opr_mode_e {
+    ZXDH_ERAM128_OPR_128b = 0,
+    ZXDH_ERAM128_OPR_64b  = 1,
+    ZXDH_ERAM128_OPR_1b   = 2,
+    ZXDH_ERAM128_OPR_32b  = 3
+
+} ZXDH_ERAM128_OPR_MODE_E;
+
+typedef enum zxdh_dtb_table_info_e {
+    ZXDH_DTB_TABLE_DDR           = 0,
+    ZXDH_DTB_TABLE_ERAM_1        = 1,
+    ZXDH_DTB_TABLE_ERAM_64       = 2,
+    ZXDH_DTB_TABLE_ERAM_128      = 3,
+    ZXDH_DTB_TABLE_ZCAM          = 4,
+    ZXDH_DTB_TABLE_ETCAM         = 5,
+    ZXDH_DTB_TABLE_MC_HASH       = 6,
+    ZXDH_DTB_TABLE_ENUM_MAX
+} ZXDH_DTB_TABLE_INFO_E;
+
+typedef enum zxdh_sdt_table_type_e {
+    ZXDH_SDT_TBLT_INVALID = 0,
+    ZXDH_SDT_TBLT_ERAM    = 1,
+    ZXDH_SDT_TBLT_DDR3    = 2,
+    ZXDH_SDT_TBLT_HASH    = 3,
+    ZXDH_SDT_TBLT_LPM     = 4,
+    ZXDH_SDT_TBLT_ETCAM   = 5,
+    ZXDH_SDT_TBLT_PORTTBL = 6,
+    ZXDH_SDT_TBLT_MAX     = 7,
+} ZXDH_SDT_TABLE_TYPE_E;
+
+typedef struct zxdh_dtb_lpm_entry_t {
+    uint32_t dtb_len0;
+    uint8_t *p_data_buff0;
+    uint32_t dtb_len1;
+    uint8_t *p_data_buff1;
+} ZXDH_DTB_LPM_ENTRY_T;
+
+typedef struct zxdh_dtb_entry_t {
+    uint8_t *cmd;
+    uint8_t *data;
+    uint32_t data_in_cmd_flag;
+    uint32_t data_size;
+} ZXDH_DTB_ENTRY_T;
+
+typedef struct zxdh_dtb_eram_table_form_t {
+    uint32_t valid;
+    uint32_t type_mode;
+    uint32_t data_mode;
+    uint32_t cpu_wr;
+    uint32_t cpu_rd;
+    uint32_t cpu_rd_mode;
+    uint32_t addr;
+    uint32_t data_h;
+    uint32_t data_l;
+} ZXDH_DTB_ERAM_TABLE_FORM_T;
+
+typedef struct zxdh_sdt_tbl_eram_t {
+    uint32_t table_type;
+    uint32_t eram_mode;
+    uint32_t eram_base_addr;
+    uint32_t eram_table_depth;
+    uint32_t eram_clutch_en;
+} ZXDH_SDTTBL_ERAM_T;
+
+typedef union zxdh_endian_u {
+    unsigned int     a;
+    unsigned char    b;
+} ZXDH_ENDIAN_U;
+
+typedef struct zxdh_dtb_field_t {
+    const char    *p_name;
+    uint16_t  lsb_pos;
+    uint16_t  len;
+} ZXDH_DTB_FIELD_T;
+
+typedef struct zxdh_dtb_table_t {
+    const char    *table_type;
+    uint32_t  table_no;
+    uint32_t  field_num;
+    ZXDH_DTB_FIELD_T *p_fields;
+} ZXDH_DTB_TABLE_T;
+
+typedef struct zxdh_dtb_queue_item_info_t {
+    uint32_t cmd_vld;
+    uint32_t cmd_type;
+    uint32_t int_en;
+    uint32_t data_len;
+    uint32_t data_laddr;
+    uint32_t data_hddr;
+} ZXDH_DTB_QUEUE_ITEM_INFO_T;
+
+typedef struct zxdh_dtb_queue_len_t {
+    uint32_t cfg_dtb_cmd_type;
+    uint32_t cfg_dtb_cmd_int_en;
+    uint32_t cfg_queue_dtb_len;
+} ZXDH_DTB_QUEUE_LEN_T;
+
+typedef struct zxdh_dtb_eram_entry_info_t {
+    uint32_t index;
+    uint32_t *p_data;
+} ZXDH_DTB_ERAM_ENTRY_INFO_T;
+
+typedef struct zxdh_dtb_user_entry_t {
+    uint32_t sdt_no;
+    void *p_entry_data;
+} ZXDH_DTB_USER_ENTRY_T;
+
 int zxdh_np_host_init(uint32_t dev_id, ZXDH_DEV_INIT_CTRL_T *p_dev_init_ctrl);
 int zxdh_np_online_uninit(uint32_t dev_id, char *port_name, uint32_t queue_id);
+int zxdh_np_dtb_table_entry_write(uint32_t dev_id, uint32_t queue_id,
+            uint32_t entrynum, ZXDH_DTB_USER_ENTRY_T *down_entries);
 
 #endif /* ZXDH_NP_H */
diff --git a/drivers/net/zxdh/zxdh_pci.h b/drivers/net/zxdh/zxdh_pci.h
index d6487a574f..e3f13cb17d 100644
--- a/drivers/net/zxdh/zxdh_pci.h
+++ b/drivers/net/zxdh/zxdh_pci.h
@@ -12,6 +12,8 @@
 
 #include "zxdh_ethdev.h"
 
+#define ZXDH_PF_PCIE_ID(pcie_id)  (((pcie_id) & 0xff00) | 1 << 11)
+
 enum zxdh_msix_status {
     ZXDH_MSIX_NONE     = 0,
     ZXDH_MSIX_DISABLED = 1,
diff --git a/drivers/net/zxdh/zxdh_tables.c b/drivers/net/zxdh/zxdh_tables.c
new file mode 100644
index 0000000000..91376e6ec0
--- /dev/null
+++ b/drivers/net/zxdh/zxdh_tables.c
@@ -0,0 +1,105 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 ZTE Corporation
+ */
+
+#include "zxdh_ethdev.h"
+#include "zxdh_msg.h"
+#include "zxdh_np.h"
+#include "zxdh_tables.h"
+#include "zxdh_logs.h"
+
+#define ZXDH_SDT_VPORT_ATT_TABLE          1
+#define ZXDH_SDT_PANEL_ATT_TABLE          2
+
+int zxdh_set_port_attr(uint16_t vfid, struct zxdh_port_attr_table *port_attr)
+{
+    int ret = 0;
+
+    ZXDH_DTB_ERAM_ENTRY_INFO_T entry = {vfid, (uint32_t *)port_attr};
+    ZXDH_DTB_USER_ENTRY_T user_entry_write = {ZXDH_SDT_VPORT_ATT_TABLE, (void *)&entry};
+
+    ret = zxdh_np_dtb_table_entry_write(ZXDH_DEVICE_NO,
+                g_dtb_data.queueid, 1, &user_entry_write);
+    if (ret != 0)
+        PMD_DRV_LOG(ERR, "write vport_att failed vfid:%d failed", vfid);
+
+    return ret;
+}
+
+int
+zxdh_port_attr_init(struct rte_eth_dev *dev)
+{
+    struct zxdh_hw *hw = dev->data->dev_private;
+    struct zxdh_port_attr_table port_attr = {0};
+    struct zxdh_msg_info msg_info = {0};
+    int ret;
+
+    if (hw->is_pf) {
+        port_attr.hit_flag = 1;
+        port_attr.phy_port = hw->phyport;
+        port_attr.pf_vfid = zxdh_vport_to_vfid(hw->vport);
+        port_attr.rss_enable = 0;
+        if (!hw->is_pf)
+            port_attr.is_vf = 1;
+
+        port_attr.mtu = dev->data->mtu;
+        port_attr.mtu_enable = 1;
+        port_attr.is_up = 0;
+        if (!port_attr.rss_enable)
+            port_attr.port_base_qid = 0;
+
+        ret = zxdh_set_port_attr(hw->vfid, &port_attr);
+        if (ret) {
+            PMD_DRV_LOG(ERR, "write port_attr failed");
+            ret = -1;
+        }
+    } else {
+        struct zxdh_vf_init_msg *vf_init_msg = &msg_info.data.vf_init_msg;
+
+        zxdh_msg_head_build(hw, ZXDH_VF_PORT_INIT, &msg_info);
+        msg_info.msg_head.msg_type = ZXDH_VF_PORT_INIT;
+        vf_init_msg->link_up = 1;
+        vf_init_msg->base_qid = 0;
+        vf_init_msg->rss_enable = 0;
+        ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
+        if (ret) {
+            PMD_DRV_LOG(ERR, "vf port_init failed");
+            ret = -1;
+        }
+    }
+    return ret;
+};
+
+int zxdh_panel_table_init(struct rte_eth_dev *dev)
+{
+    struct zxdh_hw *hw = dev->data->dev_private;
+    int ret;
+
+    if (!hw->is_pf)
+        return 0;
+
+    struct zxdh_panel_table panel;
+
+    memset(&panel, 0, sizeof(panel));
+    panel.hit_flag = 1;
+    panel.pf_vfid = zxdh_vport_to_vfid(hw->vport);
+    panel.mtu_enable = 1;
+    panel.mtu = dev->data->mtu;
+
+    ZXDH_DTB_ERAM_ENTRY_INFO_T panel_entry = {
+        .index = hw->phyport,
+        .p_data = (uint32_t *)&panel
+    };
+    ZXDH_DTB_USER_ENTRY_T entry = {
+        .sdt_no = ZXDH_SDT_PANEL_ATT_TABLE,
+        .p_entry_data = (void *)&panel_entry
+    };
+    ret = zxdh_np_dtb_table_entry_write(ZXDH_DEVICE_NO, g_dtb_data.queueid, 1, &entry);
+
+    if (ret) {
+        PMD_DRV_LOG(ERR, "Insert eram-panel failed, code:%u", ret);
+        ret = -1;
+    }
+
+    return ret;
+}
diff --git a/drivers/net/zxdh/zxdh_tables.h b/drivers/net/zxdh/zxdh_tables.h
new file mode 100644
index 0000000000..5d34af2f05
--- /dev/null
+++ b/drivers/net/zxdh/zxdh_tables.h
@@ -0,0 +1,148 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 ZTE Corporation
+ */
+
+#ifndef ZXDH_TABLES_H
+#define ZXDH_TABLES_H
+
+#include <stdint.h>
+
+extern struct zxdh_dtb_shared_data g_dtb_data;
+
+#define ZXDH_DEVICE_NO                    0
+
+struct zxdh_port_attr_table {
+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
+    uint8_t byte4_rsv1: 1;
+    uint8_t ingress_meter_enable: 1;
+    uint8_t egress_meter_enable: 1;
+    uint8_t byte4_rsv2: 2;
+    uint8_t fd_enable: 1;
+    uint8_t vepa_enable: 1;
+    uint8_t spoof_check_enable: 1;
+
+    uint8_t inline_sec_offload: 1;
+    uint8_t ovs_enable: 1;
+    uint8_t lag_enable: 1;
+    uint8_t is_passthrough: 1;
+    uint8_t is_vf: 1;
+    uint8_t virtion_version: 2;
+    uint8_t virtio_enable: 1;
+
+    uint8_t accelerator_offload_flag: 1;
+    uint8_t lro_offload: 1;
+    uint8_t ip_fragment_offload: 1;
+    uint8_t tcp_udp_checksum_offload: 1;
+    uint8_t ip_checksum_offload: 1;
+    uint8_t outer_ip_checksum_offload: 1;
+    uint8_t is_up: 1;
+    uint8_t rsv1: 1;
+
+    uint8_t rsv3 : 1;
+    uint8_t rdma_offload_enable: 1;
+    uint8_t vlan_filter_enable: 1;
+    uint8_t vlan_strip_offload: 1;
+    uint8_t qinq_valn_strip_offload: 1;
+    uint8_t rss_enable: 1;
+    uint8_t mtu_enable: 1;
+    uint8_t hit_flag: 1;
+
+    uint16_t mtu;
+
+    uint16_t port_base_qid : 12;
+    uint16_t hash_search_index : 3;
+    uint16_t rsv: 1;
+
+    uint8_t rss_hash_factor;
+
+    uint8_t hash_alg: 4;
+    uint8_t phy_port: 4;
+
+    uint16_t lag_id : 3;
+    uint16_t pf_vfid : 11;
+    uint16_t ingress_tm_enable : 1;
+    uint16_t egress_tm_enable : 1;
+
+    uint16_t tpid;
+
+    uint16_t vhca : 10;
+    uint16_t uplink_port : 6;
+#else
+    uint8_t rsv3 : 1;
+    uint8_t rdma_offload_enable: 1;
+    uint8_t vlan_filter_enable: 1;
+    uint8_t vlan_strip_offload: 1;
+    uint8_t qinq_valn_strip_offload: 1;
+    uint8_t rss_enable: 1;
+    uint8_t mtu_enable: 1;
+    uint8_t hit_flag: 1;
+
+    uint8_t accelerator_offload_flag: 1;
+    uint8_t lro_offload: 1;
+    uint8_t ip_fragment_offload: 1;
+    uint8_t tcp_udp_checksum_offload: 1;
+    uint8_t ip_checksum_offload: 1;
+    uint8_t outer_ip_checksum_offload: 1;
+    uint8_t is_up: 1;
+    uint8_t rsv1: 1;
+
+    uint8_t inline_sec_offload: 1;
+    uint8_t ovs_enable: 1;
+    uint8_t lag_enable: 1;
+    uint8_t is_passthrough: 1;
+    uint8_t is_vf: 1;
+    uint8_t virtion_version: 2;
+    uint8_t virtio_enable: 1;
+
+    uint8_t byte4_rsv1: 1;
+    uint8_t ingress_meter_enable: 1;
+    uint8_t egress_meter_enable: 1;
+    uint8_t byte4_rsv2: 2;
+    uint8_t fd_enable: 1;
+    uint8_t vepa_enable: 1;
+    uint8_t spoof_check_enable: 1;
+
+    uint16_t port_base_qid : 12;
+    uint16_t hash_search_index : 3;
+    uint16_t rsv: 1;
+
+    uint16_t mtu;
+
+    uint16_t lag_id : 3;
+    uint16_t pf_vfid : 11;
+    uint16_t ingress_tm_enable : 1;
+    uint16_t egress_tm_enable : 1;
+
+    uint8_t hash_alg: 4;
+    uint8_t phy_port: 4;
+
+    uint8_t rss_hash_factor;
+
+    uint16_t tpid;
+
+    uint16_t vhca : 10;
+    uint16_t uplink_port : 6;
+#endif
+};
+
+struct zxdh_panel_table {
+    uint16_t port_vfid_1588 : 11,
+             rsv2           : 5;
+    uint16_t pf_vfid        : 11,
+             rsv1           : 1,
+             enable_1588_tc : 2,
+             trust_mode     : 1,
+             hit_flag       : 1;
+    uint32_t mtu            : 16,
+             mtu_enable     : 1,
+             rsv            : 3,
+             tm_base_queue  : 12;
+    uint32_t rsv_1;
+    uint32_t rsv_2;
+}; /* 16B */
+
+int zxdh_port_attr_init(struct rte_eth_dev *dev);
+int zxdh_panel_table_init(struct rte_eth_dev *dev);
+int zxdh_set_port_attr(uint16_t vfid, struct zxdh_port_attr_table *port_attr);
+
+#endif /* ZXDH_TABLES_H */
-- 
2.27.0