aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw')
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c63
-rw-r--r--drivers/infiniband/hw/mlx4/user.h5
2 files changed, 51 insertions, 17 deletions
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 5706f988e2ec..a824bc5f79fd 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -188,14 +188,32 @@ static int send_wqe_overhead(enum ib_qp_type type)
188 } 188 }
189} 189}
190 190
191static int set_qp_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 enum ib_qp_type type, struct mlx4_ib_qp *qp) 192 struct mlx4_ib_qp *qp)
193{ 193{
194 /* Sanity check QP size before proceeding */ 194 /* Sanity check RQ size before proceeding */
195 if (cap->max_recv_wr > dev->dev->caps.max_wqes ||
196 cap->max_recv_sge > dev->dev->caps.max_rq_sg)
197 return -EINVAL;
198
199 qp->rq.max = cap->max_recv_wr ? roundup_pow_of_two(cap->max_recv_wr) : 0;
200
201 qp->rq.wqe_shift = ilog2(roundup_pow_of_two(cap->max_recv_sge *
202 sizeof (struct mlx4_wqe_data_seg)));
203 qp->rq.max_gs = (1 << qp->rq.wqe_shift) / sizeof (struct mlx4_wqe_data_seg);
204
205 cap->max_recv_wr = qp->rq.max;
206 cap->max_recv_sge = qp->rq.max_gs;
207
208 return 0;
209}
210
211static int set_kernel_sq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
212 enum ib_qp_type type, struct mlx4_ib_qp *qp)
213{
214 /* Sanity check SQ size before proceeding */
195 if (cap->max_send_wr > dev->dev->caps.max_wqes || 215 if (cap->max_send_wr > dev->dev->caps.max_wqes ||
196 cap->max_recv_wr > dev->dev->caps.max_wqes ||
197 cap->max_send_sge > dev->dev->caps.max_sq_sg || 216 cap->max_send_sge > dev->dev->caps.max_sq_sg ||
198 cap->max_recv_sge > dev->dev->caps.max_rq_sg ||
199 cap->max_inline_data + send_wqe_overhead(type) + 217 cap->max_inline_data + send_wqe_overhead(type) +
200 sizeof (struct mlx4_wqe_inline_seg) > dev->dev->caps.max_sq_desc_sz) 218 sizeof (struct mlx4_wqe_inline_seg) > dev->dev->caps.max_sq_desc_sz)
201 return -EINVAL; 219 return -EINVAL;
@@ -208,12 +226,7 @@ static int set_qp_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
208 cap->max_send_sge + 2 > dev->dev->caps.max_sq_sg) 226 cap->max_send_sge + 2 > dev->dev->caps.max_sq_sg)
209 return -EINVAL; 227 return -EINVAL;
210 228
211 qp->rq.max = cap->max_recv_wr ? roundup_pow_of_two(cap->max_recv_wr) : 0; 229 qp->sq.max = cap->max_send_wr ? roundup_pow_of_two(cap->max_send_wr) : 1;
212 qp->sq.max = cap->max_send_wr ? roundup_pow_of_two(cap->max_send_wr) : 0;
213
214 qp->rq.wqe_shift = ilog2(roundup_pow_of_two(cap->max_recv_sge *
215 sizeof (struct mlx4_wqe_data_seg)));
216 qp->rq.max_gs = (1 << qp->rq.wqe_shift) / sizeof (struct mlx4_wqe_data_seg);
217 230
218 qp->sq.wqe_shift = ilog2(roundup_pow_of_two(max(cap->max_send_sge * 231 qp->sq.wqe_shift = ilog2(roundup_pow_of_two(max(cap->max_send_sge *
219 sizeof (struct mlx4_wqe_data_seg), 232 sizeof (struct mlx4_wqe_data_seg),
@@ -233,16 +246,26 @@ static int set_qp_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
233 qp->sq.offset = 0; 246 qp->sq.offset = 0;
234 } 247 }
235 248
236 cap->max_send_wr = qp->sq.max; 249 cap->max_send_wr = qp->sq.max;
237 cap->max_recv_wr = qp->rq.max; 250 cap->max_send_sge = qp->sq.max_gs;
238 cap->max_send_sge = qp->sq.max_gs;
239 cap->max_recv_sge = qp->rq.max_gs;
240 cap->max_inline_data = (1 << qp->sq.wqe_shift) - send_wqe_overhead(type) - 251 cap->max_inline_data = (1 << qp->sq.wqe_shift) - send_wqe_overhead(type) -
241 sizeof (struct mlx4_wqe_inline_seg); 252 sizeof (struct mlx4_wqe_inline_seg);
242 253
243 return 0; 254 return 0;
244} 255}
245 256
257static int set_user_sq_size(struct mlx4_ib_qp *qp,
258 struct mlx4_ib_create_qp *ucmd)
259{
260 qp->sq.max = 1 << ucmd->log_sq_bb_count;
261 qp->sq.wqe_shift = ucmd->log_sq_stride;
262
263 qp->buf_size = (qp->rq.max << qp->rq.wqe_shift) +
264 (qp->sq.max << qp->sq.wqe_shift);
265
266 return 0;
267}
268
246static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, 269static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
247 struct ib_qp_init_attr *init_attr, 270 struct ib_qp_init_attr *init_attr,
248 struct ib_udata *udata, int sqpn, struct mlx4_ib_qp *qp) 271 struct ib_udata *udata, int sqpn, struct mlx4_ib_qp *qp)
@@ -264,7 +287,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
264 qp->sq.head = 0; 287 qp->sq.head = 0;
265 qp->sq.tail = 0; 288 qp->sq.tail = 0;
266 289
267 err = set_qp_size(dev, &init_attr->cap, init_attr->qp_type, qp); 290 err = set_rq_size(dev, &init_attr->cap, qp);
268 if (err) 291 if (err)
269 goto err; 292 goto err;
270 293
@@ -276,6 +299,10 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
276 goto err; 299 goto err;
277 } 300 }
278 301
302 err = set_user_sq_size(qp, &ucmd);
303 if (err)
304 goto err;
305
279 qp->umem = ib_umem_get(pd->uobject->context, ucmd.buf_addr, 306 qp->umem = ib_umem_get(pd->uobject->context, ucmd.buf_addr,
280 qp->buf_size, 0); 307 qp->buf_size, 0);
281 if (IS_ERR(qp->umem)) { 308 if (IS_ERR(qp->umem)) {
@@ -297,6 +324,10 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
297 if (err) 324 if (err)
298 goto err_mtt; 325 goto err_mtt;
299 } else { 326 } else {
327 err = set_kernel_sq_size(dev, &init_attr->cap, init_attr->qp_type, qp);
328 if (err)
329 goto err;
330
300 err = mlx4_ib_db_alloc(dev, &qp->db, 0); 331 err = mlx4_ib_db_alloc(dev, &qp->db, 0);
301 if (err) 332 if (err)
302 goto err; 333 goto err;
diff --git a/drivers/infiniband/hw/mlx4/user.h b/drivers/infiniband/hw/mlx4/user.h
index 5b8eddc9fa83..88c72d56368b 100644
--- a/drivers/infiniband/hw/mlx4/user.h
+++ b/drivers/infiniband/hw/mlx4/user.h
@@ -39,7 +39,7 @@
39 * Increment this value if any changes that break userspace ABI 39 * Increment this value if any changes that break userspace ABI
40 * compatibility are made. 40 * compatibility are made.
41 */ 41 */
42#define MLX4_IB_UVERBS_ABI_VERSION 1 42#define MLX4_IB_UVERBS_ABI_VERSION 2
43 43
44/* 44/*
45 * Make sure that all structs defined in this file remain laid out so 45 * Make sure that all structs defined in this file remain laid out so
@@ -87,6 +87,9 @@ struct mlx4_ib_create_srq_resp {
87struct mlx4_ib_create_qp { 87struct mlx4_ib_create_qp {
88 __u64 buf_addr; 88 __u64 buf_addr;
89 __u64 db_addr; 89 __u64 db_addr;
90 __u8 log_sq_bb_count;
91 __u8 log_sq_stride;
92 __u8 reserved[6];
90}; 93};
91 94
92#endif /* MLX4_IB_USER_H */ 95#endif /* MLX4_IB_USER_H */