diff options
author | Ralph Campbell <ralph.campbell@qlogic.com> | 2007-07-25 14:08:28 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2007-10-09 23:05:49 -0400 |
commit | 4ee97180ac76deb5a715ac45b7d7516e6ee82ae7 (patch) | |
tree | 6683d1c34d3f36271a9d8275a645ce67222ffc56 /drivers/infiniband/hw/ipath | |
parent | 210d6ca3db058cd1d6e6fd235ee3e25d6ac221cd (diff) |
IB/ipath: Change UD to queue work requests like RC & UC
The code to post UD sends tried to process work requests at the time
ib_post_send() is called without using a WQE queue. This was fine as
long as HW resources were available for sending a packet. This patch
changes UD to be handled more like RC and UC and shares more code.
Signed-off-by: Ralph Campbell <ralph.campbell@qlogic.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw/ipath')
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_qp.c | 11 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_rc.c | 61 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_ruc.c | 308 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_uc.c | 77 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_ud.c | 372 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_verbs.c | 241 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_verbs.h | 35 |
7 files changed, 494 insertions, 611 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_qp.c b/drivers/infiniband/hw/ipath/ipath_qp.c index 1324b35ff1f8..a8c4a6b03d7a 100644 --- a/drivers/infiniband/hw/ipath/ipath_qp.c +++ b/drivers/infiniband/hw/ipath/ipath_qp.c | |||
@@ -338,6 +338,7 @@ static void ipath_reset_qp(struct ipath_qp *qp) | |||
338 | qp->s_busy = 0; | 338 | qp->s_busy = 0; |
339 | qp->s_flags &= IPATH_S_SIGNAL_REQ_WR; | 339 | qp->s_flags &= IPATH_S_SIGNAL_REQ_WR; |
340 | qp->s_hdrwords = 0; | 340 | qp->s_hdrwords = 0; |
341 | qp->s_wqe = NULL; | ||
341 | qp->s_psn = 0; | 342 | qp->s_psn = 0; |
342 | qp->r_psn = 0; | 343 | qp->r_psn = 0; |
343 | qp->r_msn = 0; | 344 | qp->r_msn = 0; |
@@ -751,6 +752,9 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd, | |||
751 | switch (init_attr->qp_type) { | 752 | switch (init_attr->qp_type) { |
752 | case IB_QPT_UC: | 753 | case IB_QPT_UC: |
753 | case IB_QPT_RC: | 754 | case IB_QPT_RC: |
755 | case IB_QPT_UD: | ||
756 | case IB_QPT_SMI: | ||
757 | case IB_QPT_GSI: | ||
754 | sz = sizeof(struct ipath_sge) * | 758 | sz = sizeof(struct ipath_sge) * |
755 | init_attr->cap.max_send_sge + | 759 | init_attr->cap.max_send_sge + |
756 | sizeof(struct ipath_swqe); | 760 | sizeof(struct ipath_swqe); |
@@ -759,10 +763,6 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd, | |||
759 | ret = ERR_PTR(-ENOMEM); | 763 | ret = ERR_PTR(-ENOMEM); |
760 | goto bail; | 764 | goto bail; |
761 | } | 765 | } |
762 | /* FALLTHROUGH */ | ||
763 | case IB_QPT_UD: | ||
764 | case IB_QPT_SMI: | ||
765 | case IB_QPT_GSI: | ||
766 | sz = sizeof(*qp); | 766 | sz = sizeof(*qp); |
767 | if (init_attr->srq) { | 767 | if (init_attr->srq) { |
768 | struct ipath_srq *srq = to_isrq(init_attr->srq); | 768 | struct ipath_srq *srq = to_isrq(init_attr->srq); |
@@ -805,8 +805,7 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd, | |||
805 | spin_lock_init(&qp->r_rq.lock); | 805 | spin_lock_init(&qp->r_rq.lock); |
806 | atomic_set(&qp->refcount, 0); | 806 | atomic_set(&qp->refcount, 0); |
807 | init_waitqueue_head(&qp->wait); | 807 | init_waitqueue_head(&qp->wait); |
808 | tasklet_init(&qp->s_task, ipath_do_ruc_send, | 808 | tasklet_init(&qp->s_task, ipath_do_send, (unsigned long)qp); |
809 | (unsigned long)qp); | ||
810 | INIT_LIST_HEAD(&qp->piowait); | 809 | INIT_LIST_HEAD(&qp->piowait); |
811 | INIT_LIST_HEAD(&qp->timerwait); | 810 | INIT_LIST_HEAD(&qp->timerwait); |
812 | qp->state = IB_QPS_RESET; | 811 | qp->state = IB_QPS_RESET; |
diff --git a/drivers/infiniband/hw/ipath/ipath_rc.c b/drivers/infiniband/hw/ipath/ipath_rc.c index 46744ea2babd..53259daeb4f8 100644 --- a/drivers/infiniband/hw/ipath/ipath_rc.c +++ b/drivers/infiniband/hw/ipath/ipath_rc.c | |||
@@ -81,9 +81,8 @@ static void ipath_init_restart(struct ipath_qp *qp, struct ipath_swqe *wqe) | |||
81 | * Note that we are in the responder's side of the QP context. | 81 | * Note that we are in the responder's side of the QP context. |
82 | * Note the QP s_lock must be held. | 82 | * Note the QP s_lock must be held. |
83 | */ | 83 | */ |
84 | static int ipath_make_rc_ack(struct ipath_qp *qp, | 84 | static int ipath_make_rc_ack(struct ipath_ibdev *dev, struct ipath_qp *qp, |
85 | struct ipath_other_headers *ohdr, | 85 | struct ipath_other_headers *ohdr, u32 pmtu) |
86 | u32 pmtu, u32 *bth0p, u32 *bth2p) | ||
87 | { | 86 | { |
88 | struct ipath_ack_entry *e; | 87 | struct ipath_ack_entry *e; |
89 | u32 hwords; | 88 | u32 hwords; |
@@ -192,8 +191,7 @@ static int ipath_make_rc_ack(struct ipath_qp *qp, | |||
192 | } | 191 | } |
193 | qp->s_hdrwords = hwords; | 192 | qp->s_hdrwords = hwords; |
194 | qp->s_cur_size = len; | 193 | qp->s_cur_size = len; |
195 | *bth0p = bth0 | (1 << 22); /* Set M bit */ | 194 | ipath_make_ruc_header(dev, qp, ohdr, bth0, bth2); |
196 | *bth2p = bth2; | ||
197 | return 1; | 195 | return 1; |
198 | 196 | ||
199 | bail: | 197 | bail: |
@@ -203,32 +201,39 @@ bail: | |||
203 | /** | 201 | /** |
204 | * ipath_make_rc_req - construct a request packet (SEND, RDMA r/w, ATOMIC) | 202 | * ipath_make_rc_req - construct a request packet (SEND, RDMA r/w, ATOMIC) |
205 | * @qp: a pointer to the QP | 203 | * @qp: a pointer to the QP |
206 | * @ohdr: a pointer to the IB header being constructed | ||
207 | * @pmtu: the path MTU | ||
208 | * @bth0p: pointer to the BTH opcode word | ||
209 | * @bth2p: pointer to the BTH PSN word | ||
210 | * | 204 | * |
211 | * Return 1 if constructed; otherwise, return 0. | 205 | * Return 1 if constructed; otherwise, return 0. |
212 | * Note the QP s_lock must be held and interrupts disabled. | ||
213 | */ | 206 | */ |
214 | int ipath_make_rc_req(struct ipath_qp *qp, | 207 | int ipath_make_rc_req(struct ipath_qp *qp) |
215 | struct ipath_other_headers *ohdr, | ||
216 | u32 pmtu, u32 *bth0p, u32 *bth2p) | ||
217 | { | 208 | { |
218 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); | 209 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); |
210 | struct ipath_other_headers *ohdr; | ||
219 | struct ipath_sge_state *ss; | 211 | struct ipath_sge_state *ss; |
220 | struct ipath_swqe *wqe; | 212 | struct ipath_swqe *wqe; |
221 | u32 hwords; | 213 | u32 hwords; |
222 | u32 len; | 214 | u32 len; |
223 | u32 bth0; | 215 | u32 bth0; |
224 | u32 bth2; | 216 | u32 bth2; |
217 | u32 pmtu = ib_mtu_enum_to_int(qp->path_mtu); | ||
225 | char newreq; | 218 | char newreq; |
219 | unsigned long flags; | ||
220 | int ret = 0; | ||
221 | |||
222 | ohdr = &qp->s_hdr.u.oth; | ||
223 | if (qp->remote_ah_attr.ah_flags & IB_AH_GRH) | ||
224 | ohdr = &qp->s_hdr.u.l.oth; | ||
225 | |||
226 | /* | ||
227 | * The lock is needed to synchronize between the sending tasklet, | ||
228 | * the receive interrupt handler, and timeout resends. | ||
229 | */ | ||
230 | spin_lock_irqsave(&qp->s_lock, flags); | ||
226 | 231 | ||
227 | /* Sending responses has higher priority over sending requests. */ | 232 | /* Sending responses has higher priority over sending requests. */ |
228 | if ((qp->r_head_ack_queue != qp->s_tail_ack_queue || | 233 | if ((qp->r_head_ack_queue != qp->s_tail_ack_queue || |
229 | (qp->s_flags & IPATH_S_ACK_PENDING) || | 234 | (qp->s_flags & IPATH_S_ACK_PENDING) || |
230 | qp->s_ack_state != OP(ACKNOWLEDGE)) && | 235 | qp->s_ack_state != OP(ACKNOWLEDGE)) && |
231 | ipath_make_rc_ack(qp, ohdr, pmtu, bth0p, bth2p)) | 236 | ipath_make_rc_ack(dev, qp, ohdr, pmtu)) |
232 | goto done; | 237 | goto done; |
233 | 238 | ||
234 | if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK) || | 239 | if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK) || |
@@ -560,13 +565,12 @@ int ipath_make_rc_req(struct ipath_qp *qp, | |||
560 | qp->s_hdrwords = hwords; | 565 | qp->s_hdrwords = hwords; |
561 | qp->s_cur_sge = ss; | 566 | qp->s_cur_sge = ss; |
562 | qp->s_cur_size = len; | 567 | qp->s_cur_size = len; |
563 | *bth0p = bth0 | (qp->s_state << 24); | 568 | ipath_make_ruc_header(dev, qp, ohdr, bth0 | (qp->s_state << 24), bth2); |
564 | *bth2p = bth2; | ||
565 | done: | 569 | done: |
566 | return 1; | 570 | ret = 1; |
567 | |||
568 | bail: | 571 | bail: |
569 | return 0; | 572 | spin_unlock_irqrestore(&qp->s_lock, flags); |
573 | return ret; | ||
570 | } | 574 | } |
571 | 575 | ||
572 | /** | 576 | /** |
@@ -627,7 +631,7 @@ static void send_rc_ack(struct ipath_qp *qp) | |||
627 | /* | 631 | /* |
628 | * If we can send the ACK, clear the ACK state. | 632 | * If we can send the ACK, clear the ACK state. |
629 | */ | 633 | */ |
630 | if (ipath_verbs_send(dev->dd, hwords, (u32 *) &hdr, 0, NULL) == 0) { | 634 | if (ipath_verbs_send(qp, &hdr, hwords, NULL, 0) == 0) { |
631 | dev->n_unicast_xmit++; | 635 | dev->n_unicast_xmit++; |
632 | goto done; | 636 | goto done; |
633 | } | 637 | } |
@@ -757,7 +761,9 @@ void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc) | |||
757 | wc->vendor_err = 0; | 761 | wc->vendor_err = 0; |
758 | wc->byte_len = 0; | 762 | wc->byte_len = 0; |
759 | wc->qp = &qp->ibqp; | 763 | wc->qp = &qp->ibqp; |
764 | wc->imm_data = 0; | ||
760 | wc->src_qp = qp->remote_qpn; | 765 | wc->src_qp = qp->remote_qpn; |
766 | wc->wc_flags = 0; | ||
761 | wc->pkey_index = 0; | 767 | wc->pkey_index = 0; |
762 | wc->slid = qp->remote_ah_attr.dlid; | 768 | wc->slid = qp->remote_ah_attr.dlid; |
763 | wc->sl = qp->remote_ah_attr.sl; | 769 | wc->sl = qp->remote_ah_attr.sl; |
@@ -1041,7 +1047,9 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode, | |||
1041 | wc.vendor_err = 0; | 1047 | wc.vendor_err = 0; |
1042 | wc.byte_len = 0; | 1048 | wc.byte_len = 0; |
1043 | wc.qp = &qp->ibqp; | 1049 | wc.qp = &qp->ibqp; |
1050 | wc.imm_data = 0; | ||
1044 | wc.src_qp = qp->remote_qpn; | 1051 | wc.src_qp = qp->remote_qpn; |
1052 | wc.wc_flags = 0; | ||
1045 | wc.pkey_index = 0; | 1053 | wc.pkey_index = 0; |
1046 | wc.slid = qp->remote_ah_attr.dlid; | 1054 | wc.slid = qp->remote_ah_attr.dlid; |
1047 | wc.sl = qp->remote_ah_attr.sl; | 1055 | wc.sl = qp->remote_ah_attr.sl; |
@@ -1454,6 +1462,19 @@ static inline int ipath_rc_rcv_error(struct ipath_ibdev *dev, | |||
1454 | goto send_ack; | 1462 | goto send_ack; |
1455 | } | 1463 | } |
1456 | /* | 1464 | /* |
1465 | * Try to send a simple ACK to work around a Mellanox bug | ||
1466 | * which doesn't accept a RDMA read response or atomic | ||
1467 | * response as an ACK for earlier SENDs or RDMA writes. | ||
1468 | */ | ||
1469 | if (qp->r_head_ack_queue == qp->s_tail_ack_queue && | ||
1470 | !(qp->s_flags & IPATH_S_ACK_PENDING) && | ||
1471 | qp->s_ack_state == OP(ACKNOWLEDGE)) { | ||
1472 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
1473 | qp->r_nak_state = 0; | ||
1474 | qp->r_ack_psn = qp->s_ack_queue[i].psn - 1; | ||
1475 | goto send_ack; | ||
1476 | } | ||
1477 | /* | ||
1457 | * Resend the RDMA read or atomic op which | 1478 | * Resend the RDMA read or atomic op which |
1458 | * ACKs this duplicate request. | 1479 | * ACKs this duplicate request. |
1459 | */ | 1480 | */ |
diff --git a/drivers/infiniband/hw/ipath/ipath_ruc.c b/drivers/infiniband/hw/ipath/ipath_ruc.c index c69c25239443..4b6b7ee8e5c1 100644 --- a/drivers/infiniband/hw/ipath/ipath_ruc.c +++ b/drivers/infiniband/hw/ipath/ipath_ruc.c | |||
@@ -31,6 +31,8 @@ | |||
31 | * SOFTWARE. | 31 | * SOFTWARE. |
32 | */ | 32 | */ |
33 | 33 | ||
34 | #include <linux/spinlock.h> | ||
35 | |||
34 | #include "ipath_verbs.h" | 36 | #include "ipath_verbs.h" |
35 | #include "ipath_kernel.h" | 37 | #include "ipath_kernel.h" |
36 | 38 | ||
@@ -106,27 +108,30 @@ void ipath_insert_rnr_queue(struct ipath_qp *qp) | |||
106 | spin_unlock_irqrestore(&dev->pending_lock, flags); | 108 | spin_unlock_irqrestore(&dev->pending_lock, flags); |
107 | } | 109 | } |
108 | 110 | ||
109 | static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe) | 111 | /** |
112 | * ipath_init_sge - Validate a RWQE and fill in the SGE state | ||
113 | * @qp: the QP | ||
114 | * | ||
115 | * Return 1 if OK. | ||
116 | */ | ||
117 | int ipath_init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe, | ||
118 | u32 *lengthp, struct ipath_sge_state *ss) | ||
110 | { | 119 | { |
111 | int user = to_ipd(qp->ibqp.pd)->user; | ||
112 | int i, j, ret; | 120 | int i, j, ret; |
113 | struct ib_wc wc; | 121 | struct ib_wc wc; |
114 | 122 | ||
115 | qp->r_len = 0; | 123 | *lengthp = 0; |
116 | for (i = j = 0; i < wqe->num_sge; i++) { | 124 | for (i = j = 0; i < wqe->num_sge; i++) { |
117 | if (wqe->sg_list[i].length == 0) | 125 | if (wqe->sg_list[i].length == 0) |
118 | continue; | 126 | continue; |
119 | /* Check LKEY */ | 127 | /* Check LKEY */ |
120 | if ((user && wqe->sg_list[i].lkey == 0) || | 128 | if (!ipath_lkey_ok(qp, j ? &ss->sg_list[j - 1] : &ss->sge, |
121 | !ipath_lkey_ok(qp, &qp->r_sg_list[j], &wqe->sg_list[i], | 129 | &wqe->sg_list[i], IB_ACCESS_LOCAL_WRITE)) |
122 | IB_ACCESS_LOCAL_WRITE)) | ||
123 | goto bad_lkey; | 130 | goto bad_lkey; |
124 | qp->r_len += wqe->sg_list[i].length; | 131 | *lengthp += wqe->sg_list[i].length; |
125 | j++; | 132 | j++; |
126 | } | 133 | } |
127 | qp->r_sge.sge = qp->r_sg_list[0]; | 134 | ss->num_sge = j; |
128 | qp->r_sge.sg_list = qp->r_sg_list + 1; | ||
129 | qp->r_sge.num_sge = j; | ||
130 | ret = 1; | 135 | ret = 1; |
131 | goto bail; | 136 | goto bail; |
132 | 137 | ||
@@ -172,6 +177,8 @@ int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only) | |||
172 | u32 tail; | 177 | u32 tail; |
173 | int ret; | 178 | int ret; |
174 | 179 | ||
180 | qp->r_sge.sg_list = qp->r_sg_list; | ||
181 | |||
175 | if (qp->ibqp.srq) { | 182 | if (qp->ibqp.srq) { |
176 | srq = to_isrq(qp->ibqp.srq); | 183 | srq = to_isrq(qp->ibqp.srq); |
177 | handler = srq->ibsrq.event_handler; | 184 | handler = srq->ibsrq.event_handler; |
@@ -199,7 +206,8 @@ int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only) | |||
199 | wqe = get_rwqe_ptr(rq, tail); | 206 | wqe = get_rwqe_ptr(rq, tail); |
200 | if (++tail >= rq->size) | 207 | if (++tail >= rq->size) |
201 | tail = 0; | 208 | tail = 0; |
202 | } while (!wr_id_only && !init_sge(qp, wqe)); | 209 | } while (!wr_id_only && !ipath_init_sge(qp, wqe, &qp->r_len, |
210 | &qp->r_sge)); | ||
203 | qp->r_wr_id = wqe->wr_id; | 211 | qp->r_wr_id = wqe->wr_id; |
204 | wq->tail = tail; | 212 | wq->tail = tail; |
205 | 213 | ||
@@ -239,9 +247,9 @@ bail: | |||
239 | 247 | ||
240 | /** | 248 | /** |
241 | * ipath_ruc_loopback - handle UC and RC lookback requests | 249 | * ipath_ruc_loopback - handle UC and RC lookback requests |
242 | * @sqp: the loopback QP | 250 | * @sqp: the sending QP |
243 | * | 251 | * |
244 | * This is called from ipath_do_uc_send() or ipath_do_rc_send() to | 252 | * This is called from ipath_do_send() to |
245 | * forward a WQE addressed to the same HCA. | 253 | * forward a WQE addressed to the same HCA. |
246 | * Note that although we are single threaded due to the tasklet, we still | 254 | * Note that although we are single threaded due to the tasklet, we still |
247 | * have to protect against post_send(). We don't have to worry about | 255 | * have to protect against post_send(). We don't have to worry about |
@@ -450,40 +458,18 @@ again: | |||
450 | wc.byte_len = wqe->length; | 458 | wc.byte_len = wqe->length; |
451 | wc.qp = &qp->ibqp; | 459 | wc.qp = &qp->ibqp; |
452 | wc.src_qp = qp->remote_qpn; | 460 | wc.src_qp = qp->remote_qpn; |
453 | /* XXX do we know which pkey matched? Only needed for GSI. */ | ||
454 | wc.pkey_index = 0; | 461 | wc.pkey_index = 0; |
455 | wc.slid = qp->remote_ah_attr.dlid; | 462 | wc.slid = qp->remote_ah_attr.dlid; |
456 | wc.sl = qp->remote_ah_attr.sl; | 463 | wc.sl = qp->remote_ah_attr.sl; |
457 | wc.dlid_path_bits = 0; | 464 | wc.dlid_path_bits = 0; |
465 | wc.port_num = 1; | ||
458 | /* Signal completion event if the solicited bit is set. */ | 466 | /* Signal completion event if the solicited bit is set. */ |
459 | ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, | 467 | ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, |
460 | wqe->wr.send_flags & IB_SEND_SOLICITED); | 468 | wqe->wr.send_flags & IB_SEND_SOLICITED); |
461 | 469 | ||
462 | send_comp: | 470 | send_comp: |
463 | sqp->s_rnr_retry = sqp->s_rnr_retry_cnt; | 471 | sqp->s_rnr_retry = sqp->s_rnr_retry_cnt; |
464 | 472 | ipath_send_complete(sqp, wqe, IB_WC_SUCCESS); | |
465 | if (!(sqp->s_flags & IPATH_S_SIGNAL_REQ_WR) || | ||
466 | (wqe->wr.send_flags & IB_SEND_SIGNALED)) { | ||
467 | wc.wr_id = wqe->wr.wr_id; | ||
468 | wc.status = IB_WC_SUCCESS; | ||
469 | wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; | ||
470 | wc.vendor_err = 0; | ||
471 | wc.byte_len = wqe->length; | ||
472 | wc.qp = &sqp->ibqp; | ||
473 | wc.src_qp = 0; | ||
474 | wc.pkey_index = 0; | ||
475 | wc.slid = 0; | ||
476 | wc.sl = 0; | ||
477 | wc.dlid_path_bits = 0; | ||
478 | wc.port_num = 0; | ||
479 | ipath_cq_enter(to_icq(sqp->ibqp.send_cq), &wc, 0); | ||
480 | } | ||
481 | |||
482 | /* Update s_last now that we are finished with the SWQE */ | ||
483 | spin_lock_irqsave(&sqp->s_lock, flags); | ||
484 | if (++sqp->s_last >= sqp->s_size) | ||
485 | sqp->s_last = 0; | ||
486 | spin_unlock_irqrestore(&sqp->s_lock, flags); | ||
487 | goto again; | 473 | goto again; |
488 | 474 | ||
489 | done: | 475 | done: |
@@ -491,13 +477,11 @@ done: | |||
491 | wake_up(&qp->wait); | 477 | wake_up(&qp->wait); |
492 | } | 478 | } |
493 | 479 | ||
494 | static int want_buffer(struct ipath_devdata *dd) | 480 | static void want_buffer(struct ipath_devdata *dd) |
495 | { | 481 | { |
496 | set_bit(IPATH_S_PIOINTBUFAVAIL, &dd->ipath_sendctrl); | 482 | set_bit(IPATH_S_PIOINTBUFAVAIL, &dd->ipath_sendctrl); |
497 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | 483 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, |
498 | dd->ipath_sendctrl); | 484 | dd->ipath_sendctrl); |
499 | |||
500 | return 0; | ||
501 | } | 485 | } |
502 | 486 | ||
503 | /** | 487 | /** |
@@ -507,14 +491,11 @@ static int want_buffer(struct ipath_devdata *dd) | |||
507 | * | 491 | * |
508 | * Called when we run out of PIO buffers. | 492 | * Called when we run out of PIO buffers. |
509 | */ | 493 | */ |
510 | static void ipath_no_bufs_available(struct ipath_qp *qp, struct ipath_ibdev *dev) | 494 | static void ipath_no_bufs_available(struct ipath_qp *qp, |
495 | struct ipath_ibdev *dev) | ||
511 | { | 496 | { |
512 | unsigned long flags; | 497 | unsigned long flags; |
513 | 498 | ||
514 | spin_lock_irqsave(&dev->pending_lock, flags); | ||
515 | if (list_empty(&qp->piowait)) | ||
516 | list_add_tail(&qp->piowait, &dev->piowait); | ||
517 | spin_unlock_irqrestore(&dev->pending_lock, flags); | ||
518 | /* | 499 | /* |
519 | * Note that as soon as want_buffer() is called and | 500 | * Note that as soon as want_buffer() is called and |
520 | * possibly before it returns, ipath_ib_piobufavail() | 501 | * possibly before it returns, ipath_ib_piobufavail() |
@@ -524,101 +505,14 @@ static void ipath_no_bufs_available(struct ipath_qp *qp, struct ipath_ibdev *dev | |||
524 | * We leave the busy flag set so that another post send doesn't | 505 | * We leave the busy flag set so that another post send doesn't |
525 | * try to put the same QP on the piowait list again. | 506 | * try to put the same QP on the piowait list again. |
526 | */ | 507 | */ |
508 | spin_lock_irqsave(&dev->pending_lock, flags); | ||
509 | list_add_tail(&qp->piowait, &dev->piowait); | ||
510 | spin_unlock_irqrestore(&dev->pending_lock, flags); | ||
527 | want_buffer(dev->dd); | 511 | want_buffer(dev->dd); |
528 | dev->n_piowait++; | 512 | dev->n_piowait++; |
529 | } | 513 | } |
530 | 514 | ||
531 | /** | 515 | /** |
532 | * ipath_post_ruc_send - post RC and UC sends | ||
533 | * @qp: the QP to post on | ||
534 | * @wr: the work request to send | ||
535 | */ | ||
536 | int ipath_post_ruc_send(struct ipath_qp *qp, struct ib_send_wr *wr) | ||
537 | { | ||
538 | struct ipath_swqe *wqe; | ||
539 | unsigned long flags; | ||
540 | u32 next; | ||
541 | int i, j; | ||
542 | int acc; | ||
543 | int ret; | ||
544 | |||
545 | /* | ||
546 | * Don't allow RDMA reads or atomic operations on UC or | ||
547 | * undefined operations. | ||
548 | * Make sure buffer is large enough to hold the result for atomics. | ||
549 | */ | ||
550 | if (qp->ibqp.qp_type == IB_QPT_UC) { | ||
551 | if ((unsigned) wr->opcode >= IB_WR_RDMA_READ) { | ||
552 | ret = -EINVAL; | ||
553 | goto bail; | ||
554 | } | ||
555 | } else if ((unsigned) wr->opcode > IB_WR_ATOMIC_FETCH_AND_ADD) { | ||
556 | ret = -EINVAL; | ||
557 | goto bail; | ||
558 | } else if (wr->opcode >= IB_WR_ATOMIC_CMP_AND_SWP && | ||
559 | (wr->num_sge == 0 || | ||
560 | wr->sg_list[0].length < sizeof(u64) || | ||
561 | wr->sg_list[0].addr & (sizeof(u64) - 1))) { | ||
562 | ret = -EINVAL; | ||
563 | goto bail; | ||
564 | } else if (wr->opcode >= IB_WR_RDMA_READ && !qp->s_max_rd_atomic) { | ||
565 | ret = -EINVAL; | ||
566 | goto bail; | ||
567 | } | ||
568 | /* IB spec says that num_sge == 0 is OK. */ | ||
569 | if (wr->num_sge > qp->s_max_sge) { | ||
570 | ret = -ENOMEM; | ||
571 | goto bail; | ||
572 | } | ||
573 | spin_lock_irqsave(&qp->s_lock, flags); | ||
574 | next = qp->s_head + 1; | ||
575 | if (next >= qp->s_size) | ||
576 | next = 0; | ||
577 | if (next == qp->s_last) { | ||
578 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
579 | ret = -EINVAL; | ||
580 | goto bail; | ||
581 | } | ||
582 | |||
583 | wqe = get_swqe_ptr(qp, qp->s_head); | ||
584 | wqe->wr = *wr; | ||
585 | wqe->ssn = qp->s_ssn++; | ||
586 | wqe->sg_list[0].mr = NULL; | ||
587 | wqe->sg_list[0].vaddr = NULL; | ||
588 | wqe->sg_list[0].length = 0; | ||
589 | wqe->sg_list[0].sge_length = 0; | ||
590 | wqe->length = 0; | ||
591 | acc = wr->opcode >= IB_WR_RDMA_READ ? IB_ACCESS_LOCAL_WRITE : 0; | ||
592 | for (i = 0, j = 0; i < wr->num_sge; i++) { | ||
593 | if (to_ipd(qp->ibqp.pd)->user && wr->sg_list[i].lkey == 0) { | ||
594 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
595 | ret = -EINVAL; | ||
596 | goto bail; | ||
597 | } | ||
598 | if (wr->sg_list[i].length == 0) | ||
599 | continue; | ||
600 | if (!ipath_lkey_ok(qp, &wqe->sg_list[j], &wr->sg_list[i], | ||
601 | acc)) { | ||
602 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
603 | ret = -EINVAL; | ||
604 | goto bail; | ||
605 | } | ||
606 | wqe->length += wr->sg_list[i].length; | ||
607 | j++; | ||
608 | } | ||
609 | wqe->wr.num_sge = j; | ||
610 | qp->s_head = next; | ||
611 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
612 | |||
613 | ipath_do_ruc_send((unsigned long) qp); | ||
614 | |||
615 | ret = 0; | ||
616 | |||
617 | bail: | ||
618 | return ret; | ||
619 | } | ||
620 | |||
621 | /** | ||
622 | * ipath_make_grh - construct a GRH header | 516 | * ipath_make_grh - construct a GRH header |
623 | * @dev: a pointer to the ipath device | 517 | * @dev: a pointer to the ipath device |
624 | * @hdr: a pointer to the GRH header being constructed | 518 | * @hdr: a pointer to the GRH header being constructed |
@@ -648,39 +542,66 @@ u32 ipath_make_grh(struct ipath_ibdev *dev, struct ib_grh *hdr, | |||
648 | return sizeof(struct ib_grh) / sizeof(u32); | 542 | return sizeof(struct ib_grh) / sizeof(u32); |
649 | } | 543 | } |
650 | 544 | ||
545 | void ipath_make_ruc_header(struct ipath_ibdev *dev, struct ipath_qp *qp, | ||
546 | struct ipath_other_headers *ohdr, | ||
547 | u32 bth0, u32 bth2) | ||
548 | { | ||
549 | u16 lrh0; | ||
550 | u32 nwords; | ||
551 | u32 extra_bytes; | ||
552 | |||
553 | /* Construct the header. */ | ||
554 | extra_bytes = -qp->s_cur_size & 3; | ||
555 | nwords = (qp->s_cur_size + extra_bytes) >> 2; | ||
556 | lrh0 = IPATH_LRH_BTH; | ||
557 | if (unlikely(qp->remote_ah_attr.ah_flags & IB_AH_GRH)) { | ||
558 | qp->s_hdrwords += ipath_make_grh(dev, &qp->s_hdr.u.l.grh, | ||
559 | &qp->remote_ah_attr.grh, | ||
560 | qp->s_hdrwords, nwords); | ||
561 | lrh0 = IPATH_LRH_GRH; | ||
562 | } | ||
563 | lrh0 |= qp->remote_ah_attr.sl << 4; | ||
564 | qp->s_hdr.lrh[0] = cpu_to_be16(lrh0); | ||
565 | qp->s_hdr.lrh[1] = cpu_to_be16(qp->remote_ah_attr.dlid); | ||
566 | qp->s_hdr.lrh[2] = cpu_to_be16(qp->s_hdrwords + nwords + SIZE_OF_CRC); | ||
567 | qp->s_hdr.lrh[3] = cpu_to_be16(dev->dd->ipath_lid); | ||
568 | bth0 |= ipath_get_pkey(dev->dd, qp->s_pkey_index); | ||
569 | bth0 |= extra_bytes << 20; | ||
570 | ohdr->bth[0] = cpu_to_be32(bth0 | (1 << 22)); | ||
571 | ohdr->bth[1] = cpu_to_be32(qp->remote_qpn); | ||
572 | ohdr->bth[2] = cpu_to_be32(bth2); | ||
573 | } | ||
574 | |||
651 | /** | 575 | /** |
652 | * ipath_do_ruc_send - perform a send on an RC or UC QP | 576 | * ipath_do_send - perform a send on a QP |
653 | * @data: contains a pointer to the QP | 577 | * @data: contains a pointer to the QP |
654 | * | 578 | * |
655 | * Process entries in the send work queue until credit or queue is | 579 | * Process entries in the send work queue until credit or queue is |
656 | * exhausted. Only allow one CPU to send a packet per QP (tasklet). | 580 | * exhausted. Only allow one CPU to send a packet per QP (tasklet). |
657 | * Otherwise, after we drop the QP s_lock, two threads could send | 581 | * Otherwise, two threads could send packets out of order. |
658 | * packets out of order. | ||
659 | */ | 582 | */ |
660 | void ipath_do_ruc_send(unsigned long data) | 583 | void ipath_do_send(unsigned long data) |
661 | { | 584 | { |
662 | struct ipath_qp *qp = (struct ipath_qp *)data; | 585 | struct ipath_qp *qp = (struct ipath_qp *)data; |
663 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); | 586 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); |
664 | unsigned long flags; | 587 | int (*make_req)(struct ipath_qp *qp); |
665 | u16 lrh0; | ||
666 | u32 nwords; | ||
667 | u32 extra_bytes; | ||
668 | u32 bth0; | ||
669 | u32 bth2; | ||
670 | u32 pmtu = ib_mtu_enum_to_int(qp->path_mtu); | ||
671 | struct ipath_other_headers *ohdr; | ||
672 | 588 | ||
673 | if (test_and_set_bit(IPATH_S_BUSY, &qp->s_busy)) | 589 | if (test_and_set_bit(IPATH_S_BUSY, &qp->s_busy)) |
674 | goto bail; | 590 | goto bail; |
675 | 591 | ||
676 | if (unlikely(qp->remote_ah_attr.dlid == dev->dd->ipath_lid)) { | 592 | if ((qp->ibqp.qp_type == IB_QPT_RC || |
593 | qp->ibqp.qp_type == IB_QPT_UC) && | ||
594 | qp->remote_ah_attr.dlid == dev->dd->ipath_lid) { | ||
677 | ipath_ruc_loopback(qp); | 595 | ipath_ruc_loopback(qp); |
678 | goto clear; | 596 | goto clear; |
679 | } | 597 | } |
680 | 598 | ||
681 | ohdr = &qp->s_hdr.u.oth; | 599 | if (qp->ibqp.qp_type == IB_QPT_RC) |
682 | if (qp->remote_ah_attr.ah_flags & IB_AH_GRH) | 600 | make_req = ipath_make_rc_req; |
683 | ohdr = &qp->s_hdr.u.l.oth; | 601 | else if (qp->ibqp.qp_type == IB_QPT_UC) |
602 | make_req = ipath_make_uc_req; | ||
603 | else | ||
604 | make_req = ipath_make_ud_req; | ||
684 | 605 | ||
685 | again: | 606 | again: |
686 | /* Check for a constructed packet to be sent. */ | 607 | /* Check for a constructed packet to be sent. */ |
@@ -689,9 +610,8 @@ again: | |||
689 | * If no PIO bufs are available, return. An interrupt will | 610 | * If no PIO bufs are available, return. An interrupt will |
690 | * call ipath_ib_piobufavail() when one is available. | 611 | * call ipath_ib_piobufavail() when one is available. |
691 | */ | 612 | */ |
692 | if (ipath_verbs_send(dev->dd, qp->s_hdrwords, | 613 | if (ipath_verbs_send(qp, &qp->s_hdr, qp->s_hdrwords, |
693 | (u32 *) &qp->s_hdr, qp->s_cur_size, | 614 | qp->s_cur_sge, qp->s_cur_size)) { |
694 | qp->s_cur_sge)) { | ||
695 | ipath_no_bufs_available(qp, dev); | 615 | ipath_no_bufs_available(qp, dev); |
696 | goto bail; | 616 | goto bail; |
697 | } | 617 | } |
@@ -700,54 +620,42 @@ again: | |||
700 | qp->s_hdrwords = 0; | 620 | qp->s_hdrwords = 0; |
701 | } | 621 | } |
702 | 622 | ||
703 | /* | 623 | if (make_req(qp)) |
704 | * The lock is needed to synchronize between setting | 624 | goto again; |
705 | * qp->s_ack_state, resend timer, and post_send(). | 625 | clear: |
706 | */ | 626 | clear_bit(IPATH_S_BUSY, &qp->s_busy); |
707 | spin_lock_irqsave(&qp->s_lock, flags); | 627 | bail:; |
708 | 628 | } | |
709 | if (!((qp->ibqp.qp_type == IB_QPT_RC) ? | ||
710 | ipath_make_rc_req(qp, ohdr, pmtu, &bth0, &bth2) : | ||
711 | ipath_make_uc_req(qp, ohdr, pmtu, &bth0, &bth2))) { | ||
712 | /* | ||
713 | * Clear the busy bit before unlocking to avoid races with | ||
714 | * adding new work queue items and then failing to process | ||
715 | * them. | ||
716 | */ | ||
717 | clear_bit(IPATH_S_BUSY, &qp->s_busy); | ||
718 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
719 | goto bail; | ||
720 | } | ||
721 | 629 | ||
722 | spin_unlock_irqrestore(&qp->s_lock, flags); | 630 | void ipath_send_complete(struct ipath_qp *qp, struct ipath_swqe *wqe, |
631 | enum ib_wc_status status) | ||
632 | { | ||
633 | u32 last = qp->s_last; | ||
723 | 634 | ||
724 | /* Construct the header. */ | 635 | if (++last == qp->s_size) |
725 | extra_bytes = (4 - qp->s_cur_size) & 3; | 636 | last = 0; |
726 | nwords = (qp->s_cur_size + extra_bytes) >> 2; | 637 | qp->s_last = last; |
727 | lrh0 = IPATH_LRH_BTH; | ||
728 | if (unlikely(qp->remote_ah_attr.ah_flags & IB_AH_GRH)) { | ||
729 | qp->s_hdrwords += ipath_make_grh(dev, &qp->s_hdr.u.l.grh, | ||
730 | &qp->remote_ah_attr.grh, | ||
731 | qp->s_hdrwords, nwords); | ||
732 | lrh0 = IPATH_LRH_GRH; | ||
733 | } | ||
734 | lrh0 |= qp->remote_ah_attr.sl << 4; | ||
735 | qp->s_hdr.lrh[0] = cpu_to_be16(lrh0); | ||
736 | qp->s_hdr.lrh[1] = cpu_to_be16(qp->remote_ah_attr.dlid); | ||
737 | qp->s_hdr.lrh[2] = cpu_to_be16(qp->s_hdrwords + nwords + | ||
738 | SIZE_OF_CRC); | ||
739 | qp->s_hdr.lrh[3] = cpu_to_be16(dev->dd->ipath_lid); | ||
740 | bth0 |= ipath_get_pkey(dev->dd, qp->s_pkey_index); | ||
741 | bth0 |= extra_bytes << 20; | ||
742 | ohdr->bth[0] = cpu_to_be32(bth0); | ||
743 | ohdr->bth[1] = cpu_to_be32(qp->remote_qpn); | ||
744 | ohdr->bth[2] = cpu_to_be32(bth2); | ||
745 | 638 | ||
746 | /* Check for more work to do. */ | 639 | /* See ch. 11.2.4.1 and 10.7.3.1 */ |
747 | goto again; | 640 | if (!(qp->s_flags & IPATH_S_SIGNAL_REQ_WR) || |
641 | (wqe->wr.send_flags & IB_SEND_SIGNALED) || | ||
642 | status != IB_WC_SUCCESS) { | ||
643 | struct ib_wc wc; | ||
748 | 644 | ||
749 | clear: | 645 | wc.wr_id = wqe->wr.wr_id; |
750 | clear_bit(IPATH_S_BUSY, &qp->s_busy); | 646 | wc.status = status; |
751 | bail: | 647 | wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; |
752 | return; | 648 | wc.vendor_err = 0; |
649 | wc.byte_len = wqe->length; | ||
650 | wc.imm_data = 0; | ||
651 | wc.qp = &qp->ibqp; | ||
652 | wc.src_qp = 0; | ||
653 | wc.wc_flags = 0; | ||
654 | wc.pkey_index = 0; | ||
655 | wc.slid = 0; | ||
656 | wc.sl = 0; | ||
657 | wc.dlid_path_bits = 0; | ||
658 | wc.port_num = 0; | ||
659 | ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 0); | ||
660 | } | ||
753 | } | 661 | } |
diff --git a/drivers/infiniband/hw/ipath/ipath_uc.c b/drivers/infiniband/hw/ipath/ipath_uc.c index 8380fbc50d2c..767beb903c25 100644 --- a/drivers/infiniband/hw/ipath/ipath_uc.c +++ b/drivers/infiniband/hw/ipath/ipath_uc.c | |||
@@ -37,72 +37,40 @@ | |||
37 | /* cut down ridiculously long IB macro names */ | 37 | /* cut down ridiculously long IB macro names */ |
38 | #define OP(x) IB_OPCODE_UC_##x | 38 | #define OP(x) IB_OPCODE_UC_##x |
39 | 39 | ||
40 | static void complete_last_send(struct ipath_qp *qp, struct ipath_swqe *wqe, | ||
41 | struct ib_wc *wc) | ||
42 | { | ||
43 | if (++qp->s_last == qp->s_size) | ||
44 | qp->s_last = 0; | ||
45 | if (!(qp->s_flags & IPATH_S_SIGNAL_REQ_WR) || | ||
46 | (wqe->wr.send_flags & IB_SEND_SIGNALED)) { | ||
47 | wc->wr_id = wqe->wr.wr_id; | ||
48 | wc->status = IB_WC_SUCCESS; | ||
49 | wc->opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; | ||
50 | wc->vendor_err = 0; | ||
51 | wc->byte_len = wqe->length; | ||
52 | wc->qp = &qp->ibqp; | ||
53 | wc->src_qp = qp->remote_qpn; | ||
54 | wc->pkey_index = 0; | ||
55 | wc->slid = qp->remote_ah_attr.dlid; | ||
56 | wc->sl = qp->remote_ah_attr.sl; | ||
57 | wc->dlid_path_bits = 0; | ||
58 | wc->port_num = 0; | ||
59 | ipath_cq_enter(to_icq(qp->ibqp.send_cq), wc, 0); | ||
60 | } | ||
61 | } | ||
62 | |||
63 | /** | 40 | /** |
64 | * ipath_make_uc_req - construct a request packet (SEND, RDMA write) | 41 | * ipath_make_uc_req - construct a request packet (SEND, RDMA write) |
65 | * @qp: a pointer to the QP | 42 | * @qp: a pointer to the QP |
66 | * @ohdr: a pointer to the IB header being constructed | ||
67 | * @pmtu: the path MTU | ||
68 | * @bth0p: pointer to the BTH opcode word | ||
69 | * @bth2p: pointer to the BTH PSN word | ||
70 | * | 43 | * |
71 | * Return 1 if constructed; otherwise, return 0. | 44 | * Return 1 if constructed; otherwise, return 0. |
72 | * Note the QP s_lock must be held and interrupts disabled. | ||
73 | */ | 45 | */ |
74 | int ipath_make_uc_req(struct ipath_qp *qp, | 46 | int ipath_make_uc_req(struct ipath_qp *qp) |
75 | struct ipath_other_headers *ohdr, | ||
76 | u32 pmtu, u32 *bth0p, u32 *bth2p) | ||
77 | { | 47 | { |
48 | struct ipath_other_headers *ohdr; | ||
78 | struct ipath_swqe *wqe; | 49 | struct ipath_swqe *wqe; |
79 | u32 hwords; | 50 | u32 hwords; |
80 | u32 bth0; | 51 | u32 bth0; |
81 | u32 len; | 52 | u32 len; |
82 | struct ib_wc wc; | 53 | u32 pmtu = ib_mtu_enum_to_int(qp->path_mtu); |
54 | int ret = 0; | ||
83 | 55 | ||
84 | if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK)) | 56 | if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK)) |
85 | goto done; | 57 | goto done; |
86 | 58 | ||
59 | ohdr = &qp->s_hdr.u.oth; | ||
60 | if (qp->remote_ah_attr.ah_flags & IB_AH_GRH) | ||
61 | ohdr = &qp->s_hdr.u.l.oth; | ||
62 | |||
87 | /* header size in 32-bit words LRH+BTH = (8+12)/4. */ | 63 | /* header size in 32-bit words LRH+BTH = (8+12)/4. */ |
88 | hwords = 5; | 64 | hwords = 5; |
89 | bth0 = 1 << 22; /* Set M bit */ | 65 | bth0 = 1 << 22; /* Set M bit */ |
90 | 66 | ||
91 | /* Get the next send request. */ | 67 | /* Get the next send request. */ |
92 | wqe = get_swqe_ptr(qp, qp->s_last); | 68 | wqe = get_swqe_ptr(qp, qp->s_cur); |
69 | qp->s_wqe = NULL; | ||
93 | switch (qp->s_state) { | 70 | switch (qp->s_state) { |
94 | default: | 71 | default: |
95 | /* | ||
96 | * Signal the completion of the last send | ||
97 | * (if there is one). | ||
98 | */ | ||
99 | if (qp->s_last != qp->s_tail) { | ||
100 | complete_last_send(qp, wqe, &wc); | ||
101 | wqe = get_swqe_ptr(qp, qp->s_last); | ||
102 | } | ||
103 | |||
104 | /* Check if send work queue is empty. */ | 72 | /* Check if send work queue is empty. */ |
105 | if (qp->s_tail == qp->s_head) | 73 | if (qp->s_cur == qp->s_head) |
106 | goto done; | 74 | goto done; |
107 | /* | 75 | /* |
108 | * Start a new request. | 76 | * Start a new request. |
@@ -131,6 +99,9 @@ int ipath_make_uc_req(struct ipath_qp *qp, | |||
131 | } | 99 | } |
132 | if (wqe->wr.send_flags & IB_SEND_SOLICITED) | 100 | if (wqe->wr.send_flags & IB_SEND_SOLICITED) |
133 | bth0 |= 1 << 23; | 101 | bth0 |= 1 << 23; |
102 | qp->s_wqe = wqe; | ||
103 | if (++qp->s_cur >= qp->s_size) | ||
104 | qp->s_cur = 0; | ||
134 | break; | 105 | break; |
135 | 106 | ||
136 | case IB_WR_RDMA_WRITE: | 107 | case IB_WR_RDMA_WRITE: |
@@ -157,13 +128,14 @@ int ipath_make_uc_req(struct ipath_qp *qp, | |||
157 | if (wqe->wr.send_flags & IB_SEND_SOLICITED) | 128 | if (wqe->wr.send_flags & IB_SEND_SOLICITED) |
158 | bth0 |= 1 << 23; | 129 | bth0 |= 1 << 23; |
159 | } | 130 | } |
131 | qp->s_wqe = wqe; | ||
132 | if (++qp->s_cur >= qp->s_size) | ||
133 | qp->s_cur = 0; | ||
160 | break; | 134 | break; |
161 | 135 | ||
162 | default: | 136 | default: |
163 | goto done; | 137 | goto done; |
164 | } | 138 | } |
165 | if (++qp->s_tail >= qp->s_size) | ||
166 | qp->s_tail = 0; | ||
167 | break; | 139 | break; |
168 | 140 | ||
169 | case OP(SEND_FIRST): | 141 | case OP(SEND_FIRST): |
@@ -185,6 +157,9 @@ int ipath_make_uc_req(struct ipath_qp *qp, | |||
185 | } | 157 | } |
186 | if (wqe->wr.send_flags & IB_SEND_SOLICITED) | 158 | if (wqe->wr.send_flags & IB_SEND_SOLICITED) |
187 | bth0 |= 1 << 23; | 159 | bth0 |= 1 << 23; |
160 | qp->s_wqe = wqe; | ||
161 | if (++qp->s_cur >= qp->s_size) | ||
162 | qp->s_cur = 0; | ||
188 | break; | 163 | break; |
189 | 164 | ||
190 | case OP(RDMA_WRITE_FIRST): | 165 | case OP(RDMA_WRITE_FIRST): |
@@ -207,18 +182,22 @@ int ipath_make_uc_req(struct ipath_qp *qp, | |||
207 | if (wqe->wr.send_flags & IB_SEND_SOLICITED) | 182 | if (wqe->wr.send_flags & IB_SEND_SOLICITED) |
208 | bth0 |= 1 << 23; | 183 | bth0 |= 1 << 23; |
209 | } | 184 | } |
185 | qp->s_wqe = wqe; | ||
186 | if (++qp->s_cur >= qp->s_size) | ||
187 | qp->s_cur = 0; | ||
210 | break; | 188 | break; |
211 | } | 189 | } |
212 | qp->s_len -= len; | 190 | qp->s_len -= len; |
213 | qp->s_hdrwords = hwords; | 191 | qp->s_hdrwords = hwords; |
214 | qp->s_cur_sge = &qp->s_sge; | 192 | qp->s_cur_sge = &qp->s_sge; |
215 | qp->s_cur_size = len; | 193 | qp->s_cur_size = len; |
216 | *bth0p = bth0 | (qp->s_state << 24); | 194 | ipath_make_ruc_header(to_idev(qp->ibqp.device), |
217 | *bth2p = qp->s_next_psn++ & IPATH_PSN_MASK; | 195 | qp, ohdr, bth0 | (qp->s_state << 24), |
218 | return 1; | 196 | qp->s_next_psn++ & IPATH_PSN_MASK); |
197 | ret = 1; | ||
219 | 198 | ||
220 | done: | 199 | done: |
221 | return 0; | 200 | return ret; |
222 | } | 201 | } |
223 | 202 | ||
224 | /** | 203 | /** |
diff --git a/drivers/infiniband/hw/ipath/ipath_ud.c b/drivers/infiniband/hw/ipath/ipath_ud.c index f9a3338a5fb7..34c4a0a5be31 100644 --- a/drivers/infiniband/hw/ipath/ipath_ud.c +++ b/drivers/infiniband/hw/ipath/ipath_ud.c | |||
@@ -36,68 +36,17 @@ | |||
36 | #include "ipath_verbs.h" | 36 | #include "ipath_verbs.h" |
37 | #include "ipath_kernel.h" | 37 | #include "ipath_kernel.h" |
38 | 38 | ||
39 | static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe, | ||
40 | u32 *lengthp, struct ipath_sge_state *ss) | ||
41 | { | ||
42 | int user = to_ipd(qp->ibqp.pd)->user; | ||
43 | int i, j, ret; | ||
44 | struct ib_wc wc; | ||
45 | |||
46 | *lengthp = 0; | ||
47 | for (i = j = 0; i < wqe->num_sge; i++) { | ||
48 | if (wqe->sg_list[i].length == 0) | ||
49 | continue; | ||
50 | /* Check LKEY */ | ||
51 | if ((user && wqe->sg_list[i].lkey == 0) || | ||
52 | !ipath_lkey_ok(qp, j ? &ss->sg_list[j - 1] : &ss->sge, | ||
53 | &wqe->sg_list[i], IB_ACCESS_LOCAL_WRITE)) | ||
54 | goto bad_lkey; | ||
55 | *lengthp += wqe->sg_list[i].length; | ||
56 | j++; | ||
57 | } | ||
58 | ss->num_sge = j; | ||
59 | ret = 1; | ||
60 | goto bail; | ||
61 | |||
62 | bad_lkey: | ||
63 | wc.wr_id = wqe->wr_id; | ||
64 | wc.status = IB_WC_LOC_PROT_ERR; | ||
65 | wc.opcode = IB_WC_RECV; | ||
66 | wc.vendor_err = 0; | ||
67 | wc.byte_len = 0; | ||
68 | wc.imm_data = 0; | ||
69 | wc.qp = &qp->ibqp; | ||
70 | wc.src_qp = 0; | ||
71 | wc.wc_flags = 0; | ||
72 | wc.pkey_index = 0; | ||
73 | wc.slid = 0; | ||
74 | wc.sl = 0; | ||
75 | wc.dlid_path_bits = 0; | ||
76 | wc.port_num = 0; | ||
77 | /* Signal solicited completion event. */ | ||
78 | ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, 1); | ||
79 | ret = 0; | ||
80 | bail: | ||
81 | return ret; | ||
82 | } | ||
83 | |||
84 | /** | 39 | /** |
85 | * ipath_ud_loopback - handle send on loopback QPs | 40 | * ipath_ud_loopback - handle send on loopback QPs |
86 | * @sqp: the QP | 41 | * @sqp: the sending QP |
87 | * @ss: the SGE state | 42 | * @swqe: the send work request |
88 | * @length: the length of the data to send | ||
89 | * @wr: the work request | ||
90 | * @wc: the work completion entry | ||
91 | * | 43 | * |
92 | * This is called from ipath_post_ud_send() to forward a WQE addressed | 44 | * This is called from ipath_make_ud_req() to forward a WQE addressed |
93 | * to the same HCA. | 45 | * to the same HCA. |
94 | * Note that the receive interrupt handler may be calling ipath_ud_rcv() | 46 | * Note that the receive interrupt handler may be calling ipath_ud_rcv() |
95 | * while this is being called. | 47 | * while this is being called. |
96 | */ | 48 | */ |
97 | static void ipath_ud_loopback(struct ipath_qp *sqp, | 49 | static void ipath_ud_loopback(struct ipath_qp *sqp, struct ipath_swqe *swqe) |
98 | struct ipath_sge_state *ss, | ||
99 | u32 length, struct ib_send_wr *wr, | ||
100 | struct ib_wc *wc) | ||
101 | { | 50 | { |
102 | struct ipath_ibdev *dev = to_idev(sqp->ibqp.device); | 51 | struct ipath_ibdev *dev = to_idev(sqp->ibqp.device); |
103 | struct ipath_qp *qp; | 52 | struct ipath_qp *qp; |
@@ -110,12 +59,18 @@ static void ipath_ud_loopback(struct ipath_qp *sqp, | |||
110 | struct ipath_rwq *wq; | 59 | struct ipath_rwq *wq; |
111 | struct ipath_rwqe *wqe; | 60 | struct ipath_rwqe *wqe; |
112 | void (*handler)(struct ib_event *, void *); | 61 | void (*handler)(struct ib_event *, void *); |
62 | struct ib_wc wc; | ||
113 | u32 tail; | 63 | u32 tail; |
114 | u32 rlen; | 64 | u32 rlen; |
65 | u32 length; | ||
115 | 66 | ||
116 | qp = ipath_lookup_qpn(&dev->qp_table, wr->wr.ud.remote_qpn); | 67 | qp = ipath_lookup_qpn(&dev->qp_table, swqe->wr.wr.ud.remote_qpn); |
117 | if (!qp) | 68 | if (!qp) { |
118 | return; | 69 | dev->n_pkt_drops++; |
70 | goto send_comp; | ||
71 | } | ||
72 | |||
73 | rsge.sg_list = NULL; | ||
119 | 74 | ||
120 | /* | 75 | /* |
121 | * Check that the qkey matches (except for QP0, see 9.6.1.4.1). | 76 | * Check that the qkey matches (except for QP0, see 9.6.1.4.1). |
@@ -123,39 +78,34 @@ static void ipath_ud_loopback(struct ipath_qp *sqp, | |||
123 | * qkey from the QP context instead of the WR (see 10.2.5). | 78 | * qkey from the QP context instead of the WR (see 10.2.5). |
124 | */ | 79 | */ |
125 | if (unlikely(qp->ibqp.qp_num && | 80 | if (unlikely(qp->ibqp.qp_num && |
126 | ((int) wr->wr.ud.remote_qkey < 0 | 81 | ((int) swqe->wr.wr.ud.remote_qkey < 0 ? |
127 | ? qp->qkey : wr->wr.ud.remote_qkey) != qp->qkey)) { | 82 | sqp->qkey : swqe->wr.wr.ud.remote_qkey) != qp->qkey)) { |
128 | /* XXX OK to lose a count once in a while. */ | 83 | /* XXX OK to lose a count once in a while. */ |
129 | dev->qkey_violations++; | 84 | dev->qkey_violations++; |
130 | dev->n_pkt_drops++; | 85 | dev->n_pkt_drops++; |
131 | goto done; | 86 | goto drop; |
132 | } | 87 | } |
133 | 88 | ||
134 | /* | 89 | /* |
135 | * A GRH is expected to preceed the data even if not | 90 | * A GRH is expected to preceed the data even if not |
136 | * present on the wire. | 91 | * present on the wire. |
137 | */ | 92 | */ |
138 | wc->byte_len = length + sizeof(struct ib_grh); | 93 | length = swqe->length; |
94 | wc.byte_len = length + sizeof(struct ib_grh); | ||
139 | 95 | ||
140 | if (wr->opcode == IB_WR_SEND_WITH_IMM) { | 96 | if (swqe->wr.opcode == IB_WR_SEND_WITH_IMM) { |
141 | wc->wc_flags = IB_WC_WITH_IMM; | 97 | wc.wc_flags = IB_WC_WITH_IMM; |
142 | wc->imm_data = wr->imm_data; | 98 | wc.imm_data = swqe->wr.imm_data; |
143 | } else { | 99 | } else { |
144 | wc->wc_flags = 0; | 100 | wc.wc_flags = 0; |
145 | wc->imm_data = 0; | 101 | wc.imm_data = 0; |
146 | } | 102 | } |
147 | 103 | ||
148 | if (wr->num_sge > 1) { | ||
149 | rsge.sg_list = kmalloc((wr->num_sge - 1) * | ||
150 | sizeof(struct ipath_sge), | ||
151 | GFP_ATOMIC); | ||
152 | } else | ||
153 | rsge.sg_list = NULL; | ||
154 | |||
155 | /* | 104 | /* |
156 | * Get the next work request entry to find where to put the data. | 105 | * This would be a lot simpler if we could call ipath_get_rwqe() |
157 | * Note that it is safe to drop the lock after changing rq->tail | 106 | * but that uses state that the receive interrupt handler uses |
158 | * since ipath_post_receive() won't fill the empty slot. | 107 | * so we would need to lock out receive interrupts while doing |
108 | * local loopback. | ||
159 | */ | 109 | */ |
160 | if (qp->ibqp.srq) { | 110 | if (qp->ibqp.srq) { |
161 | srq = to_isrq(qp->ibqp.srq); | 111 | srq = to_isrq(qp->ibqp.srq); |
@@ -167,32 +117,53 @@ static void ipath_ud_loopback(struct ipath_qp *sqp, | |||
167 | rq = &qp->r_rq; | 117 | rq = &qp->r_rq; |
168 | } | 118 | } |
169 | 119 | ||
120 | if (rq->max_sge > 1) { | ||
121 | /* | ||
122 | * XXX We could use GFP_KERNEL if ipath_do_send() | ||
123 | * was always called from the tasklet instead of | ||
124 | * from ipath_post_send(). | ||
125 | */ | ||
126 | rsge.sg_list = kmalloc((rq->max_sge - 1) * | ||
127 | sizeof(struct ipath_sge), | ||
128 | GFP_ATOMIC); | ||
129 | if (!rsge.sg_list) { | ||
130 | dev->n_pkt_drops++; | ||
131 | goto drop; | ||
132 | } | ||
133 | } | ||
134 | |||
135 | /* | ||
136 | * Get the next work request entry to find where to put the data. | ||
137 | * Note that it is safe to drop the lock after changing rq->tail | ||
138 | * since ipath_post_receive() won't fill the empty slot. | ||
139 | */ | ||
170 | spin_lock_irqsave(&rq->lock, flags); | 140 | spin_lock_irqsave(&rq->lock, flags); |
171 | wq = rq->wq; | 141 | wq = rq->wq; |
172 | tail = wq->tail; | 142 | tail = wq->tail; |
173 | while (1) { | 143 | /* Validate tail before using it since it is user writable. */ |
174 | if (unlikely(tail == wq->head)) { | 144 | if (tail >= rq->size) |
175 | spin_unlock_irqrestore(&rq->lock, flags); | 145 | tail = 0; |
176 | dev->n_pkt_drops++; | 146 | if (unlikely(tail == wq->head)) { |
177 | goto bail_sge; | 147 | spin_unlock_irqrestore(&rq->lock, flags); |
178 | } | 148 | dev->n_pkt_drops++; |
179 | /* Make sure entry is read after head index is read. */ | 149 | goto drop; |
180 | smp_rmb(); | 150 | } |
181 | wqe = get_rwqe_ptr(rq, tail); | 151 | wqe = get_rwqe_ptr(rq, tail); |
182 | if (++tail >= rq->size) | 152 | if (!ipath_init_sge(qp, wqe, &rlen, &rsge)) { |
183 | tail = 0; | 153 | spin_unlock_irqrestore(&rq->lock, flags); |
184 | if (init_sge(qp, wqe, &rlen, &rsge)) | 154 | dev->n_pkt_drops++; |
185 | break; | 155 | goto drop; |
186 | wq->tail = tail; | ||
187 | } | 156 | } |
188 | /* Silently drop packets which are too big. */ | 157 | /* Silently drop packets which are too big. */ |
189 | if (wc->byte_len > rlen) { | 158 | if (wc.byte_len > rlen) { |
190 | spin_unlock_irqrestore(&rq->lock, flags); | 159 | spin_unlock_irqrestore(&rq->lock, flags); |
191 | dev->n_pkt_drops++; | 160 | dev->n_pkt_drops++; |
192 | goto bail_sge; | 161 | goto drop; |
193 | } | 162 | } |
163 | if (++tail >= rq->size) | ||
164 | tail = 0; | ||
194 | wq->tail = tail; | 165 | wq->tail = tail; |
195 | wc->wr_id = wqe->wr_id; | 166 | wc.wr_id = wqe->wr_id; |
196 | if (handler) { | 167 | if (handler) { |
197 | u32 n; | 168 | u32 n; |
198 | 169 | ||
@@ -221,13 +192,13 @@ static void ipath_ud_loopback(struct ipath_qp *sqp, | |||
221 | } else | 192 | } else |
222 | spin_unlock_irqrestore(&rq->lock, flags); | 193 | spin_unlock_irqrestore(&rq->lock, flags); |
223 | 194 | ||
224 | ah_attr = &to_iah(wr->wr.ud.ah)->attr; | 195 | ah_attr = &to_iah(swqe->wr.wr.ud.ah)->attr; |
225 | if (ah_attr->ah_flags & IB_AH_GRH) { | 196 | if (ah_attr->ah_flags & IB_AH_GRH) { |
226 | ipath_copy_sge(&rsge, &ah_attr->grh, sizeof(struct ib_grh)); | 197 | ipath_copy_sge(&rsge, &ah_attr->grh, sizeof(struct ib_grh)); |
227 | wc->wc_flags |= IB_WC_GRH; | 198 | wc.wc_flags |= IB_WC_GRH; |
228 | } else | 199 | } else |
229 | ipath_skip_sge(&rsge, sizeof(struct ib_grh)); | 200 | ipath_skip_sge(&rsge, sizeof(struct ib_grh)); |
230 | sge = &ss->sge; | 201 | sge = swqe->sg_list; |
231 | while (length) { | 202 | while (length) { |
232 | u32 len = sge->length; | 203 | u32 len = sge->length; |
233 | 204 | ||
@@ -241,8 +212,8 @@ static void ipath_ud_loopback(struct ipath_qp *sqp, | |||
241 | sge->length -= len; | 212 | sge->length -= len; |
242 | sge->sge_length -= len; | 213 | sge->sge_length -= len; |
243 | if (sge->sge_length == 0) { | 214 | if (sge->sge_length == 0) { |
244 | if (--ss->num_sge) | 215 | if (--swqe->wr.num_sge) |
245 | *sge = *ss->sg_list++; | 216 | sge++; |
246 | } else if (sge->length == 0 && sge->mr != NULL) { | 217 | } else if (sge->length == 0 && sge->mr != NULL) { |
247 | if (++sge->n >= IPATH_SEGSZ) { | 218 | if (++sge->n >= IPATH_SEGSZ) { |
248 | if (++sge->m >= sge->mr->mapsz) | 219 | if (++sge->m >= sge->mr->mapsz) |
@@ -256,123 +227,60 @@ static void ipath_ud_loopback(struct ipath_qp *sqp, | |||
256 | } | 227 | } |
257 | length -= len; | 228 | length -= len; |
258 | } | 229 | } |
259 | wc->status = IB_WC_SUCCESS; | 230 | wc.status = IB_WC_SUCCESS; |
260 | wc->opcode = IB_WC_RECV; | 231 | wc.opcode = IB_WC_RECV; |
261 | wc->vendor_err = 0; | 232 | wc.vendor_err = 0; |
262 | wc->qp = &qp->ibqp; | 233 | wc.qp = &qp->ibqp; |
263 | wc->src_qp = sqp->ibqp.qp_num; | 234 | wc.src_qp = sqp->ibqp.qp_num; |
264 | /* XXX do we know which pkey matched? Only needed for GSI. */ | 235 | /* XXX do we know which pkey matched? Only needed for GSI. */ |
265 | wc->pkey_index = 0; | 236 | wc.pkey_index = 0; |
266 | wc->slid = dev->dd->ipath_lid | | 237 | wc.slid = dev->dd->ipath_lid | |
267 | (ah_attr->src_path_bits & | 238 | (ah_attr->src_path_bits & |
268 | ((1 << (dev->mkeyprot_resv_lmc & 7)) - 1)); | 239 | ((1 << (dev->mkeyprot_resv_lmc & 7)) - 1)); |
269 | wc->sl = ah_attr->sl; | 240 | wc.sl = ah_attr->sl; |
270 | wc->dlid_path_bits = | 241 | wc.dlid_path_bits = |
271 | ah_attr->dlid & ((1 << (dev->mkeyprot_resv_lmc & 7)) - 1); | 242 | ah_attr->dlid & ((1 << (dev->mkeyprot_resv_lmc & 7)) - 1); |
243 | wc.port_num = 1; | ||
272 | /* Signal completion event if the solicited bit is set. */ | 244 | /* Signal completion event if the solicited bit is set. */ |
273 | ipath_cq_enter(to_icq(qp->ibqp.recv_cq), wc, | 245 | ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, |
274 | wr->send_flags & IB_SEND_SOLICITED); | 246 | swqe->wr.send_flags & IB_SEND_SOLICITED); |
275 | 247 | drop: | |
276 | bail_sge: | ||
277 | kfree(rsge.sg_list); | 248 | kfree(rsge.sg_list); |
278 | done: | ||
279 | if (atomic_dec_and_test(&qp->refcount)) | 249 | if (atomic_dec_and_test(&qp->refcount)) |
280 | wake_up(&qp->wait); | 250 | wake_up(&qp->wait); |
251 | send_comp: | ||
252 | ipath_send_complete(sqp, swqe, IB_WC_SUCCESS); | ||
281 | } | 253 | } |
282 | 254 | ||
283 | /** | 255 | /** |
284 | * ipath_post_ud_send - post a UD send on QP | 256 | * ipath_make_ud_req - construct a UD request packet |
285 | * @qp: the QP | 257 | * @qp: the QP |
286 | * @wr: the work request | ||
287 | * | 258 | * |
288 | * Note that we actually send the data as it is posted instead of putting | 259 | * Return 1 if constructed; otherwise, return 0. |
289 | * the request into a ring buffer. If we wanted to use a ring buffer, | ||
290 | * we would need to save a reference to the destination address in the SWQE. | ||
291 | */ | 260 | */ |
292 | int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr) | 261 | int ipath_make_ud_req(struct ipath_qp *qp) |
293 | { | 262 | { |
294 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); | 263 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); |
295 | struct ipath_other_headers *ohdr; | 264 | struct ipath_other_headers *ohdr; |
296 | struct ib_ah_attr *ah_attr; | 265 | struct ib_ah_attr *ah_attr; |
297 | struct ipath_sge_state ss; | 266 | struct ipath_swqe *wqe; |
298 | struct ipath_sge *sg_list; | ||
299 | struct ib_wc wc; | ||
300 | u32 hwords; | ||
301 | u32 nwords; | 267 | u32 nwords; |
302 | u32 len; | ||
303 | u32 extra_bytes; | 268 | u32 extra_bytes; |
304 | u32 bth0; | 269 | u32 bth0; |
305 | u16 lrh0; | 270 | u16 lrh0; |
306 | u16 lid; | 271 | u16 lid; |
307 | int i; | 272 | int ret = 0; |
308 | int ret; | ||
309 | 273 | ||
310 | if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK)) { | 274 | if (unlikely(!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK))) |
311 | ret = 0; | ||
312 | goto bail; | 275 | goto bail; |
313 | } | ||
314 | 276 | ||
315 | if (wr->wr.ud.ah->pd != qp->ibqp.pd) { | 277 | if (qp->s_cur == qp->s_head) |
316 | ret = -EPERM; | ||
317 | goto bail; | 278 | goto bail; |
318 | } | ||
319 | 279 | ||
320 | /* IB spec says that num_sge == 0 is OK. */ | 280 | wqe = get_swqe_ptr(qp, qp->s_cur); |
321 | if (wr->num_sge > qp->s_max_sge) { | ||
322 | ret = -EINVAL; | ||
323 | goto bail; | ||
324 | } | ||
325 | |||
326 | if (wr->num_sge > 1) { | ||
327 | sg_list = kmalloc((qp->s_max_sge - 1) * sizeof(*sg_list), | ||
328 | GFP_ATOMIC); | ||
329 | if (!sg_list) { | ||
330 | ret = -ENOMEM; | ||
331 | goto bail; | ||
332 | } | ||
333 | } else | ||
334 | sg_list = NULL; | ||
335 | |||
336 | /* Check the buffer to send. */ | ||
337 | ss.sg_list = sg_list; | ||
338 | ss.sge.mr = NULL; | ||
339 | ss.sge.vaddr = NULL; | ||
340 | ss.sge.length = 0; | ||
341 | ss.sge.sge_length = 0; | ||
342 | ss.num_sge = 0; | ||
343 | len = 0; | ||
344 | for (i = 0; i < wr->num_sge; i++) { | ||
345 | /* Check LKEY */ | ||
346 | if (to_ipd(qp->ibqp.pd)->user && wr->sg_list[i].lkey == 0) { | ||
347 | ret = -EINVAL; | ||
348 | goto bail; | ||
349 | } | ||
350 | |||
351 | if (wr->sg_list[i].length == 0) | ||
352 | continue; | ||
353 | if (!ipath_lkey_ok(qp, ss.num_sge ? | ||
354 | sg_list + ss.num_sge - 1 : &ss.sge, | ||
355 | &wr->sg_list[i], 0)) { | ||
356 | ret = -EINVAL; | ||
357 | goto bail; | ||
358 | } | ||
359 | len += wr->sg_list[i].length; | ||
360 | ss.num_sge++; | ||
361 | } | ||
362 | /* Check for invalid packet size. */ | ||
363 | if (len > dev->dd->ipath_ibmtu) { | ||
364 | ret = -EINVAL; | ||
365 | goto bail; | ||
366 | } | ||
367 | extra_bytes = (4 - len) & 3; | ||
368 | nwords = (len + extra_bytes) >> 2; | ||
369 | 281 | ||
370 | /* Construct the header. */ | 282 | /* Construct the header. */ |
371 | ah_attr = &to_iah(wr->wr.ud.ah)->attr; | 283 | ah_attr = &to_iah(wqe->wr.wr.ud.ah)->attr; |
372 | if (ah_attr->dlid == 0) { | ||
373 | ret = -EINVAL; | ||
374 | goto bail; | ||
375 | } | ||
376 | if (ah_attr->dlid >= IPATH_MULTICAST_LID_BASE) { | 284 | if (ah_attr->dlid >= IPATH_MULTICAST_LID_BASE) { |
377 | if (ah_attr->dlid != IPATH_PERMISSIVE_LID) | 285 | if (ah_attr->dlid != IPATH_PERMISSIVE_LID) |
378 | dev->n_multicast_xmit++; | 286 | dev->n_multicast_xmit++; |
@@ -383,64 +291,53 @@ int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr) | |||
383 | lid = ah_attr->dlid & | 291 | lid = ah_attr->dlid & |
384 | ~((1 << (dev->mkeyprot_resv_lmc & 7)) - 1); | 292 | ~((1 << (dev->mkeyprot_resv_lmc & 7)) - 1); |
385 | if (unlikely(lid == dev->dd->ipath_lid)) { | 293 | if (unlikely(lid == dev->dd->ipath_lid)) { |
386 | /* | 294 | ipath_ud_loopback(qp, wqe); |
387 | * Pass in an uninitialized ib_wc to save stack | ||
388 | * space. | ||
389 | */ | ||
390 | ipath_ud_loopback(qp, &ss, len, wr, &wc); | ||
391 | goto done; | 295 | goto done; |
392 | } | 296 | } |
393 | } | 297 | } |
298 | |||
299 | extra_bytes = -wqe->length & 3; | ||
300 | nwords = (wqe->length + extra_bytes) >> 2; | ||
301 | |||
302 | /* header size in 32-bit words LRH+BTH+DETH = (8+12+8)/4. */ | ||
303 | qp->s_hdrwords = 7; | ||
304 | if (wqe->wr.opcode == IB_WR_SEND_WITH_IMM) | ||
305 | qp->s_hdrwords++; | ||
306 | qp->s_cur_size = wqe->length; | ||
307 | qp->s_cur_sge = &qp->s_sge; | ||
308 | qp->s_wqe = wqe; | ||
309 | qp->s_sge.sge = wqe->sg_list[0]; | ||
310 | qp->s_sge.sg_list = wqe->sg_list + 1; | ||
311 | qp->s_sge.num_sge = wqe->wr.num_sge; | ||
312 | |||
394 | if (ah_attr->ah_flags & IB_AH_GRH) { | 313 | if (ah_attr->ah_flags & IB_AH_GRH) { |
395 | /* Header size in 32-bit words. */ | 314 | /* Header size in 32-bit words. */ |
396 | hwords = 17; | 315 | qp->s_hdrwords += ipath_make_grh(dev, &qp->s_hdr.u.l.grh, |
316 | &ah_attr->grh, | ||
317 | qp->s_hdrwords, nwords); | ||
397 | lrh0 = IPATH_LRH_GRH; | 318 | lrh0 = IPATH_LRH_GRH; |
398 | ohdr = &qp->s_hdr.u.l.oth; | 319 | ohdr = &qp->s_hdr.u.l.oth; |
399 | qp->s_hdr.u.l.grh.version_tclass_flow = | ||
400 | cpu_to_be32((6 << 28) | | ||
401 | (ah_attr->grh.traffic_class << 20) | | ||
402 | ah_attr->grh.flow_label); | ||
403 | qp->s_hdr.u.l.grh.paylen = | ||
404 | cpu_to_be16(((wr->opcode == | ||
405 | IB_WR_SEND_WITH_IMM ? 6 : 5) + | ||
406 | nwords + SIZE_OF_CRC) << 2); | ||
407 | /* next_hdr is defined by C8-7 in ch. 8.4.1 */ | ||
408 | qp->s_hdr.u.l.grh.next_hdr = 0x1B; | ||
409 | qp->s_hdr.u.l.grh.hop_limit = ah_attr->grh.hop_limit; | ||
410 | /* The SGID is 32-bit aligned. */ | ||
411 | qp->s_hdr.u.l.grh.sgid.global.subnet_prefix = | ||
412 | dev->gid_prefix; | ||
413 | qp->s_hdr.u.l.grh.sgid.global.interface_id = | ||
414 | dev->dd->ipath_guid; | ||
415 | qp->s_hdr.u.l.grh.dgid = ah_attr->grh.dgid; | ||
416 | /* | 320 | /* |
417 | * Don't worry about sending to locally attached multicast | 321 | * Don't worry about sending to locally attached multicast |
418 | * QPs. It is unspecified by the spec. what happens. | 322 | * QPs. It is unspecified by the spec. what happens. |
419 | */ | 323 | */ |
420 | } else { | 324 | } else { |
421 | /* Header size in 32-bit words. */ | 325 | /* Header size in 32-bit words. */ |
422 | hwords = 7; | ||
423 | lrh0 = IPATH_LRH_BTH; | 326 | lrh0 = IPATH_LRH_BTH; |
424 | ohdr = &qp->s_hdr.u.oth; | 327 | ohdr = &qp->s_hdr.u.oth; |
425 | } | 328 | } |
426 | if (wr->opcode == IB_WR_SEND_WITH_IMM) { | 329 | if (wqe->wr.opcode == IB_WR_SEND_WITH_IMM) { |
427 | ohdr->u.ud.imm_data = wr->imm_data; | 330 | ohdr->u.ud.imm_data = wqe->wr.imm_data; |
428 | wc.imm_data = wr->imm_data; | ||
429 | hwords += 1; | ||
430 | bth0 = IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE << 24; | 331 | bth0 = IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE << 24; |
431 | } else if (wr->opcode == IB_WR_SEND) { | 332 | } else |
432 | wc.imm_data = 0; | ||
433 | bth0 = IB_OPCODE_UD_SEND_ONLY << 24; | 333 | bth0 = IB_OPCODE_UD_SEND_ONLY << 24; |
434 | } else { | ||
435 | ret = -EINVAL; | ||
436 | goto bail; | ||
437 | } | ||
438 | lrh0 |= ah_attr->sl << 4; | 334 | lrh0 |= ah_attr->sl << 4; |
439 | if (qp->ibqp.qp_type == IB_QPT_SMI) | 335 | if (qp->ibqp.qp_type == IB_QPT_SMI) |
440 | lrh0 |= 0xF000; /* Set VL (see ch. 13.5.3.1) */ | 336 | lrh0 |= 0xF000; /* Set VL (see ch. 13.5.3.1) */ |
441 | qp->s_hdr.lrh[0] = cpu_to_be16(lrh0); | 337 | qp->s_hdr.lrh[0] = cpu_to_be16(lrh0); |
442 | qp->s_hdr.lrh[1] = cpu_to_be16(ah_attr->dlid); /* DEST LID */ | 338 | qp->s_hdr.lrh[1] = cpu_to_be16(ah_attr->dlid); /* DEST LID */ |
443 | qp->s_hdr.lrh[2] = cpu_to_be16(hwords + nwords + SIZE_OF_CRC); | 339 | qp->s_hdr.lrh[2] = cpu_to_be16(qp->s_hdrwords + nwords + |
340 | SIZE_OF_CRC); | ||
444 | lid = dev->dd->ipath_lid; | 341 | lid = dev->dd->ipath_lid; |
445 | if (lid) { | 342 | if (lid) { |
446 | lid |= ah_attr->src_path_bits & | 343 | lid |= ah_attr->src_path_bits & |
@@ -448,7 +345,7 @@ int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr) | |||
448 | qp->s_hdr.lrh[3] = cpu_to_be16(lid); | 345 | qp->s_hdr.lrh[3] = cpu_to_be16(lid); |
449 | } else | 346 | } else |
450 | qp->s_hdr.lrh[3] = IB_LID_PERMISSIVE; | 347 | qp->s_hdr.lrh[3] = IB_LID_PERMISSIVE; |
451 | if (wr->send_flags & IB_SEND_SOLICITED) | 348 | if (wqe->wr.send_flags & IB_SEND_SOLICITED) |
452 | bth0 |= 1 << 23; | 349 | bth0 |= 1 << 23; |
453 | bth0 |= extra_bytes << 20; | 350 | bth0 |= extra_bytes << 20; |
454 | bth0 |= qp->ibqp.qp_type == IB_QPT_SMI ? IPATH_DEFAULT_P_KEY : | 351 | bth0 |= qp->ibqp.qp_type == IB_QPT_SMI ? IPATH_DEFAULT_P_KEY : |
@@ -460,38 +357,20 @@ int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr) | |||
460 | ohdr->bth[1] = ah_attr->dlid >= IPATH_MULTICAST_LID_BASE && | 357 | ohdr->bth[1] = ah_attr->dlid >= IPATH_MULTICAST_LID_BASE && |
461 | ah_attr->dlid != IPATH_PERMISSIVE_LID ? | 358 | ah_attr->dlid != IPATH_PERMISSIVE_LID ? |
462 | __constant_cpu_to_be32(IPATH_MULTICAST_QPN) : | 359 | __constant_cpu_to_be32(IPATH_MULTICAST_QPN) : |
463 | cpu_to_be32(wr->wr.ud.remote_qpn); | 360 | cpu_to_be32(wqe->wr.wr.ud.remote_qpn); |
464 | /* XXX Could lose a PSN count but not worth locking */ | ||
465 | ohdr->bth[2] = cpu_to_be32(qp->s_next_psn++ & IPATH_PSN_MASK); | 361 | ohdr->bth[2] = cpu_to_be32(qp->s_next_psn++ & IPATH_PSN_MASK); |
466 | /* | 362 | /* |
467 | * Qkeys with the high order bit set mean use the | 363 | * Qkeys with the high order bit set mean use the |
468 | * qkey from the QP context instead of the WR (see 10.2.5). | 364 | * qkey from the QP context instead of the WR (see 10.2.5). |
469 | */ | 365 | */ |
470 | ohdr->u.ud.deth[0] = cpu_to_be32((int)wr->wr.ud.remote_qkey < 0 ? | 366 | ohdr->u.ud.deth[0] = cpu_to_be32((int)wqe->wr.wr.ud.remote_qkey < 0 ? |
471 | qp->qkey : wr->wr.ud.remote_qkey); | 367 | qp->qkey : wqe->wr.wr.ud.remote_qkey); |
472 | ohdr->u.ud.deth[1] = cpu_to_be32(qp->ibqp.qp_num); | 368 | ohdr->u.ud.deth[1] = cpu_to_be32(qp->ibqp.qp_num); |
473 | if (ipath_verbs_send(dev->dd, hwords, (u32 *) &qp->s_hdr, | ||
474 | len, &ss)) | ||
475 | dev->n_no_piobuf++; | ||
476 | 369 | ||
477 | done: | 370 | done: |
478 | /* Queue the completion status entry. */ | 371 | if (++qp->s_cur >= qp->s_size) |
479 | if (!(qp->s_flags & IPATH_S_SIGNAL_REQ_WR) || | 372 | qp->s_cur = 0; |
480 | (wr->send_flags & IB_SEND_SIGNALED)) { | 373 | ret = 1; |
481 | wc.wr_id = wr->wr_id; | ||
482 | wc.status = IB_WC_SUCCESS; | ||
483 | wc.vendor_err = 0; | ||
484 | wc.opcode = IB_WC_SEND; | ||
485 | wc.byte_len = len; | ||
486 | wc.qp = &qp->ibqp; | ||
487 | wc.src_qp = 0; | ||
488 | wc.wc_flags = 0; | ||
489 | /* XXX initialize other fields? */ | ||
490 | ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 0); | ||
491 | } | ||
492 | kfree(sg_list); | ||
493 | |||
494 | ret = 0; | ||
495 | 374 | ||
496 | bail: | 375 | bail: |
497 | return ret; | 376 | return ret; |
@@ -673,6 +552,7 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, | |||
673 | */ | 552 | */ |
674 | wc.dlid_path_bits = dlid >= IPATH_MULTICAST_LID_BASE ? 0 : | 553 | wc.dlid_path_bits = dlid >= IPATH_MULTICAST_LID_BASE ? 0 : |
675 | dlid & ((1 << (dev->mkeyprot_resv_lmc & 7)) - 1); | 554 | dlid & ((1 << (dev->mkeyprot_resv_lmc & 7)) - 1); |
555 | wc.port_num = 1; | ||
676 | /* Signal completion event if the solicited bit is set. */ | 556 | /* Signal completion event if the solicited bit is set. */ |
677 | ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, | 557 | ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, |
678 | (ohdr->bth[0] & | 558 | (ohdr->bth[0] & |
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c index 559d4a662937..3cc82b62b3c5 100644 --- a/drivers/infiniband/hw/ipath/ipath_verbs.c +++ b/drivers/infiniband/hw/ipath/ipath_verbs.c | |||
@@ -231,6 +231,103 @@ void ipath_skip_sge(struct ipath_sge_state *ss, u32 length) | |||
231 | } | 231 | } |
232 | 232 | ||
233 | /** | 233 | /** |
234 | * ipath_post_one_send - post one RC, UC, or UD send work request | ||
235 | * @qp: the QP to post on | ||
236 | * @wr: the work request to send | ||
237 | */ | ||
238 | static int ipath_post_one_send(struct ipath_qp *qp, struct ib_send_wr *wr) | ||
239 | { | ||
240 | struct ipath_swqe *wqe; | ||
241 | u32 next; | ||
242 | int i; | ||
243 | int j; | ||
244 | int acc; | ||
245 | int ret; | ||
246 | unsigned long flags; | ||
247 | |||
248 | spin_lock_irqsave(&qp->s_lock, flags); | ||
249 | |||
250 | /* Check that state is OK to post send. */ | ||
251 | if (!(ib_ipath_state_ops[qp->state] & IPATH_POST_SEND_OK)) | ||
252 | goto bail_inval; | ||
253 | |||
254 | /* IB spec says that num_sge == 0 is OK. */ | ||
255 | if (wr->num_sge > qp->s_max_sge) | ||
256 | goto bail_inval; | ||
257 | |||
258 | /* | ||
259 | * Don't allow RDMA reads or atomic operations on UC or | ||
260 | * undefined operations. | ||
261 | * Make sure buffer is large enough to hold the result for atomics. | ||
262 | */ | ||
263 | if (qp->ibqp.qp_type == IB_QPT_UC) { | ||
264 | if ((unsigned) wr->opcode >= IB_WR_RDMA_READ) | ||
265 | goto bail_inval; | ||
266 | } else if (qp->ibqp.qp_type == IB_QPT_UD) { | ||
267 | /* Check UD opcode */ | ||
268 | if (wr->opcode != IB_WR_SEND && | ||
269 | wr->opcode != IB_WR_SEND_WITH_IMM) | ||
270 | goto bail_inval; | ||
271 | /* Check UD destination address PD */ | ||
272 | if (qp->ibqp.pd != wr->wr.ud.ah->pd) | ||
273 | goto bail_inval; | ||
274 | } else if ((unsigned) wr->opcode > IB_WR_ATOMIC_FETCH_AND_ADD) | ||
275 | goto bail_inval; | ||
276 | else if (wr->opcode >= IB_WR_ATOMIC_CMP_AND_SWP && | ||
277 | (wr->num_sge == 0 || | ||
278 | wr->sg_list[0].length < sizeof(u64) || | ||
279 | wr->sg_list[0].addr & (sizeof(u64) - 1))) | ||
280 | goto bail_inval; | ||
281 | else if (wr->opcode >= IB_WR_RDMA_READ && !qp->s_max_rd_atomic) | ||
282 | goto bail_inval; | ||
283 | |||
284 | next = qp->s_head + 1; | ||
285 | if (next >= qp->s_size) | ||
286 | next = 0; | ||
287 | if (next == qp->s_last) | ||
288 | goto bail_inval; | ||
289 | |||
290 | wqe = get_swqe_ptr(qp, qp->s_head); | ||
291 | wqe->wr = *wr; | ||
292 | wqe->ssn = qp->s_ssn++; | ||
293 | wqe->length = 0; | ||
294 | if (wr->num_sge) { | ||
295 | acc = wr->opcode >= IB_WR_RDMA_READ ? | ||
296 | IB_ACCESS_LOCAL_WRITE : 0; | ||
297 | for (i = 0, j = 0; i < wr->num_sge; i++) { | ||
298 | u32 length = wr->sg_list[i].length; | ||
299 | int ok; | ||
300 | |||
301 | if (length == 0) | ||
302 | continue; | ||
303 | ok = ipath_lkey_ok(qp, &wqe->sg_list[j], | ||
304 | &wr->sg_list[i], acc); | ||
305 | if (!ok) | ||
306 | goto bail_inval; | ||
307 | wqe->length += length; | ||
308 | j++; | ||
309 | } | ||
310 | wqe->wr.num_sge = j; | ||
311 | } | ||
312 | if (qp->ibqp.qp_type == IB_QPT_UC || | ||
313 | qp->ibqp.qp_type == IB_QPT_RC) { | ||
314 | if (wqe->length > 0x80000000U) | ||
315 | goto bail_inval; | ||
316 | } else if (wqe->length > to_idev(qp->ibqp.device)->dd->ipath_ibmtu) | ||
317 | goto bail_inval; | ||
318 | qp->s_head = next; | ||
319 | |||
320 | ret = 0; | ||
321 | goto bail; | ||
322 | |||
323 | bail_inval: | ||
324 | ret = -EINVAL; | ||
325 | bail: | ||
326 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
327 | return ret; | ||
328 | } | ||
329 | |||
330 | /** | ||
234 | * ipath_post_send - post a send on a QP | 331 | * ipath_post_send - post a send on a QP |
235 | * @ibqp: the QP to post the send on | 332 | * @ibqp: the QP to post the send on |
236 | * @wr: the list of work requests to post | 333 | * @wr: the list of work requests to post |
@@ -244,35 +341,17 @@ static int ipath_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
244 | struct ipath_qp *qp = to_iqp(ibqp); | 341 | struct ipath_qp *qp = to_iqp(ibqp); |
245 | int err = 0; | 342 | int err = 0; |
246 | 343 | ||
247 | /* Check that state is OK to post send. */ | ||
248 | if (!(ib_ipath_state_ops[qp->state] & IPATH_POST_SEND_OK)) { | ||
249 | *bad_wr = wr; | ||
250 | err = -EINVAL; | ||
251 | goto bail; | ||
252 | } | ||
253 | |||
254 | for (; wr; wr = wr->next) { | 344 | for (; wr; wr = wr->next) { |
255 | switch (qp->ibqp.qp_type) { | 345 | err = ipath_post_one_send(qp, wr); |
256 | case IB_QPT_UC: | ||
257 | case IB_QPT_RC: | ||
258 | err = ipath_post_ruc_send(qp, wr); | ||
259 | break; | ||
260 | |||
261 | case IB_QPT_SMI: | ||
262 | case IB_QPT_GSI: | ||
263 | case IB_QPT_UD: | ||
264 | err = ipath_post_ud_send(qp, wr); | ||
265 | break; | ||
266 | |||
267 | default: | ||
268 | err = -EINVAL; | ||
269 | } | ||
270 | if (err) { | 346 | if (err) { |
271 | *bad_wr = wr; | 347 | *bad_wr = wr; |
272 | break; | 348 | goto bail; |
273 | } | 349 | } |
274 | } | 350 | } |
275 | 351 | ||
352 | /* Try to do the send work in the caller's context. */ | ||
353 | ipath_do_send((unsigned long) qp); | ||
354 | |||
276 | bail: | 355 | bail: |
277 | return err; | 356 | return err; |
278 | } | 357 | } |
@@ -641,11 +720,11 @@ static void copy_io(u32 __iomem *piobuf, struct ipath_sge_state *ss, | |||
641 | u32 len = ss->sge.length; | 720 | u32 len = ss->sge.length; |
642 | u32 off; | 721 | u32 off; |
643 | 722 | ||
644 | BUG_ON(len == 0); | ||
645 | if (len > length) | 723 | if (len > length) |
646 | len = length; | 724 | len = length; |
647 | if (len > ss->sge.sge_length) | 725 | if (len > ss->sge.sge_length) |
648 | len = ss->sge.sge_length; | 726 | len = ss->sge.sge_length; |
727 | BUG_ON(len == 0); | ||
649 | /* If the source address is not aligned, try to align it. */ | 728 | /* If the source address is not aligned, try to align it. */ |
650 | off = (unsigned long)ss->sge.vaddr & (sizeof(u32) - 1); | 729 | off = (unsigned long)ss->sge.vaddr & (sizeof(u32) - 1); |
651 | if (off) { | 730 | if (off) { |
@@ -767,30 +846,15 @@ static void copy_io(u32 __iomem *piobuf, struct ipath_sge_state *ss, | |||
767 | __raw_writel(last, piobuf); | 846 | __raw_writel(last, piobuf); |
768 | } | 847 | } |
769 | 848 | ||
770 | /** | 849 | static int ipath_verbs_send_pio(struct ipath_qp *qp, u32 *hdr, u32 hdrwords, |
771 | * ipath_verbs_send - send a packet | 850 | struct ipath_sge_state *ss, u32 len, |
772 | * @dd: the infinipath device | 851 | u32 plen, u32 dwords) |
773 | * @hdrwords: the number of words in the header | ||
774 | * @hdr: the packet header | ||
775 | * @len: the length of the packet in bytes | ||
776 | * @ss: the SGE to send | ||
777 | */ | ||
778 | int ipath_verbs_send(struct ipath_devdata *dd, u32 hdrwords, | ||
779 | u32 *hdr, u32 len, struct ipath_sge_state *ss) | ||
780 | { | 852 | { |
853 | struct ipath_devdata *dd = to_idev(qp->ibqp.device)->dd; | ||
781 | u32 __iomem *piobuf; | 854 | u32 __iomem *piobuf; |
782 | unsigned flush_wc; | 855 | unsigned flush_wc; |
783 | u32 plen; | ||
784 | int ret; | 856 | int ret; |
785 | 857 | ||
786 | /* +1 is for the qword padding of pbc */ | ||
787 | plen = hdrwords + ((len + 3) >> 2) + 1; | ||
788 | if (unlikely((plen << 2) > dd->ipath_ibmaxlen)) { | ||
789 | ret = -EINVAL; | ||
790 | goto bail; | ||
791 | } | ||
792 | |||
793 | /* Get a PIO buffer to use. */ | ||
794 | piobuf = ipath_getpiobuf(dd, NULL); | 858 | piobuf = ipath_getpiobuf(dd, NULL); |
795 | if (unlikely(piobuf == NULL)) { | 859 | if (unlikely(piobuf == NULL)) { |
796 | ret = -EBUSY; | 860 | ret = -EBUSY; |
@@ -831,13 +895,10 @@ int ipath_verbs_send(struct ipath_devdata *dd, u32 hdrwords, | |||
831 | /* The common case is aligned and contained in one segment. */ | 895 | /* The common case is aligned and contained in one segment. */ |
832 | if (likely(ss->num_sge == 1 && len <= ss->sge.length && | 896 | if (likely(ss->num_sge == 1 && len <= ss->sge.length && |
833 | !((unsigned long)ss->sge.vaddr & (sizeof(u32) - 1)))) { | 897 | !((unsigned long)ss->sge.vaddr & (sizeof(u32) - 1)))) { |
834 | u32 dwords; | ||
835 | u32 *addr = (u32 *) ss->sge.vaddr; | 898 | u32 *addr = (u32 *) ss->sge.vaddr; |
836 | 899 | ||
837 | /* Update address before sending packet. */ | 900 | /* Update address before sending packet. */ |
838 | update_sge(ss, len); | 901 | update_sge(ss, len); |
839 | /* Need to round up for the last dword in the packet. */ | ||
840 | dwords = (len + 3) >> 2; | ||
841 | if (flush_wc) { | 902 | if (flush_wc) { |
842 | __iowrite32_copy(piobuf, addr, dwords - 1); | 903 | __iowrite32_copy(piobuf, addr, dwords - 1); |
843 | /* must flush early everything before trigger word */ | 904 | /* must flush early everything before trigger word */ |
@@ -851,11 +912,37 @@ int ipath_verbs_send(struct ipath_devdata *dd, u32 hdrwords, | |||
851 | } | 912 | } |
852 | copy_io(piobuf, ss, len, flush_wc); | 913 | copy_io(piobuf, ss, len, flush_wc); |
853 | done: | 914 | done: |
915 | if (qp->s_wqe) | ||
916 | ipath_send_complete(qp, qp->s_wqe, IB_WC_SUCCESS); | ||
854 | ret = 0; | 917 | ret = 0; |
855 | bail: | 918 | bail: |
856 | return ret; | 919 | return ret; |
857 | } | 920 | } |
858 | 921 | ||
922 | /** | ||
923 | * ipath_verbs_send - send a packet | ||
924 | * @qp: the QP to send on | ||
925 | * @hdr: the packet header | ||
926 | * @hdrwords: the number of words in the header | ||
927 | * @ss: the SGE to send | ||
928 | * @len: the length of the packet in bytes | ||
929 | */ | ||
930 | int ipath_verbs_send(struct ipath_qp *qp, struct ipath_ib_header *hdr, | ||
931 | u32 hdrwords, struct ipath_sge_state *ss, u32 len) | ||
932 | { | ||
933 | u32 plen; | ||
934 | int ret; | ||
935 | u32 dwords = (len + 3) >> 2; | ||
936 | |||
937 | /* +1 is for the qword padding of pbc */ | ||
938 | plen = hdrwords + dwords + 1; | ||
939 | |||
940 | ret = ipath_verbs_send_pio(qp, (u32 *) hdr, hdrwords, | ||
941 | ss, len, plen, dwords); | ||
942 | |||
943 | return ret; | ||
944 | } | ||
945 | |||
859 | int ipath_snapshot_counters(struct ipath_devdata *dd, u64 *swords, | 946 | int ipath_snapshot_counters(struct ipath_devdata *dd, u64 *swords, |
860 | u64 *rwords, u64 *spkts, u64 *rpkts, | 947 | u64 *rwords, u64 *spkts, u64 *rpkts, |
861 | u64 *xmit_wait) | 948 | u64 *xmit_wait) |
@@ -864,7 +951,6 @@ int ipath_snapshot_counters(struct ipath_devdata *dd, u64 *swords, | |||
864 | 951 | ||
865 | if (!(dd->ipath_flags & IPATH_INITTED)) { | 952 | if (!(dd->ipath_flags & IPATH_INITTED)) { |
866 | /* no hardware, freeze, etc. */ | 953 | /* no hardware, freeze, etc. */ |
867 | ipath_dbg("unit %u not usable\n", dd->ipath_unit); | ||
868 | ret = -EINVAL; | 954 | ret = -EINVAL; |
869 | goto bail; | 955 | goto bail; |
870 | } | 956 | } |
@@ -890,48 +976,44 @@ bail: | |||
890 | int ipath_get_counters(struct ipath_devdata *dd, | 976 | int ipath_get_counters(struct ipath_devdata *dd, |
891 | struct ipath_verbs_counters *cntrs) | 977 | struct ipath_verbs_counters *cntrs) |
892 | { | 978 | { |
979 | struct ipath_cregs const *crp = dd->ipath_cregs; | ||
893 | int ret; | 980 | int ret; |
894 | 981 | ||
895 | if (!(dd->ipath_flags & IPATH_INITTED)) { | 982 | if (!(dd->ipath_flags & IPATH_INITTED)) { |
896 | /* no hardware, freeze, etc. */ | 983 | /* no hardware, freeze, etc. */ |
897 | ipath_dbg("unit %u not usable\n", dd->ipath_unit); | ||
898 | ret = -EINVAL; | 984 | ret = -EINVAL; |
899 | goto bail; | 985 | goto bail; |
900 | } | 986 | } |
901 | cntrs->symbol_error_counter = | 987 | cntrs->symbol_error_counter = |
902 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_ibsymbolerrcnt); | 988 | ipath_snap_cntr(dd, crp->cr_ibsymbolerrcnt); |
903 | cntrs->link_error_recovery_counter = | 989 | cntrs->link_error_recovery_counter = |
904 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_iblinkerrrecovcnt); | 990 | ipath_snap_cntr(dd, crp->cr_iblinkerrrecovcnt); |
905 | /* | 991 | /* |
906 | * The link downed counter counts when the other side downs the | 992 | * The link downed counter counts when the other side downs the |
907 | * connection. We add in the number of times we downed the link | 993 | * connection. We add in the number of times we downed the link |
908 | * due to local link integrity errors to compensate. | 994 | * due to local link integrity errors to compensate. |
909 | */ | 995 | */ |
910 | cntrs->link_downed_counter = | 996 | cntrs->link_downed_counter = |
911 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_iblinkdowncnt); | 997 | ipath_snap_cntr(dd, crp->cr_iblinkdowncnt); |
912 | cntrs->port_rcv_errors = | 998 | cntrs->port_rcv_errors = |
913 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_rxdroppktcnt) + | 999 | ipath_snap_cntr(dd, crp->cr_rxdroppktcnt) + |
914 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_rcvovflcnt) + | 1000 | ipath_snap_cntr(dd, crp->cr_rcvovflcnt) + |
915 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_portovflcnt) + | 1001 | ipath_snap_cntr(dd, crp->cr_portovflcnt) + |
916 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_err_rlencnt) + | 1002 | ipath_snap_cntr(dd, crp->cr_err_rlencnt) + |
917 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_invalidrlencnt) + | 1003 | ipath_snap_cntr(dd, crp->cr_invalidrlencnt) + |
918 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_erricrccnt) + | 1004 | ipath_snap_cntr(dd, crp->cr_errlinkcnt) + |
919 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_errvcrccnt) + | 1005 | ipath_snap_cntr(dd, crp->cr_erricrccnt) + |
920 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_errlpcrccnt) + | 1006 | ipath_snap_cntr(dd, crp->cr_errvcrccnt) + |
921 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_badformatcnt) + | 1007 | ipath_snap_cntr(dd, crp->cr_errlpcrccnt) + |
1008 | ipath_snap_cntr(dd, crp->cr_badformatcnt) + | ||
922 | dd->ipath_rxfc_unsupvl_errs; | 1009 | dd->ipath_rxfc_unsupvl_errs; |
923 | cntrs->port_rcv_remphys_errors = | 1010 | cntrs->port_rcv_remphys_errors = |
924 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_rcvebpcnt); | 1011 | ipath_snap_cntr(dd, crp->cr_rcvebpcnt); |
925 | cntrs->port_xmit_discards = | 1012 | cntrs->port_xmit_discards = ipath_snap_cntr(dd, crp->cr_unsupvlcnt); |
926 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_unsupvlcnt); | 1013 | cntrs->port_xmit_data = ipath_snap_cntr(dd, crp->cr_wordsendcnt); |
927 | cntrs->port_xmit_data = | 1014 | cntrs->port_rcv_data = ipath_snap_cntr(dd, crp->cr_wordrcvcnt); |
928 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_wordsendcnt); | 1015 | cntrs->port_xmit_packets = ipath_snap_cntr(dd, crp->cr_pktsendcnt); |
929 | cntrs->port_rcv_data = | 1016 | cntrs->port_rcv_packets = ipath_snap_cntr(dd, crp->cr_pktrcvcnt); |
930 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_wordrcvcnt); | ||
931 | cntrs->port_xmit_packets = | ||
932 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_pktsendcnt); | ||
933 | cntrs->port_rcv_packets = | ||
934 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_pktrcvcnt); | ||
935 | cntrs->local_link_integrity_errors = | 1017 | cntrs->local_link_integrity_errors = |
936 | (dd->ipath_flags & IPATH_GPIO_ERRINTRS) ? | 1018 | (dd->ipath_flags & IPATH_GPIO_ERRINTRS) ? |
937 | dd->ipath_lli_errs : dd->ipath_lli_errors; | 1019 | dd->ipath_lli_errs : dd->ipath_lli_errors; |
@@ -1045,8 +1127,9 @@ static int ipath_query_port(struct ib_device *ibdev, | |||
1045 | u8 port, struct ib_port_attr *props) | 1127 | u8 port, struct ib_port_attr *props) |
1046 | { | 1128 | { |
1047 | struct ipath_ibdev *dev = to_idev(ibdev); | 1129 | struct ipath_ibdev *dev = to_idev(ibdev); |
1130 | struct ipath_devdata *dd = dev->dd; | ||
1048 | enum ib_mtu mtu; | 1131 | enum ib_mtu mtu; |
1049 | u16 lid = dev->dd->ipath_lid; | 1132 | u16 lid = dd->ipath_lid; |
1050 | u64 ibcstat; | 1133 | u64 ibcstat; |
1051 | 1134 | ||
1052 | memset(props, 0, sizeof(*props)); | 1135 | memset(props, 0, sizeof(*props)); |
@@ -1054,16 +1137,16 @@ static int ipath_query_port(struct ib_device *ibdev, | |||
1054 | props->lmc = dev->mkeyprot_resv_lmc & 7; | 1137 | props->lmc = dev->mkeyprot_resv_lmc & 7; |
1055 | props->sm_lid = dev->sm_lid; | 1138 | props->sm_lid = dev->sm_lid; |
1056 | props->sm_sl = dev->sm_sl; | 1139 | props->sm_sl = dev->sm_sl; |
1057 | ibcstat = dev->dd->ipath_lastibcstat; | 1140 | ibcstat = dd->ipath_lastibcstat; |
1058 | props->state = ((ibcstat >> 4) & 0x3) + 1; | 1141 | props->state = ((ibcstat >> 4) & 0x3) + 1; |
1059 | /* See phys_state_show() */ | 1142 | /* See phys_state_show() */ |
1060 | props->phys_state = ipath_cvt_physportstate[ | 1143 | props->phys_state = ipath_cvt_physportstate[ |
1061 | dev->dd->ipath_lastibcstat & 0xf]; | 1144 | dd->ipath_lastibcstat & 0xf]; |
1062 | props->port_cap_flags = dev->port_cap_flags; | 1145 | props->port_cap_flags = dev->port_cap_flags; |
1063 | props->gid_tbl_len = 1; | 1146 | props->gid_tbl_len = 1; |
1064 | props->max_msg_sz = 0x80000000; | 1147 | props->max_msg_sz = 0x80000000; |
1065 | props->pkey_tbl_len = ipath_get_npkeys(dev->dd); | 1148 | props->pkey_tbl_len = ipath_get_npkeys(dd); |
1066 | props->bad_pkey_cntr = ipath_get_cr_errpkey(dev->dd) - | 1149 | props->bad_pkey_cntr = ipath_get_cr_errpkey(dd) - |
1067 | dev->z_pkey_violations; | 1150 | dev->z_pkey_violations; |
1068 | props->qkey_viol_cntr = dev->qkey_violations; | 1151 | props->qkey_viol_cntr = dev->qkey_violations; |
1069 | props->active_width = IB_WIDTH_4X; | 1152 | props->active_width = IB_WIDTH_4X; |
@@ -1073,12 +1156,12 @@ static int ipath_query_port(struct ib_device *ibdev, | |||
1073 | props->init_type_reply = 0; | 1156 | props->init_type_reply = 0; |
1074 | 1157 | ||
1075 | /* | 1158 | /* |
1076 | * Note: the chips support a maximum MTU of 4096, but the driver | 1159 | * Note: the chip supports a maximum MTU of 4096, but the driver |
1077 | * hasn't implemented this feature yet, so set the maximum value | 1160 | * hasn't implemented this feature yet, so set the maximum value |
1078 | * to 2048. | 1161 | * to 2048. |
1079 | */ | 1162 | */ |
1080 | props->max_mtu = IB_MTU_2048; | 1163 | props->max_mtu = IB_MTU_2048; |
1081 | switch (dev->dd->ipath_ibmtu) { | 1164 | switch (dd->ipath_ibmtu) { |
1082 | case 4096: | 1165 | case 4096: |
1083 | mtu = IB_MTU_4096; | 1166 | mtu = IB_MTU_4096; |
1084 | break; | 1167 | break; |
@@ -1427,9 +1510,7 @@ static int disable_timer(struct ipath_devdata *dd) | |||
1427 | { | 1510 | { |
1428 | /* Disable GPIO bit 2 interrupt */ | 1511 | /* Disable GPIO bit 2 interrupt */ |
1429 | if (dd->ipath_flags & IPATH_GPIO_INTR) { | 1512 | if (dd->ipath_flags & IPATH_GPIO_INTR) { |
1430 | u64 val; | ||
1431 | /* Disable GPIO bit 2 interrupt */ | 1513 | /* Disable GPIO bit 2 interrupt */ |
1432 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_gpio_mask); | ||
1433 | dd->ipath_gpio_mask &= ~((u64) (1 << IPATH_GPIO_PORT0_BIT)); | 1514 | dd->ipath_gpio_mask &= ~((u64) (1 << IPATH_GPIO_PORT0_BIT)); |
1434 | ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_mask, | 1515 | ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_mask, |
1435 | dd->ipath_gpio_mask); | 1516 | dd->ipath_gpio_mask); |
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.h b/drivers/infiniband/hw/ipath/ipath_verbs.h index 1a24c6a4a814..619ad728b07b 100644 --- a/drivers/infiniband/hw/ipath/ipath_verbs.h +++ b/drivers/infiniband/hw/ipath/ipath_verbs.h | |||
@@ -42,6 +42,8 @@ | |||
42 | #include <rdma/ib_pack.h> | 42 | #include <rdma/ib_pack.h> |
43 | #include <rdma/ib_user_verbs.h> | 43 | #include <rdma/ib_user_verbs.h> |
44 | 44 | ||
45 | #include "ipath_kernel.h" | ||
46 | |||
45 | #define IPATH_MAX_RDMA_ATOMIC 4 | 47 | #define IPATH_MAX_RDMA_ATOMIC 4 |
46 | 48 | ||
47 | #define QPN_MAX (1 << 24) | 49 | #define QPN_MAX (1 << 24) |
@@ -59,6 +61,7 @@ | |||
59 | */ | 61 | */ |
60 | #define IB_CQ_NONE (IB_CQ_NEXT_COMP + 1) | 62 | #define IB_CQ_NONE (IB_CQ_NEXT_COMP + 1) |
61 | 63 | ||
64 | /* AETH NAK opcode values */ | ||
62 | #define IB_RNR_NAK 0x20 | 65 | #define IB_RNR_NAK 0x20 |
63 | #define IB_NAK_PSN_ERROR 0x60 | 66 | #define IB_NAK_PSN_ERROR 0x60 |
64 | #define IB_NAK_INVALID_REQUEST 0x61 | 67 | #define IB_NAK_INVALID_REQUEST 0x61 |
@@ -66,6 +69,7 @@ | |||
66 | #define IB_NAK_REMOTE_OPERATIONAL_ERROR 0x63 | 69 | #define IB_NAK_REMOTE_OPERATIONAL_ERROR 0x63 |
67 | #define IB_NAK_INVALID_RD_REQUEST 0x64 | 70 | #define IB_NAK_INVALID_RD_REQUEST 0x64 |
68 | 71 | ||
72 | /* Flags for checking QP state (see ib_ipath_state_ops[]) */ | ||
69 | #define IPATH_POST_SEND_OK 0x01 | 73 | #define IPATH_POST_SEND_OK 0x01 |
70 | #define IPATH_POST_RECV_OK 0x02 | 74 | #define IPATH_POST_RECV_OK 0x02 |
71 | #define IPATH_PROCESS_RECV_OK 0x04 | 75 | #define IPATH_PROCESS_RECV_OK 0x04 |
@@ -239,7 +243,7 @@ struct ipath_mregion { | |||
239 | */ | 243 | */ |
240 | struct ipath_sge { | 244 | struct ipath_sge { |
241 | struct ipath_mregion *mr; | 245 | struct ipath_mregion *mr; |
242 | void *vaddr; /* current pointer into the segment */ | 246 | void *vaddr; /* kernel virtual address of segment */ |
243 | u32 sge_length; /* length of the SGE */ | 247 | u32 sge_length; /* length of the SGE */ |
244 | u32 length; /* remaining length of the segment */ | 248 | u32 length; /* remaining length of the segment */ |
245 | u16 m; /* current index: mr->map[m] */ | 249 | u16 m; /* current index: mr->map[m] */ |
@@ -407,6 +411,7 @@ struct ipath_qp { | |||
407 | u32 s_ssn; /* SSN of tail entry */ | 411 | u32 s_ssn; /* SSN of tail entry */ |
408 | u32 s_lsn; /* limit sequence number (credit) */ | 412 | u32 s_lsn; /* limit sequence number (credit) */ |
409 | struct ipath_swqe *s_wq; /* send work queue */ | 413 | struct ipath_swqe *s_wq; /* send work queue */ |
414 | struct ipath_swqe *s_wqe; | ||
410 | struct ipath_rq r_rq; /* receive work queue */ | 415 | struct ipath_rq r_rq; /* receive work queue */ |
411 | struct ipath_sge r_sg_list[0]; /* verified SGEs */ | 416 | struct ipath_sge r_sg_list[0]; /* verified SGEs */ |
412 | }; | 417 | }; |
@@ -683,8 +688,8 @@ void ipath_sqerror_qp(struct ipath_qp *qp, struct ib_wc *wc); | |||
683 | 688 | ||
684 | void ipath_get_credit(struct ipath_qp *qp, u32 aeth); | 689 | void ipath_get_credit(struct ipath_qp *qp, u32 aeth); |
685 | 690 | ||
686 | int ipath_verbs_send(struct ipath_devdata *dd, u32 hdrwords, | 691 | int ipath_verbs_send(struct ipath_qp *qp, struct ipath_ib_header *hdr, |
687 | u32 *hdr, u32 len, struct ipath_sge_state *ss); | 692 | u32 hdrwords, struct ipath_sge_state *ss, u32 len); |
688 | 693 | ||
689 | void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int sig); | 694 | void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int sig); |
690 | 695 | ||
@@ -692,8 +697,6 @@ void ipath_copy_sge(struct ipath_sge_state *ss, void *data, u32 length); | |||
692 | 697 | ||
693 | void ipath_skip_sge(struct ipath_sge_state *ss, u32 length); | 698 | void ipath_skip_sge(struct ipath_sge_state *ss, u32 length); |
694 | 699 | ||
695 | int ipath_post_ruc_send(struct ipath_qp *qp, struct ib_send_wr *wr); | ||
696 | |||
697 | void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, | 700 | void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, |
698 | int has_grh, void *data, u32 tlen, struct ipath_qp *qp); | 701 | int has_grh, void *data, u32 tlen, struct ipath_qp *qp); |
699 | 702 | ||
@@ -733,6 +736,8 @@ int ipath_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr); | |||
733 | 736 | ||
734 | int ipath_destroy_srq(struct ib_srq *ibsrq); | 737 | int ipath_destroy_srq(struct ib_srq *ibsrq); |
735 | 738 | ||
739 | void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int sig); | ||
740 | |||
736 | int ipath_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry); | 741 | int ipath_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry); |
737 | 742 | ||
738 | struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries, int comp_vector, | 743 | struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries, int comp_vector, |
@@ -782,18 +787,28 @@ int ipath_mmap(struct ib_ucontext *context, struct vm_area_struct *vma); | |||
782 | 787 | ||
783 | void ipath_insert_rnr_queue(struct ipath_qp *qp); | 788 | void ipath_insert_rnr_queue(struct ipath_qp *qp); |
784 | 789 | ||
790 | int ipath_init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe, | ||
791 | u32 *lengthp, struct ipath_sge_state *ss); | ||
792 | |||
785 | int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only); | 793 | int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only); |
786 | 794 | ||
787 | u32 ipath_make_grh(struct ipath_ibdev *dev, struct ib_grh *hdr, | 795 | u32 ipath_make_grh(struct ipath_ibdev *dev, struct ib_grh *hdr, |
788 | struct ib_global_route *grh, u32 hwords, u32 nwords); | 796 | struct ib_global_route *grh, u32 hwords, u32 nwords); |
789 | 797 | ||
790 | void ipath_do_ruc_send(unsigned long data); | 798 | void ipath_make_ruc_header(struct ipath_ibdev *dev, struct ipath_qp *qp, |
799 | struct ipath_other_headers *ohdr, | ||
800 | u32 bth0, u32 bth2); | ||
801 | |||
802 | void ipath_do_send(unsigned long data); | ||
803 | |||
804 | void ipath_send_complete(struct ipath_qp *qp, struct ipath_swqe *wqe, | ||
805 | enum ib_wc_status status); | ||
806 | |||
807 | int ipath_make_rc_req(struct ipath_qp *qp); | ||
791 | 808 | ||
792 | int ipath_make_rc_req(struct ipath_qp *qp, struct ipath_other_headers *ohdr, | 809 | int ipath_make_uc_req(struct ipath_qp *qp); |
793 | u32 pmtu, u32 *bth0p, u32 *bth2p); | ||
794 | 810 | ||
795 | int ipath_make_uc_req(struct ipath_qp *qp, struct ipath_other_headers *ohdr, | 811 | int ipath_make_ud_req(struct ipath_qp *qp); |
796 | u32 pmtu, u32 *bth0p, u32 *bth2p); | ||
797 | 812 | ||
798 | int ipath_register_ib_device(struct ipath_devdata *); | 813 | int ipath_register_ib_device(struct ipath_devdata *); |
799 | 814 | ||