aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/cxgb3/iwch_qp.c
diff options
context:
space:
mode:
authorSteve Wise <swise@opengridcomputing.com>2008-07-15 02:48:45 -0400
committerRoland Dreier <rolandd@cisco.com>2008-07-15 02:48:45 -0400
commite7e55829999deaab3f43e201a087731c02c54cf9 (patch)
tree665f2ff291045af9469bbb929f99224e9707965b /drivers/infiniband/hw/cxgb3/iwch_qp.c
parent00f7ec36c9324928e4cd23f02e6d8550f30c32ca (diff)
RDMA/cxgb3: MEM_MGT_EXTENSIONS support
- set IB_DEVICE_MEM_MGT_EXTENSIONS capability bit if fw supports it. - set max_fast_reg_page_list_len device attribute. - add iwch_alloc_fast_reg_mr function. - add iwch_alloc_fastreg_pbl - add iwch_free_fastreg_pbl - adjust the WQ depth for kernel mode work queues to account for fastreg possibly taking 2 WR slots. - add fastreg_mr work request support. - add local_inv work request support. - add send_with_inv and send_with_se_inv work request support. - removed useless duplicate enums/defines for TPT/MW/MR stuff. Signed-off-by: Steve Wise <swise@opengridcomputing.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw/cxgb3/iwch_qp.c')
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_qp.c142
1 files changed, 97 insertions, 45 deletions
diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c
index 992613799228..3b44300a3036 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_qp.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c
@@ -44,54 +44,39 @@ static int iwch_build_rdma_send(union t3_wr *wqe, struct ib_send_wr *wr,
44 44
45 switch (wr->opcode) { 45 switch (wr->opcode) {
46 case IB_WR_SEND: 46 case IB_WR_SEND:
47 case IB_WR_SEND_WITH_IMM:
48 if (wr->send_flags & IB_SEND_SOLICITED) 47 if (wr->send_flags & IB_SEND_SOLICITED)
49 wqe->send.rdmaop = T3_SEND_WITH_SE; 48 wqe->send.rdmaop = T3_SEND_WITH_SE;
50 else 49 else
51 wqe->send.rdmaop = T3_SEND; 50 wqe->send.rdmaop = T3_SEND;
52 wqe->send.rem_stag = 0; 51 wqe->send.rem_stag = 0;
53 break; 52 break;
54#if 0 /* Not currently supported */ 53 case IB_WR_SEND_WITH_INV:
55 case TYPE_SEND_INVALIDATE: 54 if (wr->send_flags & IB_SEND_SOLICITED)
56 case TYPE_SEND_INVALIDATE_IMMEDIATE: 55 wqe->send.rdmaop = T3_SEND_WITH_SE_INV;
57 wqe->send.rdmaop = T3_SEND_WITH_INV; 56 else
58 wqe->send.rem_stag = cpu_to_be32(wr->wr.rdma.rkey); 57 wqe->send.rdmaop = T3_SEND_WITH_INV;
59 break; 58 wqe->send.rem_stag = cpu_to_be32(wr->ex.invalidate_rkey);
60 case TYPE_SEND_SE_INVALIDATE:
61 wqe->send.rdmaop = T3_SEND_WITH_SE_INV;
62 wqe->send.rem_stag = cpu_to_be32(wr->wr.rdma.rkey);
63 break; 59 break;
64#endif
65 default: 60 default:
66 break; 61 return -EINVAL;
67 } 62 }
68 if (wr->num_sge > T3_MAX_SGE) 63 if (wr->num_sge > T3_MAX_SGE)
69 return -EINVAL; 64 return -EINVAL;
70 wqe->send.reserved[0] = 0; 65 wqe->send.reserved[0] = 0;
71 wqe->send.reserved[1] = 0; 66 wqe->send.reserved[1] = 0;
72 wqe->send.reserved[2] = 0; 67 wqe->send.reserved[2] = 0;
73 if (wr->opcode == IB_WR_SEND_WITH_IMM) { 68 plen = 0;
74 plen = 4; 69 for (i = 0; i < wr->num_sge; i++) {
75 wqe->send.sgl[0].stag = wr->ex.imm_data; 70 if ((plen + wr->sg_list[i].length) < plen)
76 wqe->send.sgl[0].len = __constant_cpu_to_be32(0); 71 return -EMSGSIZE;
77 wqe->send.num_sgle = __constant_cpu_to_be32(0); 72
78 *flit_cnt = 5; 73 plen += wr->sg_list[i].length;
79 } else { 74 wqe->send.sgl[i].stag = cpu_to_be32(wr->sg_list[i].lkey);
80 plen = 0; 75 wqe->send.sgl[i].len = cpu_to_be32(wr->sg_list[i].length);
81 for (i = 0; i < wr->num_sge; i++) { 76 wqe->send.sgl[i].to = cpu_to_be64(wr->sg_list[i].addr);
82 if ((plen + wr->sg_list[i].length) < plen) {
83 return -EMSGSIZE;
84 }
85 plen += wr->sg_list[i].length;
86 wqe->send.sgl[i].stag =
87 cpu_to_be32(wr->sg_list[i].lkey);
88 wqe->send.sgl[i].len =
89 cpu_to_be32(wr->sg_list[i].length);
90 wqe->send.sgl[i].to = cpu_to_be64(wr->sg_list[i].addr);
91 }
92 wqe->send.num_sgle = cpu_to_be32(wr->num_sge);
93 *flit_cnt = 4 + ((wr->num_sge) << 1);
94 } 77 }
78 wqe->send.num_sgle = cpu_to_be32(wr->num_sge);
79 *flit_cnt = 4 + ((wr->num_sge) << 1);
95 wqe->send.plen = cpu_to_be32(plen); 80 wqe->send.plen = cpu_to_be32(plen);
96 return 0; 81 return 0;
97} 82}
@@ -143,9 +128,12 @@ static int iwch_build_rdma_read(union t3_wr *wqe, struct ib_send_wr *wr,
143 if (wr->num_sge > 1) 128 if (wr->num_sge > 1)
144 return -EINVAL; 129 return -EINVAL;
145 wqe->read.rdmaop = T3_READ_REQ; 130 wqe->read.rdmaop = T3_READ_REQ;
131 if (wr->opcode == IB_WR_RDMA_READ_WITH_INV)
132 wqe->read.local_inv = 1;
133 else
134 wqe->read.local_inv = 0;
146 wqe->read.reserved[0] = 0; 135 wqe->read.reserved[0] = 0;
147 wqe->read.reserved[1] = 0; 136 wqe->read.reserved[1] = 0;
148 wqe->read.reserved[2] = 0;
149 wqe->read.rem_stag = cpu_to_be32(wr->wr.rdma.rkey); 137 wqe->read.rem_stag = cpu_to_be32(wr->wr.rdma.rkey);
150 wqe->read.rem_to = cpu_to_be64(wr->wr.rdma.remote_addr); 138 wqe->read.rem_to = cpu_to_be64(wr->wr.rdma.remote_addr);
151 wqe->read.local_stag = cpu_to_be32(wr->sg_list[0].lkey); 139 wqe->read.local_stag = cpu_to_be32(wr->sg_list[0].lkey);
@@ -155,6 +143,57 @@ static int iwch_build_rdma_read(union t3_wr *wqe, struct ib_send_wr *wr,
155 return 0; 143 return 0;
156} 144}
157 145
146static int iwch_build_fastreg(union t3_wr *wqe, struct ib_send_wr *wr,
147 u8 *flit_cnt, int *wr_cnt, struct t3_wq *wq)
148{
149 int i;
150 __be64 *p;
151
152 if (wr->wr.fast_reg.page_list_len > T3_MAX_FASTREG_DEPTH)
153 return -EINVAL;
154 *wr_cnt = 1;
155 wqe->fastreg.stag = cpu_to_be32(wr->wr.fast_reg.rkey);
156 wqe->fastreg.len = cpu_to_be32(wr->wr.fast_reg.length);
157 wqe->fastreg.va_base_hi = cpu_to_be32(wr->wr.fast_reg.iova_start >> 32);
158 wqe->fastreg.va_base_lo_fbo =
159 cpu_to_be32(wr->wr.fast_reg.iova_start & 0xffffffff);
160 wqe->fastreg.page_type_perms = cpu_to_be32(
161 V_FR_PAGE_COUNT(wr->wr.fast_reg.page_list_len) |
162 V_FR_PAGE_SIZE(wr->wr.fast_reg.page_shift-12) |
163 V_FR_TYPE(TPT_VATO) |
164 V_FR_PERMS(iwch_ib_to_tpt_access(wr->wr.fast_reg.access_flags)));
165 p = &wqe->fastreg.pbl_addrs[0];
166 for (i = 0; i < wr->wr.fast_reg.page_list_len; i++, p++) {
167
168 /* If we need a 2nd WR, then set it up */
169 if (i == T3_MAX_FASTREG_FRAG) {
170 *wr_cnt = 2;
171 wqe = (union t3_wr *)(wq->queue +
172 Q_PTR2IDX((wq->wptr+1), wq->size_log2));
173 build_fw_riwrh((void *)wqe, T3_WR_FASTREG, 0,
174 Q_GENBIT(wq->wptr + 1, wq->size_log2),
175 0, 1 + wr->wr.fast_reg.page_list_len - T3_MAX_FASTREG_FRAG,
176 T3_EOP);
177
178 p = &wqe->pbl_frag.pbl_addrs[0];
179 }
180 *p = cpu_to_be64((u64)wr->wr.fast_reg.page_list->page_list[i]);
181 }
182 *flit_cnt = 5 + wr->wr.fast_reg.page_list_len;
183 if (*flit_cnt > 15)
184 *flit_cnt = 15;
185 return 0;
186}
187
188static int iwch_build_inv_stag(union t3_wr *wqe, struct ib_send_wr *wr,
189 u8 *flit_cnt)
190{
191 wqe->local_inv.stag = cpu_to_be32(wr->ex.invalidate_rkey);
192 wqe->local_inv.reserved = 0;
193 *flit_cnt = sizeof(struct t3_local_inv_wr) >> 3;
194 return 0;
195}
196
158/* 197/*
159 * TBD: this is going to be moved to firmware. Missing pdid/qpid check for now. 198 * TBD: this is going to be moved to firmware. Missing pdid/qpid check for now.
160 */ 199 */
@@ -238,6 +277,7 @@ int iwch_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
238 u32 num_wrs; 277 u32 num_wrs;
239 unsigned long flag; 278 unsigned long flag;
240 struct t3_swsq *sqp; 279 struct t3_swsq *sqp;
280 int wr_cnt = 1;
241 281
242 qhp = to_iwch_qp(ibqp); 282 qhp = to_iwch_qp(ibqp);
243 spin_lock_irqsave(&qhp->lock, flag); 283 spin_lock_irqsave(&qhp->lock, flag);
@@ -262,15 +302,15 @@ int iwch_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
262 t3_wr_flags = 0; 302 t3_wr_flags = 0;
263 if (wr->send_flags & IB_SEND_SOLICITED) 303 if (wr->send_flags & IB_SEND_SOLICITED)
264 t3_wr_flags |= T3_SOLICITED_EVENT_FLAG; 304 t3_wr_flags |= T3_SOLICITED_EVENT_FLAG;
265 if (wr->send_flags & IB_SEND_FENCE)
266 t3_wr_flags |= T3_READ_FENCE_FLAG;
267 if (wr->send_flags & IB_SEND_SIGNALED) 305 if (wr->send_flags & IB_SEND_SIGNALED)
268 t3_wr_flags |= T3_COMPLETION_FLAG; 306 t3_wr_flags |= T3_COMPLETION_FLAG;
269 sqp = qhp->wq.sq + 307 sqp = qhp->wq.sq +
270 Q_PTR2IDX(qhp->wq.sq_wptr, qhp->wq.sq_size_log2); 308 Q_PTR2IDX(qhp->wq.sq_wptr, qhp->wq.sq_size_log2);
271 switch (wr->opcode) { 309 switch (wr->opcode) {
272 case IB_WR_SEND: 310 case IB_WR_SEND:
273 case IB_WR_SEND_WITH_IMM: 311 case IB_WR_SEND_WITH_INV:
312 if (wr->send_flags & IB_SEND_FENCE)
313 t3_wr_flags |= T3_READ_FENCE_FLAG;
274 t3_wr_opcode = T3_WR_SEND; 314 t3_wr_opcode = T3_WR_SEND;
275 err = iwch_build_rdma_send(wqe, wr, &t3_wr_flit_cnt); 315 err = iwch_build_rdma_send(wqe, wr, &t3_wr_flit_cnt);
276 break; 316 break;
@@ -280,6 +320,7 @@ int iwch_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
280 err = iwch_build_rdma_write(wqe, wr, &t3_wr_flit_cnt); 320 err = iwch_build_rdma_write(wqe, wr, &t3_wr_flit_cnt);
281 break; 321 break;
282 case IB_WR_RDMA_READ: 322 case IB_WR_RDMA_READ:
323 case IB_WR_RDMA_READ_WITH_INV:
283 t3_wr_opcode = T3_WR_READ; 324 t3_wr_opcode = T3_WR_READ;
284 t3_wr_flags = 0; /* T3 reads are always signaled */ 325 t3_wr_flags = 0; /* T3 reads are always signaled */
285 err = iwch_build_rdma_read(wqe, wr, &t3_wr_flit_cnt); 326 err = iwch_build_rdma_read(wqe, wr, &t3_wr_flit_cnt);
@@ -289,6 +330,17 @@ int iwch_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
289 if (!qhp->wq.oldest_read) 330 if (!qhp->wq.oldest_read)
290 qhp->wq.oldest_read = sqp; 331 qhp->wq.oldest_read = sqp;
291 break; 332 break;
333 case IB_WR_FAST_REG_MR:
334 t3_wr_opcode = T3_WR_FASTREG;
335 err = iwch_build_fastreg(wqe, wr, &t3_wr_flit_cnt,
336 &wr_cnt, &qhp->wq);
337 break;
338 case IB_WR_LOCAL_INV:
339 if (wr->send_flags & IB_SEND_FENCE)
340 t3_wr_flags |= T3_LOCAL_FENCE_FLAG;
341 t3_wr_opcode = T3_WR_INV_STAG;
342 err = iwch_build_inv_stag(wqe, wr, &t3_wr_flit_cnt);
343 break;
292 default: 344 default:
293 PDBG("%s post of type=%d TBD!\n", __func__, 345 PDBG("%s post of type=%d TBD!\n", __func__,
294 wr->opcode); 346 wr->opcode);
@@ -307,14 +359,15 @@ int iwch_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
307 359
308 build_fw_riwrh((void *) wqe, t3_wr_opcode, t3_wr_flags, 360 build_fw_riwrh((void *) wqe, t3_wr_opcode, t3_wr_flags,
309 Q_GENBIT(qhp->wq.wptr, qhp->wq.size_log2), 361 Q_GENBIT(qhp->wq.wptr, qhp->wq.size_log2),
310 0, t3_wr_flit_cnt); 362 0, t3_wr_flit_cnt,
363 (wr_cnt == 1) ? T3_SOPEOP : T3_SOP);
311 PDBG("%s cookie 0x%llx wq idx 0x%x swsq idx %ld opcode %d\n", 364 PDBG("%s cookie 0x%llx wq idx 0x%x swsq idx %ld opcode %d\n",
312 __func__, (unsigned long long) wr->wr_id, idx, 365 __func__, (unsigned long long) wr->wr_id, idx,
313 Q_PTR2IDX(qhp->wq.sq_wptr, qhp->wq.sq_size_log2), 366 Q_PTR2IDX(qhp->wq.sq_wptr, qhp->wq.sq_size_log2),
314 sqp->opcode); 367 sqp->opcode);
315 wr = wr->next; 368 wr = wr->next;
316 num_wrs--; 369 num_wrs--;
317 ++(qhp->wq.wptr); 370 qhp->wq.wptr += wr_cnt;
318 ++(qhp->wq.sq_wptr); 371 ++(qhp->wq.sq_wptr);
319 } 372 }
320 spin_unlock_irqrestore(&qhp->lock, flag); 373 spin_unlock_irqrestore(&qhp->lock, flag);
@@ -359,7 +412,7 @@ int iwch_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
359 wr->wr_id; 412 wr->wr_id;
360 build_fw_riwrh((void *) wqe, T3_WR_RCV, T3_COMPLETION_FLAG, 413 build_fw_riwrh((void *) wqe, T3_WR_RCV, T3_COMPLETION_FLAG,
361 Q_GENBIT(qhp->wq.wptr, qhp->wq.size_log2), 414 Q_GENBIT(qhp->wq.wptr, qhp->wq.size_log2),
362 0, sizeof(struct t3_receive_wr) >> 3); 415 0, sizeof(struct t3_receive_wr) >> 3, T3_SOPEOP);
363 PDBG("%s cookie 0x%llx idx 0x%x rq_wptr 0x%x rw_rptr 0x%x " 416 PDBG("%s cookie 0x%llx idx 0x%x rq_wptr 0x%x rw_rptr 0x%x "
364 "wqe %p \n", __func__, (unsigned long long) wr->wr_id, 417 "wqe %p \n", __func__, (unsigned long long) wr->wr_id,
365 idx, qhp->wq.rq_wptr, qhp->wq.rq_rptr, wqe); 418 idx, qhp->wq.rq_wptr, qhp->wq.rq_rptr, wqe);
@@ -419,10 +472,10 @@ int iwch_bind_mw(struct ib_qp *qp,
419 sgl.lkey = mw_bind->mr->lkey; 472 sgl.lkey = mw_bind->mr->lkey;
420 sgl.length = mw_bind->length; 473 sgl.length = mw_bind->length;
421 wqe->bind.reserved = 0; 474 wqe->bind.reserved = 0;
422 wqe->bind.type = T3_VA_BASED_TO; 475 wqe->bind.type = TPT_VATO;
423 476
424 /* TBD: check perms */ 477 /* TBD: check perms */
425 wqe->bind.perms = iwch_ib_to_mwbind_access(mw_bind->mw_access_flags); 478 wqe->bind.perms = iwch_ib_to_tpt_access(mw_bind->mw_access_flags);
426 wqe->bind.mr_stag = cpu_to_be32(mw_bind->mr->lkey); 479 wqe->bind.mr_stag = cpu_to_be32(mw_bind->mr->lkey);
427 wqe->bind.mw_stag = cpu_to_be32(mw->rkey); 480 wqe->bind.mw_stag = cpu_to_be32(mw->rkey);
428 wqe->bind.mw_len = cpu_to_be32(mw_bind->length); 481 wqe->bind.mw_len = cpu_to_be32(mw_bind->length);
@@ -430,7 +483,7 @@ int iwch_bind_mw(struct ib_qp *qp,
430 err = iwch_sgl2pbl_map(rhp, &sgl, 1, &pbl_addr, &page_size); 483 err = iwch_sgl2pbl_map(rhp, &sgl, 1, &pbl_addr, &page_size);
431 if (err) { 484 if (err) {
432 spin_unlock_irqrestore(&qhp->lock, flag); 485 spin_unlock_irqrestore(&qhp->lock, flag);
433 return err; 486 return err;
434 } 487 }
435 wqe->send.wrid.id0.hi = qhp->wq.sq_wptr; 488 wqe->send.wrid.id0.hi = qhp->wq.sq_wptr;
436 sqp = qhp->wq.sq + Q_PTR2IDX(qhp->wq.sq_wptr, qhp->wq.sq_size_log2); 489 sqp = qhp->wq.sq + Q_PTR2IDX(qhp->wq.sq_wptr, qhp->wq.sq_size_log2);
@@ -441,10 +494,9 @@ int iwch_bind_mw(struct ib_qp *qp,
441 sqp->signaled = (mw_bind->send_flags & IB_SEND_SIGNALED); 494 sqp->signaled = (mw_bind->send_flags & IB_SEND_SIGNALED);
442 wqe->bind.mr_pbl_addr = cpu_to_be32(pbl_addr); 495 wqe->bind.mr_pbl_addr = cpu_to_be32(pbl_addr);
443 wqe->bind.mr_pagesz = page_size; 496 wqe->bind.mr_pagesz = page_size;
444 wqe->flit[T3_SQ_COOKIE_FLIT] = mw_bind->wr_id;
445 build_fw_riwrh((void *)wqe, T3_WR_BIND, t3_wr_flags, 497 build_fw_riwrh((void *)wqe, T3_WR_BIND, t3_wr_flags,
446 Q_GENBIT(qhp->wq.wptr, qhp->wq.size_log2), 0, 498 Q_GENBIT(qhp->wq.wptr, qhp->wq.size_log2), 0,
447 sizeof(struct t3_bind_mw_wr) >> 3); 499 sizeof(struct t3_bind_mw_wr) >> 3, T3_SOPEOP);
448 ++(qhp->wq.wptr); 500 ++(qhp->wq.wptr);
449 ++(qhp->wq.sq_wptr); 501 ++(qhp->wq.sq_wptr);
450 spin_unlock_irqrestore(&qhp->lock, flag); 502 spin_unlock_irqrestore(&qhp->lock, flag);