diff options
author | Chien Tung <chien.tin.tung@intel.com> | 2009-12-09 16:51:37 -0500 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2009-12-09 16:51:37 -0500 |
commit | 649fe4aeab8c9b90eb31c899791534add0c78e04 (patch) | |
tree | a5c3911b19fe503db4265fea45d52fae816b2504 /drivers/infiniband | |
parent | 4293fdc115e1e4f83dcb9ec6cbd3a54c563835f0 (diff) |
RDMA/nes: Add support for IB_WR_*INV
Add support for IB_WR_SEND_WITH_INV, IB_WR_RDMA_READ_WITH_INV
and IB_WR_LOCAL_INV.
Signed-off-by: Chien Tung <chien.tin.tung@intel.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/hw/nes/nes_verbs.c | 203 |
1 files changed, 113 insertions, 90 deletions
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 0b17c01bb9fa..499dd78cb821 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c | |||
@@ -3373,18 +3373,12 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, | |||
3373 | struct nes_device *nesdev = nesvnic->nesdev; | 3373 | struct nes_device *nesdev = nesvnic->nesdev; |
3374 | struct nes_qp *nesqp = to_nesqp(ibqp); | 3374 | struct nes_qp *nesqp = to_nesqp(ibqp); |
3375 | struct nes_hw_qp_wqe *wqe; | 3375 | struct nes_hw_qp_wqe *wqe; |
3376 | int err; | 3376 | int err = 0; |
3377 | u32 qsize = nesqp->hwqp.sq_size; | 3377 | u32 qsize = nesqp->hwqp.sq_size; |
3378 | u32 head; | 3378 | u32 head; |
3379 | u32 wqe_misc; | 3379 | u32 wqe_misc = 0; |
3380 | u32 wqe_count; | 3380 | u32 wqe_count = 0; |
3381 | u32 counter; | 3381 | u32 counter; |
3382 | u32 total_payload_length; | ||
3383 | |||
3384 | err = 0; | ||
3385 | wqe_misc = 0; | ||
3386 | wqe_count = 0; | ||
3387 | total_payload_length = 0; | ||
3388 | 3382 | ||
3389 | if (nesqp->ibqp_state > IB_QPS_RTS) { | 3383 | if (nesqp->ibqp_state > IB_QPS_RTS) { |
3390 | err = -EINVAL; | 3384 | err = -EINVAL; |
@@ -3415,91 +3409,117 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, | |||
3415 | u64temp = (u64)(ib_wr->wr_id); | 3409 | u64temp = (u64)(ib_wr->wr_id); |
3416 | set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_COMP_SCRATCH_LOW_IDX, | 3410 | set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_COMP_SCRATCH_LOW_IDX, |
3417 | u64temp); | 3411 | u64temp); |
3418 | switch (ib_wr->opcode) { | 3412 | switch (ib_wr->opcode) { |
3419 | case IB_WR_SEND: | 3413 | case IB_WR_SEND: |
3420 | if (ib_wr->send_flags & IB_SEND_SOLICITED) { | 3414 | case IB_WR_SEND_WITH_INV: |
3421 | wqe_misc = NES_IWARP_SQ_OP_SENDSE; | 3415 | if (IB_WR_SEND == ib_wr->opcode) { |
3422 | } else { | 3416 | if (ib_wr->send_flags & IB_SEND_SOLICITED) |
3423 | wqe_misc = NES_IWARP_SQ_OP_SEND; | 3417 | wqe_misc = NES_IWARP_SQ_OP_SENDSE; |
3424 | } | 3418 | else |
3425 | if (ib_wr->num_sge > nesdev->nesadapter->max_sge) { | 3419 | wqe_misc = NES_IWARP_SQ_OP_SEND; |
3426 | err = -EINVAL; | 3420 | } else { |
3427 | break; | 3421 | if (ib_wr->send_flags & IB_SEND_SOLICITED) |
3428 | } | 3422 | wqe_misc = NES_IWARP_SQ_OP_SENDSEINV; |
3429 | if (ib_wr->send_flags & IB_SEND_FENCE) { | 3423 | else |
3430 | wqe_misc |= NES_IWARP_SQ_WQE_LOCAL_FENCE; | 3424 | wqe_misc = NES_IWARP_SQ_OP_SENDINV; |
3431 | } | ||
3432 | if ((ib_wr->send_flags & IB_SEND_INLINE) && | ||
3433 | ((nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) == 0) && | ||
3434 | (ib_wr->sg_list[0].length <= 64)) { | ||
3435 | memcpy(&wqe->wqe_words[NES_IWARP_SQ_WQE_IMM_DATA_START_IDX], | ||
3436 | (void *)(unsigned long)ib_wr->sg_list[0].addr, ib_wr->sg_list[0].length); | ||
3437 | set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX, | ||
3438 | ib_wr->sg_list[0].length); | ||
3439 | wqe_misc |= NES_IWARP_SQ_WQE_IMM_DATA; | ||
3440 | } else { | ||
3441 | fill_wqe_sg_send(wqe, ib_wr, 1); | ||
3442 | } | ||
3443 | 3425 | ||
3444 | break; | 3426 | set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_INV_STAG_LOW_IDX, |
3445 | case IB_WR_RDMA_WRITE: | 3427 | ib_wr->ex.invalidate_rkey); |
3446 | wqe_misc = NES_IWARP_SQ_OP_RDMAW; | 3428 | } |
3447 | if (ib_wr->num_sge > nesdev->nesadapter->max_sge) { | ||
3448 | nes_debug(NES_DBG_IW_TX, "Exceeded max sge, ib_wr=%u, max=%u\n", | ||
3449 | ib_wr->num_sge, | ||
3450 | nesdev->nesadapter->max_sge); | ||
3451 | err = -EINVAL; | ||
3452 | break; | ||
3453 | } | ||
3454 | if (ib_wr->send_flags & IB_SEND_FENCE) { | ||
3455 | wqe_misc |= NES_IWARP_SQ_WQE_LOCAL_FENCE; | ||
3456 | } | ||
3457 | 3429 | ||
3458 | set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_STAG_IDX, | 3430 | if (ib_wr->num_sge > nesdev->nesadapter->max_sge) { |
3459 | ib_wr->wr.rdma.rkey); | 3431 | err = -EINVAL; |
3460 | set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_TO_LOW_IDX, | 3432 | break; |
3461 | ib_wr->wr.rdma.remote_addr); | ||
3462 | |||
3463 | if ((ib_wr->send_flags & IB_SEND_INLINE) && | ||
3464 | ((nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) == 0) && | ||
3465 | (ib_wr->sg_list[0].length <= 64)) { | ||
3466 | memcpy(&wqe->wqe_words[NES_IWARP_SQ_WQE_IMM_DATA_START_IDX], | ||
3467 | (void *)(unsigned long)ib_wr->sg_list[0].addr, ib_wr->sg_list[0].length); | ||
3468 | set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX, | ||
3469 | ib_wr->sg_list[0].length); | ||
3470 | wqe_misc |= NES_IWARP_SQ_WQE_IMM_DATA; | ||
3471 | } else { | ||
3472 | fill_wqe_sg_send(wqe, ib_wr, 1); | ||
3473 | } | ||
3474 | wqe->wqe_words[NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX] = | ||
3475 | wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX]; | ||
3476 | break; | ||
3477 | case IB_WR_RDMA_READ: | ||
3478 | /* iWARP only supports 1 sge for RDMA reads */ | ||
3479 | if (ib_wr->num_sge > 1) { | ||
3480 | nes_debug(NES_DBG_IW_TX, "Exceeded max sge, ib_wr=%u, max=1\n", | ||
3481 | ib_wr->num_sge); | ||
3482 | err = -EINVAL; | ||
3483 | break; | ||
3484 | } | ||
3485 | wqe_misc = NES_IWARP_SQ_OP_RDMAR; | ||
3486 | set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_TO_LOW_IDX, | ||
3487 | ib_wr->wr.rdma.remote_addr); | ||
3488 | set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_STAG_IDX, | ||
3489 | ib_wr->wr.rdma.rkey); | ||
3490 | set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX, | ||
3491 | ib_wr->sg_list->length); | ||
3492 | set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_FRAG0_LOW_IDX, | ||
3493 | ib_wr->sg_list->addr); | ||
3494 | set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_STAG0_IDX, | ||
3495 | ib_wr->sg_list->lkey); | ||
3496 | break; | ||
3497 | default: | ||
3498 | /* error */ | ||
3499 | err = -EINVAL; | ||
3500 | break; | ||
3501 | } | 3433 | } |
3502 | 3434 | ||
3435 | if (ib_wr->send_flags & IB_SEND_FENCE) | ||
3436 | wqe_misc |= NES_IWARP_SQ_WQE_LOCAL_FENCE; | ||
3437 | |||
3438 | if ((ib_wr->send_flags & IB_SEND_INLINE) && | ||
3439 | ((nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) == 0) && | ||
3440 | (ib_wr->sg_list[0].length <= 64)) { | ||
3441 | memcpy(&wqe->wqe_words[NES_IWARP_SQ_WQE_IMM_DATA_START_IDX], | ||
3442 | (void *)(unsigned long)ib_wr->sg_list[0].addr, ib_wr->sg_list[0].length); | ||
3443 | set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX, | ||
3444 | ib_wr->sg_list[0].length); | ||
3445 | wqe_misc |= NES_IWARP_SQ_WQE_IMM_DATA; | ||
3446 | } else { | ||
3447 | fill_wqe_sg_send(wqe, ib_wr, 1); | ||
3448 | } | ||
3449 | |||
3450 | break; | ||
3451 | case IB_WR_RDMA_WRITE: | ||
3452 | wqe_misc = NES_IWARP_SQ_OP_RDMAW; | ||
3453 | if (ib_wr->num_sge > nesdev->nesadapter->max_sge) { | ||
3454 | nes_debug(NES_DBG_IW_TX, "Exceeded max sge, ib_wr=%u, max=%u\n", | ||
3455 | ib_wr->num_sge, nesdev->nesadapter->max_sge); | ||
3456 | err = -EINVAL; | ||
3457 | break; | ||
3458 | } | ||
3459 | |||
3460 | if (ib_wr->send_flags & IB_SEND_FENCE) | ||
3461 | wqe_misc |= NES_IWARP_SQ_WQE_LOCAL_FENCE; | ||
3462 | |||
3463 | set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_STAG_IDX, | ||
3464 | ib_wr->wr.rdma.rkey); | ||
3465 | set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_TO_LOW_IDX, | ||
3466 | ib_wr->wr.rdma.remote_addr); | ||
3467 | |||
3468 | if ((ib_wr->send_flags & IB_SEND_INLINE) && | ||
3469 | ((nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) == 0) && | ||
3470 | (ib_wr->sg_list[0].length <= 64)) { | ||
3471 | memcpy(&wqe->wqe_words[NES_IWARP_SQ_WQE_IMM_DATA_START_IDX], | ||
3472 | (void *)(unsigned long)ib_wr->sg_list[0].addr, ib_wr->sg_list[0].length); | ||
3473 | set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX, | ||
3474 | ib_wr->sg_list[0].length); | ||
3475 | wqe_misc |= NES_IWARP_SQ_WQE_IMM_DATA; | ||
3476 | } else { | ||
3477 | fill_wqe_sg_send(wqe, ib_wr, 1); | ||
3478 | } | ||
3479 | |||
3480 | wqe->wqe_words[NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX] = | ||
3481 | wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX]; | ||
3482 | break; | ||
3483 | case IB_WR_RDMA_READ: | ||
3484 | case IB_WR_RDMA_READ_WITH_INV: | ||
3485 | /* iWARP only supports 1 sge for RDMA reads */ | ||
3486 | if (ib_wr->num_sge > 1) { | ||
3487 | nes_debug(NES_DBG_IW_TX, "Exceeded max sge, ib_wr=%u, max=1\n", | ||
3488 | ib_wr->num_sge); | ||
3489 | err = -EINVAL; | ||
3490 | break; | ||
3491 | } | ||
3492 | if (ib_wr->opcode == IB_WR_RDMA_READ) { | ||
3493 | wqe_misc = NES_IWARP_SQ_OP_RDMAR; | ||
3494 | } else { | ||
3495 | wqe_misc = NES_IWARP_SQ_OP_RDMAR_LOCINV; | ||
3496 | set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_INV_STAG_LOW_IDX, | ||
3497 | ib_wr->ex.invalidate_rkey); | ||
3498 | } | ||
3499 | |||
3500 | set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_TO_LOW_IDX, | ||
3501 | ib_wr->wr.rdma.remote_addr); | ||
3502 | set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_STAG_IDX, | ||
3503 | ib_wr->wr.rdma.rkey); | ||
3504 | set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX, | ||
3505 | ib_wr->sg_list->length); | ||
3506 | set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_FRAG0_LOW_IDX, | ||
3507 | ib_wr->sg_list->addr); | ||
3508 | set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_STAG0_IDX, | ||
3509 | ib_wr->sg_list->lkey); | ||
3510 | break; | ||
3511 | case IB_WR_LOCAL_INV: | ||
3512 | wqe_misc = NES_IWARP_SQ_OP_LOCINV; | ||
3513 | set_wqe_32bit_value(wqe->wqe_words, | ||
3514 | NES_IWARP_SQ_LOCINV_WQE_INV_STAG_IDX, | ||
3515 | ib_wr->ex.invalidate_rkey); | ||
3516 | break; | ||
3517 | default: | ||
3518 | /* error */ | ||
3519 | err = -EINVAL; | ||
3520 | break; | ||
3521 | } | ||
3522 | |||
3503 | if (err) | 3523 | if (err) |
3504 | break; | 3524 | break; |
3505 | 3525 | ||
@@ -3729,6 +3749,9 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry) | |||
3729 | nes_debug(NES_DBG_CQ, "Operation = Send.\n"); | 3749 | nes_debug(NES_DBG_CQ, "Operation = Send.\n"); |
3730 | entry->opcode = IB_WC_SEND; | 3750 | entry->opcode = IB_WC_SEND; |
3731 | break; | 3751 | break; |
3752 | case NES_IWARP_SQ_OP_LOCINV: | ||
3753 | entry->opcode = IB_WR_LOCAL_INV; | ||
3754 | break; | ||
3732 | } | 3755 | } |
3733 | 3756 | ||
3734 | nesqp->hwqp.sq_tail = (wqe_index+1)&(nesqp->hwqp.sq_size - 1); | 3757 | nesqp->hwqp.sq_tail = (wqe_index+1)&(nesqp->hwqp.sq_size - 1); |