Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ec34a922 authored by Roland Dreier's avatar Roland Dreier Committed by Roland Dreier
Browse files

[PATCH] IB/mthca: Add SRQ implementation



Add mthca support for shared receive queues (SRQs),
including userspace SRQs.

Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent d20a4019
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -9,4 +9,4 @@ obj-$(CONFIG_INFINIBAND_MTHCA) += ib_mthca.o
ib_mthca-y :=	mthca_main.o mthca_cmd.o mthca_profile.o mthca_reset.o \
		mthca_allocator.o mthca_eq.o mthca_pd.o mthca_cq.o \
		mthca_mr.o mthca_qp.o mthca_av.o mthca_mcg.o mthca_mad.o \
		mthca_provider.o mthca_memfree.o mthca_uar.o
		mthca_provider.o mthca_memfree.o mthca_uar.o mthca_srq.o
+24 −0
Original line number Diff line number Diff line
@@ -109,6 +109,7 @@ enum {
	CMD_SW2HW_SRQ 	    = 0x35,
	CMD_HW2SW_SRQ 	    = 0x36,
	CMD_QUERY_SRQ       = 0x37,
	CMD_ARM_SRQ         = 0x40,

	/* QP/EE commands */
	CMD_RST2INIT_QPEE   = 0x19,
@@ -1032,6 +1033,8 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,

	mthca_dbg(dev, "Max QPs: %d, reserved QPs: %d, entry size: %d\n",
		  dev_lim->max_qps, dev_lim->reserved_qps, dev_lim->qpc_entry_sz);
	mthca_dbg(dev, "Max SRQs: %d, reserved SRQs: %d, entry size: %d\n",
		  dev_lim->max_srqs, dev_lim->reserved_srqs, dev_lim->srq_entry_sz);
	mthca_dbg(dev, "Max CQs: %d, reserved CQs: %d, entry size: %d\n",
		  dev_lim->max_cqs, dev_lim->reserved_cqs, dev_lim->cqc_entry_sz);
	mthca_dbg(dev, "Max EQs: %d, reserved EQs: %d, entry size: %d\n",
@@ -1500,6 +1503,27 @@ int mthca_HW2SW_CQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
			     CMD_TIME_CLASS_A, status);
}

int mthca_SW2HW_SRQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
		    int srq_num, u8 *status)
{
	return mthca_cmd(dev, mailbox->dma, srq_num, 0, CMD_SW2HW_SRQ,
			CMD_TIME_CLASS_A, status);
}

int mthca_HW2SW_SRQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
		    int srq_num, u8 *status)
{
	return mthca_cmd_box(dev, 0, mailbox->dma, srq_num, 0,
			     CMD_HW2SW_SRQ,
			     CMD_TIME_CLASS_A, status);
}

int mthca_ARM_SRQ(struct mthca_dev *dev, int srq_num, int limit, u8 *status)
{
	return mthca_cmd(dev, limit, srq_num, 0, CMD_ARM_SRQ,
			 CMD_TIME_CLASS_B, status);
}

int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num,
		    int is_ee, struct mthca_mailbox *mailbox, u32 optmask,
		    u8 *status)
+5 −0
Original line number Diff line number Diff line
@@ -298,6 +298,11 @@ int mthca_SW2HW_CQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
		   int cq_num, u8 *status);
int mthca_HW2SW_CQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
		   int cq_num, u8 *status);
int mthca_SW2HW_SRQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
		    int srq_num, u8 *status);
int mthca_HW2SW_SRQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
		    int srq_num, u8 *status);
int mthca_ARM_SRQ(struct mthca_dev *dev, int srq_num, int limit, u8 *status);
int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num,
		    int is_ee, struct mthca_mailbox *mailbox, u32 optmask,
		    u8 *status);
+20 −12
Original line number Diff line number Diff line
@@ -224,7 +224,8 @@ void mthca_cq_event(struct mthca_dev *dev, u32 cqn)
	cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context);
}

void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn)
void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,
		    struct mthca_srq *srq)
{
	struct mthca_cq *cq;
	struct mthca_cqe *cqe;
@@ -265,8 +266,11 @@ void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn)
	 */
	while (prod_index > cq->cons_index) {
		cqe = get_cqe(cq, (prod_index - 1) & cq->ibcq.cqe);
		if (cqe->my_qpn == cpu_to_be32(qpn))
		if (cqe->my_qpn == cpu_to_be32(qpn)) {
			if (srq)
				mthca_free_srq_wqe(srq, be32_to_cpu(cqe->wqe));
			++nfreed;
		}
		else if (nfreed)
			memcpy(get_cqe(cq, (prod_index - 1 + nfreed) &
				       cq->ibcq.cqe),
@@ -455,23 +459,27 @@ static inline int mthca_poll_one(struct mthca_dev *dev,
			     >> wq->wqe_shift);
		entry->wr_id = (*cur_qp)->wrid[wqe_index +
					       (*cur_qp)->rq.max];
	} else if ((*cur_qp)->ibqp.srq) {
		struct mthca_srq *srq = to_msrq((*cur_qp)->ibqp.srq);
		u32 wqe = be32_to_cpu(cqe->wqe);
		wq = NULL;
		wqe_index = wqe >> srq->wqe_shift;
		entry->wr_id = srq->wrid[wqe_index];
		mthca_free_srq_wqe(srq, wqe);
	} else {
		wq = &(*cur_qp)->rq;
		wqe_index = be32_to_cpu(cqe->wqe) >> wq->wqe_shift;
		entry->wr_id = (*cur_qp)->wrid[wqe_index];
	}

	if (wq) {
		if (wq->last_comp < wqe_index)
			wq->tail += wqe_index - wq->last_comp;
		else
			wq->tail += wqe_index + wq->max - wq->last_comp;

		wq->last_comp = wqe_index;

	if (0)
		mthca_dbg(dev, "%s completion for QP %06x, index %d (nr %d)\n",
			  is_send ? "Send" : "Receive",
			  (*cur_qp)->qpn, wqe_index, wq->max);
	}

	if (is_error) {
		err = handle_error_cqe(dev, cq, *cur_qp, wqe_index, is_send,
+23 −1
Original line number Diff line number Diff line
@@ -218,6 +218,13 @@ struct mthca_cq_table {
	struct mthca_icm_table *table;
};

struct mthca_srq_table {
	struct mthca_alloc 	alloc;
	spinlock_t         	lock;
	struct mthca_array      srq;
	struct mthca_icm_table *table;
};

struct mthca_qp_table {
	struct mthca_alloc     	alloc;
	u32                    	rdb_base;
@@ -299,6 +306,7 @@ struct mthca_dev {
	struct mthca_mr_table  mr_table;
	struct mthca_eq_table  eq_table;
	struct mthca_cq_table  cq_table;
	struct mthca_srq_table srq_table;
	struct mthca_qp_table  qp_table;
	struct mthca_av_table  av_table;
	struct mthca_mcg_table mcg_table;
@@ -372,6 +380,7 @@ int mthca_init_pd_table(struct mthca_dev *dev);
int mthca_init_mr_table(struct mthca_dev *dev);
int mthca_init_eq_table(struct mthca_dev *dev);
int mthca_init_cq_table(struct mthca_dev *dev);
int mthca_init_srq_table(struct mthca_dev *dev);
int mthca_init_qp_table(struct mthca_dev *dev);
int mthca_init_av_table(struct mthca_dev *dev);
int mthca_init_mcg_table(struct mthca_dev *dev);
@@ -381,6 +390,7 @@ void mthca_cleanup_pd_table(struct mthca_dev *dev);
void mthca_cleanup_mr_table(struct mthca_dev *dev);
void mthca_cleanup_eq_table(struct mthca_dev *dev);
void mthca_cleanup_cq_table(struct mthca_dev *dev);
void mthca_cleanup_srq_table(struct mthca_dev *dev);
void mthca_cleanup_qp_table(struct mthca_dev *dev);
void mthca_cleanup_av_table(struct mthca_dev *dev);
void mthca_cleanup_mcg_table(struct mthca_dev *dev);
@@ -431,7 +441,19 @@ int mthca_init_cq(struct mthca_dev *dev, int nent,
void mthca_free_cq(struct mthca_dev *dev,
		   struct mthca_cq *cq);
void mthca_cq_event(struct mthca_dev *dev, u32 cqn);
void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn);
void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,
		    struct mthca_srq *srq);

int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd,
		    struct ib_srq_attr *attr, struct mthca_srq *srq);
void mthca_free_srq(struct mthca_dev *dev, struct mthca_srq *srq);
void mthca_srq_event(struct mthca_dev *dev, u32 srqn,
		     enum ib_event_type event_type);
void mthca_free_srq_wqe(struct mthca_srq *srq, u32 wqe_addr);
int mthca_tavor_post_srq_recv(struct ib_srq *srq, struct ib_recv_wr *wr,
			      struct ib_recv_wr **bad_wr);
int mthca_arbel_post_srq_recv(struct ib_srq *srq, struct ib_recv_wr *wr,
			      struct ib_recv_wr **bad_wr);

void mthca_qp_event(struct mthca_dev *dev, u32 qpn,
		    enum ib_event_type event_type);
Loading