aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-23 12:56:11 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-23 12:56:11 -0400
commit0b776eb5426752d4e53354ac89e3710d857e09a7 (patch)
tree1eebeeaabab90de5834b32e72d2e259dc8a4a635 /drivers/infiniband/hw
parent0d6810091cdbd05efeb31654c6a41a6cbdfdd2c8 (diff)
parent77109cc2823f025ccd66ebd9b88fbab90437b2d8 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband: mlx4_core: Increase command timeout for INIT_HCA to 10 seconds IPoIB/cm: Use common CQ for CM send completions IB/uverbs: Fix checking of userspace object ownership IB/mlx4: Sanity check userspace send queue sizes IPoIB: Rewrite "if (!likely(...))" as "if (unlikely(!(...)))" IB/ehca: Enable large page MRs by default IB/ehca: Change meaning of hca_cap_mr_pgsize IB/ehca: Fix ehca_encode_hwpage_size() and alloc_fmr() IB/ehca: Fix masking error in {,re}reg_phys_mr() IB/ehca: Supply QP token for SRQ base QPs IPoIB: Use round_jiffies() for ah_reap_task RDMA/cma: Fix deadlock destroying listen requests RDMA/cma: Add locking around QP accesses IB/mthca: Avoid alignment traps when writing doorbells mlx4_core: Kill mlx4_write64_raw()
Diffstat (limited to 'drivers/infiniband/hw')
-rw-r--r--drivers/infiniband/hw/ehca/ehca_classes.h1
-rw-r--r--drivers/infiniband/hw/ehca/ehca_hca.c1
-rw-r--r--drivers/infiniband/hw/ehca/ehca_main.c20
-rw-r--r--drivers/infiniband/hw/ehca/ehca_mrmw.c57
-rw-r--r--drivers/infiniband/hw/ehca/ehca_qp.c4
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c16
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cq.c53
-rw-r--r--drivers/infiniband/hw/mthca/mthca_doorbell.h13
-rw-r--r--drivers/infiniband/hw/mthca/mthca_eq.c21
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c45
-rw-r--r--drivers/infiniband/hw/mthca/mthca_srq.c11
11 files changed, 107 insertions, 135 deletions
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h
index 3f2d68cff76..2d660ae189e 100644
--- a/drivers/infiniband/hw/ehca/ehca_classes.h
+++ b/drivers/infiniband/hw/ehca/ehca_classes.h
@@ -323,7 +323,6 @@ extern int ehca_static_rate;
323extern int ehca_port_act_time; 323extern int ehca_port_act_time;
324extern int ehca_use_hp_mr; 324extern int ehca_use_hp_mr;
325extern int ehca_scaling_code; 325extern int ehca_scaling_code;
326extern int ehca_mr_largepage;
327 326
328struct ipzu_queue_resp { 327struct ipzu_queue_resp {
329 u32 qe_size; /* queue entry size */ 328 u32 qe_size; /* queue entry size */
diff --git a/drivers/infiniband/hw/ehca/ehca_hca.c b/drivers/infiniband/hw/ehca/ehca_hca.c
index 4aa3ffa6a19..15806d14046 100644
--- a/drivers/infiniband/hw/ehca/ehca_hca.c
+++ b/drivers/infiniband/hw/ehca/ehca_hca.c
@@ -77,6 +77,7 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props)
77 } 77 }
78 78
79 memset(props, 0, sizeof(struct ib_device_attr)); 79 memset(props, 0, sizeof(struct ib_device_attr));
80 props->page_size_cap = shca->hca_cap_mr_pgsize;
80 props->fw_ver = rblock->hw_ver; 81 props->fw_ver = rblock->hw_ver;
81 props->max_mr_size = rblock->max_mr_size; 82 props->max_mr_size = rblock->max_mr_size;
82 props->vendor_id = rblock->vendor_id >> 8; 83 props->vendor_id = rblock->vendor_id >> 8;
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index 7a7dab890f6..c6cd38c5321 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -65,7 +65,7 @@ int ehca_port_act_time = 30;
65int ehca_poll_all_eqs = 1; 65int ehca_poll_all_eqs = 1;
66int ehca_static_rate = -1; 66int ehca_static_rate = -1;
67int ehca_scaling_code = 0; 67int ehca_scaling_code = 0;
68int ehca_mr_largepage = 0; 68int ehca_mr_largepage = 1;
69 69
70module_param_named(open_aqp1, ehca_open_aqp1, int, S_IRUGO); 70module_param_named(open_aqp1, ehca_open_aqp1, int, S_IRUGO);
71module_param_named(debug_level, ehca_debug_level, int, S_IRUGO); 71module_param_named(debug_level, ehca_debug_level, int, S_IRUGO);
@@ -260,13 +260,20 @@ static struct cap_descr {
260 { HCA_CAP_MINI_QP, "HCA_CAP_MINI_QP" }, 260 { HCA_CAP_MINI_QP, "HCA_CAP_MINI_QP" },
261}; 261};
262 262
263int ehca_sense_attributes(struct ehca_shca *shca) 263static int ehca_sense_attributes(struct ehca_shca *shca)
264{ 264{
265 int i, ret = 0; 265 int i, ret = 0;
266 u64 h_ret; 266 u64 h_ret;
267 struct hipz_query_hca *rblock; 267 struct hipz_query_hca *rblock;
268 struct hipz_query_port *port; 268 struct hipz_query_port *port;
269 269
270 static const u32 pgsize_map[] = {
271 HCA_CAP_MR_PGSIZE_4K, 0x1000,
272 HCA_CAP_MR_PGSIZE_64K, 0x10000,
273 HCA_CAP_MR_PGSIZE_1M, 0x100000,
274 HCA_CAP_MR_PGSIZE_16M, 0x1000000,
275 };
276
270 rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL); 277 rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
271 if (!rblock) { 278 if (!rblock) {
272 ehca_gen_err("Cannot allocate rblock memory."); 279 ehca_gen_err("Cannot allocate rblock memory.");
@@ -329,8 +336,15 @@ int ehca_sense_attributes(struct ehca_shca *shca)
329 if (EHCA_BMASK_GET(hca_cap_descr[i].mask, shca->hca_cap)) 336 if (EHCA_BMASK_GET(hca_cap_descr[i].mask, shca->hca_cap))
330 ehca_gen_dbg(" %s", hca_cap_descr[i].descr); 337 ehca_gen_dbg(" %s", hca_cap_descr[i].descr);
331 338
332 shca->hca_cap_mr_pgsize = rblock->memory_page_size_supported; 339 /* translate supported MR page sizes; always support 4K */
340 shca->hca_cap_mr_pgsize = EHCA_PAGESIZE;
341 if (ehca_mr_largepage) { /* support extra sizes only if enabled */
342 for (i = 0; i < ARRAY_SIZE(pgsize_map); i += 2)
343 if (rblock->memory_page_size_supported & pgsize_map[i])
344 shca->hca_cap_mr_pgsize |= pgsize_map[i + 1];
345 }
333 346
347 /* query max MTU from first port -- it's the same for all ports */
334 port = (struct hipz_query_port *)rblock; 348 port = (struct hipz_query_port *)rblock;
335 h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port); 349 h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port);
336 if (h_ret != H_SUCCESS) { 350 if (h_ret != H_SUCCESS) {
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c
index ead7230d773..e239bbf54da 100644
--- a/drivers/infiniband/hw/ehca/ehca_mrmw.c
+++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c
@@ -72,24 +72,14 @@ enum ehca_mr_pgsize {
72 72
73static u32 ehca_encode_hwpage_size(u32 pgsize) 73static u32 ehca_encode_hwpage_size(u32 pgsize)
74{ 74{
75 u32 idx = 0; 75 int log = ilog2(pgsize);
76 pgsize >>= 12; 76 WARN_ON(log < 12 || log > 24 || log & 3);
77 /* 77 return (log - 12) / 4;
78 * map mr page size into hw code:
79 * 0, 1, 2, 3 for 4K, 64K, 1M, 64M
80 */
81 while (!(pgsize & 1)) {
82 idx++;
83 pgsize >>= 4;
84 }
85 return idx;
86} 78}
87 79
88static u64 ehca_get_max_hwpage_size(struct ehca_shca *shca) 80static u64 ehca_get_max_hwpage_size(struct ehca_shca *shca)
89{ 81{
90 if (shca->hca_cap_mr_pgsize & HCA_CAP_MR_PGSIZE_16M) 82 return 1UL << ilog2(shca->hca_cap_mr_pgsize);
91 return EHCA_MR_PGSIZE16M;
92 return EHCA_MR_PGSIZE4K;
93} 83}
94 84
95static struct ehca_mr *ehca_mr_new(void) 85static struct ehca_mr *ehca_mr_new(void)
@@ -259,7 +249,7 @@ struct ib_mr *ehca_reg_phys_mr(struct ib_pd *pd,
259 pginfo.u.phy.num_phys_buf = num_phys_buf; 249 pginfo.u.phy.num_phys_buf = num_phys_buf;
260 pginfo.u.phy.phys_buf_array = phys_buf_array; 250 pginfo.u.phy.phys_buf_array = phys_buf_array;
261 pginfo.next_hwpage = 251 pginfo.next_hwpage =
262 ((u64)iova_start & ~(hw_pgsize - 1)) / hw_pgsize; 252 ((u64)iova_start & ~PAGE_MASK) / hw_pgsize;
263 253
264 ret = ehca_reg_mr(shca, e_mr, iova_start, size, mr_access_flags, 254 ret = ehca_reg_mr(shca, e_mr, iova_start, size, mr_access_flags,
265 e_pd, &pginfo, &e_mr->ib.ib_mr.lkey, 255 e_pd, &pginfo, &e_mr->ib.ib_mr.lkey,
@@ -296,7 +286,7 @@ struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
296 container_of(pd->device, struct ehca_shca, ib_device); 286 container_of(pd->device, struct ehca_shca, ib_device);
297 struct ehca_pd *e_pd = container_of(pd, struct ehca_pd, ib_pd); 287 struct ehca_pd *e_pd = container_of(pd, struct ehca_pd, ib_pd);
298 struct ehca_mr_pginfo pginfo; 288 struct ehca_mr_pginfo pginfo;
299 int ret; 289 int ret, page_shift;
300 u32 num_kpages; 290 u32 num_kpages;
301 u32 num_hwpages; 291 u32 num_hwpages;
302 u64 hwpage_size; 292 u64 hwpage_size;
@@ -351,19 +341,20 @@ struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
351 /* determine number of MR pages */ 341 /* determine number of MR pages */
352 num_kpages = NUM_CHUNKS((virt % PAGE_SIZE) + length, PAGE_SIZE); 342 num_kpages = NUM_CHUNKS((virt % PAGE_SIZE) + length, PAGE_SIZE);
353 /* select proper hw_pgsize */ 343 /* select proper hw_pgsize */
354 if (ehca_mr_largepage && 344 page_shift = PAGE_SHIFT;
355 (shca->hca_cap_mr_pgsize & HCA_CAP_MR_PGSIZE_16M)) { 345 if (e_mr->umem->hugetlb) {
356 int page_shift = PAGE_SHIFT; 346 /* determine page_shift, clamp between 4K and 16M */
357 if (e_mr->umem->hugetlb) { 347 page_shift = (fls64(length - 1) + 3) & ~3;
358 /* determine page_shift, clamp between 4K and 16M */ 348 page_shift = min(max(page_shift, EHCA_MR_PGSHIFT4K),
359 page_shift = (fls64(length - 1) + 3) & ~3; 349 EHCA_MR_PGSHIFT16M);
360 page_shift = min(max(page_shift, EHCA_MR_PGSHIFT4K), 350 }
361 EHCA_MR_PGSHIFT16M); 351 hwpage_size = 1UL << page_shift;
362 } 352
363 hwpage_size = 1UL << page_shift; 353 /* now that we have the desired page size, shift until it's
364 } else 354 * supported, too. 4K is always supported, so this terminates.
365 hwpage_size = EHCA_MR_PGSIZE4K; /* ehca1 only supports 4k */ 355 */
366 ehca_dbg(pd->device, "hwpage_size=%lx", hwpage_size); 356 while (!(hwpage_size & shca->hca_cap_mr_pgsize))
357 hwpage_size >>= 4;
367 358
368reg_user_mr_fallback: 359reg_user_mr_fallback:
369 num_hwpages = NUM_CHUNKS((virt % hwpage_size) + length, hwpage_size); 360 num_hwpages = NUM_CHUNKS((virt % hwpage_size) + length, hwpage_size);
@@ -547,7 +538,7 @@ int ehca_rereg_phys_mr(struct ib_mr *mr,
547 pginfo.u.phy.num_phys_buf = num_phys_buf; 538 pginfo.u.phy.num_phys_buf = num_phys_buf;
548 pginfo.u.phy.phys_buf_array = phys_buf_array; 539 pginfo.u.phy.phys_buf_array = phys_buf_array;
549 pginfo.next_hwpage = 540 pginfo.next_hwpage =
550 ((u64)iova_start & ~(hw_pgsize - 1)) / hw_pgsize; 541 ((u64)iova_start & ~PAGE_MASK) / hw_pgsize;
551 } 542 }
552 if (mr_rereg_mask & IB_MR_REREG_ACCESS) 543 if (mr_rereg_mask & IB_MR_REREG_ACCESS)
553 new_acl = mr_access_flags; 544 new_acl = mr_access_flags;
@@ -809,8 +800,9 @@ struct ib_fmr *ehca_alloc_fmr(struct ib_pd *pd,
809 ib_fmr = ERR_PTR(-EINVAL); 800 ib_fmr = ERR_PTR(-EINVAL);
810 goto alloc_fmr_exit0; 801 goto alloc_fmr_exit0;
811 } 802 }
812 hw_pgsize = ehca_get_max_hwpage_size(shca); 803
813 if ((1 << fmr_attr->page_shift) != hw_pgsize) { 804 hw_pgsize = 1 << fmr_attr->page_shift;
805 if (!(hw_pgsize & shca->hca_cap_mr_pgsize)) {
814 ehca_err(pd->device, "unsupported fmr_attr->page_shift=%x", 806 ehca_err(pd->device, "unsupported fmr_attr->page_shift=%x",
815 fmr_attr->page_shift); 807 fmr_attr->page_shift);
816 ib_fmr = ERR_PTR(-EINVAL); 808 ib_fmr = ERR_PTR(-EINVAL);
@@ -826,6 +818,7 @@ struct ib_fmr *ehca_alloc_fmr(struct ib_pd *pd,
826 818
827 /* register MR on HCA */ 819 /* register MR on HCA */
828 memset(&pginfo, 0, sizeof(pginfo)); 820 memset(&pginfo, 0, sizeof(pginfo));
821 pginfo.hwpage_size = hw_pgsize;
829 /* 822 /*
830 * pginfo.num_hwpages==0, ie register_rpages() will not be called 823 * pginfo.num_hwpages==0, ie register_rpages() will not be called
831 * but deferred to map_phys_fmr() 824 * but deferred to map_phys_fmr()
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c
index e2bd62be11e..de182648b28 100644
--- a/drivers/infiniband/hw/ehca/ehca_qp.c
+++ b/drivers/infiniband/hw/ehca/ehca_qp.c
@@ -451,7 +451,6 @@ static struct ehca_qp *internal_create_qp(
451 has_srq = 1; 451 has_srq = 1;
452 parms.ext_type = EQPT_SRQBASE; 452 parms.ext_type = EQPT_SRQBASE;
453 parms.srq_qpn = my_srq->real_qp_num; 453 parms.srq_qpn = my_srq->real_qp_num;
454 parms.srq_token = my_srq->token;
455 } 454 }
456 455
457 if (is_llqp && has_srq) { 456 if (is_llqp && has_srq) {
@@ -583,6 +582,9 @@ static struct ehca_qp *internal_create_qp(
583 goto create_qp_exit1; 582 goto create_qp_exit1;
584 } 583 }
585 584
585 if (has_srq)
586 parms.srq_token = my_qp->token;
587
586 parms.servicetype = ibqptype2servicetype(qp_type); 588 parms.servicetype = ibqptype2servicetype(qp_type);
587 if (parms.servicetype < 0) { 589 if (parms.servicetype < 0) {
588 ret = -EINVAL; 590 ret = -EINVAL;
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 31a480e5b0d..6b3322486b5 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -63,6 +63,10 @@ struct mlx4_ib_sqp {
63 u8 header_buf[MLX4_IB_UD_HEADER_SIZE]; 63 u8 header_buf[MLX4_IB_UD_HEADER_SIZE];
64}; 64};
65 65
66enum {
67 MLX4_IB_MIN_SQ_STRIDE = 6
68};
69
66static const __be32 mlx4_ib_opcode[] = { 70static const __be32 mlx4_ib_opcode[] = {
67 [IB_WR_SEND] = __constant_cpu_to_be32(MLX4_OPCODE_SEND), 71 [IB_WR_SEND] = __constant_cpu_to_be32(MLX4_OPCODE_SEND),
68 [IB_WR_SEND_WITH_IMM] = __constant_cpu_to_be32(MLX4_OPCODE_SEND_IMM), 72 [IB_WR_SEND_WITH_IMM] = __constant_cpu_to_be32(MLX4_OPCODE_SEND_IMM),
@@ -285,9 +289,17 @@ static int set_kernel_sq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
285 return 0; 289 return 0;
286} 290}
287 291
288static int set_user_sq_size(struct mlx4_ib_qp *qp, 292static int set_user_sq_size(struct mlx4_ib_dev *dev,
293 struct mlx4_ib_qp *qp,
289 struct mlx4_ib_create_qp *ucmd) 294 struct mlx4_ib_create_qp *ucmd)
290{ 295{
296 /* Sanity check SQ size before proceeding */
297 if ((1 << ucmd->log_sq_bb_count) > dev->dev->caps.max_wqes ||
298 ucmd->log_sq_stride >
299 ilog2(roundup_pow_of_two(dev->dev->caps.max_sq_desc_sz)) ||
300 ucmd->log_sq_stride < MLX4_IB_MIN_SQ_STRIDE)
301 return -EINVAL;
302
291 qp->sq.wqe_cnt = 1 << ucmd->log_sq_bb_count; 303 qp->sq.wqe_cnt = 1 << ucmd->log_sq_bb_count;
292 qp->sq.wqe_shift = ucmd->log_sq_stride; 304 qp->sq.wqe_shift = ucmd->log_sq_stride;
293 305
@@ -330,7 +342,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
330 342
331 qp->sq_no_prefetch = ucmd.sq_no_prefetch; 343 qp->sq_no_prefetch = ucmd.sq_no_prefetch;
332 344
333 err = set_user_sq_size(qp, &ucmd); 345 err = set_user_sq_size(dev, qp, &ucmd);
334 if (err) 346 if (err)
335 goto err; 347 goto err;
336 348
diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c
index be6e1e03bda..6bd9f139334 100644
--- a/drivers/infiniband/hw/mthca/mthca_cq.c
+++ b/drivers/infiniband/hw/mthca/mthca_cq.c
@@ -204,16 +204,11 @@ static void dump_cqe(struct mthca_dev *dev, void *cqe_ptr)
204static inline void update_cons_index(struct mthca_dev *dev, struct mthca_cq *cq, 204static inline void update_cons_index(struct mthca_dev *dev, struct mthca_cq *cq,
205 int incr) 205 int incr)
206{ 206{
207 __be32 doorbell[2];
208
209 if (mthca_is_memfree(dev)) { 207 if (mthca_is_memfree(dev)) {
210 *cq->set_ci_db = cpu_to_be32(cq->cons_index); 208 *cq->set_ci_db = cpu_to_be32(cq->cons_index);
211 wmb(); 209 wmb();
212 } else { 210 } else {
213 doorbell[0] = cpu_to_be32(MTHCA_TAVOR_CQ_DB_INC_CI | cq->cqn); 211 mthca_write64(MTHCA_TAVOR_CQ_DB_INC_CI | cq->cqn, incr - 1,
214 doorbell[1] = cpu_to_be32(incr - 1);
215
216 mthca_write64(doorbell,
217 dev->kar + MTHCA_CQ_DOORBELL, 212 dev->kar + MTHCA_CQ_DOORBELL,
218 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock)); 213 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
219 /* 214 /*
@@ -731,17 +726,12 @@ repoll:
731 726
732int mthca_tavor_arm_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags) 727int mthca_tavor_arm_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags)
733{ 728{
734 __be32 doorbell[2]; 729 u32 dbhi = ((flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED ?
730 MTHCA_TAVOR_CQ_DB_REQ_NOT_SOL :
731 MTHCA_TAVOR_CQ_DB_REQ_NOT) |
732 to_mcq(cq)->cqn;
735 733
736 doorbell[0] = cpu_to_be32(((flags & IB_CQ_SOLICITED_MASK) == 734 mthca_write64(dbhi, 0xffffffff, to_mdev(cq->device)->kar + MTHCA_CQ_DOORBELL,
737 IB_CQ_SOLICITED ?
738 MTHCA_TAVOR_CQ_DB_REQ_NOT_SOL :
739 MTHCA_TAVOR_CQ_DB_REQ_NOT) |
740 to_mcq(cq)->cqn);
741 doorbell[1] = (__force __be32) 0xffffffff;
742
743 mthca_write64(doorbell,
744 to_mdev(cq->device)->kar + MTHCA_CQ_DOORBELL,
745 MTHCA_GET_DOORBELL_LOCK(&to_mdev(cq->device)->doorbell_lock)); 735 MTHCA_GET_DOORBELL_LOCK(&to_mdev(cq->device)->doorbell_lock));
746 736
747 return 0; 737 return 0;
@@ -750,19 +740,16 @@ int mthca_tavor_arm_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags)
750int mthca_arbel_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags) 740int mthca_arbel_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags)
751{ 741{
752 struct mthca_cq *cq = to_mcq(ibcq); 742 struct mthca_cq *cq = to_mcq(ibcq);
753 __be32 doorbell[2]; 743 __be32 db_rec[2];
754 u32 sn; 744 u32 dbhi;
755 __be32 ci; 745 u32 sn = cq->arm_sn & 3;
756
757 sn = cq->arm_sn & 3;
758 ci = cpu_to_be32(cq->cons_index);
759 746
760 doorbell[0] = ci; 747 db_rec[0] = cpu_to_be32(cq->cons_index);
761 doorbell[1] = cpu_to_be32((cq->cqn << 8) | (2 << 5) | (sn << 3) | 748 db_rec[1] = cpu_to_be32((cq->cqn << 8) | (2 << 5) | (sn << 3) |
762 ((flags & IB_CQ_SOLICITED_MASK) == 749 ((flags & IB_CQ_SOLICITED_MASK) ==
763 IB_CQ_SOLICITED ? 1 : 2)); 750 IB_CQ_SOLICITED ? 1 : 2));
764 751
765 mthca_write_db_rec(doorbell, cq->arm_db); 752 mthca_write_db_rec(db_rec, cq->arm_db);
766 753
767 /* 754 /*
768 * Make sure that the doorbell record in host memory is 755 * Make sure that the doorbell record in host memory is
@@ -770,14 +757,12 @@ int mthca_arbel_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags)
770 */ 757 */
771 wmb(); 758 wmb();
772 759
773 doorbell[0] = cpu_to_be32((sn << 28) | 760 dbhi = (sn << 28) |
774 ((flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED ? 761 ((flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED ?
775 MTHCA_ARBEL_CQ_DB_REQ_NOT_SOL : 762 MTHCA_ARBEL_CQ_DB_REQ_NOT_SOL :
776 MTHCA_ARBEL_CQ_DB_REQ_NOT) | 763 MTHCA_ARBEL_CQ_DB_REQ_NOT) | cq->cqn;
777 cq->cqn);
778 doorbell[1] = ci;
779 764
780 mthca_write64(doorbell, 765 mthca_write64(dbhi, cq->cons_index,
781 to_mdev(ibcq->device)->kar + MTHCA_CQ_DOORBELL, 766 to_mdev(ibcq->device)->kar + MTHCA_CQ_DOORBELL,
782 MTHCA_GET_DOORBELL_LOCK(&to_mdev(ibcq->device)->doorbell_lock)); 767 MTHCA_GET_DOORBELL_LOCK(&to_mdev(ibcq->device)->doorbell_lock));
783 768
diff --git a/drivers/infiniband/hw/mthca/mthca_doorbell.h b/drivers/infiniband/hw/mthca/mthca_doorbell.h
index dd9a44d170c..b374dc395be 100644
--- a/drivers/infiniband/hw/mthca/mthca_doorbell.h
+++ b/drivers/infiniband/hw/mthca/mthca_doorbell.h
@@ -58,10 +58,10 @@ static inline void mthca_write64_raw(__be64 val, void __iomem *dest)
58 __raw_writeq((__force u64) val, dest); 58 __raw_writeq((__force u64) val, dest);
59} 59}
60 60
61static inline void mthca_write64(__be32 val[2], void __iomem *dest, 61static inline void mthca_write64(u32 hi, u32 lo, void __iomem *dest,
62 spinlock_t *doorbell_lock) 62 spinlock_t *doorbell_lock)
63{ 63{
64 __raw_writeq(*(u64 *) val, dest); 64 __raw_writeq((__force u64) cpu_to_be64((u64) hi << 32 | lo), dest);
65} 65}
66 66
67static inline void mthca_write_db_rec(__be32 val[2], __be32 *db) 67static inline void mthca_write_db_rec(__be32 val[2], __be32 *db)
@@ -87,14 +87,17 @@ static inline void mthca_write64_raw(__be64 val, void __iomem *dest)
87 __raw_writel(((__force u32 *) &val)[1], dest + 4); 87 __raw_writel(((__force u32 *) &val)[1], dest + 4);
88} 88}
89 89
90static inline void mthca_write64(__be32 val[2], void __iomem *dest, 90static inline void mthca_write64(u32 hi, u32 lo, void __iomem *dest,
91 spinlock_t *doorbell_lock) 91 spinlock_t *doorbell_lock)
92{ 92{
93 unsigned long flags; 93 unsigned long flags;
94 94
95 hi = (__force u32) cpu_to_be32(hi);
96 lo = (__force u32) cpu_to_be32(lo);
97
95 spin_lock_irqsave(doorbell_lock, flags); 98 spin_lock_irqsave(doorbell_lock, flags);
96 __raw_writel((__force u32) val[0], dest); 99 __raw_writel(hi, dest);
97 __raw_writel((__force u32) val[1], dest + 4); 100 __raw_writel(lo, dest + 4);
98 spin_unlock_irqrestore(doorbell_lock, flags); 101 spin_unlock_irqrestore(doorbell_lock, flags);
99} 102}
100 103
diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c
index 8592b26dc4e..b29de51b7f3 100644
--- a/drivers/infiniband/hw/mthca/mthca_eq.c
+++ b/drivers/infiniband/hw/mthca/mthca_eq.c
@@ -173,11 +173,6 @@ static inline u64 async_mask(struct mthca_dev *dev)
173 173
174static inline void tavor_set_eq_ci(struct mthca_dev *dev, struct mthca_eq *eq, u32 ci) 174static inline void tavor_set_eq_ci(struct mthca_dev *dev, struct mthca_eq *eq, u32 ci)
175{ 175{
176 __be32 doorbell[2];
177
178 doorbell[0] = cpu_to_be32(MTHCA_EQ_DB_SET_CI | eq->eqn);
179 doorbell[1] = cpu_to_be32(ci & (eq->nent - 1));
180
181 /* 176 /*
182 * This barrier makes sure that all updates to ownership bits 177 * This barrier makes sure that all updates to ownership bits
183 * done by set_eqe_hw() hit memory before the consumer index 178 * done by set_eqe_hw() hit memory before the consumer index
@@ -187,7 +182,7 @@ static inline void tavor_set_eq_ci(struct mthca_dev *dev, struct mthca_eq *eq, u
187 * having set_eqe_hw() overwrite the owner field. 182 * having set_eqe_hw() overwrite the owner field.
188 */ 183 */
189 wmb(); 184 wmb();
190 mthca_write64(doorbell, 185 mthca_write64(MTHCA_EQ_DB_SET_CI | eq->eqn, ci & (eq->nent - 1),
191 dev->kar + MTHCA_EQ_DOORBELL, 186 dev->kar + MTHCA_EQ_DOORBELL,
192 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock)); 187 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
193} 188}
@@ -212,12 +207,7 @@ static inline void set_eq_ci(struct mthca_dev *dev, struct mthca_eq *eq, u32 ci)
212 207
213static inline void tavor_eq_req_not(struct mthca_dev *dev, int eqn) 208static inline void tavor_eq_req_not(struct mthca_dev *dev, int eqn)
214{ 209{
215 __be32 doorbell[2]; 210 mthca_write64(MTHCA_EQ_DB_REQ_NOT | eqn, 0,
216
217 doorbell[0] = cpu_to_be32(MTHCA_EQ_DB_REQ_NOT | eqn);
218 doorbell[1] = 0;
219
220 mthca_write64(doorbell,
221 dev->kar + MTHCA_EQ_DOORBELL, 211 dev->kar + MTHCA_EQ_DOORBELL,
222 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock)); 212 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
223} 213}
@@ -230,12 +220,7 @@ static inline void arbel_eq_req_not(struct mthca_dev *dev, u32 eqn_mask)
230static inline void disarm_cq(struct mthca_dev *dev, int eqn, int cqn) 220static inline void disarm_cq(struct mthca_dev *dev, int eqn, int cqn)
231{ 221{
232 if (!mthca_is_memfree(dev)) { 222 if (!mthca_is_memfree(dev)) {
233 __be32 doorbell[2]; 223 mthca_write64(MTHCA_EQ_DB_DISARM_CQ | eqn, cqn,
234
235 doorbell[0] = cpu_to_be32(MTHCA_EQ_DB_DISARM_CQ | eqn);
236 doorbell[1] = cpu_to_be32(cqn);
237
238 mthca_write64(doorbell,
239 dev->kar + MTHCA_EQ_DOORBELL, 224 dev->kar + MTHCA_EQ_DOORBELL,
240 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock)); 225 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
241 } 226 }
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index df01b2026a6..0e5461c6573 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -1799,15 +1799,11 @@ int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
1799 1799
1800out: 1800out:
1801 if (likely(nreq)) { 1801 if (likely(nreq)) {
1802 __be32 doorbell[2];
1803
1804 doorbell[0] = cpu_to_be32(((qp->sq.next_ind << qp->sq.wqe_shift) +
1805 qp->send_wqe_offset) | f0 | op0);
1806 doorbell[1] = cpu_to_be32((qp->qpn << 8) | size0);
1807
1808 wmb(); 1802 wmb();
1809 1803
1810 mthca_write64(doorbell, 1804 mthca_write64(((qp->sq.next_ind << qp->sq.wqe_shift) +
1805 qp->send_wqe_offset) | f0 | op0,
1806 (qp->qpn << 8) | size0,
1811 dev->kar + MTHCA_SEND_DOORBELL, 1807 dev->kar + MTHCA_SEND_DOORBELL,
1812 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock)); 1808 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
1813 /* 1809 /*
@@ -1829,7 +1825,6 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
1829{ 1825{
1830 struct mthca_dev *dev = to_mdev(ibqp->device); 1826 struct mthca_dev *dev = to_mdev(ibqp->device);
1831 struct mthca_qp *qp = to_mqp(ibqp); 1827 struct mthca_qp *qp = to_mqp(ibqp);
1832 __be32 doorbell[2];
1833 unsigned long flags; 1828 unsigned long flags;
1834 int err = 0; 1829 int err = 0;
1835 int nreq; 1830 int nreq;
@@ -1907,13 +1902,10 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
1907 if (unlikely(nreq == MTHCA_TAVOR_MAX_WQES_PER_RECV_DB)) { 1902 if (unlikely(nreq == MTHCA_TAVOR_MAX_WQES_PER_RECV_DB)) {
1908 nreq = 0; 1903 nreq = 0;
1909 1904
1910 doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0);
1911 doorbell[1] = cpu_to_be32(qp->qpn << 8);
1912
1913 wmb(); 1905 wmb();
1914 1906
1915 mthca_write64(doorbell, 1907 mthca_write64((qp->rq.next_ind << qp->rq.wqe_shift) | size0,
1916 dev->kar + MTHCA_RECEIVE_DOORBELL, 1908 qp->qpn << 8, dev->kar + MTHCA_RECEIVE_DOORBELL,
1917 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock)); 1909 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
1918 1910
1919 qp->rq.next_ind = ind; 1911 qp->rq.next_ind = ind;
@@ -1923,13 +1915,10 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
1923 1915
1924out: 1916out:
1925 if (likely(nreq)) { 1917 if (likely(nreq)) {
1926 doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0);
1927 doorbell[1] = cpu_to_be32((qp->qpn << 8) | nreq);
1928
1929 wmb(); 1918 wmb();
1930 1919
1931 mthca_write64(doorbell, 1920 mthca_write64((qp->rq.next_ind << qp->rq.wqe_shift) | size0,
1932 dev->kar + MTHCA_RECEIVE_DOORBELL, 1921 qp->qpn << 8 | nreq, dev->kar + MTHCA_RECEIVE_DOORBELL,
1933 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock)); 1922 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
1934 } 1923 }
1935 1924
@@ -1951,7 +1940,7 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
1951{ 1940{
1952 struct mthca_dev *dev = to_mdev(ibqp->device); 1941 struct mthca_dev *dev = to_mdev(ibqp->device);
1953 struct mthca_qp *qp = to_mqp(ibqp); 1942 struct mthca_qp *qp = to_mqp(ibqp);
1954 __be32 doorbell[2]; 1943 u32 dbhi;
1955 void *wqe; 1944 void *wqe;
1956 void *prev_wqe; 1945 void *prev_wqe;
1957 unsigned long flags; 1946 unsigned long flags;
@@ -1981,10 +1970,8 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
1981 if (unlikely(nreq == MTHCA_ARBEL_MAX_WQES_PER_SEND_DB)) { 1970 if (unlikely(nreq == MTHCA_ARBEL_MAX_WQES_PER_SEND_DB)) {
1982 nreq = 0; 1971 nreq = 0;
1983 1972
1984 doorbell[0] = cpu_to_be32((MTHCA_ARBEL_MAX_WQES_PER_SEND_DB << 24) | 1973 dbhi = (MTHCA_ARBEL_MAX_WQES_PER_SEND_DB << 24) |
1985 ((qp->sq.head & 0xffff) << 8) | 1974 ((qp->sq.head & 0xffff) << 8) | f0 | op0;
1986 f0 | op0);
1987 doorbell[1] = cpu_to_be32((qp->qpn << 8) | size0);
1988 1975
1989 qp->sq.head += MTHCA_ARBEL_MAX_WQES_PER_SEND_DB; 1976 qp->sq.head += MTHCA_ARBEL_MAX_WQES_PER_SEND_DB;
1990 1977
@@ -2000,7 +1987,8 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
2000 * write MMIO send doorbell. 1987 * write MMIO send doorbell.
2001 */ 1988 */
2002 wmb(); 1989 wmb();
2003 mthca_write64(doorbell, 1990
1991 mthca_write64(dbhi, (qp->qpn << 8) | size0,
2004 dev->kar + MTHCA_SEND_DOORBELL, 1992 dev->kar + MTHCA_SEND_DOORBELL,
2005 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock)); 1993 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
2006 } 1994 }
@@ -2154,10 +2142,7 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
2154 2142
2155out: 2143out:
2156 if (likely(nreq)) { 2144 if (likely(nreq)) {
2157 doorbell[0] = cpu_to_be32((nreq << 24) | 2145 dbhi = (nreq << 24) | ((qp->sq.head & 0xffff) << 8) | f0 | op0;
2158 ((qp->sq.head & 0xffff) << 8) |
2159 f0 | op0);
2160 doorbell[1] = cpu_to_be32((qp->qpn << 8) | size0);
2161 2146
2162 qp->sq.head += nreq; 2147 qp->sq.head += nreq;
2163 2148
@@ -2173,8 +2158,8 @@ out:
2173 * write MMIO send doorbell. 2158 * write MMIO send doorbell.
2174 */ 2159 */
2175 wmb(); 2160 wmb();
2176 mthca_write64(doorbell, 2161
2177 dev->kar + MTHCA_SEND_DOORBELL, 2162 mthca_write64(dbhi, (qp->qpn << 8) | size0, dev->kar + MTHCA_SEND_DOORBELL,
2178 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock)); 2163 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
2179 } 2164 }
2180 2165
diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c
index 3f58c11a62b..553d681f681 100644
--- a/drivers/infiniband/hw/mthca/mthca_srq.c
+++ b/drivers/infiniband/hw/mthca/mthca_srq.c
@@ -491,7 +491,6 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
491{ 491{
492 struct mthca_dev *dev = to_mdev(ibsrq->device); 492 struct mthca_dev *dev = to_mdev(ibsrq->device);
493 struct mthca_srq *srq = to_msrq(ibsrq); 493 struct mthca_srq *srq = to_msrq(ibsrq);
494 __be32 doorbell[2];
495 unsigned long flags; 494 unsigned long flags;
496 int err = 0; 495 int err = 0;
497 int first_ind; 496 int first_ind;
@@ -563,16 +562,13 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
563 if (unlikely(nreq == MTHCA_TAVOR_MAX_WQES_PER_RECV_DB)) { 562 if (unlikely(nreq == MTHCA_TAVOR_MAX_WQES_PER_RECV_DB)) {
564 nreq = 0; 563 nreq = 0;
565 564
566 doorbell[0] = cpu_to_be32(first_ind << srq->wqe_shift);
567 doorbell[1] = cpu_to_be32(srq->srqn << 8);
568
569 /* 565 /*
570 * Make sure that descriptors are written 566 * Make sure that descriptors are written
571 * before doorbell is rung. 567 * before doorbell is rung.
572 */ 568 */
573 wmb(); 569 wmb();
574 570
575 mthca_write64(doorbell, 571 mthca_write64(first_ind << srq->wqe_shift, srq->srqn << 8,
576 dev->kar + MTHCA_RECEIVE_DOORBELL, 572 dev->kar + MTHCA_RECEIVE_DOORBELL,
577 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock)); 573 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
578 574
@@ -581,16 +577,13 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
581 } 577 }
582 578
583 if (likely(nreq)) { 579 if (likely(nreq)) {
584 doorbell[0] = cpu_to_be32(first_ind << srq->wqe_shift);
585 doorbell[1] = cpu_to_be32((srq->srqn << 8) | nreq);
586
587 /* 580 /*
588 * Make sure that descriptors are written before 581 * Make sure that descriptors are written before
589 * doorbell is rung. 582 * doorbell is rung.
590 */ 583 */
591 wmb(); 584 wmb();
592 585
593 mthca_write64(doorbell, 586 mthca_write64(first_ind << srq->wqe_shift, (srq->srqn << 8) | nreq,
594 dev->kar + MTHCA_RECEIVE_DOORBELL, 587 dev->kar + MTHCA_RECEIVE_DOORBELL,
595 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock)); 588 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
596 } 589 }