[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