IB/ehca: Support UD low-latency QPs
Signed-off-by: Joachim Fenkes <fenkes@de.ibm.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
This commit is contained in:
parent
a6a12947fb
commit
472803dab8
@ -275,6 +275,11 @@ static inline void queue2resp(struct ipzu_queue_resp *resp,
|
||||
resp->toggle_state = queue->toggle_state;
|
||||
}
|
||||
|
||||
static inline int ll_qp_msg_size(int nr_sge)
|
||||
{
|
||||
return 128 << nr_sge;
|
||||
}
|
||||
|
||||
/*
|
||||
* init_qp_queue initializes/constructs r/squeue and registers queue pages.
|
||||
*/
|
||||
@ -363,8 +368,6 @@ struct ehca_qp *internal_create_qp(struct ib_pd *pd,
|
||||
struct ib_srq_init_attr *srq_init_attr,
|
||||
struct ib_udata *udata, int is_srq)
|
||||
{
|
||||
static int da_rc_msg_size[] = { 128, 256, 512, 1024, 2048, 4096 };
|
||||
static int da_ud_sq_msg_size[]={ 128, 384, 896, 1920, 3968 };
|
||||
struct ehca_qp *my_qp;
|
||||
struct ehca_pd *my_pd = container_of(pd, struct ehca_pd, ib_pd);
|
||||
struct ehca_shca *shca = container_of(pd->device, struct ehca_shca,
|
||||
@ -396,6 +399,7 @@ struct ehca_qp *internal_create_qp(struct ib_pd *pd,
|
||||
parms.ll_comp_flags = qp_type & LLQP_COMP_MASK;
|
||||
}
|
||||
qp_type &= 0x1F;
|
||||
init_attr->qp_type &= 0x1F;
|
||||
|
||||
/* handle SRQ base QPs */
|
||||
if (init_attr->srq) {
|
||||
@ -435,23 +439,49 @@ struct ehca_qp *internal_create_qp(struct ib_pd *pd,
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
if (is_llqp && (qp_type != IB_QPT_RC && qp_type != IB_QPT_UD)) {
|
||||
ehca_err(pd->device, "unsupported LL QP Type=%x", qp_type);
|
||||
return ERR_PTR(-EINVAL);
|
||||
} else if (is_llqp && qp_type == IB_QPT_RC &&
|
||||
(init_attr->cap.max_send_wr > 255 ||
|
||||
init_attr->cap.max_recv_wr > 255 )) {
|
||||
ehca_err(pd->device, "Invalid Number of max_sq_wr=%x "
|
||||
"or max_rq_wr=%x for RC LLQP",
|
||||
init_attr->cap.max_send_wr,
|
||||
init_attr->cap.max_recv_wr);
|
||||
return ERR_PTR(-EINVAL);
|
||||
} else if (is_llqp && qp_type == IB_QPT_UD &&
|
||||
init_attr->cap.max_send_wr > 255) {
|
||||
ehca_err(pd->device,
|
||||
"Invalid Number of max_send_wr=%x for UD QP_TYPE=%x",
|
||||
init_attr->cap.max_send_wr, qp_type);
|
||||
return ERR_PTR(-EINVAL);
|
||||
if (is_llqp) {
|
||||
switch (qp_type) {
|
||||
case IB_QPT_RC:
|
||||
if ((init_attr->cap.max_send_wr > 255) ||
|
||||
(init_attr->cap.max_recv_wr > 255)) {
|
||||
ehca_err(pd->device,
|
||||
"Invalid Number of max_sq_wr=%x "
|
||||
"or max_rq_wr=%x for RC LLQP",
|
||||
init_attr->cap.max_send_wr,
|
||||
init_attr->cap.max_recv_wr);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
break;
|
||||
case IB_QPT_UD:
|
||||
if (!EHCA_BMASK_GET(HCA_CAP_UD_LL_QP, shca->hca_cap)) {
|
||||
ehca_err(pd->device, "UD LLQP not supported "
|
||||
"by this adapter");
|
||||
return ERR_PTR(-ENOSYS);
|
||||
}
|
||||
if (!(init_attr->cap.max_send_sge <= 5
|
||||
&& init_attr->cap.max_send_sge >= 1
|
||||
&& init_attr->cap.max_recv_sge <= 5
|
||||
&& init_attr->cap.max_recv_sge >= 1)) {
|
||||
ehca_err(pd->device,
|
||||
"Invalid Number of max_send_sge=%x "
|
||||
"or max_recv_sge=%x for UD LLQP",
|
||||
init_attr->cap.max_send_sge,
|
||||
init_attr->cap.max_recv_sge);
|
||||
return ERR_PTR(-EINVAL);
|
||||
} else if (init_attr->cap.max_send_wr > 255) {
|
||||
ehca_err(pd->device,
|
||||
"Invalid Number of "
|
||||
"ax_send_wr=%x for UD QP_TYPE=%x",
|
||||
init_attr->cap.max_send_wr, qp_type);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ehca_err(pd->device, "unsupported LL QP Type=%x",
|
||||
qp_type);
|
||||
return ERR_PTR(-EINVAL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pd->uobject && udata)
|
||||
@ -509,7 +539,7 @@ struct ehca_qp *internal_create_qp(struct ib_pd *pd,
|
||||
/* UD_AV CIRCUMVENTION */
|
||||
max_send_sge = init_attr->cap.max_send_sge;
|
||||
max_recv_sge = init_attr->cap.max_recv_sge;
|
||||
if (parms.servicetype == ST_UD) {
|
||||
if (parms.servicetype == ST_UD && !is_llqp) {
|
||||
max_send_sge += 2;
|
||||
max_recv_sge += 2;
|
||||
}
|
||||
@ -547,8 +577,8 @@ struct ehca_qp *internal_create_qp(struct ib_pd *pd,
|
||||
rwqe_size = offsetof(struct ehca_wqe, u.nud.sg_list[
|
||||
(parms.act_nr_recv_sges)]);
|
||||
} else { /* for LLQP we need to use msg size, not wqe size */
|
||||
swqe_size = da_rc_msg_size[max_send_sge];
|
||||
rwqe_size = da_rc_msg_size[max_recv_sge];
|
||||
swqe_size = ll_qp_msg_size(max_send_sge);
|
||||
rwqe_size = ll_qp_msg_size(max_recv_sge);
|
||||
parms.act_nr_send_sges = 1;
|
||||
parms.act_nr_recv_sges = 1;
|
||||
}
|
||||
@ -563,15 +593,15 @@ struct ehca_qp *internal_create_qp(struct ib_pd *pd,
|
||||
case IB_QPT_UD:
|
||||
case IB_QPT_GSI:
|
||||
case IB_QPT_SMI:
|
||||
/* UD circumvention */
|
||||
parms.act_nr_recv_sges -= 2;
|
||||
parms.act_nr_send_sges -= 2;
|
||||
if (is_llqp) {
|
||||
swqe_size = da_ud_sq_msg_size[max_send_sge];
|
||||
rwqe_size = da_rc_msg_size[max_recv_sge];
|
||||
swqe_size = ll_qp_msg_size(parms.act_nr_send_sges);
|
||||
rwqe_size = ll_qp_msg_size(parms.act_nr_recv_sges);
|
||||
parms.act_nr_send_sges = 1;
|
||||
parms.act_nr_recv_sges = 1;
|
||||
} else {
|
||||
/* UD circumvention */
|
||||
parms.act_nr_send_sges -= 2;
|
||||
parms.act_nr_recv_sges -= 2;
|
||||
swqe_size = offsetof(struct ehca_wqe,
|
||||
u.ud_av.sg_list[parms.act_nr_send_sges]);
|
||||
rwqe_size = offsetof(struct ehca_wqe,
|
||||
|
Loading…
Reference in New Issue
Block a user