Add msg chan enable implementation to support<br />send msg to backend(device side) get infos.<br /> <br />Signed-off-by: Junlong Wang <wang.junlong1@zte.com.cn> <br />---<br /> drivers/net/zxdh/zxdh_ethdev.c |   6 +<br /> drivers/net/zxdh/zxdh_ethdev.h |  12 +<br /> drivers/net/zxdh/zxdh_msg.c    | 657 +++++++++++++++++++++++++++++++++<br /> drivers/net/zxdh/zxdh_msg.h    | 128 +++++++<br /> 4 files changed, 803 insertions(+)<br /> <br />diff --git a/drivers/net/zxdh/zxdh_ethdev.c b/drivers/net/zxdh/zxdh_ethdev.c<br />index bb7c1253c9..105c18f9e0 100644<br />--- a/drivers/net/zxdh/zxdh_ethdev.c<br />+++ b/drivers/net/zxdh/zxdh_ethdev.c<br />@@ -99,6 +99,12 @@ zxdh_eth_dev_init(struct rte_eth_dev *eth_dev)<br />         goto err_zxdh_init;<br />     }<br />  <br />+    ret = zxdh_msg_chan_enable(eth_dev);<br />+    if (ret != 0) {<br />+        PMD_DRV_LOG(ERR, "zxdh_msg_bar_chan_enable failed ret %d", ret);<br />+        goto err_zxdh_init;<br />+    }<br />+<br />     return ret;<br />  <br /> err_zxdh_init:<br />diff --git a/drivers/net/zxdh/zxdh_ethdev.h b/drivers/net/zxdh/zxdh_ethdev.h<br />index 20ead56e44..7434cc15d7 100644<br />--- a/drivers/net/zxdh/zxdh_ethdev.h<br />+++ b/drivers/net/zxdh/zxdh_ethdev.h<br />@@ -28,10 +28,22 @@ extern "C" {<br /> #define ZXDH_RX_QUEUES_MAX        128U<br /> #define ZXDH_TX_QUEUES_MAX        128U<br />  <br />+union zxdh_virport_num {<br />+    uint16_t vport;<br />+    struct {<br />+        uint16_t vfid:8;<br />+        uint16_t pfid:3;<br />+        uint16_t vf_flag:1;<br />+        uint16_t epid:3;<br />+        uint16_t direct_flag:1;<br />+    };<br />+};<br />+<br /> struct zxdh_hw {<br />     struct rte_eth_dev *eth_dev;<br />     struct zxdh_pci_common_cfg *common_cfg;<br />     struct zxdh_net_config *dev_cfg;<br />+    union zxdh_virport_num vport;<br />  <br />     uint64_t bar_addr[ZXDH_NUM_BARS];<br />     uint64_t host_features;<br />diff --git a/drivers/net/zxdh/zxdh_msg.c b/drivers/net/zxdh/zxdh_msg.c<br />index 319a9cab57..336ba217d3 100644<br />--- a/drivers/net/zxdh/zxdh_msg.c<br />+++ b/drivers/net/zxdh/zxdh_msg.c<br />@@ -17,6 +17,7 @@<br />  <br /> #define ZXDH_REPS_INFO_FLAG_USABLE  0x00<br /> #define ZXDH_BAR_SEQID_NUM_MAX      256<br />+#define ZXDH_REPS_INFO_FLAG_USED    0xa0<br />  <br /> #define ZXDH_PCIEID_IS_PF_MASK      (0x0800)<br /> #define ZXDH_PCIEID_PF_IDX_MASK     (0x0700)<br />@@ -33,12 +34,85 @@<br /> #define ZXDH_MAX_EP_NUM              (4)<br /> #define ZXDH_MAX_HARD_SPINLOCK_NUM   (511)<br />  <br />+#define ZXDH_LOCK_PRIMARY_ID_MASK       (0x8000)<br />+/* bar offset */<br />+#define ZXDH_BAR0_CHAN_RISC_OFFSET      (0x2000)<br />+#define ZXDH_BAR0_CHAN_PFVF_OFFSET      (0x3000)<br /> #define ZXDH_BAR0_SPINLOCK_OFFSET       (0x4000)<br /> #define ZXDH_FW_SHRD_OFFSET             (0x5000)<br /> #define ZXDH_FW_SHRD_INNER_HW_LABEL_PAT (0x800)<br /> #define ZXDH_HW_LABEL_OFFSET   \<br />     (ZXDH_FW_SHRD_OFFSET + ZXDH_FW_SHRD_INNER_HW_LABEL_PAT)<br />  <br />+#define ZXDH_CHAN_RISC_SPINLOCK_OFFSET \<br />+    (ZXDH_BAR0_SPINLOCK_OFFSET - ZXDH_BAR0_CHAN_RISC_OFFSET)<br />+#define ZXDH_CHAN_PFVF_SPINLOCK_OFFSET \<br />+    (ZXDH_BAR0_SPINLOCK_OFFSET - ZXDH_BAR0_CHAN_PFVF_OFFSET)<br />+#define ZXDH_CHAN_RISC_LABEL_OFFSET    \<br />+    (ZXDH_HW_LABEL_OFFSET - ZXDH_BAR0_CHAN_RISC_OFFSET)<br />+#define ZXDH_CHAN_PFVF_LABEL_OFFSET    \<br />+    (ZXDH_HW_LABEL_OFFSET - ZXDH_BAR0_CHAN_PFVF_OFFSET)<br />+<br />+#define ZXDH_REPS_HEADER_LEN_OFFSET      1<br />+#define ZXDH_REPS_HEADER_PAYLOAD_OFFSET  4<br />+#define ZXDH_REPS_HEADER_REPLYED         0xff<br />+<br />+#define ZXDH_BAR_MSG_CHAN_USABLE  0<br />+#define ZXDH_BAR_MSG_CHAN_USED    1<br />+<br />+#define ZXDH_BAR_MSG_POL_MASK     (0x10)<br />+#define ZXDH_BAR_MSG_POL_OFFSET   (4)<br />+<br />+#define ZXDH_BAR_ALIGN_WORD_MASK   0xfffffffc<br />+#define ZXDH_BAR_MSG_VALID_MASK    1<br />+#define ZXDH_BAR_MSG_VALID_OFFSET  0<br />+<br />+#define ZXDH_BAR_PF_NUM             7<br />+#define ZXDH_BAR_VF_NUM             256<br />+#define ZXDH_BAR_INDEX_PF_TO_VF     0<br />+#define ZXDH_BAR_INDEX_MPF_TO_MPF   0xff<br />+#define ZXDH_BAR_INDEX_MPF_TO_PFVF  0<br />+#define ZXDH_BAR_INDEX_PFVF_TO_MPF  0<br />+<br />+#define ZXDH_MAX_HARD_SPINLOCK_ASK_TIMES  (1000)<br />+#define ZXDH_SPINLOCK_POLLING_SPAN_US     (100)<br />+<br />+#define ZXDH_BAR_MSG_SRC_NUM   3<br />+#define ZXDH_BAR_MSG_SRC_MPF   0<br />+#define ZXDH_BAR_MSG_SRC_PF    1<br />+#define ZXDH_BAR_MSG_SRC_VF    2<br />+#define ZXDH_BAR_MSG_SRC_ERR   0xff<br />+#define ZXDH_BAR_MSG_DST_NUM   3<br />+#define ZXDH_BAR_MSG_DST_RISC  0<br />+#define ZXDH_BAR_MSG_DST_MPF   2<br />+#define ZXDH_BAR_MSG_DST_PFVF  1<br />+#define ZXDH_BAR_MSG_DST_ERR   0xff<br />+<br />+#define ZXDH_LOCK_TYPE_HARD    (1)<br />+#define ZXDH_LOCK_TYPE_SOFT    (0)<br />+#define ZXDH_BAR_INDEX_TO_RISC  0<br />+<br />+#define ZXDH_BAR_CHAN_INDEX_SEND  0<br />+#define ZXDH_BAR_CHAN_INDEX_RECV  1<br />+<br />+uint8_t subchan_id_tbl[ZXDH_BAR_MSG_SRC_NUM][ZXDH_BAR_MSG_DST_NUM] = {<br />+    {ZXDH_BAR_CHAN_INDEX_SEND, ZXDH_BAR_CHAN_INDEX_SEND, ZXDH_BAR_CHAN_INDEX_SEND},<br />+    {ZXDH_BAR_CHAN_INDEX_SEND, ZXDH_BAR_CHAN_INDEX_SEND, ZXDH_BAR_CHAN_INDEX_RECV},<br />+    {ZXDH_BAR_CHAN_INDEX_SEND, ZXDH_BAR_CHAN_INDEX_RECV, ZXDH_BAR_CHAN_INDEX_RECV}<br />+};<br />+<br />+uint8_t chan_id_tbl[ZXDH_BAR_MSG_SRC_NUM][ZXDH_BAR_MSG_DST_NUM] = {<br />+    {ZXDH_BAR_INDEX_TO_RISC, ZXDH_BAR_INDEX_MPF_TO_PFVF, ZXDH_BAR_INDEX_MPF_TO_MPF},<br />+    {ZXDH_BAR_INDEX_TO_RISC, ZXDH_BAR_INDEX_PF_TO_VF,   ZXDH_BAR_INDEX_PFVF_TO_MPF},<br />+    {ZXDH_BAR_INDEX_TO_RISC, ZXDH_BAR_INDEX_PF_TO_VF,   ZXDH_BAR_INDEX_PFVF_TO_MPF}<br />+};<br />+<br />+uint8_t lock_type_tbl[ZXDH_BAR_MSG_SRC_NUM][ZXDH_BAR_MSG_DST_NUM] = {<br />+    {ZXDH_LOCK_TYPE_HARD, ZXDH_LOCK_TYPE_HARD, ZXDH_LOCK_TYPE_HARD},<br />+    {ZXDH_LOCK_TYPE_SOFT, ZXDH_LOCK_TYPE_SOFT, ZXDH_LOCK_TYPE_HARD},<br />+    {ZXDH_LOCK_TYPE_HARD, ZXDH_LOCK_TYPE_HARD, ZXDH_LOCK_TYPE_HARD}<br />+};<br />+<br /> struct zxdh_dev_stat {<br />     bool is_mpf_scanned;<br />     bool is_res_init;<br />@@ -60,6 +134,7 @@ struct zxdh_seqid_ring {<br />  <br /> static struct zxdh_dev_stat g_dev_stat;<br /> static struct zxdh_seqid_ring g_seqid_ring;<br />+static uint8_t tmp_msg_header[ZXDH_BAR_MSG_ADDR_CHAN_INTERVAL];<br /> static rte_spinlock_t chan_lock;<br />  <br /> static uint16_t<br />@@ -102,6 +177,35 @@ spinlock_write(uint64_t virt_lock_addr, uint32_t lock_id, uint8_t data)<br />     *(volatile uint8_t *)((uint64_t)virt_lock_addr + (uint64_t)lock_id) = data;<br /> }<br />  <br />+static uint8_t<br />+spinlock_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 int32_t<br />+zxdh_spinlock_lock(uint32_t virt_lock_id, uint64_t virt_addr,<br />+        uint64_t label_addr, uint16_t primary_id)<br />+{<br />+    uint32_t lock_rd_cnt = 0;<br />+<br />+    do {<br />+        /* read to lock */<br />+        uint8_t spl_val = spinlock_read(virt_addr, virt_lock_id);<br />+<br />+        if (spl_val == 0) {<br />+            label_write((uint64_t)label_addr, virt_lock_id, primary_id);<br />+            break;<br />+        }<br />+        rte_delay_us_block(ZXDH_SPINLOCK_POLLING_SPAN_US);<br />+        lock_rd_cnt++;<br />+    } while (lock_rd_cnt < ZXDH_MAX_HARD_SPINLOCK_ASK_TIMES);<br />+    if (lock_rd_cnt >= ZXDH_MAX_HARD_SPINLOCK_ASK_TIMES)<br />+        return -1;<br />+<br />+    return 0;<br />+}<br />+<br /> static int32_t<br /> zxdh_spinlock_unlock(uint32_t virt_lock_id, uint64_t virt_addr, uint64_t label_addr)<br /> {<br />@@ -168,3 +272,556 @@ zxdh_bar_msg_chan_exit(void)<br />     g_dev_stat.is_res_init = false;<br />     return ZXDH_BAR_MSG_OK;<br /> }<br />+<br />+static int<br />+zxdh_bar_chan_msgid_allocate(uint16_t *msgid)<br />+{<br />+    struct zxdh_seqid_item *seqid_reps_info = NULL;<br />+<br />+    rte_spinlock_lock(&g_seqid_ring.lock);<br />+    uint16_t g_id = g_seqid_ring.cur_id;<br />+    uint16_t count = 0;<br />+    int rc = 0;<br />+<br />+    do {<br />+        count++;<br />+        ++g_id;<br />+        g_id %= ZXDH_BAR_SEQID_NUM_MAX;<br />+        seqid_reps_info = &g_seqid_ring.reps_info_tbl[g_id];<br />+    } while ((seqid_reps_info->flag != ZXDH_REPS_INFO_FLAG_USABLE) && <br />+        (count < ZXDH_BAR_SEQID_NUM_MAX));<br />+<br />+    if (count >= ZXDH_BAR_SEQID_NUM_MAX) {<br />+        rc = -1;<br />+        goto out;<br />+    }<br />+    seqid_reps_info->flag = ZXDH_REPS_INFO_FLAG_USED;<br />+    g_seqid_ring.cur_id = g_id;<br />+    *msgid = g_id;<br />+    rc = ZXDH_BAR_MSG_OK;<br />+<br />+out:<br />+    rte_spinlock_unlock(&g_seqid_ring.lock);<br />+    return rc;<br />+}<br />+<br />+static uint16_t<br />+zxdh_bar_chan_save_recv_info(struct zxdh_msg_recviver_mem *result, uint16_t *msg_id)<br />+{<br />+    int ret = zxdh_bar_chan_msgid_allocate(msg_id);<br />+<br />+    if (ret != ZXDH_BAR_MSG_OK)<br />+        return ZXDH_BAR_MSG_ERR_MSGID;<br />+<br />+    PMD_MSG_LOG(DEBUG, "allocate msg_id: %u", *msg_id);<br />+    struct zxdh_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 ZXDH_BAR_MSG_OK;<br />+}<br />+<br />+static uint8_t<br />+zxdh_bar_msg_src_index_trans(uint8_t src)<br />+{<br />+    uint8_t src_index = 0;<br />+<br />+    switch (src) {<br />+    case ZXDH_MSG_CHAN_END_MPF:<br />+        src_index = ZXDH_BAR_MSG_SRC_MPF;<br />+        break;<br />+    case ZXDH_MSG_CHAN_END_PF:<br />+        src_index = ZXDH_BAR_MSG_SRC_PF;<br />+        break;<br />+    case ZXDH_MSG_CHAN_END_VF:<br />+        src_index = ZXDH_BAR_MSG_SRC_VF;<br />+        break;<br />+    default:<br />+        src_index = ZXDH_BAR_MSG_SRC_ERR;<br />+        break;<br />+    }<br />+    return src_index;<br />+}<br />+<br />+static uint8_t<br />+zxdh_bar_msg_dst_index_trans(uint8_t dst)<br />+{<br />+    uint8_t dst_index = 0;<br />+<br />+    switch (dst) {<br />+    case ZXDH_MSG_CHAN_END_MPF:<br />+        dst_index = ZXDH_BAR_MSG_DST_MPF;<br />+        break;<br />+    case ZXDH_MSG_CHAN_END_PF:<br />+        dst_index = ZXDH_BAR_MSG_DST_PFVF;<br />+        break;<br />+    case ZXDH_MSG_CHAN_END_VF:<br />+        dst_index = ZXDH_BAR_MSG_DST_PFVF;<br />+        break;<br />+    case ZXDH_MSG_CHAN_END_RISC:<br />+        dst_index = ZXDH_BAR_MSG_DST_RISC;<br />+        break;<br />+    default:<br />+        dst_index = ZXDH_BAR_MSG_SRC_ERR;<br />+        break;<br />+    }<br />+    return dst_index;<br />+}<br />+<br />+static int<br />+zxdh_bar_chan_send_para_check(struct zxdh_pci_bar_msg *in,<br />+        struct zxdh_msg_recviver_mem *result)<br />+{<br />+    uint8_t src_index = 0;<br />+    uint8_t dst_index = 0;<br />+<br />+    if (in == NULL || result == NULL) {<br />+        PMD_MSG_LOG(ERR, "send para ERR: null para.");<br />+        return ZXDH_BAR_MSG_ERR_NULL_PARA;<br />+    }<br />+    src_index = zxdh_bar_msg_src_index_trans(in->src);<br />+    dst_index = zxdh_bar_msg_dst_index_trans(in->dst);<br />+<br />+    if (src_index == ZXDH_BAR_MSG_SRC_ERR || dst_index == ZXDH_BAR_MSG_DST_ERR) {<br />+        PMD_MSG_LOG(ERR, "send para ERR: chan doesn't exist.");<br />+        return ZXDH_BAR_MSG_ERR_TYPE;<br />+    }<br />+    if (in->module_id >= ZXDH_BAR_MSG_MODULE_NUM) {<br />+        PMD_MSG_LOG(ERR, "send para ERR: invalid module_id: %d.", in->module_id);<br />+        return ZXDH_BAR_MSG_ERR_MODULE;<br />+    }<br />+    if (in->payload_addr == NULL) {<br />+        PMD_MSG_LOG(ERR, "send para ERR: null message.");<br />+        return ZXDH_BAR_MSG_ERR_BODY_NULL;<br />+    }<br />+    if (in->payload_len > ZXDH_BAR_MSG_PAYLOAD_MAX_LEN) {<br />+        PMD_MSG_LOG(ERR, "send para ERR: len %d is too long.", in->payload_len);<br />+        return ZXDH_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 ZXDH_BAR_MSG_ERR_VIRTADDR_NULL;<br />+    }<br />+    if (result->buffer_len < ZXDH_REPS_HEADER_PAYLOAD_OFFSET)<br />+        PMD_MSG_LOG(ERR, "recv buffer len is short than minimal 4 bytes");<br />+<br />+    return ZXDH_BAR_MSG_OK;<br />+}<br />+<br />+static uint64_t<br />+zxdh_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) * ZXDH_BAR_MSG_ADDR_CHAN_INTERVAL;<br />+}<br />+<br />+static uint16_t<br />+zxdh_bar_chan_subchan_addr_get(struct zxdh_pci_bar_msg *in, uint64_t *subchan_addr)<br />+{<br />+    uint8_t src_index = zxdh_bar_msg_src_index_trans(in->src);<br />+    uint8_t dst_index = zxdh_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 = zxdh_subchan_addr_cal(in->virt_addr, chan_id, subchan_id);<br />+    return ZXDH_BAR_MSG_OK;<br />+}<br />+<br />+static int<br />+zxdh_bar_hard_lock(uint16_t src_pcieid, uint8_t dst, uint64_t virt_addr)<br />+{<br />+    int ret = 0;<br />+    uint16_t lockid = zxdh_pcie_id_to_hard_lock(src_pcieid, dst);<br />+<br />+    PMD_MSG_LOG(DEBUG, "dev pcieid: 0x%x lock, get hardlockid: %u", src_pcieid, lockid);<br />+    if (dst == ZXDH_MSG_CHAN_END_RISC)<br />+        ret = zxdh_spinlock_lock(lockid, virt_addr + ZXDH_CHAN_RISC_SPINLOCK_OFFSET,<br />+                    virt_addr + ZXDH_CHAN_RISC_LABEL_OFFSET,<br />+                    src_pcieid | ZXDH_LOCK_PRIMARY_ID_MASK);<br />+    else<br />+        ret = zxdh_spinlock_lock(lockid, virt_addr + ZXDH_CHAN_PFVF_SPINLOCK_OFFSET,<br />+                    virt_addr + ZXDH_CHAN_PFVF_LABEL_OFFSET,<br />+                    src_pcieid | ZXDH_LOCK_PRIMARY_ID_MASK);<br />+<br />+    return ret;<br />+}<br />+<br />+static void<br />+zxdh_bar_hard_unlock(uint16_t src_pcieid, uint8_t dst, uint64_t virt_addr)<br />+{<br />+    uint16_t lockid = zxdh_pcie_id_to_hard_lock(src_pcieid, dst);<br />+<br />+    PMD_MSG_LOG(DEBUG, "dev pcieid: 0x%x unlock, get hardlockid: %u", src_pcieid, lockid);<br />+    if (dst == ZXDH_MSG_CHAN_END_RISC)<br />+        zxdh_spinlock_unlock(lockid, virt_addr + ZXDH_CHAN_RISC_SPINLOCK_OFFSET,<br />+                virt_addr + ZXDH_CHAN_RISC_LABEL_OFFSET);<br />+    else<br />+        zxdh_spinlock_unlock(lockid, virt_addr + ZXDH_CHAN_PFVF_SPINLOCK_OFFSET,<br />+                virt_addr + ZXDH_CHAN_PFVF_LABEL_OFFSET);<br />+}<br />+<br />+static int<br />+zxdh_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 = zxdh_bar_msg_src_index_trans(src);<br />+    uint8_t dst_index = zxdh_bar_msg_dst_index_trans(dst);<br />+<br />+    if (src_index == ZXDH_BAR_MSG_SRC_ERR || dst_index == ZXDH_BAR_MSG_DST_ERR) {<br />+        PMD_MSG_LOG(ERR, "lock ERR: chan doesn't exist.");<br />+        return ZXDH_BAR_MSG_ERR_TYPE;<br />+    }<br />+<br />+    ret = zxdh_bar_hard_lock(src_pcieid, dst, virt_addr);<br />+    if (ret != 0)<br />+        PMD_MSG_LOG(ERR, "dev: 0x%x failed to lock.", src_pcieid);<br />+<br />+    return ret;<br />+}<br />+<br />+static int<br />+zxdh_bar_chan_unlock(uint8_t src, uint8_t dst, uint16_t src_pcieid, uint64_t virt_addr)<br />+{<br />+    uint8_t src_index = zxdh_bar_msg_src_index_trans(src);<br />+    uint8_t dst_index = zxdh_bar_msg_dst_index_trans(dst);<br />+<br />+    if (src_index == ZXDH_BAR_MSG_SRC_ERR || dst_index == ZXDH_BAR_MSG_DST_ERR) {<br />+        PMD_MSG_LOG(ERR, "unlock ERR: chan doesn't exist.");<br />+        return ZXDH_BAR_MSG_ERR_TYPE;<br />+    }<br />+<br />+    zxdh_bar_hard_unlock(src_pcieid, dst, virt_addr);<br />+<br />+    return ZXDH_BAR_MSG_OK;<br />+}<br />+<br />+static void<br />+zxdh_bar_chan_msgid_free(uint16_t msg_id)<br />+{<br />+    struct zxdh_seqid_item *seqid_reps_info = &g_seqid_ring.reps_info_tbl[msg_id];<br />+<br />+    rte_spinlock_lock(&g_seqid_ring.lock);<br />+    seqid_reps_info->flag = ZXDH_REPS_INFO_FLAG_USABLE;<br />+    PMD_MSG_LOG(DEBUG, "free msg_id: %u", msg_id);<br />+    rte_spinlock_unlock(&g_seqid_ring.lock);<br />+}<br />+<br />+static int<br />+zxdh_bar_chan_reg_write(uint64_t subchan_addr, uint32_t offset, uint32_t data)<br />+{<br />+    uint32_t algin_offset = (offset & ZXDH_BAR_ALIGN_WORD_MASK);<br />+<br />+    if (unlikely(algin_offset >= ZXDH_BAR_MSG_ADDR_CHAN_INTERVAL)) {<br />+        PMD_MSG_LOG(ERR, "algin_offset exceeds channel size!");<br />+        return -1;<br />+    }<br />+    *(uint32_t *)(subchan_addr + algin_offset) = data;<br />+    return 0;<br />+}<br />+<br />+static int<br />+zxdh_bar_chan_reg_read(uint64_t subchan_addr, uint32_t offset, uint32_t *pdata)<br />+{<br />+    uint32_t algin_offset = (offset & ZXDH_BAR_ALIGN_WORD_MASK);<br />+<br />+    if (unlikely(algin_offset >= ZXDH_BAR_MSG_ADDR_CHAN_INTERVAL)) {<br />+        PMD_MSG_LOG(ERR, "algin_offset exceeds channel size!");<br />+        return -1;<br />+    }<br />+    *pdata = *(uint32_t *)(subchan_addr + algin_offset);<br />+    return 0;<br />+}<br />+<br />+static uint16_t<br />+zxdh_bar_chan_msg_header_set(uint64_t subchan_addr,<br />+        struct zxdh_bar_msg_header *msg_header)<br />+{<br />+    uint32_t *data = (uint32_t *)msg_header;<br />+    uint16_t i;<br />+<br />+    for (i = 0; i < (ZXDH_BAR_MSG_PLAYLOAD_OFFSET >> 2); i++)<br />+        zxdh_bar_chan_reg_write(subchan_addr, i * 4, *(data + i));<br />+<br />+    return ZXDH_BAR_MSG_OK;<br />+}<br />+<br />+static uint16_t<br />+zxdh_bar_chan_msg_header_get(uint64_t subchan_addr,<br />+        struct zxdh_bar_msg_header *msg_header)<br />+{<br />+    uint32_t *data = (uint32_t *)msg_header;<br />+    uint16_t i;<br />+<br />+    for (i = 0; i < (ZXDH_BAR_MSG_PLAYLOAD_OFFSET >> 2); i++)<br />+        zxdh_bar_chan_reg_read(subchan_addr, i * 4, data + i);<br />+<br />+    return ZXDH_BAR_MSG_OK;<br />+}<br />+<br />+static uint16_t<br />+zxdh_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);<br />+    uint32_t remain = (len & 0x3);<br />+    uint32_t remain_data = 0;<br />+    uint32_t i;<br />+<br />+    for (i = 0; i < count; i++)<br />+        zxdh_bar_chan_reg_write(subchan_addr, 4 * i +<br />+                ZXDH_BAR_MSG_PLAYLOAD_OFFSET, *(data + i));<br />+    if (remain) {<br />+        for (i = 0; i < remain; i++)<br />+            remain_data |= *((uint8_t *)(msg + len - remain + i)) << (8 * i);<br />+<br />+        zxdh_bar_chan_reg_write(subchan_addr, 4 * count +<br />+                ZXDH_BAR_MSG_PLAYLOAD_OFFSET, remain_data);<br />+    }<br />+    return ZXDH_BAR_MSG_OK;<br />+}<br />+<br />+static uint16_t<br />+zxdh_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 remain_data = 0;<br />+    uint32_t remain = (len & 0x3);<br />+    uint32_t i;<br />+<br />+    for (i = 0; i < count; i++)<br />+        zxdh_bar_chan_reg_read(subchan_addr, 4 * i +<br />+            ZXDH_BAR_MSG_PLAYLOAD_OFFSET, (data + i));<br />+    if (remain) {<br />+        zxdh_bar_chan_reg_read(subchan_addr, 4 * count +<br />+                ZXDH_BAR_MSG_PLAYLOAD_OFFSET, &remain_data);<br />+        for (i = 0; i < remain; i++)<br />+            *((uint8_t *)(msg + (len - remain + i))) = remain_data >> (8 * i);<br />+    }<br />+    return ZXDH_BAR_MSG_OK;<br />+}<br />+<br />+static uint16_t<br />+zxdh_bar_chan_msg_valid_set(uint64_t subchan_addr, uint8_t valid_label)<br />+{<br />+    uint32_t data;<br />+<br />+    zxdh_bar_chan_reg_read(subchan_addr, ZXDH_BAR_MSG_VALID_OFFSET, &data);<br />+    data &= (~ZXDH_BAR_MSG_VALID_MASK);<br />+    data |= (uint32_t)valid_label;<br />+    zxdh_bar_chan_reg_write(subchan_addr, ZXDH_BAR_MSG_VALID_OFFSET, data);<br />+    return ZXDH_BAR_MSG_OK;<br />+}<br />+<br />+static uint16_t<br />+zxdh_bar_chan_msg_send(uint64_t subchan_addr, void *payload_addr,<br />+        uint16_t payload_len, struct zxdh_bar_msg_header *msg_header)<br />+{<br />+    uint16_t ret = 0;<br />+    ret = zxdh_bar_chan_msg_header_set(subchan_addr, msg_header);<br />+<br />+    ret = zxdh_bar_chan_msg_header_get(subchan_addr,<br />+                (struct zxdh_bar_msg_header *)tmp_msg_header);<br />+<br />+    ret = zxdh_bar_chan_msg_payload_set(subchan_addr,<br />+                (uint8_t *)(payload_addr), payload_len);<br />+<br />+    ret = zxdh_bar_chan_msg_payload_get(subchan_addr,<br />+                tmp_msg_header, payload_len);<br />+<br />+    ret = zxdh_bar_chan_msg_valid_set(subchan_addr, ZXDH_BAR_MSG_CHAN_USED);<br />+    return ret;<br />+}<br />+<br />+static uint16_t<br />+zxdh_bar_msg_valid_stat_get(uint64_t subchan_addr)<br />+{<br />+    uint32_t data;<br />+<br />+    zxdh_bar_chan_reg_read(subchan_addr, ZXDH_BAR_MSG_VALID_OFFSET, &data);<br />+    if (ZXDH_BAR_MSG_CHAN_USABLE == (data & ZXDH_BAR_MSG_VALID_MASK))<br />+        return ZXDH_BAR_MSG_CHAN_USABLE;<br />+<br />+    return ZXDH_BAR_MSG_CHAN_USED;<br />+}<br />+<br />+static uint16_t<br />+zxdh_bar_chan_msg_poltag_set(uint64_t subchan_addr, uint8_t label)<br />+{<br />+    uint32_t data;<br />+<br />+    zxdh_bar_chan_reg_read(subchan_addr, ZXDH_BAR_MSG_VALID_OFFSET, &data);<br />+    data &= (~(uint32_t)ZXDH_BAR_MSG_POL_MASK);<br />+    data |= ((uint32_t)label << ZXDH_BAR_MSG_POL_OFFSET);<br />+    zxdh_bar_chan_reg_write(subchan_addr, ZXDH_BAR_MSG_VALID_OFFSET, data);<br />+    return ZXDH_BAR_MSG_OK;<br />+}<br />+<br />+static uint16_t<br />+zxdh_bar_chan_sync_msg_reps_get(uint64_t subchan_addr,<br />+        uint64_t recv_buffer, uint16_t buffer_len)<br />+{<br />+    struct zxdh_bar_msg_header msg_header = {0};<br />+    uint16_t msg_id = 0;<br />+    uint16_t msg_len = 0;<br />+<br />+    zxdh_bar_chan_msg_header_get(subchan_addr, &msg_header);<br />+    msg_id = msg_header.msg_id;<br />+    struct zxdh_seqid_item *reps_info = &g_seqid_ring.reps_info_tbl[msg_id];<br />+<br />+    if (reps_info->flag != ZXDH_REPS_INFO_FLAG_USED) {<br />+        PMD_MSG_LOG(ERR, "msg_id %u unused", msg_id);<br />+        return ZXDH_BAR_MSG_ERR_REPLY;<br />+    }<br />+    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 ZXDH_BAR_MSG_ERR_REPSBUFF_LEN;<br />+    }<br />+    uint8_t *recv_msg = (uint8_t *)recv_buffer;<br />+<br />+    zxdh_bar_chan_msg_payload_get(subchan_addr,<br />+            recv_msg + ZXDH_REPS_HEADER_PAYLOAD_OFFSET, msg_len);<br />+    *(uint16_t *)(recv_msg + ZXDH_REPS_HEADER_LEN_OFFSET) = msg_len;<br />+    *recv_msg = ZXDH_REPS_HEADER_REPLYED; /* set reps's valid */<br />+    return ZXDH_BAR_MSG_OK;<br />+}<br />+<br />+int<br />+zxdh_bar_chan_sync_msg_send(struct zxdh_pci_bar_msg *in, struct zxdh_msg_recviver_mem *result)<br />+{<br />+    struct zxdh_bar_msg_header msg_header = {0};<br />+    uint16_t seq_id = 0;<br />+    uint64_t subchan_addr = 0;<br />+    uint32_t time_out_cnt = 0;<br />+    uint16_t valid = 0;<br />+    int ret = 0;<br />+<br />+    ret = zxdh_bar_chan_send_para_check(in, result);<br />+    if (ret != ZXDH_BAR_MSG_OK)<br />+        goto exit;<br />+<br />+    ret = zxdh_bar_chan_save_recv_info(result, &seq_id);<br />+    if (ret != ZXDH_BAR_MSG_OK)<br />+        goto exit;<br />+<br />+    zxdh_bar_chan_subchan_addr_get(in, &subchan_addr);<br />+<br />+    msg_header.sync = ZXDH_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 = zxdh_bar_chan_lock(in->src, in->dst, in->src_pcieid, in->virt_addr);<br />+    if (ret != ZXDH_BAR_MSG_OK) {<br />+        zxdh_bar_chan_msgid_free(seq_id);<br />+        goto exit;<br />+    }<br />+    zxdh_bar_chan_msg_send(subchan_addr, in->payload_addr, in->payload_len, &msg_header);<br />+<br />+    do {<br />+        rte_delay_us_block(ZXDH_BAR_MSG_POLLING_SPAN);<br />+        valid = zxdh_bar_msg_valid_stat_get(subchan_addr);<br />+        ++time_out_cnt;<br />+    } while ((time_out_cnt < ZXDH_BAR_MSG_TIMEOUT_TH) && (valid == ZXDH_BAR_MSG_CHAN_USED));<br />+<br />+    if (time_out_cnt == ZXDH_BAR_MSG_TIMEOUT_TH && valid != ZXDH_BAR_MSG_CHAN_USABLE) {<br />+        zxdh_bar_chan_msg_valid_set(subchan_addr, ZXDH_BAR_MSG_CHAN_USABLE);<br />+        zxdh_bar_chan_msg_poltag_set(subchan_addr, 0);<br />+        PMD_MSG_LOG(ERR, "BAR MSG ERR: chan type time out.");<br />+        ret = ZXDH_BAR_MSG_ERR_TIME_OUT;<br />+    } else {<br />+        ret = zxdh_bar_chan_sync_msg_reps_get(subchan_addr,<br />+                    (uint64_t)result->recv_buffer, result->buffer_len);<br />+    }<br />+    zxdh_bar_chan_msgid_free(seq_id);<br />+    zxdh_bar_chan_unlock(in->src, in->dst, in->src_pcieid, in->virt_addr);<br />+<br />+exit:<br />+    return ret;<br />+}<br />+<br />+static int<br />+zxdh_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<br />+zxdh_bar_chan_enable(struct zxdh_msix_para *para, uint16_t *vport)<br />+{<br />+    struct zxdh_bar_recv_msg recv_msg = {0};<br />+    int ret = 0;<br />+    int check_token = 0;<br />+    int sum_res = 0;<br />+<br />+    if (!para)<br />+        return ZXDH_BAR_MSG_ERR_NULL;<br />+<br />+    struct zxdh_msix_msg msix_msg = {<br />+        .pcie_id = para->pcie_id,<br />+        .vector_risc = para->vector_risc,<br />+        .vector_pfvf = para->vector_pfvf,<br />+        .vector_mpf = para->vector_mpf,<br />+    };<br />+    struct zxdh_pci_bar_msg in = {<br />+        .virt_addr = para->virt_addr,<br />+        .payload_addr = &msix_msg,<br />+        .payload_len = sizeof(msix_msg),<br />+        .emec = 0,<br />+        .src = para->driver_type,<br />+        .dst = ZXDH_MSG_CHAN_END_RISC,<br />+        .module_id = ZXDH_BAR_MODULE_MISX,<br />+        .src_pcieid = para->pcie_id,<br />+        .dst_pcieid = 0,<br />+        .usr = 0,<br />+    };<br />+<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 />+    if (ret != ZXDH_BAR_MSG_OK)<br />+        return -ret;<br />+<br />+    check_token = recv_msg.msix_reps.check;<br />+    sum_res = zxdh_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.", sum_res, check_token);<br />+        return ZXDH_BAR_MSG_ERR_REPLY;<br />+    }<br />+    *vport = recv_msg.msix_reps.vport;<br />+    PMD_MSG_LOG(DEBUG, "vport of pcieid: 0x%x get success.", para->pcie_id);<br />+    return ZXDH_BAR_MSG_OK;<br />+}<br />+<br />+int<br />+zxdh_msg_chan_enable(struct rte_eth_dev *dev)<br />+{<br />+    struct zxdh_hw *hw = dev->data->dev_private;<br />+    struct zxdh_msix_para misx_info = {<br />+        .vector_risc = ZXDH_MSIX_FROM_RISCV,<br />+        .vector_pfvf = ZXDH_MSIX_FROM_PFVF,<br />+        .vector_mpf  = ZXDH_MSIX_FROM_MPF,<br />+        .pcie_id     = hw->pcie_id,<br />+        .driver_type = hw->is_pf ? ZXDH_MSG_CHAN_END_PF : ZXDH_MSG_CHAN_END_VF,<br />+        .virt_addr   = (uint64_t)(hw->bar_addr[ZXDH_BAR0_INDEX] + ZXDH_CTRLCH_OFFSET),<br />+    };<br />+<br />+    return zxdh_bar_chan_enable(&misx_info, &hw->vport.vport);<br />+}<br />diff --git a/drivers/net/zxdh/zxdh_msg.h b/drivers/net/zxdh/zxdh_msg.h<br />index 64e1ad0e7f..83e2fe6d5b 100644<br />--- a/drivers/net/zxdh/zxdh_msg.h<br />+++ b/drivers/net/zxdh/zxdh_msg.h<br />@@ -14,6 +14,21 @@ extern "C" {<br /> #endif<br />  <br /> #define ZXDH_BAR0_INDEX     0<br />+#define ZXDH_CTRLCH_OFFSET            (0x2000)<br />+<br />+#define ZXDH_MSIX_INTR_MSG_VEC_BASE   1<br />+<br />+#define ZXDH_BAR_MSG_POLLING_SPAN     100<br />+#define ZXDH_BAR_MSG_POLL_CNT_PER_MS  (1 * 1000 / ZXDH_BAR_MSG_POLLING_SPAN)<br />+#define ZXDH_BAR_MSG_POLL_CNT_PER_S   (1 * 1000 * 1000 / ZXDH_BAR_MSG_POLLING_SPAN)<br />+#define ZXDH_BAR_MSG_TIMEOUT_TH       (10 * 1000 * 1000 / ZXDH_BAR_MSG_POLLING_SPAN)<br />+<br />+#define ZXDH_BAR_CHAN_MSG_SYNC         0<br />+<br />+#define ZXDH_BAR_MSG_ADDR_CHAN_INTERVAL  (2 * 1024) /* channel size */<br />+#define ZXDH_BAR_MSG_PLAYLOAD_OFFSET     (sizeof(struct zxdh_bar_msg_header))<br />+#define ZXDH_BAR_MSG_PAYLOAD_MAX_LEN     \<br />+    (ZXDH_BAR_MSG_ADDR_CHAN_INTERVAL - sizeof(struct zxdh_bar_msg_header))<br />  <br /> enum ZXDH_DRIVER_TYPE {<br />     ZXDH_MSG_CHAN_END_MPF = 0,<br />@@ -22,6 +37,13 @@ enum ZXDH_DRIVER_TYPE {<br />     ZXDH_MSG_CHAN_END_RISC,<br /> };<br />  <br />+enum ZXDH_MSG_VEC {<br />+    ZXDH_MSIX_FROM_PFVF = ZXDH_MSIX_INTR_MSG_VEC_BASE,<br />+    ZXDH_MSIX_FROM_MPF,<br />+    ZXDH_MSIX_FROM_RISCV,<br />+    ZXDH_MSG_VEC_NUM,<br />+};<br />+<br /> enum ZXDH_BAR_MSG_RTN {<br />     ZXDH_BAR_MSG_OK = 0,<br />     ZXDH_BAR_MSG_ERR_MSGID,<br />@@ -56,10 +78,116 @@ enum ZXDH_BAR_MSG_RTN {<br />     ZXDH_BAR_MSG_ERR_SOCKET, /* netlink sockte err */<br /> };<br />  <br />+enum ZXDH_BAR_MODULE_ID {<br />+    ZXDH_BAR_MODULE_DBG = 0, /* 0:  debug */<br />+    ZXDH_BAR_MODULE_TBL,     /* 1:  resource table */<br />+    ZXDH_BAR_MODULE_MISX,    /* 2:  config msix */<br />+    ZXDH_BAR_MODULE_SDA,     /* 3: */<br />+    ZXDH_BAR_MODULE_RDMA,    /* 4: */<br />+    ZXDH_BAR_MODULE_DEMO,    /* 5:  channel test */<br />+    ZXDH_BAR_MODULE_SMMU,    /* 6: */<br />+    ZXDH_BAR_MODULE_MAC,     /* 7:  mac rx/tx stats */<br />+    ZXDH_BAR_MODULE_VDPA,    /* 8:  vdpa live migration */<br />+    ZXDH_BAR_MODULE_VQM,     /* 9:  vqm live migration */<br />+    ZXDH_BAR_MODULE_NP,      /* 10: vf msg callback np */<br />+    ZXDH_BAR_MODULE_VPORT,   /* 11: get vport */<br />+    ZXDH_BAR_MODULE_BDF,     /* 12: get bdf */<br />+    ZXDH_BAR_MODULE_RISC_READY, /* 13: */<br />+    ZXDH_BAR_MODULE_REVERSE,    /* 14: byte stream reverse */<br />+    ZXDH_BAR_MDOULE_NVME,       /* 15: */<br />+    ZXDH_BAR_MDOULE_NPSDK,      /* 16: */<br />+    ZXDH_BAR_MODULE_NP_TODO,    /* 17: */<br />+    ZXDH_MODULE_BAR_MSG_TO_PF,  /* 18: */<br />+    ZXDH_MODULE_BAR_MSG_TO_VF,  /* 19: */<br />+<br />+    ZXDH_MODULE_FLASH = 32,<br />+    ZXDH_BAR_MODULE_OFFSET_GET = 33,<br />+    ZXDH_BAR_EVENT_OVS_WITH_VCB = 36,<br />+<br />+    ZXDH_BAR_MSG_MODULE_NUM = 100,<br />+};<br />+<br />+struct zxdh_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 zxdh_msix_msg {<br />+    uint16_t pcie_id;<br />+    uint16_t vector_risc;<br />+    uint16_t vector_pfvf;<br />+    uint16_t vector_mpf;<br />+};<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 />+};<br />+<br />+struct zxdh_bar_msix_reps {<br />+    uint16_t pcie_id;<br />+    uint16_t check;<br />+    uint16_t vport;<br />+    uint16_t rsv;<br />+} __rte_packed;<br />+<br />+struct zxdh_bar_offset_reps {<br />+    uint16_t check;<br />+    uint16_t rsv;<br />+    uint32_t offset;<br />+    uint32_t length;<br />+} __rte_packed;<br />+<br />+struct zxdh_bar_recv_msg {<br />+    uint8_t reps_ok;<br />+    uint16_t reps_len;<br />+    uint8_t rsv;<br />+    union {<br />+        struct zxdh_bar_msix_reps msix_reps;<br />+        struct zxdh_bar_offset_reps offset_reps;<br />+    } __rte_packed;<br />+} __rte_packed;<br />+<br />+struct zxdh_msg_recviver_mem {<br />+    void *recv_buffer; /* first 4B is head, followed by payload */<br />+    uint64_t buffer_len;<br />+};<br />+<br />+struct zxdh_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 />+};<br />+<br /> int zxdh_msg_chan_init(void);<br /> int zxdh_bar_msg_chan_exit(void);<br /> int zxdh_msg_chan_hwlock_init(struct rte_eth_dev *dev);<br />  <br />+int zxdh_msg_chan_enable(struct rte_eth_dev *dev);<br />+int zxdh_bar_chan_sync_msg_send(struct zxdh_pci_bar_msg *in,<br />+        struct zxdh_msg_recviver_mem *result);<br />+<br /> #ifdef __cplusplus<br /> }<br /> #endif<br />--  <br />2.27.0<br />