// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
/*
 * Copyright (c) 2018-2025 Advanced Micro Devices, Inc.  All rights reserved.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>
#include <errno.h>
#include <sys/mman.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <infiniband/verbs.h>
#include <linux/types.h>
#include <util/util.h>

#include "ionic_fw.h"
#include "ionic.h"

static void ionic_reserve_sync_cq(struct ionic_ctx *ctx, struct ionic_cq *cq);
static int ionic_poll_cq(struct ibv_cq *ibcq, int nwc, struct ibv_wc *wc);
static void ionic_post_send_cmb(struct ionic_ctx *ctx, struct ionic_qp *qp);
static int ionic_v1_prep_one_rc(struct ionic_qp *qp, struct ibv_send_wr *wr,
				bool send_path);

#ifdef __x86_64__
static bool ionic_have_movdir64b;

#ifndef bit_MOVDIR64B
#define bit_MOVDIR64B	BIT(28)
#endif

static inline bool have_movdir64b(void)
{
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
	unsigned int ax, bx, cx, dx, count = 0, leaf = 7;

	/* Return highest supported cpuid input value.  */
	__asm__ volatile ("cpuid\n\t"
			  : "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx)
			  : "0" (0));

	if (ax == 0 || ax < leaf)
		return 0;

	__asm__ volatile ("cpuid\n\t"
			  : "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx)
			  : "0" (leaf), "2" (count));

	return cx & bit_MOVDIR64B ? 1 : 0;
#else
	return 0;
#endif
}

static __attribute__((constructor))
void init_ionic_mmio_memcpy(void)
{
	ionic_have_movdir64b = have_movdir64b();
}

static inline void ionic_movdir64b_mmio_memcpy_x64_64(void *dst, const void *src)
{
	const struct { char _[64]; } *__src = src;
	struct { char _[64]; } *__dst = dst;

	/*
	 * Caller must guarantee:
	 *   assert(((uintptr_t)dst) % 64 == 0);
	 *   assert(((uintptr_t)src) % 64 == 0);
	 */

	/*
	 * MOVDIR64B %(rdx), rax.
	 *
	 * Both __src and __dst must be memory constraints in order to tell the
	 * compiler that no other memory accesses should be reordered around
	 * this one.
	 *
	 * Also, both must be supplied as lvalues because this tells
	 * the compiler what the object is (its size) the instruction accesses.
	 * I.e., not the pointers but what they point to, thus the deref'ing '*'.
	 */
	asm volatile(".byte 0x66, 0x0f, 0x38, 0xf8, 0x02"
		     : "+m" (*__dst)
		     :  "m" (*__src), "a" (__dst), "d" (__src));
}

static inline void ionic_movdir64b_mmio_memcpy_x64(void *dst, const void *src,
						   size_t bytecnt)
{
	/*
	 * Caller must guarantee:
	 *   assert(bytecnt != 0);
	 *   assert((bytecnt % 64) == 0);
	 *   assert(((uintptr_t)dst) % 64 == 0);
	 *   assert(((uintptr_t)src) % 64 == 0);
	 */

	do {
		ionic_movdir64b_mmio_memcpy_x64_64(dst, src);
		bytecnt -= 64;
		src += 64;
		dst += 64;
	} while (bytecnt > 0);
}
#endif /* #if defined(__x86_64__) */

static inline void ionic_mmio_memcpy_x64_64(void *dst, const void *src)
{
#ifdef __x86_64__
	if (likely(ionic_have_movdir64b))
		ionic_movdir64b_mmio_memcpy_x64_64(dst, src);
	else
#endif
		mmio_memcpy_x64(dst, src, 64);
}

static inline void ionic_mmio_memcpy_x64(void *dst, const void *src, size_t bytecnt)
{
#ifdef __x86_64__
	if (likely(ionic_have_movdir64b))
		ionic_movdir64b_mmio_memcpy_x64(dst, src, bytecnt);
	else
#endif
		mmio_memcpy_x64(dst, src, bytecnt);
}

#define ionic_cq_spin_lock(cq) do {			\
	if (unlikely(!(cq)->lockfree))			\
		pthread_spin_lock(&(cq)->lock);		\
} while (0)

#define ionic_cq_spin_trylock(cq)			\
	(likely((cq)->lockfree) ?			\
	 0 : pthread_spin_trylock(&(cq)->lock))

#define ionic_cq_spin_unlock(cq) do {			\
	if (unlikely(!(cq)->lockfree))			\
		pthread_spin_unlock(&(cq)->lock);	\
} while (0)

#define ionic_rq_spin_lock(qp) do {			\
	if (unlikely(!(qp)->lockfree))			\
		pthread_spin_lock(&(qp)->rq.lock);	\
} while (0)

#define ionic_rq_spin_unlock(qp) do {			\
	if (unlikely(!(qp)->lockfree))			\
		pthread_spin_unlock(&(qp)->rq.lock);	\
} while (0)

#define ionic_sq_spin_lock(qp) do {			\
	if (unlikely(!(qp)->lockfree))			\
		pthread_spin_lock(&(qp)->sq.lock);	\
} while (0)

#define ionic_sq_spin_unlock(qp) do {			\
	if (unlikely(!(qp)->lockfree))			\
		pthread_spin_unlock(&(qp)->sq.lock);	\
} while (0)

#define IONIC_OP(version, opname) \
	((version) < 2 ? IONIC_V1_OP_##opname : IONIC_V2_OP_##opname)

static int ionic_phc_update(struct ionic_phc *phc, struct ib_uverbs_clock_info *state)
{
	uint32_t sign, *state_sign;
	int retry;

	state_sign = &state->sign;

	for (retry = 10; true; --retry) {
		if (!retry)
			return EBUSY;

		sign = atomic_load((_Atomic(uint32_t) *)state_sign);

		/* odd sign means state is updating */
		if (sign & 1)
			continue;

		phc->mask = state->mask;
		phc->cycles = state->cycles;
		phc->nsec = state->nsec;
		phc->frac = state->frac;
		phc->mult = state->mult;
		phc->shift = state->shift;

		/* same sign means state did not update */
		if (sign == atomic_load((_Atomic(uint32_t) *)state_sign))
			break;
	}

	return 0;
}

static int ionic_query_device_ex(struct ibv_context *ibctx,
				 const struct ibv_query_device_ex_input *input,
				 struct ibv_device_attr_ex *ex,
				 size_t ex_size)
{
	struct ibv_device_attr *dev_attr = &ex->orig_attr;
	struct ib_uverbs_ex_query_device_resp resp = {};
	struct ionic_ctx *ctx = to_ionic_ctx(ibctx);
	size_t resp_size = sizeof(resp);
	int rc;

	rc = ibv_cmd_query_device_any(ibctx, input, ex, ex_size, &resp, &resp_size);
	if (rc)
		return rc;

	rc = ibv_read_sysfs_file(ibctx->device->ibdev_path, "fw_ver",
				 dev_attr->fw_ver, sizeof(dev_attr->fw_ver));
	if (rc < 0)
		dev_attr->fw_ver[0] = 0;

	if (ctx->phc_state) {
		struct ionic_phc phc = {};

		rc = ionic_phc_update(&phc, ctx->phc_state);
		if (!rc) {
			const uint64_t ns_per_ms = 1000000;
			const uint32_t shift = phc.shift;
			const uint32_t mult = phc.mult;

			if (ex_size > offsetof(typeof(*ex), completion_timestamp_mask))
				ex->completion_timestamp_mask = phc.mask;

			if (ex_size > offsetof(typeof(*ex), hca_core_clock))
				ex->hca_core_clock =
					((ns_per_ms << shift) + (mult >> 1)) / mult;
		}
	}

	return 0;
}

static int ionic_query_port(struct ibv_context *ibctx, uint8_t port,
			    struct ibv_port_attr *port_attr)
{
	struct ibv_query_port req = {};

	return ibv_cmd_query_port(ibctx, port, port_attr,
				  &req, sizeof(req));
}

static struct ibv_td *ionic_alloc_td(struct ibv_context *ibctx,
				     struct ibv_td_init_attr *init_attr)
{
	struct ionic_td *td;

	if (init_attr->comp_mask) {
		errno = EOPNOTSUPP;
		return NULL;
	}

	td = calloc(1, sizeof(*td));
	if (!td) {
		errno = ENOMEM;
		return NULL;
	}

	td->ibtd.context = ibctx;
	atomic_init(&td->refcount, 1);

	return &td->ibtd;
}

static int ionic_dealloc_td(struct ibv_td *ibtd)
{
	struct ionic_td *td = to_ionic_td(ibtd);

	if (atomic_load(&td->refcount) > 1)
		return EBUSY;

	free(td);

	return 0;
}

static struct ibv_pd *ionic_alloc_parent_domain(struct ibv_context *context,
						struct ibv_parent_domain_init_attr *attr)
{
	struct ionic_pd *pd, *init_pd;
	struct ibv_pd *root_ibpd;
	int rc;

	if (ibv_check_alloc_parent_domain(attr)) {
		rc = errno;
		goto err_pd;
	}

	if (!check_comp_mask(attr->comp_mask,
			     IBV_PARENT_DOMAIN_INIT_ATTR_ALLOCATORS |
			     IBV_PARENT_DOMAIN_INIT_ATTR_PD_CONTEXT)) {
		rc = EINVAL;
		goto err_pd;
	}

	pd = calloc(1, sizeof(*pd));
	if (!pd) {
		rc = errno;
		goto err_pd;
	}

	init_pd = to_ionic_pd(attr->pd);
	root_ibpd = ionic_root_ibpd(init_pd);

	ibv_initialize_parent_domain(&pd->ibpd, root_ibpd);

	pd->root_ibpd = root_ibpd;
	pd->udma_mask = init_pd->udma_mask;
	pd->sq_cmb = init_pd->sq_cmb;
	pd->rq_cmb = init_pd->rq_cmb;

	if (attr->td) {
		pd->td = to_ionic_td(attr->td);
		atomic_fetch_add(&pd->td->refcount, 1);
	}

	if (attr->comp_mask & IBV_PARENT_DOMAIN_INIT_ATTR_ALLOCATORS) {
		pd->alloc = attr->alloc;
		pd->free = attr->free;
	}

	if (attr->comp_mask & IBV_PARENT_DOMAIN_INIT_ATTR_PD_CONTEXT)
		pd->pd_context = attr->pd_context;

	return &pd->ibpd;

err_pd:
	errno = rc;
	return NULL;
}

static struct ibv_pd *ionic_alloc_pd(struct ibv_context *ibctx)
{
	struct ionic_ctx *ctx = to_ionic_ctx(ibctx);
	struct ionic_pd *pd;
	struct ibv_alloc_pd req = {};
	struct ib_uverbs_alloc_pd_resp resp = {};
	int rc;

	pd = calloc(1, sizeof(*pd));
	if (!pd) {
		rc = errno;
		goto err_pd;
	}

	pd->root_ibpd = &pd->ibpd;

	rc = ibv_cmd_alloc_pd(ibctx, &pd->ibpd,
			      &req, sizeof(req),
			      &resp, sizeof(resp));
	if (rc)
		goto err_cmd;

	pd->udma_mask = ionic_ctx_udma_mask(ctx);

	pd->sq_cmb = IONIC_CMB_ENABLE;
	if (ctx->sq_expdb)
		pd->sq_cmb |= IONIC_CMB_EXPDB;

	pd->rq_cmb = IONIC_CMB_ENABLE;
	if (ctx->rq_expdb)
		pd->rq_cmb |= IONIC_CMB_EXPDB;

	return &pd->ibpd;

err_cmd:
	free(pd);
err_pd:
	errno = rc;
	return NULL;
}

static int ionic_dealloc_pd(struct ibv_pd *ibpd)
{
	struct ionic_pd *pd = to_ionic_pd(ibpd);
	int rc;

	if (&pd->ibpd == pd->root_ibpd) {
		rc = ibv_cmd_dealloc_pd(&pd->ibpd);
		if (rc)
			return rc;
	} else if (pd->td) {
		atomic_fetch_sub(&pd->td->refcount, 1);
	}

	free(pd);

	return 0;
}

static struct ibv_mr *ionic_reg_dmabuf_mr(struct ibv_pd *ibpd, uint64_t offset,
					  size_t length, uint64_t iova,
					  int fd, int access)
{
	struct ibv_pd *root_ibpd = to_ionic_root_ibpd(ibpd);
	struct verbs_mr *vmr;
	int rc;

	vmr = calloc(1, sizeof(*vmr));
	if (!vmr) {
		rc = errno;
		goto err_mr;
	}

	rc = ibv_cmd_reg_dmabuf_mr(root_ibpd, offset, length, iova, fd, access, vmr, NULL);
	if (rc)
		goto err_cmd;

	return &vmr->ibv_mr;

err_cmd:
	free(vmr);
err_mr:
	errno = rc;
	return NULL;
}

static struct ibv_mr *ionic_reg_mr(struct ibv_pd *ibpd,
				   void *addr,
				   size_t len,
				   uint64_t hca_va,
				   int access)
{
	struct ibv_pd *root_ibpd = to_ionic_root_ibpd(ibpd);
	struct verbs_mr *vmr;
	struct ib_uverbs_reg_mr_resp resp = {};
	struct ibv_reg_mr req = {};
	int rc;

	vmr = calloc(1, sizeof(*vmr));
	if (!vmr) {
		rc = errno;
		goto err_mr;
	}

	rc = ibv_cmd_reg_mr(root_ibpd, addr, len,
			    hca_va,
			    access, vmr,
			    &req, sizeof(req),
			    &resp, sizeof(resp));
	if (rc)
		goto err_cmd;

	return &vmr->ibv_mr;

err_cmd:
	free(vmr);
err_mr:
	errno = rc;
	return NULL;
}

static int ionic_dereg_mr(struct verbs_mr *vmr)
{
	int rc;

	rc = ibv_cmd_dereg_mr(vmr);
	if (rc)
		return rc;

	free(vmr);

	return 0;
}

static void ionic_vcq_cq_deinit(struct ionic_cq *cq)
{
	if (!cq->vcq)
		return;

	cq->vcq = NULL;
	ionic_queue_destroy(&cq->q);
	pthread_spin_destroy(&cq->lock);
}

static int ionic_vcq_cq_init1(struct ionic_ctx *ctx,
			      struct ionic_vcq *vcq,
			      struct ionic_cq *cq,
			      struct ibv_cq_init_attr_ex *ex,
			      struct ionic_pd *pd,
			      struct ionic_qdesc *req_cq)
{
	int rc;

	cq->vcq = vcq;

	cq->lockfree = pd ? ionic_pd_lockfree(&pd->ibpd) : false;
	pthread_spin_init(&cq->lock, PTHREAD_PROCESS_PRIVATE);
	list_head_init(&cq->poll_sq);
	list_head_init(&cq->poll_rq);
	list_head_init(&cq->flush_sq);
	list_head_init(&cq->flush_rq);

	rc = ionic_queue_init(&cq->q, pd, IONIC_PD_TAG_CQ,
			      ctx->pg_shift, ex->cqe + IONIC_CQ_GRACE,
			      sizeof(struct ionic_v1_cqe));
	if (rc)
		goto err_queue;

	cq->color = true;
	cq->reserve = cq->q.mask;
	cq->reserve_pending = 0;

	req_cq->addr = (uintptr_t)cq->q.ptr;
	req_cq->size = cq->q.size;
	req_cq->mask = cq->q.mask;
	req_cq->depth_log2 = cq->q.depth_log2;
	req_cq->stride_log2 = cq->q.stride_log2;

	return 0;

err_queue:
	pthread_spin_destroy(&cq->lock);

	return rc;
}

static void ionic_vcq_cq_init2(struct ionic_cq *cq, uint32_t resp_cqid)
{
	cq->cqid = resp_cqid;

	ionic_queue_dbell_init(&cq->q, cq->cqid);
}

static uint64_t ionic_phc_ts_to_ns(struct ionic_phc *phc, uint64_t ts)
{
	uint64_t dt, dt_sign, ns;

	dt = (ts - phc->cycles) & phc->mask;
	dt_sign = phc->mask ^ (phc->mask >> 1);

	ns = phc->nsec;

	if (dt & dt_sign) {
		dt = -dt & phc->mask;
		ns -= ((dt * phc->mult) - phc->frac) >> phc->shift;
	} else {
		ns += ((dt * phc->mult) + phc->frac) >> phc->shift;
	}

	return ns;
}

/*
 * NOTE: ionic_start_poll, ionic_next_poll and ionic_end_poll provide a
 * minimal implementations of the ibv_cq_ex polling mechanism, sufficient to
 * make functional tests pass but not performant. The intention of the API is
 * that start_poll should take any required locks, next_poll should assume the
 * locks are held and end_poll should release them.
 */
static int ionic_start_poll(struct ibv_cq_ex *ibcq_ex, struct ibv_poll_cq_attr *attr)
{
	struct ibv_cq *ibcq = ibv_cq_ex_to_cq(ibcq_ex);
	struct ionic_vcq *vcq = to_ionic_vcq(ibcq);
	int rc;

	if (!vcq->cur_wc_pending) {
		rc = ionic_poll_cq(ibcq, 1, &vcq->cur_wc);

		if (rc != 1) /* no completions ready or poll failed */
			return (rc == 0) ? ENOENT : rc;

		ibcq_ex->wr_id = vcq->cur_wc.wr_id;
		ibcq_ex->status = vcq->cur_wc.status;

		/* if there is an error after polling the cur_wc,
		 * don't replace it in the next call to start.
		 */
		vcq->cur_wc_pending = true;
	}

	if (vcq->phc_update) {
		struct ionic_ctx *ctx = to_ionic_ctx(ibcq->context);

		rc = ionic_phc_update(&vcq->phc, ctx->phc_state);
		if (rc)
			return rc;
	}

	/* success, so the next call to start should replace cur_wc */
	vcq->cur_wc_pending = false;

	return 0;
}

static int ionic_next_poll(struct ibv_cq_ex *ibcq_ex)
{
	return ionic_start_poll(ibcq_ex, NULL);
}

static void ionic_end_poll(struct ibv_cq_ex *ibcq_ex)
{
	/* nothing to do here */
}

static enum ibv_wc_opcode ionic_wc_read_opcode(struct ibv_cq_ex *ibcq_ex)
{
	struct ibv_cq *ibcq = ibv_cq_ex_to_cq(ibcq_ex);
	struct ionic_vcq *vcq = to_ionic_vcq(ibcq);

	return vcq->cur_wc.opcode;
}

static uint32_t ionic_wc_read_vendor_err(struct ibv_cq_ex *ibcq_ex)
{
	struct ibv_cq *ibcq = ibv_cq_ex_to_cq(ibcq_ex);
	struct ionic_vcq *vcq = to_ionic_vcq(ibcq);

	return vcq->cur_wc.vendor_err;
}

static uint32_t ionic_wc_read_byte_len(struct ibv_cq_ex *ibcq_ex)
{
	struct ibv_cq *ibcq = ibv_cq_ex_to_cq(ibcq_ex);
	struct ionic_vcq *vcq = to_ionic_vcq(ibcq);

	return vcq->cur_wc.byte_len;
}

static __be32 ionic_wc_read_imm_data(struct ibv_cq_ex *ibcq_ex)
{
	struct ibv_cq *ibcq = ibv_cq_ex_to_cq(ibcq_ex);
	struct ionic_vcq *vcq = to_ionic_vcq(ibcq);

	return vcq->cur_wc.imm_data;
}

static uint32_t ionic_wc_read_qp_num(struct ibv_cq_ex *ibcq_ex)
{
	struct ibv_cq *ibcq = ibv_cq_ex_to_cq(ibcq_ex);
	struct ionic_vcq *vcq = to_ionic_vcq(ibcq);

	return vcq->cur_wc.qp_num;
}

static uint32_t ionic_wc_read_src_qp(struct ibv_cq_ex *ibcq_ex)
{
	struct ibv_cq *ibcq = ibv_cq_ex_to_cq(ibcq_ex);
	struct ionic_vcq *vcq = to_ionic_vcq(ibcq);

	return vcq->cur_wc.src_qp;
}

static unsigned int ionic_wc_read_wc_flags(struct ibv_cq_ex *ibcq_ex)
{
	struct ibv_cq *ibcq = ibv_cq_ex_to_cq(ibcq_ex);
	struct ionic_vcq *vcq = to_ionic_vcq(ibcq);

	return vcq->cur_wc.wc_flags;
}

static uint8_t ionic_wc_read_sl(struct ibv_cq_ex *ibcq_ex)
{
	struct ibv_cq *ibcq = ibv_cq_ex_to_cq(ibcq_ex);
	struct ionic_vcq *vcq = to_ionic_vcq(ibcq);

	return vcq->cur_wc.sl;
}

static uint32_t ionic_wc_read_slid(struct ibv_cq_ex *ibcq_ex)
{
	struct ibv_cq *ibcq = ibv_cq_ex_to_cq(ibcq_ex);
	struct ionic_vcq *vcq = to_ionic_vcq(ibcq);

	return vcq->cur_wc.slid;
}

static uint8_t ionic_wc_read_dlid_path_bits(struct ibv_cq_ex *ibcq_ex)
{
	struct ibv_cq *ibcq = ibv_cq_ex_to_cq(ibcq_ex);
	struct ionic_vcq *vcq = to_ionic_vcq(ibcq);

	return vcq->cur_wc.dlid_path_bits;
}

static uint64_t ionic_wc_read_completion_ts(struct ibv_cq_ex *ibcq_ex)
{
	struct ibv_cq *ibcq = ibv_cq_ex_to_cq(ibcq_ex);
	struct ionic_vcq *vcq = to_ionic_vcq(ibcq);

	return vcq->cur_wc_timestamp;
}

static uint64_t ionic_wc_read_completion_wallclock_ns(struct ibv_cq_ex *ibcq_ex)
{
	struct ibv_cq *ibcq = ibv_cq_ex_to_cq(ibcq_ex);
	struct ionic_vcq *vcq = to_ionic_vcq(ibcq);

	return ionic_phc_ts_to_ns(&vcq->phc, vcq->cur_wc_timestamp);
}

static struct ibv_cq_ex *ionic_create_cq_ex(struct ibv_context *ibctx,
					    struct ibv_cq_init_attr_ex *ex)
{
	struct ionic_ctx *ctx = to_ionic_ctx(ibctx);
	struct ionic_pd *pd = NULL;
	struct ionic_vcq *vcq;
	struct uionic_cq req = {};
	struct uionic_cq_resp resp = {};
	int cq_i, rc;

	if (ex->wc_flags & ~IONIC_CQ_SUPPORTED_WC_FLAGS) {
		rc = ENOTSUP;
		goto err;
	}

	if (ex->cqe < 1 || ex->cqe + IONIC_CQ_GRACE > 0xffff) {
		rc = EINVAL;
		goto err;
	}

	vcq = calloc(1, sizeof(*vcq));
	if (!vcq) {
		rc = ENOMEM;
		goto err;
	}

	if (ex->comp_mask & IBV_CQ_INIT_ATTR_MASK_PD) {
		pd = to_ionic_pd(ex->parent_domain);
		vcq->udma_mask = pd->udma_mask;
	} else {
		vcq->udma_mask = ionic_ctx_udma_mask(ctx);
	}

	for (cq_i = 0; cq_i < ctx->udma_count; ++cq_i) {
		if (!(vcq->udma_mask & BIT(cq_i)))
			continue;

		rc = ionic_vcq_cq_init1(ctx, vcq, &vcq->cq[cq_i], ex, pd, &req.cq[cq_i]);
		if (rc)
			goto err_cq;
	}

	req.udma_mask = vcq->udma_mask;

	rc = ibv_cmd_create_cq(ibctx, ex->cqe, ex->channel,
			       ex->comp_vector, &vcq->vcq.cq,
			       &req.ibv_cmd, sizeof(req),
			       &resp.ibv_resp, sizeof(resp));
	if (rc)
		goto err_cmd;

	if (resp.udma_mask != vcq->udma_mask) {
		rc = EINVAL;
		goto err_udma;
	}

	for (cq_i = 0; cq_i < ctx->udma_count; ++cq_i) {
		if (!(vcq->udma_mask & BIT(cq_i)))
			continue;

		ionic_vcq_cq_init2(&vcq->cq[cq_i], resp.cqid[cq_i]);
	}

	vcq->vcq.cq_ex.start_poll = ionic_start_poll;
	vcq->vcq.cq_ex.next_poll = ionic_next_poll;
	vcq->vcq.cq_ex.end_poll = ionic_end_poll;

	vcq->vcq.cq_ex.read_opcode = ionic_wc_read_opcode;
	vcq->vcq.cq_ex.read_vendor_err = ionic_wc_read_vendor_err;
	vcq->vcq.cq_ex.read_wc_flags = ionic_wc_read_wc_flags;

	if (ex->wc_flags & IBV_WC_EX_WITH_BYTE_LEN)
		vcq->vcq.cq_ex.read_byte_len = ionic_wc_read_byte_len;
	if (ex->wc_flags & IBV_WC_EX_WITH_IMM)
		vcq->vcq.cq_ex.read_imm_data = ionic_wc_read_imm_data;
	if (ex->wc_flags & IBV_WC_EX_WITH_QP_NUM)
		vcq->vcq.cq_ex.read_qp_num = ionic_wc_read_qp_num;
	if (ex->wc_flags & IBV_WC_EX_WITH_SRC_QP)
		vcq->vcq.cq_ex.read_src_qp = ionic_wc_read_src_qp;
	if (ex->wc_flags & IBV_WC_EX_WITH_SL)
		vcq->vcq.cq_ex.read_sl = ionic_wc_read_sl;
	if (ex->wc_flags & IBV_WC_EX_WITH_SLID)
		vcq->vcq.cq_ex.read_slid = ionic_wc_read_slid;
	if (ex->wc_flags & IBV_WC_EX_WITH_DLID_PATH_BITS)
		vcq->vcq.cq_ex.read_dlid_path_bits = ionic_wc_read_dlid_path_bits;
	if (ex->wc_flags & IBV_WC_EX_WITH_COMPLETION_TIMESTAMP) {
		if (!ctx->phc_state) {
			rc = EOPNOTSUPP;
			goto err_udma;
		}
		vcq->vcq.cq_ex.read_completion_ts = ionic_wc_read_completion_ts;
	}
	if (ex->wc_flags & IBV_WC_EX_WITH_COMPLETION_TIMESTAMP_WALLCLOCK) {
		if (!ctx->phc_state) {
			rc = EOPNOTSUPP;
			goto err_udma;
		}

		vcq->phc_update = true;
		vcq->vcq.cq_ex.read_completion_wallclock_ns =
			ionic_wc_read_completion_wallclock_ns;
	}

	return &vcq->vcq.cq_ex;

err_udma:
	(void)ibv_cmd_destroy_cq(&vcq->vcq.cq);
err_cmd:
	while (cq_i) {
		--cq_i;
		if (!(vcq->udma_mask & BIT(cq_i)))
			continue;
		ionic_vcq_cq_deinit(&vcq->cq[cq_i]);
err_cq:
		;
	}
	free(vcq);
err:
	errno = rc;
	return NULL;
}

static struct ibv_cq *ionic_create_cq(struct ibv_context *ibctx, int ncqe,
				      struct ibv_comp_channel *channel,
				      int vec)
{
	struct ibv_cq_init_attr_ex ex = {
		.cqe = ncqe,
		.channel = channel,
		.comp_vector = vec,
	};
	struct ibv_cq_ex *ibcq;

	if (ncqe < 0) {
		errno = EINVAL;
		return NULL;
	}

	ibcq = ionic_create_cq_ex(ibctx, &ex);

	return ibv_cq_ex_to_cq(ibcq);
}

static int ionic_destroy_cq(struct ibv_cq *ibcq)
{
	struct ionic_ctx *ctx = to_ionic_ctx(ibcq->context);
	struct ionic_vcq *vcq = to_ionic_vcq(ibcq);
	int cq_i, rc;

	rc = ibv_cmd_destroy_cq(ibcq);
	if (rc)
		return rc;

	for (cq_i = ctx->udma_count; cq_i;) {
		--cq_i;

		if (!(vcq->udma_mask & BIT(cq_i)))
			continue;

		ionic_vcq_cq_deinit(&vcq->cq[cq_i]);
	}

	free(vcq);

	return 0;
}

static int ionic_flush_recv(struct ionic_qp *qp, struct ibv_wc *wc)
{
	struct ionic_rq_meta *meta;
	struct ionic_v1_wqe *wqe;
	struct ionic_ctx *ctx;
	uint64_t wqe_idx;

	if (!qp->rq.flush)
		return 0;

	if (ionic_queue_empty(&qp->rq.queue))
		return 0;

	wqe = ionic_queue_at_cons(&qp->rq.queue);
	wqe_idx = le64toh(wqe->base.wqe_idx);
	ctx = to_ionic_ctx(qp->vqp.qp.context);

	/* wqe_idx must be a valid queue index */
	if (unlikely(wqe_idx >> qp->rq.queue.depth_log2)) {
		verbs_err(&ctx->vctx, "invalid id %#lx", (unsigned long)wqe_idx);
		return -EIO;
	}

	/* wqe_idx must indicate a request that is outstanding */
	meta = &qp->rq.meta[wqe_idx];
	if (unlikely(meta->next != IONIC_META_POSTED)) {
		verbs_err(&ctx->vctx, "wqe not posted %#lx", (unsigned long)wqe_idx);
		return -EIO;
	}

	ionic_queue_consume(&qp->rq.queue);

	memset(wc, 0, sizeof(*wc));

	wc->status = IBV_WC_WR_FLUSH_ERR;
	wc->wr_id = meta->wrid;
	wc->qp_num = qp->qpid;

	meta->next = qp->rq.meta_head;
	qp->rq.meta_head = meta;

	return 1;
}

static int ionic_flush_recv_many(struct ionic_qp *qp,
				 struct ibv_wc *wc, int nwc)
{
	int rc = 0, npolled = 0;

	while (npolled < nwc) {
		rc = ionic_flush_recv(qp, wc + npolled);
		if (rc <= 0)
			break;

		npolled += rc;
	}

	return npolled ?: rc;
}

static int ionic_flush_send(struct ionic_qp *qp, struct ibv_wc *wc)
{
	struct ionic_sq_meta *meta;

	if (!qp->sq.flush)
		return 0;

	if (ionic_queue_empty(&qp->sq.queue))
		return 0;

	meta = &qp->sq.meta[qp->sq.queue.cons];

	ionic_queue_consume(&qp->sq.queue);

	memset(wc, 0, sizeof(*wc));

	wc->status = IBV_WC_WR_FLUSH_ERR;
	wc->wr_id = meta->wrid;
	wc->qp_num = qp->qpid;

	return 1;
}

static int ionic_flush_send_many(struct ionic_qp *qp,
				 struct ibv_wc *wc, int nwc)
{
	int rc = 0, npolled = 0;

	while (npolled < nwc) {
		rc = ionic_flush_send(qp, wc + npolled);
		if (rc <= 0)
			break;

		npolled += rc;
	}

	return npolled ?: rc;
}

static int ionic_poll_recv(struct ionic_ctx *ctx, struct ionic_cq *cq,
			   struct ionic_qp *cqe_qp, struct ionic_v1_cqe *cqe,
			   struct ibv_wc *wc)
{
	struct ionic_qp *qp = NULL;
	struct ionic_rq_meta *meta;
	uint64_t wqe_idx_timestamp;
	uint16_t vlan_tag, wqe_idx;
	uint32_t src_qpn, st_len;
	uint8_t op;

	if (cqe_qp->rq.flush)
		return 0;

	qp = cqe_qp;

	st_len = be32toh(cqe->status_length);

	/* ignore wqe_idx in case of flush error */
	if (ionic_v1_cqe_error(cqe) && st_len == IONIC_STS_WQE_FLUSHED_ERR) {
		cqe_qp->rq.flush = true;
		cq->flush = true;
		list_del(&cqe_qp->cq_flush_rq);
		list_add_tail(&cq->flush_rq, &cqe_qp->cq_flush_rq);

		/* posted recvs (if any) flushed by ionic_flush_recv */
		return 0;
	}

	/* there had better be something in the recv queue to complete */
	if (ionic_queue_empty(&qp->rq.queue)) {
		verbs_err(&ctx->vctx, "rq is empty %u", qp->qpid);
		return -EIO;
	}

	wqe_idx_timestamp = le64toh(cqe->recv.wqe_idx_timestamp);
	wqe_idx = wqe_idx_timestamp & IONIC_V1_CQE_WQE_IDX_MASK;

	/* wqe_idx must be a valid queue index */
	if (unlikely(wqe_idx >> qp->rq.queue.depth_log2)) {
		verbs_err(&ctx->vctx, "invalid id %#lx", (unsigned long)wqe_idx);
		return -EIO;
	}

	/* wqe_idx must indicate a request that is outstanding */
	meta = &qp->rq.meta[qp->rq.meta_idx[wqe_idx]];
	if (unlikely(meta->next != IONIC_META_POSTED)) {
		verbs_err(&ctx->vctx, "wqe is not posted for idx %lu meta_idx %u qpid %u rq.prod %u rq.cons %u cqid %u",
			  (unsigned long)wqe_idx,
			  qp->rq.meta_idx[wqe_idx],
			  qp->qpid, qp->rq.queue.prod,
			  qp->rq.queue.cons, cq->cqid);
		return -EIO;
	}

	meta->next = qp->rq.meta_head;
	qp->rq.meta_head = meta;
	cq->vcq->cur_wc_timestamp = wqe_idx_timestamp >> IONIC_V1_CQE_TIMESTAMP_SHIFT;

	memset(wc, 0, sizeof(*wc));

	wc->wr_id = meta->wrid;
	wc->qp_num = cqe_qp->qpid;

	if (ionic_v1_cqe_error(cqe)) {
		wc->vendor_err = st_len;
		wc->status = ionic_to_ibv_status(st_len);

		cqe_qp->rq.flush = true;
		cq->flush = true;
		list_del(&cqe_qp->cq_flush_rq);
		list_add_tail(&cq->flush_rq, &cqe_qp->cq_flush_rq);

		verbs_err(&ctx->vctx, "cqe with error %u for %#x (recv), qpid %u cqid %u",
			  wc->status, be32toh(cqe->send.msg_msn),
			  qp->qpid, cq->cqid);

		goto out;
	}

	wc->vendor_err = 0;
	wc->status = IBV_WC_SUCCESS;

	src_qpn = be32toh(cqe->recv.src_qpn_op);
	op = src_qpn >> IONIC_V1_CQE_RECV_OP_SHIFT;

	src_qpn &= IONIC_V1_CQE_RECV_QPN_MASK;
	op &= IONIC_V1_CQE_RECV_OP_MASK;

	wc->opcode = IBV_WC_RECV;
	switch (op) {
	case IONIC_V1_CQE_RECV_OP_RDMA_IMM:
		wc->opcode = IBV_WC_RECV_RDMA_WITH_IMM;
		SWITCH_FALLTHROUGH;
	case IONIC_V1_CQE_RECV_OP_SEND_IMM:
		wc->wc_flags |= IBV_WC_WITH_IMM;
		wc->imm_data = cqe->recv.imm_data_rkey; /* be32 in wc */
		break;
	case IONIC_V1_CQE_RECV_OP_SEND_INV:
		wc->wc_flags |= IBV_WC_WITH_INV;
		wc->invalidated_rkey = be32toh(cqe->recv.imm_data_rkey);
	}

	wc->byte_len = st_len;
	wc->src_qp = src_qpn;

	if (qp->vqp.qp.qp_type == IBV_QPT_UD) {
		wc->wc_flags |= IBV_WC_GRH;

		/* vlan_tag in cqe will be valid from dpath even if no vlan */
		vlan_tag = be16toh(cqe->recv.vlan_tag);
		wc->sl = vlan_tag >> 13; /* 802.1q PCP */
	}

	wc->pkey_index = 0;

out:
	verbs_debug(&ctx->vctx,  "poll cq %u qp %u cons %u st %u wrid %" PRIx64 " op %u len %u",
		    cq->cqid, qp->qpid, qp->rq.queue.cons, wc->status,
		    meta->wrid, wc->opcode, st_len);
	cq->reserve_pending++;
	ionic_queue_consume(&qp->rq.queue);

	return 1;
}

static bool ionic_peek_send(struct ionic_qp *qp)
{
	struct ionic_sq_meta *meta;

	if (qp->sq.flush)
		return 0;

	/* completed all send queue requests? */
	if (ionic_queue_empty(&qp->sq.queue))
		return false;

	meta = &qp->sq.meta[qp->sq.queue.cons];

	/* waiting for remote completion? */
	if (meta->remote && meta->seq == qp->sq.msn_cons)
		return false;

	/* waiting for local completion? */
	if (!meta->remote && !meta->local_comp)
		return false;

	return true;
}

static int ionic_poll_send(struct ionic_ctx *ctx,
			   struct ionic_cq *cq,
			   struct ionic_qp *qp,
			   struct ibv_wc *wc)
{
	struct ionic_sq_meta *meta;

	if (qp->sq.flush)
		return 0;

	do {
		/* completed all send queue requests? */
		if (ionic_queue_empty(&qp->sq.queue))
			goto out_empty;

		meta = &qp->sq.meta[qp->sq.queue.cons];

		/* waiting for remote completion? */
		if (meta->remote && meta->seq == qp->sq.msn_cons)
			goto out_empty;

		/* waiting for local completion? */
		if (!meta->remote && !meta->local_comp)
			goto out_empty;

		verbs_debug(&ctx->vctx, "poll cq %u qp %u cons %u st %u wr %" PRIx64 " op %u l %u",
			    cq->cqid, qp->qpid, qp->sq.queue.cons, meta->ibsts,
			    meta->wrid, meta->ibop, meta->len);
		cq->reserve_pending++;
		ionic_queue_consume(&qp->sq.queue);

		/* produce wc only if signaled or error status */
	} while (!meta->signal && meta->ibsts == IBV_WC_SUCCESS);

	cq->vcq->cur_wc_timestamp = meta->cqe_timestamp;

	memset(wc, 0, sizeof(*wc));

	wc->status = meta->ibsts;
	wc->wr_id = meta->wrid;
	wc->qp_num = qp->qpid;

	if (meta->ibsts == IBV_WC_SUCCESS) {
		wc->byte_len = meta->len;
		wc->opcode = meta->ibop;
	} else {
		wc->vendor_err = meta->len;

		qp->sq.flush = true;
		cq->flush = true;
		list_del(&qp->cq_flush_sq);
		list_add_tail(&cq->flush_sq, &qp->cq_flush_sq);
	}

	return 1;

out_empty:
	if (qp->sq.flush_rcvd) {
		qp->sq.flush = true;
		cq->flush = true;
		list_del(&qp->cq_flush_sq);
		list_add_tail(&cq->flush_sq, &qp->cq_flush_sq);
	}
	return 0;
}

static int ionic_poll_send_many(struct ionic_ctx *ctx,
				struct ionic_cq *cq,
				struct ionic_qp *qp,
				struct ibv_wc *wc, int nwc)
{
	int rc = 0, npolled = 0;

	while (npolled < nwc) {
		rc = ionic_poll_send(ctx, cq, qp, wc + npolled);
		if (rc <= 0)
			break;

		npolled += rc;
	}

	return npolled ?: rc;
}

static int ionic_validate_cons(uint16_t prod, uint16_t cons,
			       uint16_t comp, uint16_t mask)
{
	if (((prod - cons) & mask) <= ((comp - cons) & mask))
		return -EIO;

	return 0;
}

static int ionic_comp_msn(struct ionic_ctx *ctx,
			  struct ionic_qp *qp,
			  struct ionic_v1_cqe *cqe)
{
	struct ionic_sq_meta *meta;
	uint16_t cqe_seq, cqe_idx;
	uint64_t timestamp;
	int rc;

	if (qp->sq.flush)
		return 0;

	cqe_seq = be32toh(cqe->send.msg_msn) & qp->sq.queue.mask;

	rc = ionic_validate_cons(qp->sq.msn_prod,
				 qp->sq.msn_cons,
				 cqe_seq - 1,
				 qp->sq.queue.mask);
	if (rc) {
		struct ionic_cq *cq =
			to_ionic_vcq_cq(qp->vqp.qp.send_cq, qp->udma_idx);

		verbs_err(&ctx->vctx, "wqe is not posted for %#x (msn), qpid %u cqid %u seq %u for prod %u cons %u\n",
			  be32toh(cqe->send.msg_msn), qp->qpid, cq->cqid,
			  cqe_seq, qp->sq.msn_prod, qp->sq.msn_cons);
		return rc;
	}

	timestamp = le64toh(cqe->send.npg_wqe_idx_timestamp) >> IONIC_V1_CQE_TIMESTAMP_SHIFT;

	for (cqe_idx = qp->sq.msn_cons;
	     cqe_idx != cqe_seq;
	     cqe_idx = ionic_queue_next(&qp->sq.queue, cqe_idx)) {
		meta = &qp->sq.meta[cqe_idx];
		if (meta->remote)
			meta->cqe_timestamp = timestamp;
	}

	qp->sq.msn_cons = cqe_seq;

	if (ionic_v1_cqe_error(cqe)) {
		struct ionic_cq *cq =
			to_ionic_vcq_cq(qp->vqp.qp.send_cq, qp->udma_idx);

		cqe_idx = qp->sq.msn_idx[(cqe_seq - 1) & qp->sq.queue.mask];

		meta = &qp->sq.meta[cqe_idx];
		meta->len = be32toh(cqe->status_length);
		meta->ibsts = ionic_to_ibv_status(meta->len);

		verbs_err(&ctx->vctx, "cqe with error %u for %#x (msn), qpid %u cqid %u",
			  meta->ibsts, be32toh(cqe->send.msg_msn),
			  qp->qpid, cq->cqid);
	}

	return 0;
}

static int ionic_comp_npg(struct ionic_ctx *ctx,
			  struct ionic_qp *qp,
			  struct ionic_v1_cqe *cqe)
{
	struct ionic_sq_meta *meta;
	uint64_t wqe_idx_timestamp;
	uint16_t wqe_idx;
	uint32_t st_len;

	if (qp->sq.flush)
		return 0;

	st_len = be32toh(cqe->status_length);

	if (ionic_v1_cqe_error(cqe) && st_len == IONIC_STS_WQE_FLUSHED_ERR) {
		/* Flush cqe does not consume a wqe on the device, and maybe
		 * no such work request is posted.
		 *
		 * The driver should begin flushing after the last indicated
		 * normal or error completion.  Here, only set a hint that the
		 * flush request was indicated.  In poll_send, if nothing more
		 * can be polled normally, then begin flushing.
		 */
		qp->sq.flush_rcvd = true;
		return 0;
	}

	wqe_idx_timestamp = le64toh(cqe->send.npg_wqe_idx_timestamp);
	wqe_idx = wqe_idx_timestamp & qp->sq.queue.mask;
	meta = &qp->sq.meta[wqe_idx];
	meta->local_comp = true;
	meta->cqe_timestamp = wqe_idx_timestamp >> IONIC_V1_CQE_TIMESTAMP_SHIFT;

	if (ionic_v1_cqe_error(cqe)) {
		struct ionic_cq *cq =
			to_ionic_vcq_cq(qp->vqp.qp.send_cq, qp->udma_idx);

		meta->len = st_len;
		meta->ibsts = ionic_to_ibv_status(st_len);
		meta->remote = false;
		verbs_err(&ctx->vctx, "cqe with error %s for %#x (npg), qpid %u cqid %u",
			  ibv_wc_status_str(meta->ibsts),
			  be32toh(cqe->send.msg_msn),
			  qp->qpid, cq->cqid);
	}

	return 0;
}

static bool ionic_next_cqe(struct ionic_ctx *ctx,
			   struct ionic_cq *cq,
			   struct ionic_v1_cqe **cqe)
{
	struct ionic_v1_cqe *qcqe = ionic_queue_at_prod(&cq->q);

	if (unlikely(cq->color != ionic_v1_cqe_color(qcqe)))
		return false;

	udma_from_device_barrier();

	ionic_dbg_xdump(ctx, "cqe", qcqe, 1u << cq->q.stride_log2);
	*cqe = qcqe;

	return true;
}

static void ionic_clean_cq(struct ionic_cq *cq, uint32_t qpid)
{
	struct ionic_v1_cqe *qcqe;
	int prod, qtf, qid;
	bool color;

	color = cq->color;
	prod = cq->q.prod;
	qcqe = ionic_queue_at(&cq->q, prod);

	while (color == ionic_v1_cqe_color(qcqe)) {
		qtf = ionic_v1_cqe_qtf(qcqe);
		qid = ionic_v1_cqe_qtf_qid(qtf);

		if (qid == qpid)
			ionic_v1_cqe_clean(qcqe);

		prod = ionic_queue_next(&cq->q, prod);
		qcqe = ionic_queue_at(&cq->q, prod);
		color = ionic_color_wrap(prod, color);
	}
}

static void ionic_reserve_sync_cq(struct ionic_ctx *ctx, struct ionic_cq *cq)
{
	if (!ionic_queue_empty(&cq->q)) {
		cq->reserve += cq->reserve_pending;
		cq->reserve_pending = 0;
		cq->q.cons = cq->q.prod;

		verbs_debug(&ctx->vctx, "dbell cq %u val %" PRIx64 " rsv %d",
			    cq->cqid, ionic_queue_dbell_val(&cq->q),
			    cq->reserve);
		ionic_dbell_ring(&ctx->dbpage[ctx->cq_qtype],
				 ionic_queue_dbell_val(&cq->q));
	}
}

static void ionic_arm_cq(struct ionic_ctx *ctx, struct ionic_cq *cq)
{
	uint64_t dbell_val = cq->q.dbell;

	if (cq->deferred_arm_sol_only) {
		cq->arm_sol_prod = ionic_queue_next(&cq->q, cq->arm_sol_prod);
		dbell_val |= cq->arm_sol_prod | IONIC_DBELL_RING_SONLY;
	} else {
		cq->arm_any_prod = ionic_queue_next(&cq->q, cq->arm_any_prod);
		dbell_val |= cq->arm_any_prod | IONIC_DBELL_RING_ARM;
	}

	verbs_debug(&ctx->vctx, "dbell cq %u val %" PRIx64 " (%s)",
		    cq->cqid, dbell_val,
		    cq->deferred_arm_sol_only ? "sonly" : "arm");
	ionic_dbell_ring(&ctx->dbpage[ctx->cq_qtype], dbell_val);
}

static void ionic_reserve_cq(struct ionic_ctx *ctx, struct ionic_cq *cq,
			     int spend)
{
	cq->reserve -= spend;

	if (cq->reserve <= 0 || cq->deferred_arm)
		ionic_reserve_sync_cq(ctx, cq);

	if (cq->deferred_arm) {
		ionic_arm_cq(ctx, cq);
		cq->deferred_arm = false;
	}
}

static int ionic_poll_vcq_cq(struct ionic_ctx *ctx, struct ionic_cq *cq,
			     int nwc, struct ibv_wc *wc)
{
	struct ionic_qp *qp, *qp_next;
	struct ionic_v1_cqe *cqe;
	uint32_t qtf, qid;
	uint8_t type;
	bool peek;
	int rc = 0, npolled = 0;
	uint16_t old_prod;

	if (nwc < 1)
		return 0;

	ionic_cq_spin_lock(cq);
	++cq->cqseq;

	old_prod = cq->q.prod;

	/* poll already indicated work completions for send queue */

	list_for_each_safe(&cq->poll_sq, qp, qp_next, cq_poll_sq) {
		if (npolled == nwc)
			goto out;

		ionic_sq_spin_lock(qp);
		rc = ionic_poll_send_many(ctx, cq, qp, wc + npolled, nwc - npolled);
		peek = ionic_peek_send(qp);
		ionic_sq_spin_unlock(qp);

		if (rc < 0)
			goto out;

		npolled += rc;

		if (!peek)
			list_del_init(&qp->cq_poll_sq);
	}

	/* poll for more work completions */

	while (likely(ionic_next_cqe(ctx, cq, &cqe))) {
		if (npolled == nwc)
			goto out;

		qtf = ionic_v1_cqe_qtf(cqe);
		qid = ionic_v1_cqe_qtf_qid(qtf);
		type = ionic_v1_cqe_qtf_type(qtf);

		qp = ionic_tbl_lookup(&ctx->qp_tbl, qid);

		if (unlikely(!qp)) {
			verbs_err(&ctx->vctx, "cq %d pos %d missing qp for qid %#x",
				  cq->cqid, cq->q.prod, qid);
			goto cq_next;
		}

		switch (type) {
		case IONIC_V1_CQE_TYPE_RECV:
			ionic_rq_spin_lock(qp);
			rc = ionic_poll_recv(ctx, cq, qp, cqe, wc + npolled);
			ionic_rq_spin_unlock(qp);

			if (rc < 0)
				goto out;

			npolled += rc;
			break;

		case IONIC_V1_CQE_TYPE_SEND_MSN:
			ionic_sq_spin_lock(qp);
			rc = ionic_comp_msn(ctx, qp, cqe);
			if (!rc) {
				rc = ionic_poll_send_many(ctx, cq, qp,
							  wc + npolled,
							  nwc - npolled);
				peek = ionic_peek_send(qp);
			}
			ionic_sq_spin_unlock(qp);

			if (rc < 0)
				goto out;

			npolled += rc;

			if (peek) {
				list_del(&qp->cq_poll_sq);
				list_add_tail(&cq->poll_sq, &qp->cq_poll_sq);
			}

			break;

		case IONIC_V1_CQE_TYPE_SEND_NPG:
			ionic_sq_spin_lock(qp);
			rc = ionic_comp_npg(ctx, qp, cqe);
			if (!rc) {
				rc = ionic_poll_send_many(ctx, cq, qp,
							  wc + npolled,
							  nwc - npolled);
				peek = ionic_peek_send(qp);
			}
			ionic_sq_spin_unlock(qp);

			if (rc < 0)
				goto out;

			npolled += rc;

			if (peek) {
				list_del(&qp->cq_poll_sq);
				list_add_tail(&cq->poll_sq, &qp->cq_poll_sq);
			}

			break;

		case IONIC_V1_CQE_TYPE_RECV_INDIR:
			list_del(&qp->cq_poll_rq);
			list_add_tail(&cq->poll_rq, &qp->cq_poll_rq);
			break;

		default:
			verbs_err(&ctx->vctx, "unexpected cqe type %u", type);
			rc = -EIO;
			goto out;
		}

cq_next:
		ionic_queue_produce(&cq->q);
		cq->color = ionic_color_wrap(cq->q.prod, cq->color);
	}

	/* lastly, flush send and recv queues */
	if (likely(!cq->flush))
		goto out;

	cq->flush = false;

	list_for_each_safe(&cq->flush_sq, qp, qp_next, cq_flush_sq) {
		if (npolled == nwc)
			goto out;

		ionic_sq_spin_lock(qp);
		rc = ionic_flush_send_many(qp, wc + npolled, nwc - npolled);
		ionic_sq_spin_unlock(qp);

		if (rc > 0)
			npolled += rc;

		if (npolled < nwc)
			list_del_init(&qp->cq_flush_sq);
		else
			cq->flush = true;
	}

	list_for_each_safe(&cq->flush_rq, qp, qp_next, cq_flush_rq) {
		if (npolled == nwc)
			goto out;

		ionic_rq_spin_lock(qp);
		rc = ionic_flush_recv_many(qp, wc + npolled, nwc - npolled);
		ionic_rq_spin_unlock(qp);

		if (rc > 0)
			npolled += rc;

		if (npolled < nwc)
			list_del_init(&qp->cq_flush_rq);
		else
			cq->flush = true;
	}

out:
	ionic_reserve_cq(ctx, cq, 0);

	old_prod = (cq->q.prod - old_prod) & cq->q.mask;

	ionic_cq_spin_unlock(cq);

	return npolled ?: rc;
}

/*
 * Note about rc: (noted here because poll is different)
 *
 * Functions without "poll" in the name, if they return an integer, return
 * zero on success, or a positive error number.  Functions returning a
 * pointer return NULL on error and set errno to a positive error number.
 *
 * Functions with "poll" in the name return negative error numbers, or
 * greater or equal to zero number of completions on success.
 */
static int ionic_poll_cq(struct ibv_cq *ibcq, int nwc, struct ibv_wc *wc)
{
	struct ionic_ctx *ctx = to_ionic_ctx(ibcq->context);
	struct ionic_vcq *vcq = to_ionic_vcq(ibcq);
	int rc_tmp, rc = 0, npolled = 0;
	int cq_i, cq_x, cq_ix;

	cq_x = vcq->poll_idx;

	vcq->poll_idx ^= ctx->udma_count - 1;

	for (cq_i = 0; npolled < nwc && cq_i < ctx->udma_count; ++cq_i) {
		cq_ix = cq_i ^ cq_x;

		if (!(vcq->udma_mask & BIT(cq_ix)))
			continue;

		rc_tmp = ionic_poll_vcq_cq(ctx, &vcq->cq[cq_ix],
					   nwc - npolled, wc + npolled);

		if (rc_tmp >= 0)
			npolled += rc_tmp;
		else if (!rc)
			rc = rc_tmp;
	}

	return npolled ?: rc;
}

static void ionic_req_notify_vcq_cq(struct ionic_cq *cq, int solicited_only)
{
	ionic_cq_spin_lock(cq);

	if (cq->deferred_arm && !cq->deferred_arm_sol_only)
		solicited_only = 0; /* do not downgrade scheduled ARM to SARM */

	cq->deferred_arm = true;
	cq->deferred_arm_sol_only = (bool)solicited_only;

	ionic_cq_spin_unlock(cq);
}

static int ionic_req_notify_cq(struct ibv_cq *ibcq, int solicited_only)
{
	struct ionic_ctx *ctx = to_ionic_ctx(ibcq->context);
	struct ionic_vcq *vcq = to_ionic_vcq(ibcq);
	int cq_i;

	if (!vcq->vcq.cq.channel)
		return -ENOENT;

	for (cq_i = 0; cq_i < ctx->udma_count; ++cq_i) {
		if (!(vcq->udma_mask & BIT(cq_i)))
			continue;

		ionic_req_notify_vcq_cq(&vcq->cq[cq_i], solicited_only);
	}

	return 0;
}

static bool ionic_expdb_wqe_size_supported(struct ionic_ctx *ctx,
					   uint32_t wqe_size)
{
	switch (wqe_size) {
	case 64: return ctx->expdb_mask & IONIC_EXPDB_64;
	case 128: return ctx->expdb_mask & IONIC_EXPDB_128;
	case 256: return ctx->expdb_mask & IONIC_EXPDB_256;
	case 512: return ctx->expdb_mask & IONIC_EXPDB_512;
	}

	return false;
}

static int ionic_set_cmb(struct ionic_ctx *ctx, struct ionic_queue *queue,
			 uint8_t cmb, uint64_t cmb_offset, uint8_t qtype,
			 void **cmb_ptr)
{
	uint64_t db_base, db_data;
	uint16_t wqe_sz, pos;
	__le64 *db_addr;
	void *db_ptr;

	if (!(cmb & IONIC_CMB_ENABLE)) {
		*cmb_ptr = NULL;
		return 0;
	}

	*cmb_ptr = ionic_map_device(queue->size, ctx->vctx.context.cmd_fd,
				    cmb_offset);
	if (!*cmb_ptr)
		return errno;

	if (cmb & IONIC_CMB_EXPDB) {
		/* Pre-fill express doorbells into our buffer */
		wqe_sz = 1 << queue->stride_log2;
		db_ptr = queue->ptr + wqe_sz - IONIC_EXP_DBELL_SZ;

		/* Assume ring 0 */
		db_base = ((uint64_t)qtype << 48) | queue->dbell |
			((0x03 | 0x8) << 19); /* SCHED_SET | PICI_PISET */

		for (pos = 0; pos <= queue->mask; pos++, db_ptr += wqe_sz) {
			db_addr = (__le64 *)db_ptr;
			db_data = db_base | ((pos + 1) & queue->mask);
			*db_addr = htole64(db_data);
		}
	}

	return 0;
}

static int ionic_qp_sq_init(struct ionic_ctx *ctx, struct ionic_qp *qp, struct ionic_pd *pd,
			    int max_wr, int max_sge, int max_data)
{
	uint32_t wqe_size;
	int rc;

	if (!qp->has_sq)
		return 0;

	if (max_wr < 0 || max_wr > 0xffff)
		return EINVAL;
	if (max_sge < 0)
		return EINVAL;
	if (max_sge > ionic_v1_send_wqe_max_sge(ctx->max_stride, 0, false))
		return EINVAL;
	if (max_data < 0)
		return EINVAL;
	if (max_data > ionic_v1_send_wqe_max_data(ctx->max_stride, false))
		return EINVAL;

	qp->sq.spec = ionic_v1_use_spec_sge(max_sge, ctx->spec);

	if (qp->sq.cmb & IONIC_CMB_EXPDB) {
		wqe_size = ionic_v1_send_wqe_min_size(max_sge, max_data,
						      qp->sq.spec, true);

		if (!ionic_expdb_wqe_size_supported(ctx, wqe_size))
			qp->sq.cmb &= ~IONIC_CMB_EXPDB;
	}

	if (!(qp->sq.cmb & IONIC_CMB_EXPDB))
		wqe_size = ionic_v1_send_wqe_min_size(max_sge, max_data,
						      qp->sq.spec, false);

	rc = ionic_queue_init(&qp->sq.queue, pd, IONIC_PD_TAG_SQ,
			      ctx->pg_shift, max_wr, wqe_size);
	if (rc)
		goto err_sq;

	qp->sq.cmb_ptr = NULL;
	qp->sq.cmb_prod = 0;
	qp->sq.color = true;

	qp->sq.meta = calloc((uint32_t)qp->sq.queue.mask + 1,
			     sizeof(*qp->sq.meta));
	if (!qp->sq.meta) {
		rc = ENOMEM;
		goto err_sq_meta;
	}

	qp->sq.msn_idx = calloc((uint32_t)qp->sq.queue.mask + 1,
				sizeof(*qp->sq.msn_idx));
	if (!qp->sq.msn_idx) {
		rc = ENOMEM;
		goto err_sq_msn;
	}

	return 0;

err_sq_msn:
	free(qp->sq.meta);
err_sq_meta:
	ionic_queue_destroy(&qp->sq.queue);
err_sq:
	return rc;
}

static void ionic_qp_sq_destroy(struct ionic_qp *qp)
{
	if (!qp->has_sq)
		return;

	free(qp->sq.msn_idx);
	free(qp->sq.meta);
	ionic_queue_destroy(&qp->sq.queue);
}

static int ionic_qp_rq_init(struct ionic_ctx *ctx, struct ionic_qp *qp, struct ionic_pd *pd,
			    int max_wr, int max_sge)
{
	uint32_t wqe_size;
	uint64_t pd_tag;
	int rc, i;

	if (!qp->has_rq)
		return 0;

	if (max_wr < 0 || max_wr > 0xffff)
		return EINVAL;
	if (max_sge < 0)
		return EINVAL;
	if (max_sge > ionic_v1_recv_wqe_max_sge(ctx->max_stride, 0, false))
		return EINVAL;

	pd_tag = IONIC_PD_TAG_RQ;
	qp->rq.spec = ionic_v1_use_spec_sge(max_sge, ctx->spec);

	if (qp->rq.cmb & IONIC_CMB_EXPDB) {
		wqe_size = ionic_v1_recv_wqe_min_size(max_sge, qp->rq.spec, true);

		if (!ionic_expdb_wqe_size_supported(ctx, wqe_size))
			qp->rq.cmb &= ~IONIC_CMB_EXPDB;
	}

	if (!(qp->rq.cmb & IONIC_CMB_EXPDB))
		wqe_size = ionic_v1_recv_wqe_min_size(max_sge, qp->rq.spec, false);

	rc = ionic_queue_init(&qp->rq.queue, pd, pd_tag, ctx->pg_shift, max_wr, wqe_size);
	if (rc)
		goto err_rq;

	qp->rq.cmb_ptr = NULL;
	qp->rq.cmb_prod = 0;

	qp->rq.meta = calloc((uint32_t)qp->rq.queue.mask + 1,
			     sizeof(*qp->rq.meta));
	if (!qp->rq.meta) {
		rc = ENOMEM;
		goto err_rq_meta;
	}

	for (i = 0; i < qp->rq.queue.mask; ++i)
		qp->rq.meta[i].next = &qp->rq.meta[i + 1];

	qp->rq.meta[i].next = IONIC_META_LAST;
	qp->rq.meta_head = &qp->rq.meta[0];

	qp->rq.meta_idx = calloc((uint32_t)qp->rq.queue.mask + 1,
				 sizeof(*qp->rq.meta_idx));
	if (!qp->rq.meta_idx) {
		rc = ENOMEM;
		goto err_rq_meta_idx;
	}

	return 0;

err_rq_meta_idx:
	free(qp->rq.meta);
err_rq_meta:
	ionic_queue_destroy(&qp->rq.queue);
err_rq:
	return rc;
}

static void ionic_qp_rq_destroy(struct ionic_qp *qp)
{
	if (!qp->has_rq)
		return;

	free(qp->rq.meta_idx);
	free(qp->rq.meta);
	ionic_queue_destroy(&qp->rq.queue);
}

static void ionic_wr_start(struct ibv_qp_ex *ibqp_ex)
{
	struct ionic_qp *qp = to_ionic_qp_ex(ibqp_ex);
	struct ionic_cq *cq = to_ionic_vcq_cq(qp->vqp.qp.send_cq, qp->udma_idx);

	ionic_cq_spin_lock(cq);
	ionic_sq_spin_lock(qp);

	qp->ex_rc = 0;

	if (unlikely(!qp->has_sq))
		qp->ex_rc = EINVAL;

	if (unlikely(qp->vqp.qp.state < IBV_QPS_RTS))
		qp->ex_rc = EINVAL;
}

static void ionic_wr_abort(struct ibv_qp_ex *ibqp_ex)
{
	struct ionic_qp *qp = to_ionic_qp_ex(ibqp_ex);
	struct ionic_cq *cq = to_ionic_vcq_cq(qp->vqp.qp.send_cq, qp->udma_idx);

	qp->sq.queue.prod = qp->sq.old_prod;

	ionic_sq_spin_unlock(qp);
	ionic_cq_spin_unlock(cq);
}

static int ionic_wr_complete(struct ibv_qp_ex *ibqp_ex)
{
	struct ionic_qp *qp = to_ionic_qp_ex(ibqp_ex);
	struct ionic_cq *cq = to_ionic_vcq_cq(qp->vqp.qp.send_cq, qp->udma_idx);
	struct ionic_ctx *ctx = to_ionic_ctx(qp->vqp.qp.context);
	int spend, rc = qp->ex_rc;

	if (rc) {
		ionic_wr_abort(ibqp_ex);
		return rc;
	}

	if (likely(qp->sq.queue.prod != qp->sq.old_prod)) {
		/* ring cq doorbell just in time */
		spend = (qp->sq.queue.prod - qp->sq.old_prod) & qp->sq.queue.mask;
		ionic_reserve_cq(ctx, cq, spend);

		qp->sq.old_prod = qp->sq.queue.prod;

		if (qp->sq.cmb_ptr) {
			ionic_post_send_cmb(ctx, qp);
		} else {
			udma_to_device_barrier();
			verbs_debug(&ctx->vctx, "dbell qp %u sq val %" PRIx64,
				    qp->qpid, ionic_queue_dbell_val(&qp->sq.queue));
			ionic_dbell_ring(&ctx->dbpage[ctx->sq_qtype],
					 ionic_queue_dbell_val(&qp->sq.queue));
		}
	}

	if (qp->sq.flush) {
		cq->flush = true;
		list_del(&qp->cq_flush_sq);
		list_add_tail(&cq->flush_sq, &qp->cq_flush_sq);
	}

	ionic_sq_spin_unlock(qp);
	ionic_cq_spin_unlock(cq);

	return 0;
}

static void ionic_wr_set(struct ionic_qp *qp, int wr_flags, size_t num_sge,
			 const struct ibv_sge *sg_list)
{
	if (qp->ex_rc)
		return;

	qp->ex_wr.send_flags = qp->vqp.qp_ex.wr_flags | wr_flags,
	qp->ex_wr.sg_list = (struct ibv_sge *)sg_list;
	qp->ex_wr.num_sge = num_sge;

	qp->ex_rc = ionic_v1_prep_one_rc(qp, &qp->ex_wr, true);
}

static void ionic_wr_set_sge(struct ibv_qp_ex *ibqp_ex, uint32_t lkey, uint64_t addr,
			     uint32_t length)
{
	struct ionic_qp *qp = to_ionic_qp_ex(ibqp_ex);
	struct ibv_sge sge = {
		.addr = addr,
		.length = length,
		.lkey = lkey,
	};

	ionic_wr_set(qp, 0, 1, &sge);
}

static void ionic_wr_set_sge_list(struct ibv_qp_ex *ibqp_ex, size_t num_sge,
				  const struct ibv_sge *sg_list)
{
	struct ionic_qp *qp = to_ionic_qp_ex(ibqp_ex);

	ionic_wr_set(qp, 0, num_sge, sg_list);
}

static void ionic_wr_set_inline_data(struct ibv_qp_ex *ibqp_ex, void *addr, size_t length)
{
	struct ionic_qp *qp = to_ionic_qp_ex(ibqp_ex);
	struct ibv_sge sge = {
		.addr = (uintptr_t)addr,
		.length = length,
	};

	ionic_wr_set(qp, IBV_SEND_INLINE, 1, &sge);
}

static void ionic_wr_set_inline_data_list(struct ibv_qp_ex *ibqp_ex, size_t num_buf,
					  const struct ibv_data_buf *buf_list)
{
	struct ionic_qp *qp = to_ionic_qp_ex(ibqp_ex);
	struct ibv_sge *sg_list;
	int sge_i;

	sg_list = calloc(num_buf, sizeof(*sg_list));
	if (!sg_list) {
		qp->ex_rc = ENOMEM;
		return;
	}

	for (sge_i = 0; sge_i < num_buf; ++sge_i) {
		sg_list[sge_i].addr = (uintptr_t)buf_list[sge_i].addr;
		sg_list[sge_i].length = buf_list[sge_i].length;
	}

	ionic_wr_set(qp, IBV_SEND_INLINE, num_buf, sg_list);
	free(sg_list);
}

static void ionic_wr_rdma_write(struct ibv_qp_ex *ibqp_ex, uint32_t rkey,
				uint64_t remote_addr)
{
	struct ionic_qp *qp = to_ionic_qp_ex(ibqp_ex);
	struct ibv_send_wr wr = {
		.wr_id = qp->vqp.qp_ex.wr_id,
		.opcode = IBV_WR_RDMA_WRITE,
		.wr.rdma.remote_addr = remote_addr,
		.wr.rdma.rkey = rkey,
	};

	qp->ex_wr = wr;
}

static void ionic_wr_rdma_write_imm(struct ibv_qp_ex *ibqp_ex, uint32_t rkey,
				    uint64_t remote_addr, __be32 imm_data)
{
	struct ionic_qp *qp = to_ionic_qp_ex(ibqp_ex);
	struct ibv_send_wr wr = {
		.wr_id = qp->vqp.qp_ex.wr_id,
		.opcode = IBV_WR_RDMA_WRITE_WITH_IMM,
		.imm_data = imm_data,
		.wr.rdma.remote_addr = remote_addr,
		.wr.rdma.rkey = rkey,
	};

	qp->ex_wr = wr;
}

static void ionic_wr_rdma_read(struct ibv_qp_ex *ibqp_ex, uint32_t rkey,
			       uint64_t remote_addr)
{
	struct ionic_qp *qp = to_ionic_qp_ex(ibqp_ex);
	struct ibv_send_wr wr = {
		.wr_id = qp->vqp.qp_ex.wr_id,
		.opcode = IBV_WR_RDMA_READ,
		.wr.rdma.remote_addr = remote_addr,
		.wr.rdma.rkey = rkey,
	};

	qp->ex_wr = wr;
}

static void ionic_wr_send(struct ibv_qp_ex *ibqp_ex)
{
	struct ionic_qp *qp = to_ionic_qp_ex(ibqp_ex);
	struct ibv_send_wr wr = {
		.wr_id = qp->vqp.qp_ex.wr_id,
		.opcode = IBV_WR_SEND,
	};

	qp->ex_wr = wr;
}

static void ionic_wr_send_imm(struct ibv_qp_ex *ibqp_ex, __be32 imm_data)
{
	struct ionic_qp *qp = to_ionic_qp_ex(ibqp_ex);
	struct ibv_send_wr wr = {
		.wr_id = qp->vqp.qp_ex.wr_id,
		.opcode = IBV_WR_SEND_WITH_IMM,
		.imm_data = imm_data,
	};

	qp->ex_wr = wr;
}

static void ionic_wr_send_inv(struct ibv_qp_ex *ibqp_ex, uint32_t invalidate_rkey)
{
	struct ionic_qp *qp = to_ionic_qp_ex(ibqp_ex);
	struct ibv_send_wr wr = {
		.wr_id = qp->vqp.qp_ex.wr_id,
		.opcode = IBV_WR_SEND_WITH_INV,
		.invalidate_rkey = invalidate_rkey,
	};

	qp->ex_wr = wr;
}

static void ionic_wr_atomic_cmp_swp(struct ibv_qp_ex *ibqp_ex, uint32_t rkey,
				    uint64_t remote_addr, uint64_t compare,
				    uint64_t swap)
{
	struct ionic_qp *qp = to_ionic_qp_ex(ibqp_ex);
	struct ibv_send_wr wr = {
		.wr_id = qp->vqp.qp_ex.wr_id,
		.opcode = IBV_WR_ATOMIC_CMP_AND_SWP,
		.wr.atomic.remote_addr = remote_addr,
		.wr.atomic.compare_add = compare,
		.wr.atomic.swap = swap,
		.wr.atomic.rkey = rkey,
	};

	qp->ex_wr = wr;
}

static void ionic_wr_atomic_fetch_add(struct ibv_qp_ex *ibqp_ex, uint32_t rkey,
				      uint64_t remote_addr, uint64_t add)
{
	struct ionic_qp *qp = to_ionic_qp_ex(ibqp_ex);
	struct ibv_send_wr wr = {
		.wr_id = qp->vqp.qp_ex.wr_id,
		.opcode = IBV_WR_ATOMIC_FETCH_AND_ADD,
		.wr.atomic.remote_addr = remote_addr,
		.wr.atomic.compare_add = add,
		.wr.atomic.rkey = rkey,
	};

	qp->ex_wr = wr;
}

static void ionic_wr_bind_mw(struct ibv_qp_ex *ibqp_ex, struct ibv_mw *mw,
			     uint32_t rkey,
			     const struct ibv_mw_bind_info *bind_info)
{
	struct ionic_qp *qp = to_ionic_qp_ex(ibqp_ex);
	struct ibv_send_wr wr = {
		.wr_id = qp->vqp.qp_ex.wr_id,
		.opcode = IBV_WR_BIND_MW,
		.bind_mw.mw = mw,
		.bind_mw.rkey = rkey,
		.bind_mw.bind_info = *bind_info,
	};

	qp->ex_wr = wr;
	ionic_wr_set(qp, 0, 0, NULL);
}

static void ionic_wr_local_inv(struct ibv_qp_ex *ibqp_ex, uint32_t invalidate_rkey)
{
	struct ionic_qp *qp = to_ionic_qp_ex(ibqp_ex);
	struct ibv_send_wr wr = {
		.wr_id = qp->vqp.qp_ex.wr_id,
		.opcode = IBV_WR_LOCAL_INV,
		.invalidate_rkey = invalidate_rkey,
	};

	qp->ex_wr = wr;
	ionic_wr_set(qp, 0, 0, NULL);
}

static struct ibv_qp *ionic_create_qp_ex(struct ibv_context *ibctx,
					 struct ibv_qp_init_attr_ex *ex)
{
	struct ionic_ctx *ctx = to_ionic_ctx(ibctx);
	struct ionic_pd *pd = to_ionic_pd(ex->pd);
	struct uionic_qp_resp resp;
	struct uionic_qp req;
	struct ionic_qp *qp;
	struct ionic_cq *cq;
	int rc;

	if ((ex->comp_mask & IONIC_QP_REQUIRED_COMP_MASK) !=
	    IONIC_QP_REQUIRED_COMP_MASK) {
		rc = ENOTSUP;
		goto err_qp;
	}

	if (ex->qp_type == IBV_QPT_RC) {
		if (!check_comp_mask(ex->comp_mask,
				     IONIC_QP_SUPPORTED_COMP_MASK_RC)) {
			rc = ENOTSUP;
			goto err_qp;
		}
	} else if (ex->qp_type == IBV_QPT_UD) {
		if (!check_comp_mask(ex->comp_mask,
				     IONIC_QP_SUPPORTED_COMP_MASK_UD)) {
			rc = ENOTSUP;
			goto err_qp;
		}
	} else {
		rc = ENOTSUP;
		goto err_qp;
	}

	if (!check_comp_mask(ex->send_ops_flags,
			     IONIC_QP_SUPPORTED_SEND_OPS_FLAGS)) {
		rc = ENOTSUP;
		goto err_qp;
	}

	qp = calloc(1, sizeof(*qp));
	if (!qp) {
		rc = ENOMEM;
		goto err_qp;
	}

	qp->vqp.qp.qp_type = ex->qp_type;
	qp->has_sq = true;
	qp->has_rq = true;
	qp->lockfree = ex->pd ? ionic_pd_lockfree(ex->pd) : false;
	qp->sig_all = ex->sq_sig_all;

	list_node_init(&qp->cq_poll_sq);
	list_node_init(&qp->cq_poll_rq);
	list_node_init(&qp->cq_flush_sq);
	list_node_init(&qp->cq_flush_rq);

	pthread_spin_init(&qp->sq.lock, PTHREAD_PROCESS_PRIVATE);
	pthread_spin_init(&qp->rq.lock, PTHREAD_PROCESS_PRIVATE);

	qp->sq.cmb = pd->sq_cmb;
	qp->rq.cmb = pd->rq_cmb;

	rc = ionic_qp_sq_init(ctx, qp, pd, ex->cap.max_send_wr,
			      ex->cap.max_send_sge, ex->cap.max_inline_data);
	if (rc)
		goto err_sq;

	rc = ionic_qp_rq_init(ctx, qp, pd, ex->cap.max_recv_wr,
			      ex->cap.max_recv_sge);
	if (rc)
		goto err_rq;

	req.sq.addr = (uintptr_t)qp->sq.queue.ptr;
	req.sq.size = qp->sq.queue.size;
	req.sq.mask = qp->sq.queue.mask;
	req.sq.depth_log2 = qp->sq.queue.depth_log2;
	req.sq.stride_log2 = qp->sq.queue.stride_log2;
	req.sq_cmb = qp->sq.cmb;

	req.rq.addr = (uintptr_t)qp->rq.queue.ptr;
	req.rq.size = qp->rq.queue.size;
	req.rq.mask = qp->rq.queue.mask;
	req.rq.depth_log2 = qp->rq.queue.depth_log2;
	req.rq.stride_log2 = qp->rq.queue.stride_log2;
	req.rq_cmb = qp->rq.cmb;

	req.sq_spec = qp->sq.spec;
	req.rq_spec = qp->rq.spec;

	req.udma_mask = pd->udma_mask;

	rc = ibv_cmd_create_qp_ex2(ibctx, &qp->vqp, ex,
				   &req.ibv_cmd,
				   sizeof(req),
				   &resp.ibv_resp,
				   sizeof(resp), NULL);
	if (rc)
		goto err_cmd;

	qp->qpid = resp.qpid;
	qp->udma_idx = resp.udma_idx;

	ionic_queue_dbell_init(&qp->sq.queue, qp->qpid);
	ionic_queue_dbell_init(&qp->rq.queue, qp->qpid);

	qp->sq.cmb = resp.sq_cmb;
	qp->rq.cmb = resp.rq_cmb;

	rc = ionic_set_cmb(ctx, &qp->sq.queue, qp->sq.cmb, resp.sq_cmb_offset,
			   ctx->sq_qtype, &qp->sq.cmb_ptr);
	if (rc)
		goto err_cmb;

	rc = ionic_set_cmb(ctx, &qp->rq.queue, qp->rq.cmb, resp.rq_cmb_offset,
			   ctx->rq_qtype, &qp->rq.cmb_ptr);
	if (rc)
		goto err_cmb;

	pthread_mutex_lock(&ctx->mut);
	ionic_tbl_alloc_node(&ctx->qp_tbl);
	ionic_tbl_insert(&ctx->qp_tbl, qp, qp->qpid);
	pthread_mutex_unlock(&ctx->mut);

	if (qp->has_sq) {
		cq = to_ionic_vcq_cq(qp->vqp.qp.send_cq, qp->udma_idx);
		ionic_cq_spin_lock(cq);
		ionic_cq_spin_unlock(cq);

		ex->cap.max_send_wr = qp->sq.queue.mask;
		ex->cap.max_send_sge =
			ionic_v1_send_wqe_max_sge(qp->sq.queue.stride_log2, qp->sq.spec,
						  qp->sq.cmb & IONIC_CMB_EXPDB);
		ex->cap.max_inline_data =
			ionic_v1_send_wqe_max_data(qp->sq.queue.stride_log2,
						   qp->sq.cmb & IONIC_CMB_EXPDB);
	}

	if (qp->has_rq) {
		cq = to_ionic_vcq_cq(qp->vqp.qp.recv_cq, qp->udma_idx);
		ionic_cq_spin_lock(cq);
		ionic_cq_spin_unlock(cq);

		ex->cap.max_recv_wr = qp->rq.queue.mask;
		ex->cap.max_recv_sge =
			ionic_v1_recv_wqe_max_sge(qp->rq.queue.stride_log2, qp->rq.spec,
						  qp->rq.cmb & IONIC_CMB_EXPDB);
	}

	/* management of the critical section */
	qp->vqp.qp_ex.wr_start = ionic_wr_start;
	qp->vqp.qp_ex.wr_abort = ionic_wr_abort;
	qp->vqp.qp_ex.wr_complete = ionic_wr_complete;

	/* setters cause wqe to be posted without doorbell */
	qp->vqp.qp_ex.wr_set_sge_list = ionic_wr_set_sge_list;
	qp->vqp.qp_ex.wr_set_sge = ionic_wr_set_sge;
	qp->vqp.qp_ex.wr_set_inline_data_list = ionic_wr_set_inline_data_list;
	qp->vqp.qp_ex.wr_set_inline_data = ionic_wr_set_inline_data;

	/* builders supply opcode for the wqe to be posted by setters */
	qp->vqp.qp_ex.wr_send = ionic_wr_send;
	qp->vqp.qp_ex.wr_send_imm = ionic_wr_send_imm;
	qp->vqp.qp_ex.wr_send_inv = ionic_wr_send_inv;
	qp->vqp.qp_ex.wr_rdma_write = ionic_wr_rdma_write;
	qp->vqp.qp_ex.wr_rdma_write_imm = ionic_wr_rdma_write_imm;
	qp->vqp.qp_ex.wr_rdma_read = ionic_wr_rdma_read;
	qp->vqp.qp_ex.wr_atomic_cmp_swp = ionic_wr_atomic_cmp_swp;
	qp->vqp.qp_ex.wr_atomic_fetch_add = ionic_wr_atomic_fetch_add;
	qp->vqp.qp_ex.wr_bind_mw = ionic_wr_bind_mw;
	qp->vqp.qp_ex.wr_local_inv = ionic_wr_local_inv;

	qp->vqp.comp_mask = VERBS_QP_EX;

	return &qp->vqp.qp;

err_cmb:
	ibv_cmd_destroy_qp(&qp->vqp.qp);
	ionic_unmap(qp->sq.cmb_ptr, qp->sq.queue.size);
	ionic_unmap(qp->rq.cmb_ptr, qp->rq.queue.size);
err_cmd:
	ionic_qp_rq_destroy(qp);
err_rq:
	ionic_qp_sq_destroy(qp);
err_sq:
	pthread_spin_destroy(&qp->rq.lock);
	pthread_spin_destroy(&qp->sq.lock);
	free(qp);
err_qp:
	errno = rc;
	return NULL;
}

static void ionic_flush_qp(struct ionic_ctx *ctx, struct ionic_qp *qp)
{
	struct ionic_cq *cq;

	if (qp->vqp.qp.send_cq) {
		cq = to_ionic_vcq_cq(qp->vqp.qp.send_cq, qp->udma_idx);

		/* Hold the CQ lock and QP sq_lock while setting up flush */
		ionic_cq_spin_lock(cq);
		ionic_sq_spin_lock(qp);
		qp->sq.flush = true;

		if (!ionic_queue_empty(&qp->sq.queue)) {
			cq->flush = true;
			list_del(&qp->cq_flush_sq);
			list_add_tail(&cq->flush_sq, &qp->cq_flush_sq);
		}

		ionic_sq_spin_unlock(qp);
		ionic_cq_spin_unlock(cq);
	}

	if (qp->vqp.qp.recv_cq) {
		cq = to_ionic_vcq_cq(qp->vqp.qp.recv_cq, qp->udma_idx);

		/* Hold the CQ lock and QP rq_lock while setting up flush */
		ionic_cq_spin_lock(cq);
		ionic_rq_spin_lock(qp);
		qp->rq.flush = true;

		if (!ionic_queue_empty(&qp->rq.queue)) {
			cq->flush = true;
			list_del(&qp->cq_flush_rq);
			list_add_tail(&cq->flush_rq, &qp->cq_flush_rq);
		}

		ionic_rq_spin_unlock(qp);
		ionic_cq_spin_unlock(cq);
	}
}

static void ionic_reset_qp(struct ionic_ctx *ctx, struct ionic_qp *qp)
{
	struct ionic_cq *cq;
	int i;

	if (qp->vqp.qp.send_cq) {
		cq = to_ionic_vcq_cq(qp->vqp.qp.send_cq, qp->udma_idx);
		ionic_cq_spin_lock(cq);
		ionic_clean_cq(cq, qp->qpid);
		ionic_cq_spin_unlock(cq);
	}

	if (qp->vqp.qp.recv_cq) {
		cq = to_ionic_vcq_cq(qp->vqp.qp.recv_cq, qp->udma_idx);
		ionic_cq_spin_lock(cq);
		ionic_clean_cq(cq, qp->qpid);
		ionic_cq_spin_unlock(cq);
	}

	if (qp->has_sq) {
		ionic_sq_spin_lock(qp);
		qp->sq.flush = false;
		qp->sq.flush_rcvd = false;
		qp->sq.msn_prod = 0;
		qp->sq.msn_cons = 0;
		qp->sq.cmb_prod = 0;
		qp->sq.old_prod = 0;
		qp->sq.queue.prod = 0;
		qp->sq.queue.cons = 0;
		ionic_sq_spin_unlock(qp);
	}

	if (qp->has_rq) {
		ionic_rq_spin_lock(qp);
		qp->rq.flush = false;
		qp->rq.queue.prod = 0;
		qp->rq.queue.cons = 0;
		qp->rq.cmb_prod = 0;
		qp->rq.old_prod = 0;
		for (i = 0; i < qp->rq.queue.mask; ++i)
			qp->rq.meta[i].next = &qp->rq.meta[i + 1];
		qp->rq.meta[i].next = IONIC_META_LAST;
		qp->rq.meta_head = &qp->rq.meta[0];
		ionic_rq_spin_unlock(qp);
	}
}

static int ionic_modify_qp(struct ibv_qp *ibqp,
			   struct ibv_qp_attr *attr,
			   int attr_mask)
{
	struct ionic_ctx *ctx = to_ionic_ctx(ibqp->context);
	struct ionic_qp *qp = to_ionic_qp(ibqp);
	struct ibv_modify_qp cmd = {};
	int rc;

	if (!attr_mask)
		return 0;

	rc = ibv_cmd_modify_qp(ibqp, attr, attr_mask, &cmd, sizeof(cmd));
	if (rc)
		goto err_cmd;

	if (attr_mask & IBV_QP_STATE) {
		if (attr->qp_state == IBV_QPS_ERR)
			ionic_flush_qp(ctx, qp);
		else if (attr->qp_state == IBV_QPS_RESET)
			ionic_reset_qp(ctx, qp);
	}

err_cmd:
	if (attr_mask & IBV_QP_STATE)
		verbs_debug(&ctx->vctx, "modify qp %u state %u -> %u rc %d",
			    qp->qpid, qp->vqp.qp.state, attr->qp_state, rc);

	return rc;
}

static int ionic_query_qp(struct ibv_qp *ibqp,
			  struct ibv_qp_attr *attr,
			  int attr_mask,
			  struct ibv_qp_init_attr *init_attr)
{
	struct ionic_qp *qp = to_ionic_qp(ibqp);
	struct ionic_ctx *ctx = to_ionic_ctx(ibqp->context);
	struct ibv_query_qp cmd;
	int rc;

	rc = ibv_cmd_query_qp(ibqp, attr, attr_mask, init_attr,
			      &cmd, sizeof(cmd));

	if (qp->has_sq) {
		init_attr->cap.max_send_wr = qp->sq.queue.mask;
		init_attr->cap.max_send_sge =
			ionic_v1_send_wqe_max_sge(qp->sq.queue.stride_log2, qp->sq.spec,
						  qp->sq.cmb & IONIC_CMB_EXPDB);
		init_attr->cap.max_inline_data =
			ionic_v1_send_wqe_max_data(qp->sq.queue.stride_log2,
						   qp->sq.cmb & IONIC_CMB_EXPDB);
	}

	if (qp->has_rq) {
		init_attr->cap.max_recv_wr = qp->rq.queue.mask;
		init_attr->cap.max_recv_sge =
			ionic_v1_send_wqe_max_sge(qp->rq.queue.stride_log2, qp->rq.spec,
						  qp->rq.cmb & IONIC_CMB_EXPDB);
	}

	attr->cap = init_attr->cap;

	verbs_debug(&ctx->vctx, "query qp %u attr_state %u rc %d",
		    qp->qpid, attr->qp_state, rc);

	return rc;
}

static int ionic_destroy_qp(struct ibv_qp *ibqp)
{
	struct ionic_ctx *ctx = to_ionic_ctx(ibqp->context);
	struct ionic_qp *qp = to_ionic_qp(ibqp);
	struct ionic_cq *cq;
	int rc;

	rc = ibv_cmd_destroy_qp(ibqp);
	if (rc)
		return rc;

	pthread_mutex_lock(&ctx->mut);
	ionic_tbl_free_node(&ctx->qp_tbl);
	ionic_tbl_delete(&ctx->qp_tbl, qp->qpid);
	pthread_mutex_unlock(&ctx->mut);

	if (qp->vqp.qp.send_cq) {
		cq = to_ionic_vcq_cq(qp->vqp.qp.send_cq, qp->udma_idx);
		ionic_cq_spin_lock(cq);
		ionic_clean_cq(cq, qp->qpid);
		list_del(&qp->cq_poll_sq);
		list_del(&qp->cq_flush_sq);
		ionic_cq_spin_unlock(cq);
	}

	if (qp->vqp.qp.recv_cq) {
		cq = to_ionic_vcq_cq(qp->vqp.qp.recv_cq, qp->udma_idx);
		ionic_cq_spin_lock(cq);
		ionic_clean_cq(cq, qp->qpid);
		list_del(&qp->cq_poll_rq);
		list_del(&qp->cq_flush_rq);
		ionic_cq_spin_unlock(cq);
	}

	ionic_unmap(qp->sq.cmb_ptr, qp->sq.queue.size);
	ionic_unmap(qp->rq.cmb_ptr, qp->rq.queue.size);

	pthread_spin_destroy(&qp->rq.lock);
	pthread_spin_destroy(&qp->sq.lock);
	ionic_qp_rq_destroy(qp);
	ionic_qp_sq_destroy(qp);
	free(qp);

	return 0;
}

static int64_t ionic_prep_inline(void *data, uint32_t max_data,
				 struct ibv_sge *ibv_sgl, int num_sge)
{
	int64_t len = 0, sg_len;
	int sg_i;

	for (sg_i = 0; sg_i < num_sge; ++sg_i) {
		sg_len = ibv_sgl[sg_i].length;

		/* greater than max inline data is invalid */
		if (unlikely(len + sg_len > max_data))
			return -EINVAL;

		memcpy(data + len, (void *)(uintptr_t)ibv_sgl[sg_i].addr, sg_len);

		len += sg_len;
	}

	return len;
}

static int64_t ionic_v1_prep_pld(struct ionic_v1_wqe *wqe,
				 union ionic_v1_pld *pld,
				 int spec, uint32_t max_sge,
				 struct ibv_sge *ibv_sgl,
				 int num_sge)
{
	static const int64_t bit_31 = 1l << 31;
	int64_t len = 0, sg_len;
	struct ionic_sge *sgl;
	__be32 *spec32 = NULL;
	__be16 *spec16 = NULL;
	int sg_i = 0;

	if (unlikely(num_sge < 0 || (uint32_t)num_sge > max_sge))
		return -EINVAL;

	if (spec && num_sge > IONIC_V1_SPEC_FIRST_SGE) {
		sg_i = IONIC_V1_SPEC_FIRST_SGE;

		if (num_sge > 8) {
			wqe->base.flags |= htobe16(IONIC_V1_FLAG_SPEC16);
			spec16 = pld->spec16;
		} else {
			wqe->base.flags |= htobe16(IONIC_V1_FLAG_SPEC32);
			spec32 = pld->spec32;
		}
	}

	sgl = &pld->sgl[sg_i];

	for (sg_i = 0; sg_i < num_sge; ++sg_i) {
		sg_len = ibv_sgl[sg_i].length;

		/* greater than 2GB data is invalid */
		if (unlikely(len + sg_len > bit_31))
			return -EINVAL;

		sgl[sg_i].va = htobe64(ibv_sgl[sg_i].addr);
		sgl[sg_i].len = htobe32(sg_len);
		sgl[sg_i].lkey = htobe32(ibv_sgl[sg_i].lkey);

		if (spec32) {
			spec32[sg_i] = sgl[sg_i].len;
		} else if (spec16) {
			if (unlikely(sg_len > UINT16_MAX))
				return -EINVAL;
			spec16[sg_i] = htobe16(sg_len);
		}

		len += sg_len;
	}

	return len;
}

static void ionic_v1_prep_base(struct ionic_qp *qp,
			       struct ibv_send_wr *wr,
			       struct ionic_sq_meta *meta,
			       struct ionic_v1_wqe *wqe)
{
	struct ionic_ctx *ctx = to_ionic_ctx(qp->vqp.qp.context);

	meta->wrid = wr->wr_id;
	meta->ibsts = IBV_WC_SUCCESS;
	meta->signal = false;
	meta->local_comp = false;

	wqe->base.wqe_idx = htole64(qp->sq.queue.prod);
	if (qp->sq.color)
		wqe->base.flags |= htobe16(IONIC_V1_FLAG_COLOR);

	if (wr->send_flags & IBV_SEND_FENCE)
		wqe->base.flags |= htobe16(IONIC_V1_FLAG_FENCE);

	if (wr->send_flags & IBV_SEND_SOLICITED)
		wqe->base.flags |= htobe16(IONIC_V1_FLAG_SOL);

	if (qp->sig_all || (wr->send_flags & IBV_SEND_SIGNALED)) {
		wqe->base.flags |= htobe16(IONIC_V1_FLAG_SIG);
		meta->signal = true;
	}

	meta->seq = qp->sq.msn_prod;
	meta->remote = qp->vqp.qp.qp_type != IBV_QPT_UD &&
		!ionic_ibop_is_local(wr->opcode);

	if (meta->remote) {
		qp->sq.msn_idx[meta->seq] = qp->sq.queue.prod;
		qp->sq.msn_prod = ionic_queue_next(&qp->sq.queue, qp->sq.msn_prod);
	}

	verbs_debug(&ctx->vctx, "post send %u prod %u",
		    qp->qpid, qp->sq.queue.prod);
	ionic_dbg_xdump(ctx, "wqe", wqe, 1u << qp->sq.queue.stride_log2);

	ionic_queue_produce(&qp->sq.queue);
	qp->sq.color = ionic_color_wrap(qp->sq.queue.prod, qp->sq.color);
}

static int ionic_v1_prep_common(struct ionic_qp *qp,
				struct ibv_send_wr *wr,
				struct ionic_sq_meta *meta,
				struct ionic_v1_wqe *wqe)
{
	int64_t signed_len;
	uint32_t mval;

	if (wr->send_flags & IBV_SEND_INLINE) {
		wqe->base.num_sge_key = 0;
		wqe->base.flags |= htobe16(IONIC_V1_FLAG_INL);
		mval = ionic_v1_send_wqe_max_data(qp->sq.queue.stride_log2,
						  qp->sq.cmb & IONIC_CMB_EXPDB);
		signed_len = ionic_prep_inline(wqe->common.pld.data, mval,
					       wr->sg_list, wr->num_sge);
	} else {
		wqe->base.num_sge_key = wr->num_sge;
		mval = ionic_v1_send_wqe_max_sge(qp->sq.queue.stride_log2, qp->sq.spec,
						 qp->sq.cmb & IONIC_CMB_EXPDB);
		signed_len = ionic_v1_prep_pld(wqe, &wqe->common.pld,
					       qp->sq.spec, mval,
					       wr->sg_list, wr->num_sge);
	}

	if (unlikely(signed_len < 0))
		return -signed_len;

	meta->len = signed_len;
	wqe->common.length = htobe32(signed_len);

	ionic_v1_prep_base(qp, wr, meta, wqe);

	return 0;
}

static void ionic_prep_sq_wqe(struct ionic_qp *qp, void *wqe)
{
	uint32_t wqe_sz = 1u << qp->sq.queue.stride_log2;

	if (qp->sq.cmb & IONIC_CMB_EXPDB)
		memset(wqe, 0, wqe_sz - IONIC_EXP_DBELL_SZ);
	else
		memset(wqe, 0, wqe_sz);
}

static void ionic_prep_rq_wqe(struct ionic_qp *qp, void *wqe)
{
	uint32_t wqe_sz = 1u << qp->rq.queue.stride_log2;

	if (qp->rq.cmb & IONIC_CMB_EXPDB)
		memset(wqe, 0, wqe_sz - IONIC_EXP_DBELL_SZ);
	else
		memset(wqe, 0, wqe_sz);
}

static int ionic_v1_prep_send(struct ionic_qp *qp,
			      struct ibv_send_wr *wr)
{
	struct ionic_ctx *ctx = to_ionic_ctx(qp->vqp.qp.context);
	struct ionic_sq_meta *meta;
	struct ionic_v1_wqe *wqe;

	meta = &qp->sq.meta[qp->sq.queue.prod];
	wqe = ionic_queue_at_prod(&qp->sq.queue);

	ionic_prep_sq_wqe(qp, wqe);

	meta->ibop = IBV_WC_SEND;

	switch (wr->opcode) {
	case IBV_WR_SEND:
		wqe->base.op = IONIC_OP(ctx->version, SEND);
		break;
	case IBV_WR_SEND_WITH_IMM:
		wqe->base.op = IONIC_OP(ctx->version, SEND_IMM);
		wqe->base.imm_data_key = wr->imm_data;
		break;
	case IBV_WR_SEND_WITH_INV:
		wqe->base.op = IONIC_OP(ctx->version, SEND_INV);
		wqe->base.imm_data_key = htobe32(wr->invalidate_rkey);
		break;
	default:
		return EINVAL;
	}

	return ionic_v1_prep_common(qp, wr, meta, wqe);
}

static int ionic_v1_prep_send_ud(struct ionic_qp *qp, struct ibv_send_wr *wr)
{
	struct ionic_ctx *ctx = to_ionic_ctx(qp->vqp.qp.context);
	struct ionic_sq_meta *meta;
	struct ionic_v1_wqe *wqe;
	struct ionic_ah *ah;

	if (unlikely(!wr->wr.ud.ah))
		return EINVAL;

	ah = to_ionic_ah(wr->wr.ud.ah);

	meta = &qp->sq.meta[qp->sq.queue.prod];
	wqe = ionic_queue_at_prod(&qp->sq.queue);

	ionic_prep_sq_wqe(qp, wqe);

	wqe->common.send.ah_id = htobe32(ah->ahid);
	wqe->common.send.dest_qpn = htobe32(wr->wr.ud.remote_qpn);
	wqe->common.send.dest_qkey = htobe32(wr->wr.ud.remote_qkey);

	meta->ibop = IBV_WC_SEND;

	switch (wr->opcode) {
	case IBV_WR_SEND:
		wqe->base.op = IONIC_OP(ctx->version, SEND);
		break;
	case IBV_WR_SEND_WITH_IMM:
		wqe->base.op = IONIC_OP(ctx->version, SEND_IMM);
		wqe->base.imm_data_key = wr->imm_data;
		break;
	default:
		return EINVAL;
	}

	return ionic_v1_prep_common(qp, wr, meta, wqe);
}

static int ionic_v1_prep_rdma(struct ionic_qp *qp,
			      struct ibv_send_wr *wr)
{
	struct ionic_ctx *ctx = to_ionic_ctx(qp->vqp.qp.context);
	struct ionic_sq_meta *meta;
	struct ionic_v1_wqe *wqe;

	meta = &qp->sq.meta[qp->sq.queue.prod];
	wqe = ionic_queue_at_prod(&qp->sq.queue);

	ionic_prep_sq_wqe(qp, wqe);

	meta->ibop = IBV_WC_RDMA_WRITE;

	switch (wr->opcode) {
	case IBV_WR_RDMA_READ:
		if (wr->send_flags & (IBV_SEND_SOLICITED | IBV_SEND_INLINE))
			return EINVAL;
		meta->ibop = IBV_WC_RDMA_READ;
		wqe->base.op = IONIC_OP(ctx->version, RDMA_READ);
		break;
	case IBV_WR_RDMA_WRITE:
		if (wr->send_flags & IBV_SEND_SOLICITED)
			return EINVAL;
		wqe->base.op = IONIC_OP(ctx->version, RDMA_WRITE);
		break;
	case IBV_WR_RDMA_WRITE_WITH_IMM:
		wqe->base.op = IONIC_OP(ctx->version, RDMA_WRITE_IMM);
		wqe->base.imm_data_key = wr->imm_data;
		break;
	default:
		return EINVAL;
	}

	wqe->common.rdma.remote_va_high =
		htobe32(wr->wr.rdma.remote_addr >> 32);
	wqe->common.rdma.remote_va_low = htobe32(wr->wr.rdma.remote_addr);
	wqe->common.rdma.remote_rkey = htobe32(wr->wr.rdma.rkey);

	return ionic_v1_prep_common(qp, wr, meta, wqe);
}

static int ionic_v1_prep_atomic(struct ionic_qp *qp,
				struct ibv_send_wr *wr)
{
	struct ionic_ctx *ctx = to_ionic_ctx(qp->vqp.qp.context);
	struct ionic_sq_meta *meta;
	struct ionic_v1_wqe *wqe;

	if (wr->num_sge != 1 || wr->sg_list[0].length != 8)
		return EINVAL;

	if (wr->send_flags & (IBV_SEND_SOLICITED | IBV_SEND_INLINE))
		return EINVAL;

	meta = &qp->sq.meta[qp->sq.queue.prod];
	wqe = ionic_queue_at_prod(&qp->sq.queue);

	ionic_prep_sq_wqe(qp, wqe);

	switch (wr->opcode) {
	case IBV_WR_ATOMIC_CMP_AND_SWP:
		meta->ibop = IBV_WC_COMP_SWAP;
		wqe->base.op = IONIC_OP(ctx->version, ATOMIC_CS);
		wqe->atomic.swap_add_high = htobe32(wr->wr.atomic.swap >> 32);
		wqe->atomic.swap_add_low = htobe32(wr->wr.atomic.swap);
		wqe->atomic.compare_high =
			htobe32(wr->wr.atomic.compare_add >> 32);
		wqe->atomic.compare_low = htobe32(wr->wr.atomic.compare_add);
		break;
	case IBV_WR_ATOMIC_FETCH_AND_ADD:
		meta->ibop = IBV_WC_FETCH_ADD;
		wqe->base.op = IONIC_OP(ctx->version, ATOMIC_FA);
		wqe->atomic.swap_add_high =
			htobe32(wr->wr.atomic.compare_add >> 32);
		wqe->atomic.swap_add_low = htobe32(wr->wr.atomic.compare_add);
		break;
	default:
		return EINVAL;
	}

	wqe->atomic.remote_va_high = htobe32(wr->wr.atomic.remote_addr >> 32);
	wqe->atomic.remote_va_low = htobe32(wr->wr.atomic.remote_addr);
	wqe->atomic.remote_rkey = htobe32(wr->wr.atomic.rkey);

	wqe->base.num_sge_key = 1;

	/*
	 * The fields above are common to atomic and atomic_v2. Deal now with
	 * the fields that differ.
	 */
	if (likely(ctx->version >= 2)) {
		wqe->atomic_v2.local_va = htobe64(wr->sg_list[0].addr);
		wqe->atomic_v2.lkey = htobe32(wr->sg_list[0].lkey);
	} else {
		wqe->atomic.sge.va = htobe64(wr->sg_list[0].addr);
		wqe->atomic.sge.len = htobe32(8);
		wqe->atomic.sge.lkey = htobe32(wr->sg_list[0].lkey);
	}

	ionic_v1_prep_base(qp, wr, meta, wqe);

	return 0;
}

static int ionic_v1_prep_inv(struct ionic_qp *qp, struct ibv_send_wr *wr)
{
	struct ionic_ctx *ctx = to_ionic_ctx(qp->vqp.qp.context);
	struct ionic_sq_meta *meta;
	struct ionic_v1_wqe *wqe;

	if (wr->send_flags & (IBV_SEND_SOLICITED | IBV_SEND_INLINE))
		return EINVAL;

	meta = &qp->sq.meta[qp->sq.queue.prod];
	meta->ibop = IBV_WC_LOCAL_INV;
	wqe = ionic_queue_at_prod(&qp->sq.queue);

	ionic_prep_sq_wqe(qp, wqe);

	wqe->base.op = IONIC_OP(ctx->version, LOCAL_INV);
	wqe->base.imm_data_key = htobe32(wr->invalidate_rkey);

	ionic_v1_prep_base(qp, wr, meta, wqe);

	return 0;
}

static int ionic_v1_prep_bind(struct ionic_qp *qp,
			      struct ibv_send_wr *wr,
			      bool send_path)
{
	struct ionic_ctx *ctx = to_ionic_ctx(qp->vqp.qp.context);
	struct ionic_sq_meta *meta;
	struct ionic_v1_wqe *wqe;
	int flags;

	if (wr->send_flags & (IBV_SEND_SOLICITED | IBV_SEND_INLINE))
		return EINVAL;

	/* type 1 must use bind_mw; type 2 must use post_send */
	if (send_path == (wr->bind_mw.mw->type == IBV_MW_TYPE_1))
		return EINVAL;

	/* only type 1 can unbind with zero length */
	if (!wr->bind_mw.bind_info.length &&
	    wr->bind_mw.mw->type != IBV_MW_TYPE_1)
		return EINVAL;

	meta = &qp->sq.meta[qp->sq.queue.prod];
	meta->ibop = IBV_WC_BIND_MW;
	wqe = ionic_queue_at_prod(&qp->sq.queue);

	ionic_prep_sq_wqe(qp, wqe);

	flags = to_ionic_mr_flags(wr->bind_mw.bind_info.mw_access_flags);

	if (wr->bind_mw.mw->type == IBV_MW_TYPE_1)
		flags |= IONIC_MRF_MW_1;
	else
		flags |= IONIC_MRF_MW_2;

	wqe->base.op = IONIC_OP(ctx->version, BIND_MW);
	wqe->base.num_sge_key = wr->bind_mw.rkey;
	wqe->base.imm_data_key = htobe32(wr->bind_mw.mw->rkey);
	wqe->bind_mw.va = htobe64(wr->bind_mw.bind_info.addr);
	wqe->bind_mw.length = htobe64(wr->bind_mw.bind_info.length);
	wqe->bind_mw.lkey = htobe32(wr->bind_mw.bind_info.mr->lkey);
	wqe->bind_mw.flags = htobe16(flags);

	ionic_v1_prep_base(qp, wr, meta, wqe);

	return 0;
}

static int ionic_v1_prep_one_rc(struct ionic_qp *qp,
				struct ibv_send_wr *wr,
				bool send_path)
{
	struct ionic_ctx *ctx = to_ionic_ctx(qp->vqp.qp.context);
	int rc = 0;

	switch (wr->opcode) {
	case IBV_WR_SEND:
	case IBV_WR_SEND_WITH_IMM:
	case IBV_WR_SEND_WITH_INV:
		rc = ionic_v1_prep_send(qp, wr);
		break;
	case IBV_WR_RDMA_READ:
	case IBV_WR_RDMA_WRITE:
	case IBV_WR_RDMA_WRITE_WITH_IMM:
		rc = ionic_v1_prep_rdma(qp, wr);
		break;
	case IBV_WR_ATOMIC_CMP_AND_SWP:
	case IBV_WR_ATOMIC_FETCH_AND_ADD:
		rc = ionic_v1_prep_atomic(qp, wr);
		break;
	case IBV_WR_LOCAL_INV:
		rc = ionic_v1_prep_inv(qp, wr);
		break;
	case IBV_WR_BIND_MW:
		rc = ionic_v1_prep_bind(qp, wr, send_path);
		break;
	default:
		verbs_warn(&ctx->vctx, "invalid opcode %d", wr->opcode);
		rc = EINVAL;
	}

	return rc;
}

static int ionic_v1_prep_one_ud(struct ionic_qp *qp,
				struct ibv_send_wr *wr)
{
	struct ionic_ctx *ctx = to_ionic_ctx(qp->vqp.qp.context);
	int rc = 0;

	switch (wr->opcode) {
	case IBV_WR_SEND:
	case IBV_WR_SEND_WITH_IMM:
		rc = ionic_v1_prep_send_ud(qp, wr);
		break;
	default:
		verbs_warn(&ctx->vctx, "invalid opcode %d", wr->opcode);
		rc = EINVAL;
	}

	return rc;
}

static void ionic_post_cmb_common(struct ionic_ctx *ctx,
				  struct ionic_queue *queue,
				  uint8_t cmb,
				  void *cmb_ptr,
				  uint16_t *cmb_prod,
				  uint8_t qtype,
				  uint32_t qpid)
{
	void *cmb_dst_ptr;
	void *wqe_src_ptr;
	uint32_t stride;
	uint16_t pos, end;
	uint8_t stride_log2, cmb_wc;

	stride_log2 = queue->stride_log2;

	pos = *cmb_prod;
	end = queue->prod;

	cmb_wc = !(cmb & IONIC_CMB_UC);

	if (cmb & IONIC_CMB_EXPDB) {
		/* Express doorbell mode: copy each WQE individually with barriers */
		while (pos != end) {
			cmb_dst_ptr = cmb_ptr + ((size_t)pos << stride_log2);
			wqe_src_ptr = ionic_queue_at(queue, pos);

			stride = 1u << stride_log2;
			do {
				udma_to_device_barrier();
				/* only fence before last 64B of each
				 * WC wqe, no need to mmio_wc_start()
				 */
				if (cmb_wc && stride <= 64)
					mmio_flush_writes();
				ionic_mmio_memcpy_x64_64(cmb_dst_ptr, wqe_src_ptr);

				stride -= 64;
				cmb_dst_ptr += 64;
				wqe_src_ptr += 64;
			} while (stride);

			pos = ionic_queue_next(queue, pos);
		}
	} else {
		/* Regular doorbell mode: bulk copy with wrap-around handling */
		if (pos > end) {
			/* Handle wrap-around case: copy from pos to end of ring */
			cmb_dst_ptr = cmb_ptr + ((size_t)pos << stride_log2);
			wqe_src_ptr = ionic_queue_at(queue, pos);
			stride = (uint32_t)(queue->mask - pos + 1) << stride_log2;

			ionic_mmio_memcpy_x64(cmb_dst_ptr, wqe_src_ptr, stride);

			pos = 0;
		}

		if (pos < end) {
			/* Copy from pos to end */
			cmb_dst_ptr = cmb_ptr + ((size_t)pos << stride_log2);
			wqe_src_ptr = ionic_queue_at(queue, pos);
			stride = (uint32_t)(end - pos) << stride_log2;

			ionic_mmio_memcpy_x64(cmb_dst_ptr, wqe_src_ptr, stride);

			pos = end;
		}

		if (cmb_wc)
			mmio_flush_writes();

		/* Ring doorbell */
		verbs_debug(&ctx->vctx, "dbell qp %u qtype %d val %" PRIx64,
			    qpid, qtype, queue->dbell | pos);
		ionic_dbell_ring(&ctx->dbpage[qtype], queue->dbell | pos);
	}

	*cmb_prod = end;
}

static void ionic_post_send_cmb(struct ionic_ctx *ctx, struct ionic_qp *qp)
{
	ionic_post_cmb_common(ctx,
			      &qp->sq.queue,
			      qp->sq.cmb,
			      qp->sq.cmb_ptr,
			      &qp->sq.cmb_prod,
			      ctx->sq_qtype,
			      qp->qpid);
}

static void ionic_post_recv_cmb(struct ionic_ctx *ctx, struct ionic_qp *qp)
{
	ionic_post_cmb_common(ctx,
			      &qp->rq.queue,
			      qp->rq.cmb,
			      qp->rq.cmb_ptr,
			      &qp->rq.cmb_prod,
			      ctx->rq_qtype,
			      qp->qpid);
}

static int ionic_post_send_common(struct ionic_ctx *ctx,
				  struct ionic_cq *cq,
				  struct ionic_qp *qp,
				  struct ibv_send_wr *wr,
				  struct ibv_send_wr **bad,
				  bool send_path)
{
	int spend, rc = 0;
	uint16_t old_prod;

	if (unlikely(!bad))
		return EINVAL;

	if (unlikely(!qp->has_sq)) {
		*bad = wr;
		return EINVAL;
	}

	if (unlikely(qp->vqp.qp.state < IBV_QPS_RTS)) {
		*bad = wr;
		return EINVAL;
	}

	ionic_sq_spin_lock(qp);

	old_prod = qp->sq.queue.prod;

	while (wr) {
		if (ionic_queue_full(&qp->sq.queue)) {
			verbs_info(&ctx->vctx,
				   "send queue full cons %u prod %u",
				   qp->sq.queue.cons, qp->sq.queue.prod);
			rc = ENOMEM;
			goto out;
		}

		if (qp->vqp.qp.qp_type == IBV_QPT_UD)
			rc = ionic_v1_prep_one_ud(qp, wr);
		else
			rc = ionic_v1_prep_one_rc(qp, wr, send_path);
		if (rc)
			goto out;

		wr = wr->next;
	}

out:
	old_prod = (qp->sq.queue.prod - old_prod) & qp->sq.queue.mask;

	if (ionic_cq_spin_trylock(cq)) {
		ionic_sq_spin_unlock(qp);
		ionic_cq_spin_lock(cq);
		ionic_sq_spin_lock(qp);
	}

	if (likely(qp->sq.queue.prod != qp->sq.old_prod)) {
		/* ring cq doorbell just in time */
		spend = (qp->sq.queue.prod - qp->sq.old_prod) & qp->sq.queue.mask;
		ionic_reserve_cq(ctx, cq, spend);

		qp->sq.old_prod = qp->sq.queue.prod;

		if (qp->sq.cmb_ptr) {
			ionic_post_send_cmb(ctx, qp);
		} else {
			udma_to_device_barrier();
			verbs_debug(&ctx->vctx, "dbell qp %u sq val %" PRIx64,
				    qp->qpid, ionic_queue_dbell_val(&qp->sq.queue));
			ionic_dbell_ring(&ctx->dbpage[ctx->sq_qtype],
					 ionic_queue_dbell_val(&qp->sq.queue));
		}
	}

	if (qp->sq.flush) {
		cq->flush = true;
		list_del(&qp->cq_flush_sq);
		list_add_tail(&cq->flush_sq, &qp->cq_flush_sq);
	}

	ionic_sq_spin_unlock(qp);
	ionic_cq_spin_unlock(cq);

	*bad = wr;
	return rc;
}

static int ionic_v1_prep_recv(struct ionic_qp *qp,
			      struct ibv_recv_wr *wr)
{
	struct ionic_ctx *ctx = to_ionic_ctx(qp->vqp.qp.context);
	struct ionic_rq_meta *meta;
	struct ionic_v1_wqe *wqe;
	int64_t signed_len;
	uint32_t mval;

	wqe = ionic_queue_at_prod(&qp->rq.queue);

	/* if wqe is owned by device, caller can try posting again soon */
	if (wqe->base.flags & htobe16(IONIC_V1_FLAG_FENCE))
		return -EAGAIN;

	meta = qp->rq.meta_head;
	if (unlikely(meta == IONIC_META_LAST) ||
	    unlikely(meta == IONIC_META_POSTED))
		return -EIO;

	ionic_prep_rq_wqe(qp, wqe);

	mval = ionic_v1_recv_wqe_max_sge(qp->rq.queue.stride_log2,
					 qp->rq.spec, qp->rq.cmb & IONIC_CMB_EXPDB);
	signed_len = ionic_v1_prep_pld(wqe, &wqe->recv.pld,
				       qp->rq.spec, mval,
				       wr->sg_list, wr->num_sge);
	if (signed_len < 0)
		return -signed_len;

	meta->wrid = wr->wr_id;

	wqe->base.wqe_idx = htole64(qp->rq.queue.prod);
	wqe->base.num_sge_key = wr->num_sge;

	qp->rq.meta_idx[qp->rq.queue.prod] = meta - qp->rq.meta;

	/* total length for recv goes in base imm_data_key */
	wqe->base.imm_data_key = htobe32(signed_len);

	verbs_debug(&ctx->vctx, "post recv %u prod %u",
		    qp->qpid, qp->rq.queue.prod);
	ionic_dbg_xdump(ctx, "wqe", wqe, 1u << qp->rq.queue.stride_log2);
	ionic_queue_produce(&qp->rq.queue);

	qp->rq.meta_head = meta->next;
	meta->next = IONIC_META_POSTED;

	return 0;
}

static int ionic_post_recv_common(struct ionic_ctx *ctx,
				  struct ionic_cq *cq,
				  struct ionic_qp *qp,
				  struct ibv_recv_wr *wr,
				  struct ibv_recv_wr **bad)
{
	int spend, rc = 0;
	uint16_t old_prod;

	if (unlikely(!bad))
		return EINVAL;

	if (unlikely(!qp->has_rq)) {
		*bad = wr;
		return EINVAL;
	}

	if (unlikely(qp->vqp.qp.state < IBV_QPS_INIT)) {
		*bad = wr;
		return EINVAL;
	}

	ionic_rq_spin_lock(qp);

	old_prod = qp->rq.queue.prod;

	while (wr) {
		if (ionic_queue_full(&qp->rq.queue)) {
			verbs_info(&ctx->vctx, "recv queue full cons %u prod %u",
				   qp->rq.queue.cons, qp->rq.queue.prod);
			rc = ENOMEM;
			goto out;
		}

		rc = ionic_v1_prep_recv(qp, wr);
		if (rc)
			goto out;

		wr = wr->next;
	}

out:
	old_prod = (qp->rq.queue.prod - old_prod) & qp->rq.queue.mask;

	if (!cq) {
		ionic_rq_spin_unlock(qp);
		goto out_unlocked;
	}

	if (ionic_cq_spin_trylock(cq)) {
		ionic_rq_spin_unlock(qp);
		ionic_cq_spin_lock(cq);
		ionic_rq_spin_lock(qp);
	}

	if (likely(qp->rq.queue.prod != qp->rq.old_prod)) {
		/* ring cq doorbell just in time */
		spend = (qp->rq.queue.prod - qp->rq.old_prod) & qp->rq.queue.mask;
		ionic_reserve_cq(ctx, cq, spend);

		qp->rq.old_prod = qp->rq.queue.prod;

		if (qp->rq.cmb_ptr) {
			ionic_post_recv_cmb(ctx, qp);
		} else {
			udma_to_device_barrier();
			verbs_debug(&ctx->vctx, "dbell qp %u rq val %" PRIx64,
				    qp->qpid,
				    ionic_queue_dbell_val(&qp->rq.queue));
			ionic_dbell_ring(&ctx->dbpage[ctx->rq_qtype],
					 ionic_queue_dbell_val(&qp->rq.queue));
		}
	}

	if (qp->rq.flush) {
		cq->flush = true;
		list_del(&qp->cq_flush_rq);
		list_add_tail(&cq->flush_rq, &qp->cq_flush_rq);
	}

	ionic_rq_spin_unlock(qp);
	ionic_cq_spin_unlock(cq);

out_unlocked:
	*bad = wr;

	return rc;
}

static int ionic_post_send(struct ibv_qp *ibqp,
			   struct ibv_send_wr *wr,
			   struct ibv_send_wr **bad)
{
	struct ionic_ctx *ctx = to_ionic_ctx(ibqp->context);
	struct ionic_qp *qp = to_ionic_qp(ibqp);
	struct ionic_cq *cq = to_ionic_vcq_cq(qp->vqp.qp.send_cq, qp->udma_idx);

	return ionic_post_send_common(ctx, cq, qp, wr, bad, true);
}

static int ionic_post_recv(struct ibv_qp *ibqp,
			   struct ibv_recv_wr *wr,
			   struct ibv_recv_wr **bad)
{
	struct ionic_ctx *ctx = to_ionic_ctx(ibqp->context);
	struct ionic_qp *qp = to_ionic_qp(ibqp);
	struct ionic_cq *cq = to_ionic_vcq_cq(qp->vqp.qp.recv_cq, qp->udma_idx);

	return ionic_post_recv_common(ctx, cq, qp, wr, bad);
}

static struct ibv_qp *ionic_create_qp(struct ibv_pd *ibpd,
				      struct ibv_qp_init_attr *attr)
{
	struct ibv_qp_init_attr_ex ex = {
		.qp_context = attr->qp_context,
		.send_cq = attr->send_cq,
		.recv_cq = attr->recv_cq,
		.srq = attr->srq,
		.cap = attr->cap,
		.qp_type = attr->qp_type,
		.sq_sig_all = attr->sq_sig_all,
		.comp_mask = IBV_QP_INIT_ATTR_PD,
		.pd = ibpd,
	};
	struct verbs_context *vctx;
	struct ibv_qp *ibqp;

	vctx = container_of(ibpd->context, struct verbs_context, context);
	ibqp = vctx->create_qp_ex(&vctx->context, &ex);

	attr->cap = ex.cap;

	return ibqp;
}

static struct ibv_ah *ionic_create_ah(struct ibv_pd *ibpd,
				      struct ibv_ah_attr *attr)
{
	struct ibv_pd *root_ibpd = to_ionic_root_ibpd(ibpd);
	struct uionic_ah_resp resp;
	struct ionic_ah *ah;
	int rc;

	ah = calloc(1, sizeof(*ah));
	if (!ah) {
		rc = errno;
		goto err_ah;
	}

	rc = ibv_cmd_create_ah(root_ibpd, &ah->ibah, attr,
			       &resp.ibv_resp, sizeof(resp));
	if (rc)
		goto err_cmd;

	ah->ahid = resp.ahid;

	return &ah->ibah;

err_cmd:
	free(ah);
err_ah:
	errno = rc;
	return NULL;
}

static int ionic_destroy_ah(struct ibv_ah *ibah)
{
	struct ionic_ah *ah = to_ionic_ah(ibah);
	int rc;

	rc = ibv_cmd_destroy_ah(ibah);
	if (rc)
		return rc;

	free(ah);

	return 0;
}

static struct ibv_mw *ionic_alloc_mw(struct ibv_pd *ibpd,
				     enum ibv_mw_type type)
{
	struct ibv_pd *root_ibpd = to_ionic_root_ibpd(ibpd);
	struct ib_uverbs_alloc_mw_resp resp;
	struct ibv_alloc_mw cmd;
	struct ibv_mw *ibmw;
	int rc;

	ibmw = calloc(1, sizeof(*ibmw));
	if (!ibmw) {
		rc = errno;
		goto err_mw;
	}

	rc = ibv_cmd_alloc_mw(root_ibpd, type, ibmw,
			      &cmd, sizeof(cmd),
			      &resp, sizeof(resp));
	if (rc)
		goto err_cmd;

	return ibmw;

err_cmd:
	free(ibmw);
err_mw:
	errno = rc;
	return NULL;
}

static int ionic_bind_mw(struct ibv_qp *ibqp, struct ibv_mw *ibmw,
			 struct ibv_mw_bind *bind)
{
	struct ionic_ctx *ctx = to_ionic_ctx(ibqp->context);
	struct ionic_qp *qp = to_ionic_qp(ibqp);
	struct ionic_cq *cq = to_ionic_vcq_cq(qp->vqp.qp.send_cq, qp->udma_idx);
	struct ibv_send_wr *bad;
	struct ibv_send_wr wr = {
		.opcode = IBV_WR_BIND_MW,
		.wr_id = bind->wr_id,
		.send_flags = bind->send_flags,
		.bind_mw = {
			.mw = ibmw,
			.rkey = ibmw->rkey,
			.bind_info = bind->bind_info,
		}
	};
	int rc;

	if (bind->bind_info.length)
		wr.bind_mw.rkey = ibv_inc_rkey(ibmw->rkey);

	rc = ionic_post_send_common(ctx, cq, qp, &wr, &bad, false);
	if (!rc)
		ibmw->rkey = wr.bind_mw.rkey;

	return rc;
}

static int ionic_dealloc_mw(struct ibv_mw *ibmw)
{
	int rc;

	rc = ibv_cmd_dealloc_mw(ibmw);
	if (rc)
		return rc;

	free(ibmw);

	return 0;
}

static void ionic_free_context(struct ibv_context *ibctx)
{
	struct ionic_ctx *ctx = to_ionic_ctx(ibctx);

	ionic_tbl_destroy(&ctx->qp_tbl);

	pthread_mutex_destroy(&ctx->mut);

	if (ctx->phc_state)
		munmap(ctx->phc_state, IONIC_PAGE_SIZE);

	ionic_unmap(ctx->dbpage_page, 1u << ctx->pg_shift);

	verbs_uninit_context(&ctx->vctx);

	free(ctx);
}

bool is_ionic_ctx(struct ibv_context *ibctx)
{
	/* whatever we do here must be safe with non-ionic ibctx. */
	struct verbs_context *vctx = verbs_get_ctx_op(ibctx, alloc_parent_domain);

	return vctx && vctx->alloc_parent_domain == ionic_alloc_parent_domain;
}

static const struct verbs_context_ops ionic_ctx_ops = {
	.query_device_ex	= ionic_query_device_ex,
	.query_port		= ionic_query_port,
	.alloc_td		= ionic_alloc_td,
	.dealloc_td		= ionic_dealloc_td,
	.alloc_parent_domain	= ionic_alloc_parent_domain,
	.alloc_pd		= ionic_alloc_pd,
	.dealloc_pd		= ionic_dealloc_pd,
	.reg_dmabuf_mr		= ionic_reg_dmabuf_mr,
	.reg_mr			= ionic_reg_mr,
	.dereg_mr		= ionic_dereg_mr,
	.create_cq		= ionic_create_cq,
	.create_cq_ex		= ionic_create_cq_ex,
	.poll_cq		= ionic_poll_cq,
	.req_notify_cq		= ionic_req_notify_cq,
	.destroy_cq		= ionic_destroy_cq,
	.create_qp		= ionic_create_qp,
	.create_qp_ex		= ionic_create_qp_ex,
	.query_qp		= ionic_query_qp,
	.modify_qp		= ionic_modify_qp,
	.destroy_qp		= ionic_destroy_qp,
	.post_send		= ionic_post_send,
	.post_recv		= ionic_post_recv,
	.create_ah		= ionic_create_ah,
	.destroy_ah		= ionic_destroy_ah,
	.alloc_mw		= ionic_alloc_mw,
	.bind_mw		= ionic_bind_mw,
	.dealloc_mw		= ionic_dealloc_mw,
	.free_context		= ionic_free_context,
};

void ionic_verbs_set_ops(struct ionic_ctx *ctx)
{
	verbs_set_ops(&ctx->vctx, &ionic_ctx_ops);
}
