aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/mlx4/qp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/mlx4/qp.c')
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c33
1 files changed, 22 insertions, 11 deletions
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index dc137dec2308..5c6d05427a0f 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -189,18 +189,28 @@ static int send_wqe_overhead(enum ib_qp_type type)
189} 189}
190 190
191static int set_rq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap, 191static int set_rq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
192 struct mlx4_ib_qp *qp) 192 int is_user, int has_srq, struct mlx4_ib_qp *qp)
193{ 193{
194 /* Sanity check RQ size before proceeding */ 194 /* Sanity check RQ size before proceeding */
195 if (cap->max_recv_wr > dev->dev->caps.max_wqes || 195 if (cap->max_recv_wr > dev->dev->caps.max_wqes ||
196 cap->max_recv_sge > dev->dev->caps.max_rq_sg) 196 cap->max_recv_sge > dev->dev->caps.max_rq_sg)
197 return -EINVAL; 197 return -EINVAL;
198 198
199 qp->rq.max = cap->max_recv_wr ? roundup_pow_of_two(cap->max_recv_wr) : 0; 199 if (has_srq) {
200 /* QPs attached to an SRQ should have no RQ */
201 if (cap->max_recv_wr)
202 return -EINVAL;
203
204 qp->rq.max = qp->rq.max_gs = 0;
205 } else {
206 /* HW requires >= 1 RQ entry with >= 1 gather entry */
207 if (is_user && (!cap->max_recv_wr || !cap->max_recv_sge))
208 return -EINVAL;
200 209
201 qp->rq.wqe_shift = ilog2(roundup_pow_of_two(cap->max_recv_sge * 210 qp->rq.max = roundup_pow_of_two(max(1, cap->max_recv_wr));
202 sizeof (struct mlx4_wqe_data_seg))); 211 qp->rq.max_gs = roundup_pow_of_two(max(1, cap->max_recv_sge));
203 qp->rq.max_gs = (1 << qp->rq.wqe_shift) / sizeof (struct mlx4_wqe_data_seg); 212 qp->rq.wqe_shift = ilog2(qp->rq.max_gs * sizeof (struct mlx4_wqe_data_seg));
213 }
204 214
205 cap->max_recv_wr = qp->rq.max; 215 cap->max_recv_wr = qp->rq.max;
206 cap->max_recv_sge = qp->rq.max_gs; 216 cap->max_recv_sge = qp->rq.max_gs;
@@ -285,7 +295,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
285 qp->sq.head = 0; 295 qp->sq.head = 0;
286 qp->sq.tail = 0; 296 qp->sq.tail = 0;
287 297
288 err = set_rq_size(dev, &init_attr->cap, qp); 298 err = set_rq_size(dev, &init_attr->cap, !!pd->uobject, !!init_attr->srq, qp);
289 if (err) 299 if (err)
290 goto err; 300 goto err;
291 301
@@ -762,11 +772,6 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
762 optpar |= MLX4_QP_OPTPAR_PKEY_INDEX; 772 optpar |= MLX4_QP_OPTPAR_PKEY_INDEX;
763 } 773 }
764 774
765 if (attr_mask & IB_QP_RNR_RETRY) {
766 context->params1 |= cpu_to_be32(attr->rnr_retry << 13);
767 optpar |= MLX4_QP_OPTPAR_RNR_RETRY;
768 }
769
770 if (attr_mask & IB_QP_AV) { 775 if (attr_mask & IB_QP_AV) {
771 if (mlx4_set_path(dev, &attr->ah_attr, &context->pri_path, 776 if (mlx4_set_path(dev, &attr->ah_attr, &context->pri_path,
772 attr_mask & IB_QP_PORT ? attr->port_num : qp->port)) { 777 attr_mask & IB_QP_PORT ? attr->port_num : qp->port)) {
@@ -802,6 +807,12 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
802 807
803 context->pd = cpu_to_be32(to_mpd(ibqp->pd)->pdn); 808 context->pd = cpu_to_be32(to_mpd(ibqp->pd)->pdn);
804 context->params1 = cpu_to_be32(MLX4_IB_ACK_REQ_FREQ << 28); 809 context->params1 = cpu_to_be32(MLX4_IB_ACK_REQ_FREQ << 28);
810
811 if (attr_mask & IB_QP_RNR_RETRY) {
812 context->params1 |= cpu_to_be32(attr->rnr_retry << 13);
813 optpar |= MLX4_QP_OPTPAR_RNR_RETRY;
814 }
815
805 if (attr_mask & IB_QP_RETRY_CNT) { 816 if (attr_mask & IB_QP_RETRY_CNT) {
806 context->params1 |= cpu_to_be32(attr->retry_cnt << 16); 817 context->params1 |= cpu_to_be32(attr->retry_cnt << 16);
807 optpar |= MLX4_QP_OPTPAR_RETRY_COUNT; 818 optpar |= MLX4_QP_OPTPAR_RETRY_COUNT;