aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorChien Tung <chien.tin.tung@intel.com>2009-12-09 16:51:37 -0500
committerRoland Dreier <rolandd@cisco.com>2009-12-09 16:51:37 -0500
commit649fe4aeab8c9b90eb31c899791534add0c78e04 (patch)
treea5c3911b19fe503db4265fea45d52fae816b2504 /drivers/infiniband
parent4293fdc115e1e4f83dcb9ec6cbd3a54c563835f0 (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.c203
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 0b17c01bb9f..499dd78cb82 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);