// 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);

#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" (leaf));

	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_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 = {};
	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;

	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_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->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;
	}

	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 = 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);
}

/*
 * 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 = 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;
	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 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;

	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;

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

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

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

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

	/* wqe_id must indicate a request that is outstanding */
	meta = &qp->rq.meta[wqe->base.wqe_id];
	if (unlikely(meta->next != IONIC_META_POSTED)) {
		verbs_err(&ctx->vctx, "wqe not posted %#lx",
			  (unsigned long)wqe->base.wqe_id);
		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;
	uint32_t src_qpn, st_len;
	uint16_t vlan_tag;
	uint8_t op;

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

	qp = cqe_qp;

	st_len = be32toh(cqe->status_length);

	/* ignore wqe_id 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_id must be a valid queue index */
	if (unlikely(cqe->recv.wqe_id >> qp->rq.queue.depth_log2)) {
		verbs_err(&ctx->vctx, "invalid id %#lx",
			  (unsigned long)cqe->recv.wqe_id);
		return -EIO;
	}

	/* wqe_id must indicate a request that is outstanding */
	meta = &qp->rq.meta[qp->rq.meta_idx[cqe->recv.wqe_id]];
	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)cqe->recv.wqe_id,
			  qp->rq.meta_idx[cqe->recv.wqe_id],
			  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;

	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);

	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;
	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;
	}

	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;
	uint16_t cqe_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;
	}

	cqe_idx = cqe->send.npg_wqe_id & qp->sq.queue.mask;
	meta = &qp->sq.meta[cqe_idx];
	meta->local_comp = true;

	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 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;

	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 = 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));
	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);
	}

	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_id = 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_id = 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);

	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_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);
}
