diff options
Diffstat (limited to 'drivers/infiniband/hw/ipath/ipath_ud.c')
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_ud.c | 372 |
1 files changed, 126 insertions, 246 deletions
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] & |