Add msg channel and hwlock init implementation.

Signed-off-by: Junlong Wang <wang.junlo...@zte.com.cn>
---
 drivers/net/zxdh/meson.build   |   1 +
 drivers/net/zxdh/zxdh_ethdev.c |  15 ++++
 drivers/net/zxdh/zxdh_ethdev.h |   1 +
 drivers/net/zxdh/zxdh_msg.c    | 160 +++++++++++++++++++++++++++++++++
 drivers/net/zxdh/zxdh_msg.h    |  67 ++++++++++++++
 5 files changed, 244 insertions(+)
 create mode 100644 drivers/net/zxdh/zxdh_msg.c
 create mode 100644 drivers/net/zxdh/zxdh_msg.h

diff --git a/drivers/net/zxdh/meson.build b/drivers/net/zxdh/meson.build
index 7db4e7bc71..2e0c8fddae 100644
--- a/drivers/net/zxdh/meson.build
+++ b/drivers/net/zxdh/meson.build
@@ -16,4 +16,5 @@ endif
 sources = files(
         'zxdh_ethdev.c',
         'zxdh_pci.c',
+        'zxdh_msg.c',
 )
diff --git a/drivers/net/zxdh/zxdh_ethdev.c b/drivers/net/zxdh/zxdh_ethdev.c
index f34b2af7b3..6278fd61b6 100644
--- a/drivers/net/zxdh/zxdh_ethdev.c
+++ b/drivers/net/zxdh/zxdh_ethdev.c
@@ -9,6 +9,7 @@
 #include "zxdh_ethdev.h"
 #include "zxdh_logs.h"
 #include "zxdh_pci.h"
+#include "zxdh_msg.h"
 
 struct zxdh_hw_internal zxdh_hw_internal[RTE_MAX_ETHPORTS];
 
@@ -83,9 +84,23 @@ static int zxdh_eth_dev_init(struct rte_eth_dev *eth_dev)
        if (ret < 0)
                goto err_zxdh_init;
 
+       ret = zxdh_msg_chan_init();
+       if (ret != 0) {
+               PMD_INIT_LOG(ERR, "Failed to init bar msg chan");
+               goto err_zxdh_init;
+       }
+       hw->msg_chan_init = 1;
+
+       ret = zxdh_msg_chan_hwlock_init(eth_dev);
+       if (ret != 0) {
+               PMD_INIT_LOG(ERR, "zxdh_msg_chan_hwlock_init failed ret %d", 
ret);
+               goto err_zxdh_init;
+       }
+
        return ret;
 
 err_zxdh_init:
+       zxdh_bar_msg_chan_exit();
        rte_free(eth_dev->data->mac_addrs);
        eth_dev->data->mac_addrs = NULL;
        return ret;
diff --git a/drivers/net/zxdh/zxdh_ethdev.h b/drivers/net/zxdh/zxdh_ethdev.h
index e2db2508e2..e937713d71 100644
--- a/drivers/net/zxdh/zxdh_ethdev.h
+++ b/drivers/net/zxdh/zxdh_ethdev.h
@@ -51,6 +51,7 @@ struct zxdh_hw {
        uint8_t mac_addr[RTE_ETHER_ADDR_LEN];
        uint8_t duplex;
        uint8_t is_pf;
+       uint8_t msg_chan_init;
 };
 
 #ifdef __cplusplus
diff --git a/drivers/net/zxdh/zxdh_msg.c b/drivers/net/zxdh/zxdh_msg.c
new file mode 100644
index 0000000000..51095da5a3
--- /dev/null
+++ b/drivers/net/zxdh/zxdh_msg.c
@@ -0,0 +1,160 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 ZTE Corporation
+ */
+
+#include <stdbool.h>
+
+#include <rte_common.h>
+#include <rte_memcpy.h>
+#include <rte_spinlock.h>
+#include <rte_cycles.h>
+#include <rte_malloc.h>
+
+#include "zxdh_ethdev.h"
+#include "zxdh_logs.h"
+#include "zxdh_msg.h"
+
+#define ZXDH_REPS_INFO_FLAG_USABLE  0x00
+#define ZXDH_BAR_SEQID_NUM_MAX      256
+
+#define ZXDH_PCIEID_IS_PF_MASK      (0x0800)
+#define ZXDH_PCIEID_PF_IDX_MASK     (0x0700)
+#define ZXDH_PCIEID_VF_IDX_MASK     (0x00ff)
+#define ZXDH_PCIEID_EP_IDX_MASK     (0x7000)
+/* PCIEID bit field offset */
+#define ZXDH_PCIEID_PF_IDX_OFFSET   (8)
+#define ZXDH_PCIEID_EP_IDX_OFFSET   (12)
+
+#define ZXDH_MULTIPLY_BY_8(x)       ((x) << 3)
+#define ZXDH_MULTIPLY_BY_32(x)      ((x) << 5)
+#define ZXDH_MULTIPLY_BY_256(x)     ((x) << 8)
+
+#define ZXDH_MAX_EP_NUM              (4)
+#define ZXDH_MAX_HARD_SPINLOCK_NUM   (511)
+
+#define ZXDH_BAR0_SPINLOCK_OFFSET       (0x4000)
+#define ZXDH_FW_SHRD_OFFSET             (0x5000)
+#define ZXDH_FW_SHRD_INNER_HW_LABEL_PAT (0x800)
+#define ZXDH_HW_LABEL_OFFSET   \
+       (ZXDH_FW_SHRD_OFFSET + ZXDH_FW_SHRD_INNER_HW_LABEL_PAT)
+
+struct dev_stat {
+       uint8_t is_mpf_scanned;
+       uint8_t is_res_init;
+       int16_t dev_cnt; /* probe cnt */
+};
+struct dev_stat g_dev_stat = {0};
+
+struct seqid_item {
+       void *reps_addr;
+       uint16_t id;
+       uint16_t buffer_len;
+       uint16_t flag;
+};
+
+struct seqid_ring {
+       uint16_t cur_id;
+       rte_spinlock_t lock;
+       struct seqid_item reps_info_tbl[ZXDH_BAR_SEQID_NUM_MAX];
+};
+struct seqid_ring g_seqid_ring = {0};
+
+static uint16_t pcie_id_to_hard_lock(uint16_t src_pcieid, uint8_t dst)
+{
+       uint16_t lock_id = 0;
+       uint16_t pf_idx = (src_pcieid & ZXDH_PCIEID_PF_IDX_MASK) >> 
ZXDH_PCIEID_PF_IDX_OFFSET;
+       uint16_t ep_idx = (src_pcieid & ZXDH_PCIEID_EP_IDX_MASK) >> 
ZXDH_PCIEID_EP_IDX_OFFSET;
+
+       switch (dst) {
+       /* msg to risc */
+       case ZXDH_MSG_CHAN_END_RISC:
+               lock_id = ZXDH_MULTIPLY_BY_8(ep_idx) + pf_idx;
+               break;
+       /* msg to pf/vf */
+       case ZXDH_MSG_CHAN_END_VF:
+       case ZXDH_MSG_CHAN_END_PF:
+               lock_id = ZXDH_MULTIPLY_BY_8(ep_idx) + pf_idx +
+                               ZXDH_MULTIPLY_BY_8(1 + ZXDH_MAX_EP_NUM);
+               break;
+       default:
+               lock_id = 0;
+               break;
+       }
+       if (lock_id >= ZXDH_MAX_HARD_SPINLOCK_NUM)
+               lock_id = 0;
+
+       return lock_id;
+}
+
+static void label_write(uint64_t label_lock_addr, uint32_t lock_id, uint16_t 
value)
+{
+       *(volatile uint16_t *)(label_lock_addr + lock_id * 2) = value;
+}
+
+static void spinlock_write(uint64_t virt_lock_addr, uint32_t lock_id, uint8_t 
data)
+{
+       *(volatile uint8_t *)((uint64_t)virt_lock_addr + (uint64_t)lock_id) = 
data;
+}
+
+static int32_t zxdh_spinlock_unlock(uint32_t virt_lock_id, uint64_t virt_addr, 
uint64_t label_addr)
+{
+       label_write((uint64_t)label_addr, virt_lock_id, 0);
+       spinlock_write(virt_addr, virt_lock_id, 0);
+       return 0;
+}
+
+/**
+ * Fun: PF init hard_spinlock addr
+ */
+static int bar_chan_pf_init_spinlock(uint16_t pcie_id, uint64_t bar_base_addr)
+{
+       int lock_id = pcie_id_to_hard_lock(pcie_id, ZXDH_MSG_CHAN_END_RISC);
+
+       zxdh_spinlock_unlock(lock_id, bar_base_addr + ZXDH_BAR0_SPINLOCK_OFFSET,
+                       bar_base_addr + ZXDH_HW_LABEL_OFFSET);
+       lock_id = pcie_id_to_hard_lock(pcie_id, ZXDH_MSG_CHAN_END_VF);
+       zxdh_spinlock_unlock(lock_id, bar_base_addr + ZXDH_BAR0_SPINLOCK_OFFSET,
+                       bar_base_addr + ZXDH_HW_LABEL_OFFSET);
+       return 0;
+}
+
+int zxdh_msg_chan_hwlock_init(struct rte_eth_dev *dev)
+{
+       struct zxdh_hw *hw = dev->data->dev_private;
+
+       if (!hw->is_pf)
+               return 0;
+       return bar_chan_pf_init_spinlock(hw->pcie_id, 
(uint64_t)(hw->bar_addr[ZXDH_BAR0_INDEX]));
+}
+
+static rte_spinlock_t chan_lock;
+int zxdh_msg_chan_init(void)
+{
+       uint16_t seq_id = 0;
+
+       g_dev_stat.dev_cnt++;
+       if (g_dev_stat.is_res_init)
+               return ZXDH_BAR_MSG_OK;
+
+       rte_spinlock_init(&chan_lock);
+       g_seqid_ring.cur_id = 0;
+       rte_spinlock_init(&g_seqid_ring.lock);
+
+       for (seq_id = 0; seq_id < ZXDH_BAR_SEQID_NUM_MAX; seq_id++) {
+               struct seqid_item *reps_info = 
&g_seqid_ring.reps_info_tbl[seq_id];
+
+               reps_info->id = seq_id;
+               reps_info->flag = ZXDH_REPS_INFO_FLAG_USABLE;
+       }
+       g_dev_stat.is_res_init = true;
+       return ZXDH_BAR_MSG_OK;
+}
+
+int zxdh_bar_msg_chan_exit(void)
+{
+       if (!g_dev_stat.is_res_init || (--g_dev_stat.dev_cnt > 0))
+               return ZXDH_BAR_MSG_OK;
+
+       g_dev_stat.is_res_init = false;
+       return ZXDH_BAR_MSG_OK;
+}
diff --git a/drivers/net/zxdh/zxdh_msg.h b/drivers/net/zxdh/zxdh_msg.h
new file mode 100644
index 0000000000..2caf2ddaea
--- /dev/null
+++ b/drivers/net/zxdh/zxdh_msg.h
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 ZTE Corporation
+ */
+
+#ifndef ZXDH_MSG_H
+#define ZXDH_MSG_H
+
+#include <stdint.h>
+
+#include <ethdev_driver.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZXDH_BAR0_INDEX     0
+
+enum DRIVER_TYPE {
+       ZXDH_MSG_CHAN_END_MPF = 0,
+       ZXDH_MSG_CHAN_END_PF,
+       ZXDH_MSG_CHAN_END_VF,
+       ZXDH_MSG_CHAN_END_RISC,
+};
+
+enum BAR_MSG_RTN {
+       ZXDH_BAR_MSG_OK = 0,
+       ZXDH_BAR_MSG_ERR_MSGID,
+       ZXDH_BAR_MSG_ERR_NULL,
+       ZXDH_BAR_MSG_ERR_TYPE, /* Message type exception */
+       ZXDH_BAR_MSG_ERR_MODULE, /* Module ID exception */
+       ZXDH_BAR_MSG_ERR_BODY_NULL, /* Message body exception */
+       ZXDH_BAR_MSG_ERR_LEN, /* Message length exception */
+       ZXDH_BAR_MSG_ERR_TIME_OUT, /* Message sending length too long */
+       ZXDH_BAR_MSG_ERR_NOT_READY, /* Abnormal message sending conditions*/
+       ZXDH_BAR_MEG_ERR_NULL_FUNC, /* Empty receive processing function 
pointer*/
+       ZXDH_BAR_MSG_ERR_REPEAT_REGISTER, /* Module duplicate registration*/
+       ZXDH_BAR_MSG_ERR_UNGISTER, /* Repeated deregistration*/
+       /**
+        * The sending interface parameter boundary structure pointer is empty
+        */
+       ZXDH_BAR_MSG_ERR_NULL_PARA,
+       ZXDH_BAR_MSG_ERR_REPSBUFF_LEN, /* The length of reps_buff is too short*/
+       /**
+        * Unable to find the corresponding message processing function for 
this module
+        */
+       ZXDH_BAR_MSG_ERR_MODULE_NOEXIST,
+       /**
+        * The virtual address in the parameters passed in by the sending 
interface is empty
+        */
+       ZXDH_BAR_MSG_ERR_VIRTADDR_NULL,
+       ZXDH_BAR_MSG_ERR_REPLY, /* sync msg resp_error */
+       ZXDH_BAR_MSG_ERR_MPF_NOT_SCANNED,
+       ZXDH_BAR_MSG_ERR_KERNEL_READY,
+       ZXDH_BAR_MSG_ERR_USR_RET_ERR,
+       ZXDH_BAR_MSG_ERR_ERR_PCIEID,
+       ZXDH_BAR_MSG_ERR_SOCKET, /* netlink sockte err */
+};
+
+int zxdh_msg_chan_init(void);
+int zxdh_bar_msg_chan_exit(void);
+int zxdh_msg_chan_hwlock_init(struct rte_eth_dev *dev);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZXDH_MSG_H */
-- 
2.27.0

Reply via email to