1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
|
/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
/*
* Copyright (c) 2018-2025 Advanced Micro Devices, Inc. All rights reserved.
*/
#ifndef IONIC_H
#define IONIC_H
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <endian.h>
#include <pthread.h>
#include <infiniband/driver.h>
#include <infiniband/verbs.h>
#include <util/udma_barrier.h>
#include <ccan/list.h>
#include "ionic-abi.h"
#include "ionic_memory.h"
#include "ionic_queue.h"
#include "ionic_table.h"
#include <stdio.h>
#include <inttypes.h>
#include <stdatomic.h>
#include <stdint.h>
#define IONIC_MIN_RDMA_VERSION 1
#define IONIC_MAX_RDMA_VERSION 2
#define IONIC_META_LAST ((void *)1ul)
#define IONIC_META_POSTED ((void *)2ul)
#define IONIC_CQ_GRACE 100
#define IONIC_PAGE_SIZE 4096
#define IONIC_QUEUE_DEPTH_MAX 0xFFFF
#define IONIC_QUEUE_STRIDE_MAX 0x10000
/** IONIC_PD_TAG - tag used for parent domain resource allocation. */
#define IONIC_PD_TAG ((uint64_t)RDMA_DRIVER_IONIC << 32)
#define IONIC_PD_TAG_CQ (IONIC_PD_TAG | 1)
#define IONIC_PD_TAG_SQ (IONIC_PD_TAG | 2)
#define IONIC_PD_TAG_RQ (IONIC_PD_TAG | 3)
enum {
IONIC_CQ_SUPPORTED_WC_FLAGS =
IBV_WC_EX_WITH_BYTE_LEN |
IBV_WC_EX_WITH_IMM |
IBV_WC_EX_WITH_QP_NUM |
IBV_WC_EX_WITH_SRC_QP |
IBV_WC_EX_WITH_SLID |
IBV_WC_EX_WITH_SL |
IBV_WC_EX_WITH_DLID_PATH_BITS
};
struct ionic_ctx {
struct verbs_context vctx;
int spec;
uint32_t pg_shift;
int version;
uint8_t opcodes;
uint8_t sq_qtype;
uint8_t rq_qtype;
uint8_t cq_qtype;
uint8_t max_stride;
uint8_t udma_count;
uint8_t expdb_mask;
bool sq_expdb;
bool rq_expdb;
void *dbpage_page;
uint64_t *dbpage;
pthread_mutex_t mut;
struct ionic_tbl_root qp_tbl;
FILE *dbg_file;
};
struct ionic_pd {
struct ibv_pd ibpd;
struct ibv_pd *root_ibpd;
uint8_t udma_mask;
uint8_t sq_cmb;
uint8_t rq_cmb;
void *(*alloc)(struct ibv_pd *pd, void *pd_context, size_t size,
size_t alignment, uint64_t resource_type);
void (*free)(struct ibv_pd *pd, void *pd_context, void *ptr,
uint64_t resource_type);
void *pd_context;
};
struct ionic_cq {
struct ionic_vcq *vcq;
uint32_t cqid;
pthread_spinlock_t lock;
unsigned long cqseq;
struct list_head poll_sq;
struct list_head poll_rq;
bool flush;
struct list_head flush_sq;
struct list_head flush_rq;
struct ionic_queue q;
bool color;
bool deferred_arm;
bool deferred_arm_sol_only;
bool lockfree;
int reserve;
int reserve_pending;
uint16_t arm_any_prod;
uint16_t arm_sol_prod;
};
struct ionic_vcq {
struct verbs_cq vcq;
struct ionic_cq cq[2];
uint8_t udma_mask;
uint8_t poll_idx;
struct ibv_wc cur_wc; /* for use with start_poll/next_poll */
};
struct ionic_sq_meta {
uint64_t wrid;
uint32_t len;
uint16_t seq;
uint8_t ibop;
uint8_t ibsts;
bool remote;
bool signal;
bool local_comp;
};
struct ionic_rq_meta {
struct ionic_rq_meta *next;
uint64_t wrid;
};
struct ionic_rq {
pthread_spinlock_t lock;
struct ionic_queue queue;
void *cmb_ptr;
struct ionic_rq_meta *meta;
struct ionic_rq_meta *meta_head;
uint16_t *meta_idx;
int spec;
uint16_t old_prod;
uint16_t cmb_prod;
uint8_t cmb;
bool flush;
};
struct ionic_sq {
pthread_spinlock_t lock;
struct ionic_queue queue;
void *cmb_ptr;
struct ionic_sq_meta *meta;
uint16_t *msn_idx;
int spec;
uint16_t old_prod;
uint16_t msn_prod;
uint16_t msn_cons;
uint16_t cmb_prod;
uint8_t cmb;
bool flush;
bool flush_rcvd;
bool color;
};
struct ionic_qp {
struct verbs_qp vqp;
uint32_t qpid;
uint8_t udma_idx;
bool has_sq;
bool has_rq;
bool lockfree;
struct list_node cq_poll_sq;
struct list_node cq_poll_rq;
struct list_node cq_flush_sq;
struct list_node cq_flush_rq;
struct ionic_sq sq;
struct ionic_rq rq;
};
struct ionic_ah {
struct ibv_ah ibah;
uint32_t ahid;
};
struct ionic_dev {
struct verbs_device vdev;
int abi_ver;
};
bool is_ionic_ctx(struct ibv_context *ibctx);
static inline bool is_ionic_pd(struct ibv_pd *ibpd)
{
return is_ionic_ctx(ibpd->context);
}
static inline bool is_ionic_cq(struct ibv_cq *ibcq)
{
return is_ionic_ctx(ibcq->context);
}
static inline bool is_ionic_qp(struct ibv_qp *ibqp)
{
return is_ionic_ctx(ibqp->context);
}
static inline struct ionic_dev *to_ionic_dev(struct ibv_device *ibdev)
{
return container_of(ibdev, struct ionic_dev, vdev.device);
}
static inline struct ionic_ctx *to_ionic_ctx(struct ibv_context *ibctx)
{
return container_of(ibctx, struct ionic_ctx, vctx.context);
}
static inline struct ionic_pd *to_ionic_pd(struct ibv_pd *ibpd)
{
return container_of(ibpd, struct ionic_pd, ibpd);
}
static inline struct ibv_pd *ionic_root_ibpd(struct ionic_pd *pd)
{
return pd->root_ibpd;
}
static inline struct ibv_pd *to_ionic_root_ibpd(struct ibv_pd *ibpd)
{
return ionic_root_ibpd(to_ionic_pd(ibpd));
}
static inline struct ionic_vcq *to_ionic_vcq_ex(struct ibv_cq_ex *ibcq)
{
return container_of(ibcq, struct ionic_vcq, vcq.cq_ex);
}
static inline struct ionic_vcq *to_ionic_vcq(struct ibv_cq *ibcq)
{
return container_of(ibcq, struct ionic_vcq, vcq.cq);
}
static inline struct ionic_cq *to_ionic_vcq_cq(struct ibv_cq *ibcq,
uint8_t udma_idx)
{
return &to_ionic_vcq(ibcq)->cq[udma_idx];
}
static inline struct ionic_qp *to_ionic_qp(struct ibv_qp *ibqp)
{
return container_of(ibqp, struct ionic_qp, vqp.qp);
}
static inline struct ionic_ah *to_ionic_ah(struct ibv_ah *ibah)
{
return container_of(ibah, struct ionic_ah, ibah);
}
static inline bool ionic_ibop_is_local(enum ibv_wr_opcode op)
{
return op == IBV_WR_LOCAL_INV || op == IBV_WR_BIND_MW;
}
static inline uint8_t ionic_ctx_udma_mask(struct ionic_ctx *ctx)
{
return BIT(ctx->udma_count) - 1;
}
static inline void ionic_dbg_xdump(struct ionic_ctx *ctx, const char *str,
const void *ptr, size_t size)
{
const uint8_t *ptr8 = ptr;
int i;
for (i = 0; i < size; i += 8)
verbs_debug(&ctx->vctx,
"%s: %02x %02x %02x %02x %02x %02x %02x %02x", str,
ptr8[i + 0], ptr8[i + 1], ptr8[i + 2], ptr8[i + 3],
ptr8[i + 4], ptr8[i + 5], ptr8[i + 6], ptr8[i + 7]);
}
/* ionic_verbs.h */
void ionic_verbs_set_ops(struct ionic_ctx *ctx);
#endif /* IONIC_H */
|