aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/mthca/mthca_provider.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/mthca/mthca_provider.c')
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index daa54db00aa9..28199e42b36f 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -574,6 +574,74 @@ static int mthca_dereg_mr(struct ib_mr *mr)
574 return 0; 574 return 0;
575} 575}
576 576
577static struct ib_fmr *mthca_alloc_fmr(struct ib_pd *pd, int mr_access_flags,
578 struct ib_fmr_attr *fmr_attr)
579{
580 struct mthca_fmr *fmr;
581 int err;
582
583 fmr = kmalloc(sizeof *fmr, GFP_KERNEL);
584 if (!fmr)
585 return ERR_PTR(-ENOMEM);
586
587 memcpy(&fmr->attr, fmr_attr, sizeof *fmr_attr);
588 err = mthca_fmr_alloc(to_mdev(pd->device), to_mpd(pd)->pd_num,
589 convert_access(mr_access_flags), fmr);
590
591 if (err) {
592 kfree(fmr);
593 return ERR_PTR(err);
594 }
595
596 return &fmr->ibmr;
597}
598
599static int mthca_dealloc_fmr(struct ib_fmr *fmr)
600{
601 struct mthca_fmr *mfmr = to_mfmr(fmr);
602 int err;
603
604 err = mthca_free_fmr(to_mdev(fmr->device), mfmr);
605 if (err)
606 return err;
607
608 kfree(mfmr);
609 return 0;
610}
611
612static int mthca_unmap_fmr(struct list_head *fmr_list)
613{
614 struct ib_fmr *fmr;
615 int err;
616 u8 status;
617 struct mthca_dev *mdev = NULL;
618
619 list_for_each_entry(fmr, fmr_list, list) {
620 if (mdev && to_mdev(fmr->device) != mdev)
621 return -EINVAL;
622 mdev = to_mdev(fmr->device);
623 }
624
625 if (!mdev)
626 return 0;
627
628 if (mdev->hca_type == ARBEL_NATIVE) {
629 list_for_each_entry(fmr, fmr_list, list)
630 mthca_arbel_fmr_unmap(mdev, to_mfmr(fmr));
631
632 wmb();
633 } else
634 list_for_each_entry(fmr, fmr_list, list)
635 mthca_tavor_fmr_unmap(mdev, to_mfmr(fmr));
636
637 err = mthca_SYNC_TPT(mdev, &status);
638 if (err)
639 return err;
640 if (status)
641 return -EINVAL;
642 return 0;
643}
644
577static ssize_t show_rev(struct class_device *cdev, char *buf) 645static ssize_t show_rev(struct class_device *cdev, char *buf)
578{ 646{
579 struct mthca_dev *dev = container_of(cdev, struct mthca_dev, ib_dev.class_dev); 647 struct mthca_dev *dev = container_of(cdev, struct mthca_dev, ib_dev.class_dev);
@@ -637,6 +705,17 @@ int mthca_register_device(struct mthca_dev *dev)
637 dev->ib_dev.get_dma_mr = mthca_get_dma_mr; 705 dev->ib_dev.get_dma_mr = mthca_get_dma_mr;
638 dev->ib_dev.reg_phys_mr = mthca_reg_phys_mr; 706 dev->ib_dev.reg_phys_mr = mthca_reg_phys_mr;
639 dev->ib_dev.dereg_mr = mthca_dereg_mr; 707 dev->ib_dev.dereg_mr = mthca_dereg_mr;
708
709 if (dev->mthca_flags & MTHCA_FLAG_FMR) {
710 dev->ib_dev.alloc_fmr = mthca_alloc_fmr;
711 dev->ib_dev.unmap_fmr = mthca_unmap_fmr;
712 dev->ib_dev.dealloc_fmr = mthca_dealloc_fmr;
713 if (dev->hca_type == ARBEL_NATIVE)
714 dev->ib_dev.map_phys_fmr = mthca_arbel_map_phys_fmr;
715 else
716 dev->ib_dev.map_phys_fmr = mthca_tavor_map_phys_fmr;
717 }
718
640 dev->ib_dev.attach_mcast = mthca_multicast_attach; 719 dev->ib_dev.attach_mcast = mthca_multicast_attach;
641 dev->ib_dev.detach_mcast = mthca_multicast_detach; 720 dev->ib_dev.detach_mcast = mthca_multicast_detach;
642 dev->ib_dev.process_mad = mthca_process_mad; 721 dev->ib_dev.process_mad = mthca_process_mad;