aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw
diff options
context:
space:
mode:
authorRalph Campbell <ralph.campbell@qlogic.com>2008-01-15 18:58:13 -0500
committerRoland Dreier <rolandd@cisco.com>2008-01-16 17:42:35 -0500
commit0a69631b2869093d7306e8f66cca8eb0a05aa919 (patch)
tree32788676e5f262d540d8da36ec3f76edda9cb262 /drivers/infiniband/hw
parentcdf71a10c7b6432d9b48e292cca2c62a0b9fa6cf (diff)
IB/ipath: Fix receiving UD messages with immediate data
This fixes a small bug in ipath_ud_rcv()'s handling of UD messages with immediate data. We need to test whether immediate data is present and update the header size accordingly *before* testing the packet size from the header against the actual received length. Otherwise the wrong header size will be used and all messages with immediate data will be dropped. This bug keeps MVAPICH-UD and HP MPI from working at all on ipath devices. Signed-off-by: Ralph Campbell <ralph.campbell@qlogic.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw')
-rw-r--r--drivers/infiniband/hw/ipath/ipath_ud.c44
1 files changed, 22 insertions, 22 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_ud.c b/drivers/infiniband/hw/ipath/ipath_ud.c
index 16a2a938b520..b3df6f3c705e 100644
--- a/drivers/infiniband/hw/ipath/ipath_ud.c
+++ b/drivers/infiniband/hw/ipath/ipath_ud.c
@@ -455,6 +455,28 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
455 } 455 }
456 } 456 }
457 457
458 /*
459 * The opcode is in the low byte when its in network order
460 * (top byte when in host order).
461 */
462 opcode = be32_to_cpu(ohdr->bth[0]) >> 24;
463 if (qp->ibqp.qp_num > 1 &&
464 opcode == IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE) {
465 if (header_in_data) {
466 wc.imm_data = *(__be32 *) data;
467 data += sizeof(__be32);
468 } else
469 wc.imm_data = ohdr->u.ud.imm_data;
470 wc.wc_flags = IB_WC_WITH_IMM;
471 hdrsize += sizeof(u32);
472 } else if (opcode == IB_OPCODE_UD_SEND_ONLY) {
473 wc.imm_data = 0;
474 wc.wc_flags = 0;
475 } else {
476 dev->n_pkt_drops++;
477 goto bail;
478 }
479
458 /* Get the number of bytes the message was padded by. */ 480 /* Get the number of bytes the message was padded by. */
459 pad = (be32_to_cpu(ohdr->bth[0]) >> 20) & 3; 481 pad = (be32_to_cpu(ohdr->bth[0]) >> 20) & 3;
460 if (unlikely(tlen < (hdrsize + pad + 4))) { 482 if (unlikely(tlen < (hdrsize + pad + 4))) {
@@ -482,28 +504,6 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
482 wc.byte_len = tlen + sizeof(struct ib_grh); 504 wc.byte_len = tlen + sizeof(struct ib_grh);
483 505
484 /* 506 /*
485 * The opcode is in the low byte when its in network order
486 * (top byte when in host order).
487 */
488 opcode = be32_to_cpu(ohdr->bth[0]) >> 24;
489 if (qp->ibqp.qp_num > 1 &&
490 opcode == IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE) {
491 if (header_in_data) {
492 wc.imm_data = *(__be32 *) data;
493 data += sizeof(__be32);
494 } else
495 wc.imm_data = ohdr->u.ud.imm_data;
496 wc.wc_flags = IB_WC_WITH_IMM;
497 hdrsize += sizeof(u32);
498 } else if (opcode == IB_OPCODE_UD_SEND_ONLY) {
499 wc.imm_data = 0;
500 wc.wc_flags = 0;
501 } else {
502 dev->n_pkt_drops++;
503 goto bail;
504 }
505
506 /*
507 * Get the next work request entry to find where to put the data. 507 * Get the next work request entry to find where to put the data.
508 */ 508 */
509 if (qp->r_reuse_sge) 509 if (qp->r_reuse_sge)