2 * Copyright (c) 2006 QLogic, Inc. All rights reserved.
3 * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
34 #include "ipath_verbs.h"
35 #include "ipath_kernel.h"
37 /* cut down ridiculously long IB macro names */
38 #define OP(x) IB_OPCODE_UC_##x
40 static void complete_last_send(struct ipath_qp
*qp
, struct ipath_swqe
*wqe
,
43 if (++qp
->s_last
== qp
->s_size
)
45 if (!test_bit(IPATH_S_SIGNAL_REQ_WR
, &qp
->s_flags
) ||
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
];
51 wc
->byte_len
= wqe
->length
;
52 wc
->qp_num
= qp
->ibqp
.qp_num
;
53 wc
->src_qp
= qp
->remote_qpn
;
55 wc
->slid
= qp
->remote_ah_attr
.dlid
;
56 wc
->sl
= qp
->remote_ah_attr
.sl
;
57 wc
->dlid_path_bits
= 0;
59 ipath_cq_enter(to_icq(qp
->ibqp
.send_cq
), wc
, 0);
61 wqe
= get_swqe_ptr(qp
, qp
->s_last
);
65 * ipath_make_uc_req - construct a request packet (SEND, RDMA write)
66 * @qp: a pointer to the QP
67 * @ohdr: a pointer to the IB header being constructed
69 * @bth0p: pointer to the BTH opcode word
70 * @bth2p: pointer to the BTH PSN word
72 * Return 1 if constructed; otherwise, return 0.
73 * Note the QP s_lock must be held and interrupts disabled.
75 int ipath_make_uc_req(struct ipath_qp
*qp
,
76 struct ipath_other_headers
*ohdr
,
77 u32 pmtu
, u32
*bth0p
, u32
*bth2p
)
79 struct ipath_swqe
*wqe
;
85 if (!(ib_ipath_state_ops
[qp
->state
] & IPATH_PROCESS_SEND_OK
))
88 /* header size in 32-bit words LRH+BTH = (8+12)/4. */
92 /* Get the next send request. */
93 wqe
= get_swqe_ptr(qp
, qp
->s_last
);
94 switch (qp
->s_state
) {
97 * Signal the completion of the last send
100 if (qp
->s_last
!= qp
->s_tail
)
101 complete_last_send(qp
, wqe
, &wc
);
103 /* Check if send work queue is empty. */
104 if (qp
->s_tail
== qp
->s_head
)
107 * Start a new request.
109 qp
->s_psn
= wqe
->psn
= qp
->s_next_psn
;
110 qp
->s_sge
.sge
= wqe
->sg_list
[0];
111 qp
->s_sge
.sg_list
= wqe
->sg_list
+ 1;
112 qp
->s_sge
.num_sge
= wqe
->wr
.num_sge
;
113 qp
->s_len
= len
= wqe
->length
;
114 switch (wqe
->wr
.opcode
) {
116 case IB_WR_SEND_WITH_IMM
:
118 qp
->s_state
= OP(SEND_FIRST
);
122 if (wqe
->wr
.opcode
== IB_WR_SEND
)
123 qp
->s_state
= OP(SEND_ONLY
);
126 OP(SEND_ONLY_WITH_IMMEDIATE
);
127 /* Immediate data comes after the BTH */
128 ohdr
->u
.imm_data
= wqe
->wr
.imm_data
;
131 if (wqe
->wr
.send_flags
& IB_SEND_SOLICITED
)
135 case IB_WR_RDMA_WRITE
:
136 case IB_WR_RDMA_WRITE_WITH_IMM
:
137 ohdr
->u
.rc
.reth
.vaddr
=
138 cpu_to_be64(wqe
->wr
.wr
.rdma
.remote_addr
);
139 ohdr
->u
.rc
.reth
.rkey
=
140 cpu_to_be32(wqe
->wr
.wr
.rdma
.rkey
);
141 ohdr
->u
.rc
.reth
.length
= cpu_to_be32(len
);
142 hwords
+= sizeof(struct ib_reth
) / 4;
144 qp
->s_state
= OP(RDMA_WRITE_FIRST
);
148 if (wqe
->wr
.opcode
== IB_WR_RDMA_WRITE
)
149 qp
->s_state
= OP(RDMA_WRITE_ONLY
);
152 OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE
);
153 /* Immediate data comes after the RETH */
154 ohdr
->u
.rc
.imm_data
= wqe
->wr
.imm_data
;
156 if (wqe
->wr
.send_flags
& IB_SEND_SOLICITED
)
164 if (++qp
->s_tail
>= qp
->s_size
)
169 qp
->s_state
= OP(SEND_MIDDLE
);
171 case OP(SEND_MIDDLE
):
177 if (wqe
->wr
.opcode
== IB_WR_SEND
)
178 qp
->s_state
= OP(SEND_LAST
);
180 qp
->s_state
= OP(SEND_LAST_WITH_IMMEDIATE
);
181 /* Immediate data comes after the BTH */
182 ohdr
->u
.imm_data
= wqe
->wr
.imm_data
;
185 if (wqe
->wr
.send_flags
& IB_SEND_SOLICITED
)
189 case OP(RDMA_WRITE_FIRST
):
190 qp
->s_state
= OP(RDMA_WRITE_MIDDLE
);
192 case OP(RDMA_WRITE_MIDDLE
):
198 if (wqe
->wr
.opcode
== IB_WR_RDMA_WRITE
)
199 qp
->s_state
= OP(RDMA_WRITE_LAST
);
202 OP(RDMA_WRITE_LAST_WITH_IMMEDIATE
);
203 /* Immediate data comes after the BTH */
204 ohdr
->u
.imm_data
= wqe
->wr
.imm_data
;
206 if (wqe
->wr
.send_flags
& IB_SEND_SOLICITED
)
212 qp
->s_hdrwords
= hwords
;
213 qp
->s_cur_sge
= &qp
->s_sge
;
214 qp
->s_cur_size
= len
;
215 *bth0p
= bth0
| (qp
->s_state
<< 24);
216 *bth2p
= qp
->s_next_psn
++ & IPATH_PSN_MASK
;
224 * ipath_uc_rcv - handle an incoming UC packet
225 * @dev: the device the packet came in on
226 * @hdr: the header of the packet
227 * @has_grh: true if the packet has a GRH
228 * @data: the packet data
229 * @tlen: the length of the packet
230 * @qp: the QP for this packet.
232 * This is called from ipath_qp_rcv() to process an incoming UC packet
234 * Called at interrupt level.
236 void ipath_uc_rcv(struct ipath_ibdev
*dev
, struct ipath_ib_header
*hdr
,
237 int has_grh
, void *data
, u32 tlen
, struct ipath_qp
*qp
)
239 struct ipath_other_headers
*ohdr
;
245 u32 pmtu
= ib_mtu_enum_to_int(qp
->path_mtu
);
246 struct ib_reth
*reth
;
249 /* Validate the SLID. See Ch. 9.6.1.5 */
250 if (unlikely(be16_to_cpu(hdr
->lrh
[3]) != qp
->remote_ah_attr
.dlid
))
256 hdrsize
= 8 + 12; /* LRH + BTH */
257 psn
= be32_to_cpu(ohdr
->bth
[2]);
260 ohdr
= &hdr
->u
.l
.oth
;
261 hdrsize
= 8 + 40 + 12; /* LRH + GRH + BTH */
263 * The header with GRH is 60 bytes and the
264 * core driver sets the eager header buffer
265 * size to 56 bytes so the last 4 bytes of
266 * the BTH header (PSN) is in the data buffer.
268 header_in_data
= dev
->dd
->ipath_rcvhdrentsize
== 16;
269 if (header_in_data
) {
270 psn
= be32_to_cpu(((__be32
*) data
)[0]);
271 data
+= sizeof(__be32
);
273 psn
= be32_to_cpu(ohdr
->bth
[2]);
276 * The opcode is in the low byte when its in network order
277 * (top byte when in host order).
279 opcode
= be32_to_cpu(ohdr
->bth
[0]) >> 24;
284 /* Compare the PSN verses the expected PSN. */
285 if (unlikely(ipath_cmp24(psn
, qp
->r_psn
) != 0)) {
287 * Handle a sequence error.
288 * Silently drop any current message.
292 qp
->r_state
= OP(SEND_LAST
);
296 case OP(SEND_ONLY_WITH_IMMEDIATE
):
299 case OP(RDMA_WRITE_FIRST
):
300 case OP(RDMA_WRITE_ONLY
):
301 case OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE
):
310 /* Check for opcode sequence errors. */
311 switch (qp
->r_state
) {
313 case OP(SEND_MIDDLE
):
314 if (opcode
== OP(SEND_MIDDLE
) ||
315 opcode
== OP(SEND_LAST
) ||
316 opcode
== OP(SEND_LAST_WITH_IMMEDIATE
))
320 case OP(RDMA_WRITE_FIRST
):
321 case OP(RDMA_WRITE_MIDDLE
):
322 if (opcode
== OP(RDMA_WRITE_MIDDLE
) ||
323 opcode
== OP(RDMA_WRITE_LAST
) ||
324 opcode
== OP(RDMA_WRITE_LAST_WITH_IMMEDIATE
))
329 if (opcode
== OP(SEND_FIRST
) ||
330 opcode
== OP(SEND_ONLY
) ||
331 opcode
== OP(SEND_ONLY_WITH_IMMEDIATE
) ||
332 opcode
== OP(RDMA_WRITE_FIRST
) ||
333 opcode
== OP(RDMA_WRITE_ONLY
) ||
334 opcode
== OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE
))
339 /* OK, process the packet. */
343 case OP(SEND_ONLY_WITH_IMMEDIATE
):
345 if (qp
->r_reuse_sge
) {
347 qp
->r_sge
= qp
->s_rdma_sge
;
348 } else if (!ipath_get_rwqe(qp
, 0)) {
352 /* Save the WQE so we can reuse it in case of an error. */
353 qp
->s_rdma_sge
= qp
->r_sge
;
355 if (opcode
== OP(SEND_ONLY
))
357 else if (opcode
== OP(SEND_ONLY_WITH_IMMEDIATE
))
360 case OP(SEND_MIDDLE
):
361 /* Check for invalid length PMTU or posted rwqe len. */
362 if (unlikely(tlen
!= (hdrsize
+ pmtu
+ 4))) {
367 qp
->r_rcv_len
+= pmtu
;
368 if (unlikely(qp
->r_rcv_len
> qp
->r_len
)) {
373 ipath_copy_sge(&qp
->r_sge
, data
, pmtu
);
376 case OP(SEND_LAST_WITH_IMMEDIATE
):
378 if (header_in_data
) {
379 wc
.imm_data
= *(__be32
*) data
;
380 data
+= sizeof(__be32
);
382 /* Immediate data comes after BTH */
383 wc
.imm_data
= ohdr
->u
.imm_data
;
386 wc
.wc_flags
= IB_WC_WITH_IMM
;
390 /* Get the number of bytes the message was padded by. */
391 pad
= (be32_to_cpu(ohdr
->bth
[0]) >> 20) & 3;
392 /* Check for invalid length. */
393 /* XXX LAST len should be >= 1 */
394 if (unlikely(tlen
< (hdrsize
+ pad
+ 4))) {
399 /* Don't count the CRC. */
400 tlen
-= (hdrsize
+ pad
+ 4);
401 wc
.byte_len
= tlen
+ qp
->r_rcv_len
;
402 if (unlikely(wc
.byte_len
> qp
->r_len
)) {
407 /* XXX Need to free SGEs */
409 ipath_copy_sge(&qp
->r_sge
, data
, tlen
);
410 wc
.wr_id
= qp
->r_wr_id
;
411 wc
.status
= IB_WC_SUCCESS
;
412 wc
.opcode
= IB_WC_RECV
;
414 wc
.qp_num
= qp
->ibqp
.qp_num
;
415 wc
.src_qp
= qp
->remote_qpn
;
417 wc
.slid
= qp
->remote_ah_attr
.dlid
;
418 wc
.sl
= qp
->remote_ah_attr
.sl
;
419 wc
.dlid_path_bits
= 0;
421 /* Signal completion event if the solicited bit is set. */
422 ipath_cq_enter(to_icq(qp
->ibqp
.recv_cq
), &wc
,
424 __constant_cpu_to_be32(1 << 23)) != 0);
427 case OP(RDMA_WRITE_FIRST
):
428 case OP(RDMA_WRITE_ONLY
):
429 case OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE
): /* consume RWQE */
431 /* RETH comes after BTH */
433 reth
= &ohdr
->u
.rc
.reth
;
435 reth
= (struct ib_reth
*)data
;
436 data
+= sizeof(*reth
);
438 hdrsize
+= sizeof(*reth
);
439 qp
->r_len
= be32_to_cpu(reth
->length
);
441 if (qp
->r_len
!= 0) {
442 u32 rkey
= be32_to_cpu(reth
->rkey
);
443 u64 vaddr
= be64_to_cpu(reth
->vaddr
);
447 ok
= ipath_rkey_ok(qp
, &qp
->r_sge
, qp
->r_len
,
449 IB_ACCESS_REMOTE_WRITE
);
455 qp
->r_sge
.sg_list
= NULL
;
456 qp
->r_sge
.sge
.mr
= NULL
;
457 qp
->r_sge
.sge
.vaddr
= NULL
;
458 qp
->r_sge
.sge
.length
= 0;
459 qp
->r_sge
.sge
.sge_length
= 0;
461 if (unlikely(!(qp
->qp_access_flags
&
462 IB_ACCESS_REMOTE_WRITE
))) {
466 if (opcode
== OP(RDMA_WRITE_ONLY
))
468 else if (opcode
== OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE
))
471 case OP(RDMA_WRITE_MIDDLE
):
472 /* Check for invalid length PMTU or posted rwqe len. */
473 if (unlikely(tlen
!= (hdrsize
+ pmtu
+ 4))) {
477 qp
->r_rcv_len
+= pmtu
;
478 if (unlikely(qp
->r_rcv_len
> qp
->r_len
)) {
482 ipath_copy_sge(&qp
->r_sge
, data
, pmtu
);
485 case OP(RDMA_WRITE_LAST_WITH_IMMEDIATE
):
487 /* Get the number of bytes the message was padded by. */
488 pad
= (be32_to_cpu(ohdr
->bth
[0]) >> 20) & 3;
489 /* Check for invalid length. */
490 /* XXX LAST len should be >= 1 */
491 if (unlikely(tlen
< (hdrsize
+ pad
+ 4))) {
495 /* Don't count the CRC. */
496 tlen
-= (hdrsize
+ pad
+ 4);
497 if (unlikely(tlen
+ qp
->r_rcv_len
!= qp
->r_len
)) {
503 else if (!ipath_get_rwqe(qp
, 1)) {
507 if (header_in_data
) {
508 wc
.imm_data
= *(__be32
*) data
;
509 data
+= sizeof(__be32
);
511 /* Immediate data comes after BTH */
512 wc
.imm_data
= ohdr
->u
.imm_data
;
515 wc
.wc_flags
= IB_WC_WITH_IMM
;
519 case OP(RDMA_WRITE_LAST
):
521 /* Get the number of bytes the message was padded by. */
522 pad
= (be32_to_cpu(ohdr
->bth
[0]) >> 20) & 3;
523 /* Check for invalid length. */
524 /* XXX LAST len should be >= 1 */
525 if (unlikely(tlen
< (hdrsize
+ pad
+ 4))) {
529 /* Don't count the CRC. */
530 tlen
-= (hdrsize
+ pad
+ 4);
531 if (unlikely(tlen
+ qp
->r_rcv_len
!= qp
->r_len
)) {
535 ipath_copy_sge(&qp
->r_sge
, data
, tlen
);
539 /* Drop packet for unknown opcodes. */
544 qp
->r_state
= opcode
;