aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/nes/nes_verbs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/nes/nes_verbs.c')
-rw-r--r--drivers/infiniband/hw/nes/nes_verbs.c170
1 files changed, 63 insertions, 107 deletions
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c
index 44cb513f9a87..137880a19ebe 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.c
+++ b/drivers/infiniband/hw/nes/nes_verbs.c
@@ -51,6 +51,7 @@ atomic_t qps_created;
51atomic_t sw_qps_destroyed; 51atomic_t sw_qps_destroyed;
52 52
53static void nes_unregister_ofa_device(struct nes_ib_device *nesibdev); 53static void nes_unregister_ofa_device(struct nes_ib_device *nesibdev);
54static int nes_dereg_mr(struct ib_mr *ib_mr);
54 55
55/** 56/**
56 * nes_alloc_mw 57 * nes_alloc_mw
@@ -443,79 +444,46 @@ static struct ib_mr *nes_alloc_mr(struct ib_pd *ibpd,
443 } else { 444 } else {
444 kfree(nesmr); 445 kfree(nesmr);
445 nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index); 446 nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index);
446 ibmr = ERR_PTR(-ENOMEM); 447 return ERR_PTR(-ENOMEM);
447 } 448 }
449
450 nesmr->pages = pci_alloc_consistent(nesdev->pcidev,
451 max_num_sg * sizeof(u64),
452 &nesmr->paddr);
453 if (!nesmr->paddr)
454 goto err;
455
456 nesmr->max_pages = max_num_sg;
457
448 return ibmr; 458 return ibmr;
459
460err:
461 nes_dereg_mr(ibmr);
462
463 return ERR_PTR(-ENOMEM);
449} 464}
450 465
451/* 466static int nes_set_page(struct ib_mr *ibmr, u64 addr)
452 * nes_alloc_fast_reg_page_list
453 */
454static struct ib_fast_reg_page_list *nes_alloc_fast_reg_page_list(
455 struct ib_device *ibdev,
456 int page_list_len)
457{ 467{
458 struct nes_vnic *nesvnic = to_nesvnic(ibdev); 468 struct nes_mr *nesmr = to_nesmr(ibmr);
459 struct nes_device *nesdev = nesvnic->nesdev;
460 struct ib_fast_reg_page_list *pifrpl;
461 struct nes_ib_fast_reg_page_list *pnesfrpl;
462 469
463 if (page_list_len > (NES_4K_PBL_CHUNK_SIZE / sizeof(u64))) 470 if (unlikely(nesmr->npages == nesmr->max_pages))
464 return ERR_PTR(-E2BIG); 471 return -ENOMEM;
465 /*
466 * Allocate the ib_fast_reg_page_list structure, the
467 * nes_fast_bpl structure, and the PLB table.
468 */
469 pnesfrpl = kmalloc(sizeof(struct nes_ib_fast_reg_page_list) +
470 page_list_len * sizeof(u64), GFP_KERNEL);
471
472 if (!pnesfrpl)
473 return ERR_PTR(-ENOMEM);
474 472
475 pifrpl = &pnesfrpl->ibfrpl; 473 nesmr->pages[nesmr->npages++] = cpu_to_le64(addr);
476 pifrpl->page_list = &pnesfrpl->pbl;
477 pifrpl->max_page_list_len = page_list_len;
478 /*
479 * Allocate the WQE PBL
480 */
481 pnesfrpl->nes_wqe_pbl.kva = pci_alloc_consistent(nesdev->pcidev,
482 page_list_len * sizeof(u64),
483 &pnesfrpl->nes_wqe_pbl.paddr);
484 474
485 if (!pnesfrpl->nes_wqe_pbl.kva) { 475 return 0;
486 kfree(pnesfrpl);
487 return ERR_PTR(-ENOMEM);
488 }
489 nes_debug(NES_DBG_MR, "nes_alloc_fast_reg_pbl: nes_frpl = %p, "
490 "ibfrpl = %p, ibfrpl.page_list = %p, pbl.kva = %p, "
491 "pbl.paddr = %llx\n", pnesfrpl, &pnesfrpl->ibfrpl,
492 pnesfrpl->ibfrpl.page_list, pnesfrpl->nes_wqe_pbl.kva,
493 (unsigned long long) pnesfrpl->nes_wqe_pbl.paddr);
494
495 return pifrpl;
496} 476}
497 477
498/* 478static int nes_map_mr_sg(struct ib_mr *ibmr,
499 * nes_free_fast_reg_page_list 479 struct scatterlist *sg,
500 */ 480 int sg_nents)
501static void nes_free_fast_reg_page_list(struct ib_fast_reg_page_list *pifrpl)
502{ 481{
503 struct nes_vnic *nesvnic = to_nesvnic(pifrpl->device); 482 struct nes_mr *nesmr = to_nesmr(ibmr);
504 struct nes_device *nesdev = nesvnic->nesdev;
505 struct nes_ib_fast_reg_page_list *pnesfrpl;
506 483
507 pnesfrpl = container_of(pifrpl, struct nes_ib_fast_reg_page_list, ibfrpl); 484 nesmr->npages = 0;
508 /* 485
509 * Free the WQE PBL. 486 return ib_sg_to_pages(ibmr, sg, sg_nents, nes_set_page);
510 */
511 pci_free_consistent(nesdev->pcidev,
512 pifrpl->max_page_list_len * sizeof(u64),
513 pnesfrpl->nes_wqe_pbl.kva,
514 pnesfrpl->nes_wqe_pbl.paddr);
515 /*
516 * Free the PBL structure
517 */
518 kfree(pnesfrpl);
519} 487}
520 488
521/** 489/**
@@ -2683,6 +2651,13 @@ static int nes_dereg_mr(struct ib_mr *ib_mr)
2683 u16 major_code; 2651 u16 major_code;
2684 u16 minor_code; 2652 u16 minor_code;
2685 2653
2654
2655 if (nesmr->pages)
2656 pci_free_consistent(nesdev->pcidev,
2657 nesmr->max_pages * sizeof(u64),
2658 nesmr->pages,
2659 nesmr->paddr);
2660
2686 if (nesmr->region) { 2661 if (nesmr->region) {
2687 ib_umem_release(nesmr->region); 2662 ib_umem_release(nesmr->region);
2688 } 2663 }
@@ -3372,9 +3347,9 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr,
3372 wqe_misc |= NES_IWARP_SQ_WQE_LOCAL_FENCE; 3347 wqe_misc |= NES_IWARP_SQ_WQE_LOCAL_FENCE;
3373 3348
3374 set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_STAG_IDX, 3349 set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_STAG_IDX,
3375 ib_wr->wr.rdma.rkey); 3350 rdma_wr(ib_wr)->rkey);
3376 set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_TO_LOW_IDX, 3351 set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_TO_LOW_IDX,
3377 ib_wr->wr.rdma.remote_addr); 3352 rdma_wr(ib_wr)->remote_addr);
3378 3353
3379 if ((ib_wr->send_flags & IB_SEND_INLINE) && 3354 if ((ib_wr->send_flags & IB_SEND_INLINE) &&
3380 ((nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) == 0) && 3355 ((nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) == 0) &&
@@ -3409,9 +3384,9 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr,
3409 } 3384 }
3410 3385
3411 set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_TO_LOW_IDX, 3386 set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_TO_LOW_IDX,
3412 ib_wr->wr.rdma.remote_addr); 3387 rdma_wr(ib_wr)->remote_addr);
3413 set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_STAG_IDX, 3388 set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_STAG_IDX,
3414 ib_wr->wr.rdma.rkey); 3389 rdma_wr(ib_wr)->rkey);
3415 set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX, 3390 set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX,
3416 ib_wr->sg_list->length); 3391 ib_wr->sg_list->length);
3417 set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_FRAG0_LOW_IDX, 3392 set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_FRAG0_LOW_IDX,
@@ -3425,19 +3400,13 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr,
3425 NES_IWARP_SQ_LOCINV_WQE_INV_STAG_IDX, 3400 NES_IWARP_SQ_LOCINV_WQE_INV_STAG_IDX,
3426 ib_wr->ex.invalidate_rkey); 3401 ib_wr->ex.invalidate_rkey);
3427 break; 3402 break;
3428 case IB_WR_FAST_REG_MR: 3403 case IB_WR_REG_MR:
3429 { 3404 {
3430 int i; 3405 struct nes_mr *mr = to_nesmr(reg_wr(ib_wr)->mr);
3431 int flags = ib_wr->wr.fast_reg.access_flags; 3406 int page_shift = ilog2(reg_wr(ib_wr)->mr->page_size);
3432 struct nes_ib_fast_reg_page_list *pnesfrpl = 3407 int flags = reg_wr(ib_wr)->access;
3433 container_of(ib_wr->wr.fast_reg.page_list, 3408
3434 struct nes_ib_fast_reg_page_list, 3409 if (mr->npages > (NES_4K_PBL_CHUNK_SIZE / sizeof(u64))) {
3435 ibfrpl);
3436 u64 *src_page_list = pnesfrpl->ibfrpl.page_list;
3437 u64 *dst_page_list = pnesfrpl->nes_wqe_pbl.kva;
3438
3439 if (ib_wr->wr.fast_reg.page_list_len >
3440 (NES_4K_PBL_CHUNK_SIZE / sizeof(u64))) {
3441 nes_debug(NES_DBG_IW_TX, "SQ_FMR: bad page_list_len\n"); 3410 nes_debug(NES_DBG_IW_TX, "SQ_FMR: bad page_list_len\n");
3442 err = -EINVAL; 3411 err = -EINVAL;
3443 break; 3412 break;
@@ -3445,19 +3414,19 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr,
3445 wqe_misc = NES_IWARP_SQ_OP_FAST_REG; 3414 wqe_misc = NES_IWARP_SQ_OP_FAST_REG;
3446 set_wqe_64bit_value(wqe->wqe_words, 3415 set_wqe_64bit_value(wqe->wqe_words,
3447 NES_IWARP_SQ_FMR_WQE_VA_FBO_LOW_IDX, 3416 NES_IWARP_SQ_FMR_WQE_VA_FBO_LOW_IDX,
3448 ib_wr->wr.fast_reg.iova_start); 3417 mr->ibmr.iova);
3449 set_wqe_32bit_value(wqe->wqe_words, 3418 set_wqe_32bit_value(wqe->wqe_words,
3450 NES_IWARP_SQ_FMR_WQE_LENGTH_LOW_IDX, 3419 NES_IWARP_SQ_FMR_WQE_LENGTH_LOW_IDX,
3451 ib_wr->wr.fast_reg.length); 3420 mr->ibmr.length);
3452 set_wqe_32bit_value(wqe->wqe_words, 3421 set_wqe_32bit_value(wqe->wqe_words,
3453 NES_IWARP_SQ_FMR_WQE_LENGTH_HIGH_IDX, 0); 3422 NES_IWARP_SQ_FMR_WQE_LENGTH_HIGH_IDX, 0);
3454 set_wqe_32bit_value(wqe->wqe_words, 3423 set_wqe_32bit_value(wqe->wqe_words,
3455 NES_IWARP_SQ_FMR_WQE_MR_STAG_IDX, 3424 NES_IWARP_SQ_FMR_WQE_MR_STAG_IDX,
3456 ib_wr->wr.fast_reg.rkey); 3425 reg_wr(ib_wr)->key);
3457 /* Set page size: */ 3426
3458 if (ib_wr->wr.fast_reg.page_shift == 12) { 3427 if (page_shift == 12) {
3459 wqe_misc |= NES_IWARP_SQ_FMR_WQE_PAGE_SIZE_4K; 3428 wqe_misc |= NES_IWARP_SQ_FMR_WQE_PAGE_SIZE_4K;
3460 } else if (ib_wr->wr.fast_reg.page_shift == 21) { 3429 } else if (page_shift == 21) {
3461 wqe_misc |= NES_IWARP_SQ_FMR_WQE_PAGE_SIZE_2M; 3430 wqe_misc |= NES_IWARP_SQ_FMR_WQE_PAGE_SIZE_2M;
3462 } else { 3431 } else {
3463 nes_debug(NES_DBG_IW_TX, "Invalid page shift," 3432 nes_debug(NES_DBG_IW_TX, "Invalid page shift,"
@@ -3465,6 +3434,7 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr,
3465 err = -EINVAL; 3434 err = -EINVAL;
3466 break; 3435 break;
3467 } 3436 }
3437
3468 /* Set access_flags */ 3438 /* Set access_flags */
3469 wqe_misc |= NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_LOCAL_READ; 3439 wqe_misc |= NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_LOCAL_READ;
3470 if (flags & IB_ACCESS_LOCAL_WRITE) 3440 if (flags & IB_ACCESS_LOCAL_WRITE)
@@ -3480,35 +3450,22 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr,
3480 wqe_misc |= NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_WINDOW_BIND; 3450 wqe_misc |= NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_WINDOW_BIND;
3481 3451
3482 /* Fill in PBL info: */ 3452 /* Fill in PBL info: */
3483 if (ib_wr->wr.fast_reg.page_list_len >
3484 pnesfrpl->ibfrpl.max_page_list_len) {
3485 nes_debug(NES_DBG_IW_TX, "Invalid page list length,"
3486 " ib_wr=%p, value=%u, max=%u\n",
3487 ib_wr, ib_wr->wr.fast_reg.page_list_len,
3488 pnesfrpl->ibfrpl.max_page_list_len);
3489 err = -EINVAL;
3490 break;
3491 }
3492
3493 set_wqe_64bit_value(wqe->wqe_words, 3453 set_wqe_64bit_value(wqe->wqe_words,
3494 NES_IWARP_SQ_FMR_WQE_PBL_ADDR_LOW_IDX, 3454 NES_IWARP_SQ_FMR_WQE_PBL_ADDR_LOW_IDX,
3495 pnesfrpl->nes_wqe_pbl.paddr); 3455 mr->paddr);
3496 3456
3497 set_wqe_32bit_value(wqe->wqe_words, 3457 set_wqe_32bit_value(wqe->wqe_words,
3498 NES_IWARP_SQ_FMR_WQE_PBL_LENGTH_IDX, 3458 NES_IWARP_SQ_FMR_WQE_PBL_LENGTH_IDX,
3499 ib_wr->wr.fast_reg.page_list_len * 8); 3459 mr->npages * 8);
3500
3501 for (i = 0; i < ib_wr->wr.fast_reg.page_list_len; i++)
3502 dst_page_list[i] = cpu_to_le64(src_page_list[i]);
3503 3460
3504 nes_debug(NES_DBG_IW_TX, "SQ_FMR: iova_start: %llx, " 3461 nes_debug(NES_DBG_IW_TX, "SQ_REG_MR: iova_start: %llx, "
3505 "length: %d, rkey: %0x, pgl_paddr: %llx, " 3462 "length: %d, rkey: %0x, pgl_paddr: %llx, "
3506 "page_list_len: %u, wqe_misc: %x\n", 3463 "page_list_len: %u, wqe_misc: %x\n",
3507 (unsigned long long) ib_wr->wr.fast_reg.iova_start, 3464 (unsigned long long) mr->ibmr.iova,
3508 ib_wr->wr.fast_reg.length, 3465 mr->ibmr.length,
3509 ib_wr->wr.fast_reg.rkey, 3466 reg_wr(ib_wr)->key,
3510 (unsigned long long) pnesfrpl->nes_wqe_pbl.paddr, 3467 (unsigned long long) mr->paddr,
3511 ib_wr->wr.fast_reg.page_list_len, 3468 mr->npages,
3512 wqe_misc); 3469 wqe_misc);
3513 break; 3470 break;
3514 } 3471 }
@@ -3751,7 +3708,7 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry)
3751 entry->opcode = IB_WC_LOCAL_INV; 3708 entry->opcode = IB_WC_LOCAL_INV;
3752 break; 3709 break;
3753 case NES_IWARP_SQ_OP_FAST_REG: 3710 case NES_IWARP_SQ_OP_FAST_REG:
3754 entry->opcode = IB_WC_FAST_REG_MR; 3711 entry->opcode = IB_WC_REG_MR;
3755 break; 3712 break;
3756 } 3713 }
3757 3714
@@ -3939,8 +3896,7 @@ struct nes_ib_device *nes_init_ofa_device(struct net_device *netdev)
3939 nesibdev->ibdev.bind_mw = nes_bind_mw; 3896 nesibdev->ibdev.bind_mw = nes_bind_mw;
3940 3897
3941 nesibdev->ibdev.alloc_mr = nes_alloc_mr; 3898 nesibdev->ibdev.alloc_mr = nes_alloc_mr;
3942 nesibdev->ibdev.alloc_fast_reg_page_list = nes_alloc_fast_reg_page_list; 3899 nesibdev->ibdev.map_mr_sg = nes_map_mr_sg;
3943 nesibdev->ibdev.free_fast_reg_page_list = nes_free_fast_reg_page_list;
3944 3900
3945 nesibdev->ibdev.attach_mcast = nes_multicast_attach; 3901 nesibdev->ibdev.attach_mcast = nes_multicast_attach;
3946 nesibdev->ibdev.detach_mcast = nes_multicast_detach; 3902 nesibdev->ibdev.detach_mcast = nes_multicast_detach;