* Copyright (c) 2026 Huawei Technologies Co., Ltd.
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
* CANN Open Software License Agreement Version 2.0 (the "License").
* Please refer to the License for details. You may not use this file except in compliance with the License.
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
* See LICENSE in the root of the software repository for the full text of the License.
*
* File Name : ibv_extend.h
* Version : v3.2.0
* Created : 2026/2/14
* Updated : 2026/4/24
* Description : The declaration invoked by the Application interface of RoCE NDA Function
*/
#ifndef IBV_EXTEND_H
#define IBV_EXTEND_H
#include <infiniband/verbs.h>
#include <stdint.h>
* 版本号说明:
* - 主版本号(MAJOR): 不兼容的API变更
* - 次版本号(MINOR): 后向兼容的功能新增
* - 修订号(PATCH): 后向兼容的问题修复
*
* 兼容性规则:
* 1. 驱动和业务编译时的头文件版本必须 <= 运行时库的版本
* 2. 主版本号必须完全一致
* 3. 次版本号:驱动 <= 库
*/
#define IBV_EXTEND_VERSION_MAJOR 3
#define IBV_EXTEND_VERSION_MINOR 2
#define IBV_EXTEND_VERSION_PATCH 0
#define IBV_EXTEND_VERSION_STRING "3.2.0"
enum queue_buf_dma_mode {
QU_BUF_DMA_MODE_DEFAULT = 0,
QU_BUF_DMA_MODE_INDEP_UB,
QU_BUF_DMA_MODE_MAX
};
enum doorbell_map_mode {
DB_MAP_MODE_HOST_VA = 0,
DB_MAP_MODE_UB_RES,
DB_MAP_MODE_UB_MAX
};
enum memcpy_direction {
MEMCPY_DIR_HOST_TO_HOST = 0,
MEMCPY_DIR_HOST_TO_DEVICE,
MEMCPY_DIR_DEVICE_TO_HOST,
MEMCPY_DIR_DEVICE_TO_DEVICE,
};
enum ibv_qp_init_cap {
QP_ENABLE_DIRECT_WQE = 1 << 0,
};
enum ibv_extend_device_cap {
IBV_EXTEND_DEV_NDR = 1 << 0,
IBV_EXTEND_DEV_NDA = 1 << 1,
};
struct doorbell_map_desc {
union {
uint64_t hva;
struct {
uint64_t guid_l;
uint64_t guid_h;
struct {
uint64_t resource_id : 4;
uint64_t offset : 32;
uint64_t resv : 28;
} bits;
} ub_res;
};
uint64_t size;
uint32_t type;
uint32_t resv;
};
struct ibv_extend_ops {
void *(*alloc)(size_t size);
void (*free)(void *ptr);
void (*memset_s)(void *dst, int value, size_t count);
int (*memcpy_s)(void *dst, size_t dst_max_size, void *src, size_t size, uint32_t direct);
void *(*db_mmap)(struct doorbell_map_desc *desc);
int (*db_unmap)(void *ptr, struct doorbell_map_desc *desc);
};
struct iov_addr_desc {
void *iov_base;
size_t iov_len;
};
struct queue_buf {
uint64_t base;
uint32_t entry_cnt;
uint32_t entry_size;
uint64_t resv[4];
};
struct queue_info {
struct queue_buf qbuf;
struct iov_addr_desc dbr_pi_va;
struct iov_addr_desc dbr_ci_va;
struct iov_addr_desc db_hw_va;
uint64_t resv[4];
};
struct ibv_qp_extend {
struct ibv_qp *qp;
struct queue_info sq_info;
struct queue_info rq_info;
uint64_t resv[32];
};
struct ibv_cq_extend {
struct ibv_cq *cq;
struct queue_info cq_info;
uint64_t resv[32];
};
struct ibv_srq_extend {
struct ibv_srq *srq;
struct queue_info srq_info;
uint64_t resv[32];
};
struct ibv_qp_init_attr_extend {
struct ibv_pd *pd;
struct ibv_qp_init_attr attr;
uint32_t qp_cap_flag;
enum queue_buf_dma_mode type;
struct ibv_extend_ops *ops;
uint64_t resv[8];
};
struct ibv_cq_init_attr_extend {
struct ibv_cq_init_attr_ex attr;
uint32_t cq_cap_flag;
enum queue_buf_dma_mode type;
struct ibv_extend_ops *ops;
uint64_t resv[8];
};
struct ibv_srq_init_attr_extend {
struct ibv_pd *pd;
struct ibv_srq_init_attr attr;
uint32_t comp_mask;
uint32_t srq_cap_flag;
enum queue_buf_dma_mode type;
struct ibv_extend_ops *ops;
uint64_t resv[8];
};
struct ibv_device_attr_extend {
uint32_t ext_cap;
uint32_t resv[32];
};
struct ibv_context_extend {
struct ibv_context *context;
struct ibv_context_extend_ops *ops;
};
* @brief 获取库版本号
* @param major 主版本号输出参数(可为NULL)
* @param minor 次版本号输出参数(可为NULL)
* @param patch 修订号输出参数(可为NULL)
* @return 版本字符串指针(静态字符串,无需释放)
*/
const char *ibv_extend_get_version(uint32_t *major, uint32_t *minor, uint32_t *patch);
* @brief 检查版本兼容性
* @param driver_major 驱动编译时的主版本号
* @param driver_minor 驱动编译时的次版本号
* @param driver_patch 驱动编译时的修订号
* @return 0-兼容,-1-不兼容
*
* 此函数在运行时检查驱动编译时使用的头文件版本与当前库版本是否兼容。
* 建议在驱动和上层应用初始化时调用此函数进行版本检查。
*/
int ibv_extend_check_version(uint32_t driver_major, uint32_t driver_minor, uint32_t driver_patch);
* @brief 打开扩展上下文,初始化NDA扩展功能
* @param context RDMA设备上下文指针
* @return NULL-打开失败,Non-NULL-打开成功,返回扩展上下文指针
*/
struct ibv_context_extend *ibv_open_extend(struct ibv_context *context);
* @brief 关闭扩展上下文,释放NDA扩展资源
* @param context 扩展上下文指针
* @return 0-成功,其他值-失败
*/
int ibv_close_extend(struct ibv_context_extend *context);
* @brief 查询设备支持的扩展能力
* @param context RDMA设备上下文指针
* @param ext_dev_attr 返回设备支持的扩展能力
* @return 0-成功,其他值-失败
*/
int ibv_query_device_extend(struct ibv_context_extend *context, struct ibv_device_attr_extend *ext_dev_attr);
* @brief ibv_create_qp扩展接口,支持NDA场景创建qp
* @param context 对应ibv设备的上下文
* @param qp_init_attr 创建qp的属性
* @attention qp_init_attr需要指定对应的内存类型和内存操作集,该信息要保存到qp_ctx后续使用。
* @return NullPtr-创建失败,Non-NullPtr-创建成功,返回qp的句柄和内存信息
*/
struct ibv_qp_extend *ibv_create_qp_extend(struct ibv_context_extend *context,
struct ibv_qp_init_attr_extend *qp_init_attr);
* @brief ibv_create_cq扩展接口,支持NDA场景创建cq
* @param context 对应ibv设备的上下文
* @param cq_init_attr 创建cq的属性
* @attention cq_init_attr需要指定对应的内存类型和内存操作集,该信息要保存到cq_ctx后续使用。
* @return NullPtr-创建失败,Non-NullPtr-创建成功,返回cq的句柄和内存信息
*/
struct ibv_cq_extend *ibv_create_cq_extend(struct ibv_context_extend *context,
struct ibv_cq_init_attr_extend *cq_init_attr);
* @brief ibv_create_srq扩展接口,支持NDA场景创建srq
* @param context 对应ibv设备的上下文
* @param srq_init_attr 创建srq的属性
* @attention srq_init_attr需要指定对应的内存类型和内存操作集,该信息要保存到srq_ctx后续使用。
* @return NullPtr-创建失败,Non-NullPtr-创建成功,返回srq的句柄和内存信息
*/
struct ibv_srq_extend *ibv_create_srq_extend(struct ibv_context_extend *context,
struct ibv_srq_init_attr_extend *srq_init_attr);
* @brief ibv_destroy_qp扩展接口,支持NDA场景销毁qp
* @param qp_extend 创建接口返回的qp句柄
* @attention void
* @return 接口返回值 0-success,other-fail
*/
int ibv_destroy_qp_extend(struct ibv_context_extend *context, struct ibv_qp_extend *qp_extend);
* @brief ibv_destroy_cq扩展接口,支持NDA场景销毁cq
* @param cq_extend 创建接口返回的cq句柄
* @attention void
* @return 接口返回值 0-success,other-fail
*/
int ibv_destroy_cq_extend(struct ibv_context_extend *context, struct ibv_cq_extend *cq_extend);
* @brief ibv_destroy_srq扩展接口,支持NDA场景销毁srq
* @param srq_extend 创建接口返回的srq句柄
* @attention void
* @return 接口返回值 0-success,other-fail
*/
int ibv_destroy_srq_extend(struct ibv_context_extend *context, struct ibv_srq_extend *srq_extend);
struct ibv_context_extend_ops {
struct ibv_qp_extend *(*create_qp)(struct ibv_context *context,
struct ibv_qp_init_attr_extend *qp_init_attr);
struct ibv_cq_extend *(*create_cq)(struct ibv_context *context,
struct ibv_cq_init_attr_extend *cq_init_attr);
struct ibv_srq_extend *(*create_srq)(struct ibv_context *context,
struct ibv_srq_init_attr_extend *srq_init_attr);
int (*destroy_qp)(struct ibv_qp_extend *qp_extend);
int (*destroy_cq)(struct ibv_cq_extend *cq_extend);
int (*destroy_srq)(struct ibv_srq_extend *srq_extend);
int (*query_device)(struct ibv_context *context,
struct ibv_device_attr_extend *ext_dev_attr);
};
struct verbs_device_extend_ops {
const char *name;
struct ibv_context_extend *(*alloc_context)(struct ibv_context *context);
void (*free_context)(struct ibv_context_extend *context);
};
void verbs_register_driver_extend(const struct verbs_device_extend_ops *ops);
#define PROVIDER_EXTEND_DRIVER(drv) \
static __attribute__((constructor)) void drv##__register_extend_driver(void) \
{ \
verbs_register_driver_extend(&(drv)); \
}
#endif