[PATCH rdma v5 4/7] RDMA/zrdma: Add hardware resource initialization and verbs skeleton

Yanze Zhang <[email protected]>
Newsgroups org.kernel.vger.linux-rdma,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
Implement hardware resource initialization logic and provide a minimal
but functional verbs layer skeleton. This includes basic device
registration with an empty ops structure to satisfy the requirement
that the driver must be functional and have a valid driver ID.

Signed-off-by: Yanze Zhang <[email protected]>
---
 drivers/infiniband/hw/zrdma/Makefile      |   5 +-
 drivers/infiniband/hw/zrdma/zrdma_hw.c    | 103 +++++++++++++++++
 drivers/infiniband/hw/zrdma/zrdma_verbs.c |  41 +++++++
 drivers/infiniband/hw/zrdma/zrdma_verbs.h | 128 ++++++++++++++++++++++
 4 files changed, 276 insertions(+), 1 deletion(-)
 create mode 100644 drivers/infiniband/hw/zrdma/zrdma_hw.c
 create mode 100644 drivers/infiniband/hw/zrdma/zrdma_verbs.c
 create mode 100644 drivers/infiniband/hw/zrdma/zrdma_verbs.h

diff --git a/drivers/infiniband/hw/zrdma/Makefile b/drivers/infiniband/hw/zrdma/Makefile
index 2ddf50d1fd20..88be835f5c5c 100644
--- a/drivers/infiniband/hw/zrdma/Makefile
+++ b/drivers/infiniband/hw/zrdma/Makefile
@@ -1,4 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
 
 obj-$(CONFIG_INFINIBAND_ZRDMA) += zrdma.o
-zrdma-y := zrdma_main.o
+zrdma-y := \
+	zrdma_main.o \
+	zrdma_hw.o \
+	zrdma_verbs.o
\ No newline at end of file
diff --git a/drivers/infiniband/hw/zrdma/zrdma_hw.c b/drivers/infiniband/hw/zrdma/zrdma_hw.c
new file mode 100644
index 000000000000..c2432531f238
--- /dev/null
+++ b/drivers/infiniband/hw/zrdma/zrdma_hw.c
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
+/*
+ * ZTE DingHai Rdma driver
+ * Copyright (c) 2022-2026, ZTE Corporation
+ */
+
+#include <linux/vmalloc.h>
+#include "zrdma_hw.h"
+#include "zrdma_ctrl.h"
+#include "zrdma_main.h"
+
+static void zxdh_set_hw_rsrc(struct zxdh_pci_f *rf)
+{
+	rf->allocated_srqs = (void *)(rf->mem_rsrc);
+	rf->allocated_qps = &rf->allocated_srqs[BITS_TO_LONGS(rf->max_srq)];
+	rf->allocated_cqs = &rf->allocated_qps[BITS_TO_LONGS(rf->max_qp)];
+	rf->allocated_mrs = &rf->allocated_cqs[BITS_TO_LONGS(rf->max_cq)];
+	rf->allocated_pds = &rf->allocated_mrs[BITS_TO_LONGS(rf->max_mr)];
+	rf->allocated_ahs = &rf->allocated_pds[BITS_TO_LONGS(rf->max_pd)];
+	rf->allocated_mcgs = &rf->allocated_ahs[BITS_TO_LONGS(rf->max_ah)];
+	rf->allocated_pris = &rf->allocated_mcgs[BITS_TO_LONGS(rf->max_mcg)];
+	rf->allocated_8k_idx = &rf->allocated_pris[BITS_TO_LONGS(rf->max_pri)];
+	rf->qp_table = (struct zxdh_qp **)
+				   (&rf->allocated_8k_idx[BITS_TO_LONGS(rf->max_8k_idx)]);
+	rf->cq_table = (struct zxdh_cq **)(&rf->qp_table[rf->max_qp]);
+	rf->srq_table = (struct zxdh_srq **)(&rf->cq_table[rf->max_cq]);
+
+	spin_lock_init(&rf->rsrc_lock);
+	spin_lock_init(&rf->qptable_lock);
+	spin_lock_init(&rf->cqtable_lock);
+	spin_lock_init(&rf->srqtable_lock);
+}
+
+static u32 zxdh_calc_mem_rsrc_size(struct zxdh_pci_f *rf)
+{
+	u32 rsrc_size;
+
+	rsrc_size = sizeof(unsigned long) * BITS_TO_LONGS(rf->max_srq);
+	rsrc_size += sizeof(unsigned long) * BITS_TO_LONGS(rf->max_qp);
+	rsrc_size += sizeof(unsigned long) * BITS_TO_LONGS(rf->max_mr);
+	rsrc_size += sizeof(unsigned long) * BITS_TO_LONGS(rf->max_cq);
+	rsrc_size += sizeof(unsigned long) * BITS_TO_LONGS(rf->max_pd);
+	rsrc_size += sizeof(unsigned long) * BITS_TO_LONGS(rf->max_ah);
+	rsrc_size += sizeof(unsigned long) * BITS_TO_LONGS(rf->max_mcg);
+	rsrc_size += sizeof(unsigned long) * BITS_TO_LONGS(rf->max_pri);
+	rsrc_size += sizeof(unsigned long) * BITS_TO_LONGS(rf->max_8k_idx);
+	rsrc_size += sizeof(struct zxdh_qp **) * rf->max_qp;
+	rsrc_size += sizeof(struct zxdh_cq **) * rf->max_cq;
+	rsrc_size += sizeof(struct zxdh_srq **) * rf->max_srq;
+
+	return rsrc_size;
+}
+
+static int zxdh_initialize_hw_rsrc(struct zxdh_pci_f *rf)
+{
+	u32 rsrc_size;
+	int ret;
+
+	rf->max_cqe = ZXDH_MAX_CQE;
+	rf->max_qp = ZXDH_MAX_QP;
+	rf->max_mr = ZXDH_MAX_MR;
+	rf->max_cq = ZXDH_MAX_CQ;
+	rf->max_srq = ZXDH_MAX_SRQ;
+	rf->max_pd = ZXDH_MAX_PD;
+	rf->max_ah = ZXDH_MAX_AH;
+	rf->max_mcg = ZXDH_MAX_MCG;
+	rf->max_pri = ZXDH_MAX_USER_PRIORITY;
+	rf->max_8k_idx = ZXDH_MAX_8K_IDX;
+
+	rf->qp_cnt_8k_idxs = vzalloc(rf->max_8k_idx * sizeof(u32));
+	if (!rf->qp_cnt_8k_idxs) {
+		ret = -ENOMEM;
+		goto mem_8k_qp_cnt_vmalloc_fail;
+	}
+
+	rsrc_size = zxdh_calc_mem_rsrc_size(rf);
+	rf->mem_rsrc = vzalloc(rsrc_size);
+	if (!rf->mem_rsrc) {
+		ret = -ENOMEM;
+		goto mem_rsrc_vmalloc_fail;
+	}
+
+	zxdh_set_hw_rsrc(rf);
+
+	set_bit(0, rf->allocated_mrs);
+	set_bit(1, rf->allocated_mrs);
+	set_bit(0, rf->allocated_pds);
+	set_bit(0, rf->allocated_qps);
+	set_bit(0, rf->allocated_ahs);
+	set_bit(0, rf->allocated_mcgs);
+
+	return 0;
+
+mem_rsrc_vmalloc_fail:
+	vfree(rf->qp_cnt_8k_idxs);
+mem_8k_qp_cnt_vmalloc_fail:
+	return ret;
+}
+
+int zxdh_ctrl_init_hw(struct zxdh_pci_f *rf)
+{
+	return zxdh_initialize_hw_rsrc(rf);
+}
diff --git a/drivers/infiniband/hw/zrdma/zrdma_verbs.c b/drivers/infiniband/hw/zrdma/zrdma_verbs.c
new file mode 100644
index 000000000000..6db536c94e01
--- /dev/null
+++ b/drivers/infiniband/hw/zrdma/zrdma_verbs.c
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
+/*
+ * ZTE DingHai Rdma driver
+ * Copyright (c) 2022-2026, ZTE Corporation
+ */
+
+#include "zrdma_main.h"
+#include "zrdma_verbs.h"
+#include "zrdma_ctrl.h"
+
+static const struct ib_device_ops zxdh_dev_ops = {
+	.owner = THIS_MODULE,
+	.driver_id = RDMA_DRIVER_ZRDMA,
+	.uverbs_abi_ver = ZXDH_ABI_VER,
+};
+
+static int zxdh_init_rdma_device(struct zxdh_device *zdev)
+{
+	zdev->ibdev.phys_port_cnt = 1;
+	zdev->ibdev.num_comp_vectors = zdev->rf->ceqs_count;
+	zdev->ibdev.dev.parent = &zdev->rf->pcidev->dev;
+
+	ib_set_device_ops(&zdev->ibdev, &zxdh_dev_ops);
+
+	return 0;
+}
+
+int zxdh_ib_register_device(struct zxdh_device *zdev)
+{
+	int ret;
+
+	ret = zxdh_init_rdma_device(zdev);
+	if (ret)
+		return ret;
+
+	ret = ib_register_device(&zdev->ibdev, "zrdma%d", zdev->rf->hw.device);
+	if (ret)
+		pr_err("zrdma: Register RDMA device fail\n");
+
+	return ret;
+}
diff --git a/drivers/infiniband/hw/zrdma/zrdma_verbs.h b/drivers/infiniband/hw/zrdma/zrdma_verbs.h
new file mode 100644
index 000000000000..7af678c2becb
--- /dev/null
+++ b/drivers/infiniband/hw/zrdma/zrdma_verbs.h
@@ -0,0 +1,128 @@
+/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
+ *
+ * ZTE DingHai Rdma driver
+ * Copyright (c) 2022-2026, ZTE Corporation
+ */
+
+#ifndef ZRDMA_VERBS_H
+#define ZRDMA_VERBS_H
+
+#include <rdma/ib_umem.h>
+#include <rdma/uverbs_ioctl.h>
+
+#define CHIP_VERSION 1
+#define ZXDH_PAGE_OFFSET_NUM (PAGE_SIZE - 1)
+#define MAX_HW_WQ_FRAGS 15
+#define MAX_HW_READ_SGES 15
+#define MAX_HW_INLINE 217
+#define MAX_HW_SRQ_WR 15
+#define MAX_HW_RQ_QUANTA 15
+#define MAX_HW_SRQ_QUANTA 15
+#define MAX_HW_WQ_QUANTA 15
+#define MAX_HW_SQ_CHUNK 0x8000
+#define MAX_HW_CQ_SIZE 0x200000
+#define MIN_HW_CQ_SIZE 4
+
+#define ZXDH_MTU_HEADER_RSV 102
+
+#define ZXDH_PKEY_TBL_SZ 1
+#define ZXDH_DEFAULT_PKEY 0xFFFF
+
+#define SQ_DB_BAR_OFF 0x4c000
+#define CQ_DB_BAR_OFF 0x43000
+#define SRQ_DB_MMAP_SIZE 0x10000
+#define SRQ_DB_BAR_OFF 0x62000
+#define SRQ_DB_OFFSET 0
+
+#define MAX_MR_SIZE 0x200000000000
+#define MAX_QP 0x3fff
+#define MAX_QP_WR 0x1000
+#define MAX_CQ 0x3fff
+#define MAX_CQE 0x200000
+#define MAX_MR 0xfffe
+#define MAX_MW 0xfffe
+#define MAX_PD 0xfffff
+#define MAX_SGE_RD 0xf
+#define MAX_QP_RD_ATOM 0x10
+#define MAX_RES_RD_ATOM 0x3fff0
+#define MAX_QP_INIT_RD_ATOM 0x10
+#define MAX_SRQ 0x200
+#define MAX_SRQ_WR 0x7fff
+#define MAX_SRQ_SGE 0xf
+#define LOCAL_CA_ACK_DELAY 16
+#define HCA_CORE_CLOCK (1000 * 1000UL)
+#define MAX_WQ_TYPE_RQ 0x3fff
+#define MAX_AH 0x10000
+#define MAX_FAST_REG_PAGE_LIST_LEN 0x200
+#define MAX_CQ_MODERATION_COUNT 0xffff
+#define MAX_CQ_MODERATION_PERIOD 0x1cc
+#define TIMESTAMP_MASK 0x1ffff
+#define MAX_MSG_SZ 0x100000
+
+enum zxdh_mmap_flag {
+	ZXDH_MMAP_IO_NC,
+	ZXDH_MMAP_IO_WC,
+	ZXDH_MMAP_PFN,
+	ZXDH_MMAP_HMC,
+	ZXDH_MMAP_IO_NC_BY_SIZE,
+};
+
+struct zxdh_ucontext {
+	struct ib_ucontext ibucontext;
+	struct zxdh_device *zdev;
+	struct rdma_user_mmap_entry *sq_db_mmap_entry;
+	struct rdma_user_mmap_entry *cq_db_mmap_entry;
+	struct rdma_user_mmap_entry *srq_db_mmap_entry;
+	struct list_head cq_reg_mem_list;
+	spinlock_t cq_reg_mem_list_lock; /* protect CQ memory list */
+	struct list_head qp_reg_mem_list;
+	spinlock_t qp_reg_mem_list_lock; /* protect QP memory list */
+	struct list_head srq_reg_mem_list;
+	spinlock_t srq_reg_mem_list_lock; /* protect SRQ memory list */
+	int abi_ver;
+};
+
+struct zxdh_pd {
+	struct ib_pd ibpd;
+	struct zxdh_sc_pd sc_pd;
+};
+
+struct zxdh_user_mmap_entry {
+	struct rdma_user_mmap_entry rdma_entry;
+	u64 bar_offset;
+	u8 mmap_flag;
+};
+
+static inline struct zxdh_pd *to_zpd(struct ib_pd *ibpd)
+{
+	return container_of(ibpd, struct zxdh_pd, ibpd);
+}
+
+static inline struct zxdh_ucontext *to_ucontext(struct ib_ucontext *ibucontext)
+{
+	return container_of(ibucontext, struct zxdh_ucontext, ibucontext);
+}
+
+static inline struct zxdh_user_mmap_entry *
+to_zxdh_mmap_entry(struct rdma_user_mmap_entry *rdma_entry)
+{
+	return container_of(rdma_entry, struct zxdh_user_mmap_entry,
+			    rdma_entry);
+}
+
+static inline enum ib_mtu zxdh_mtu_int_to_enum(int mtu)
+{
+	mtu = mtu - ZXDH_MTU_HEADER_RSV;
+	if (mtu >= 4096)
+		return IB_MTU_4096;
+	else if (mtu >= 2048)
+		return IB_MTU_2048;
+	else if (mtu >= 1024)
+		return IB_MTU_1024;
+	else if (mtu >= 512)
+		return IB_MTU_512;
+	else
+		return IB_MTU_256;
+}
+
+#endif /* ZRDMA_VERBS_H */
-- 
2.27.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.