static int efa_sq_initialize()

in efawin/verbs.c [835:901]


static int efa_sq_initialize(struct efa_qp *qp,
			     const struct ibv_qp_init_attr_ex *attr,
			     struct efa_create_qp_resp *resp)
{
	struct efa_context *ctx = to_efa_context(qp->verbs_qp.qp.context);
	struct efa_wq_init_attr wq_attr;
	struct efa_sq *sq = &qp->sq;
	size_t desc_ring_size;
	int err;

	if (!sq->wq.wqe_cnt)
		return 0;

	wq_attr = (struct efa_wq_init_attr) {
		.db_mmap_key = resp->sq_db_mmap_key,
		.db_off = resp->sq_db_offset,
		.cmd_fd = qp->verbs_qp.qp.context->cmd_fd,
		.pgsz = qp->page_size,
		.sub_cq_idx = resp->send_sub_cq_idx,
	};

	err = efa_wq_initialize(&qp->sq.wq, &wq_attr);
	if (err)
		return err;

	sq->desc_offset = resp->llq_desc_offset;
	desc_ring_size = sq->wq.wqe_cnt * sizeof(struct efa_io_tx_wqe);
	sq->desc_ring_mmap_size = align(desc_ring_size + sq->desc_offset,
					qp->page_size);
	sq->max_inline_data = attr->cap.max_inline_data;

	sq->local_queue = malloc(desc_ring_size);
	if (!sq->local_queue) {
		err = ENOMEM;
		goto err_terminate_wq;
	}
#ifndef _WIN32
	sq->desc = mmap(NULL, sq->desc_ring_mmap_size, PROT_WRITE,
			MAP_SHARED, qp->verbs_qp.qp.context->cmd_fd,
			resp->llq_desc_mmap_key);
	if (sq->desc == MAP_FAILED) {
		err = errno;
		goto err_free_local_queue;
	}
	sq->desc += sq->desc_offset;
#endif
	sq->max_wr_rdma_sge = min_t(uint16_t, ctx->max_wr_rdma_sge,
				    EFA_IO_TX_DESC_NUM_RDMA_BUFS);
	sq->max_batch_wr = ctx->max_tx_batch ?
		(ctx->max_tx_batch * 64) / sizeof(struct efa_io_tx_wqe) :
		UINT16_MAX;
	if (ctx->min_sq_wr) {
		/* The device can't accept a doorbell for the whole SQ at once,
		 * set the max batch to at least (SQ size - 1).
		 */
		sq->max_batch_wr = min_t(uint32_t, sq->max_batch_wr,
					 sq->wq.wqe_cnt - 1);
	}

	return 0;

err_free_local_queue:
	free(sq->local_queue);
err_terminate_wq:
	efa_wq_terminate(&sq->wq, qp->page_size);
	return err;
}