34 #include <linux/slab.h>
35 #include <linux/errno.h>
65 #define MTHCA_MPT_FLAG_SW_OWNS (0xfUL << 28)
66 #define MTHCA_MPT_FLAG_MIO (1 << 17)
67 #define MTHCA_MPT_FLAG_BIND_ENABLE (1 << 15)
68 #define MTHCA_MPT_FLAG_PHYSICAL (1 << 9)
69 #define MTHCA_MPT_FLAG_REGION (1 << 8)
71 #define MTHCA_MTT_FLAG_PRESENT 1
73 #define MTHCA_MPT_STATUS_SW 0xF0
74 #define MTHCA_MPT_STATUS_HW 0x00
76 #define SINAI_FMR_KEY_INC 0x1000000
90 spin_lock(&buddy->
lock);
92 for (o = order; o <= buddy->
max_order; ++o)
100 spin_unlock(&buddy->
lock);
114 spin_unlock(&buddy->
lock);
125 spin_lock(&buddy->
lock);
137 spin_unlock(&buddy->
lock);
140 static int mthca_buddy_init(
struct mthca_buddy *buddy,
int max_order)
159 bitmap_zero(buddy->
bits[i],
179 static void mthca_buddy_cleanup(
struct mthca_buddy *buddy)
193 u32 seg = mthca_buddy_alloc(buddy, order);
198 if (mthca_is_memfree(dev))
200 seg + (1 << order) - 1)) {
201 mthca_buddy_free(buddy, seg, order);
223 for (i = dev->
limits.mtt_seg_size / 8; i < size; i <<= 1)
237 return __mthca_alloc_mtt(dev, size, &dev->
mr_table.mtt_buddy);
264 return PTR_ERR(mailbox);
265 mtt_entry = mailbox->
buf;
267 while (list_len > 0) {
281 mtt_entry[i + 2] = 0;
285 mthca_warn(dev,
"WRITE_MTT failed (%d)\n", err);
312 return mthca_is_memfree(dev) ? (
PAGE_SIZE /
sizeof (
u64)) : 0x7ffffff;
315 static void mthca_tavor_write_mtt_seg(
struct mthca_dev *dev,
317 u64 *buffer_list,
int list_len)
323 start_index *
sizeof (
u64);
329 static void mthca_arbel_write_mtt_seg(
struct mthca_dev *dev,
331 u64 *buffer_list,
int list_len)
336 int s = start_index *
sizeof (
u64);
344 s / dev->
limits.mtt_seg_size, &dma_handle);
359 int start_index,
u64 *buffer_list,
int list_len)
366 return __mthca_write_mtt(dev, mtt, start_index, buffer_list, list_len);
368 while (list_len > 0) {
369 chunk =
min(size, list_len);
370 if (mthca_is_memfree(dev))
371 mthca_arbel_write_mtt_seg(dev, mtt, start_index,
374 mthca_tavor_write_mtt_seg(dev, mtt, start_index,
378 start_index +=
chunk;
379 buffer_list +=
chunk;
385 static inline u32 tavor_hw_index_to_key(
u32 ind)
390 static inline u32 tavor_key_to_hw_index(
u32 key)
395 static inline u32 arbel_hw_index_to_key(
u32 ind)
397 return (ind >> 24) | (ind << 8);
400 static inline u32 arbel_key_to_hw_index(
u32 key)
402 return (key << 24) | (key >> 8);
407 if (mthca_is_memfree(dev))
408 return arbel_hw_index_to_key(ind);
410 return tavor_hw_index_to_key(ind);
415 if (mthca_is_memfree(dev))
416 return arbel_key_to_hw_index(key);
418 return tavor_key_to_hw_index(key);
424 return ((key << 20) & 0x800000) | (key & 0x7fffff);
438 WARN_ON(buffer_size_shift >= 32);
443 key = adjust_key(dev, key);
444 mr->
ibmr.rkey = mr->
ibmr.lkey = hw_index_to_key(dev, key);
446 if (mthca_is_memfree(dev)) {
449 goto err_out_mpt_free;
453 if (IS_ERR(mailbox)) {
454 err = PTR_ERR(mailbox);
457 mpt_entry = mailbox->
buf;
478 mr->
mtt->first_seg * dev->
limits.mtt_seg_size);
486 if ((i + 1) % 4 == 0)
492 key & (dev->
limits.num_mpts - 1));
494 mthca_warn(dev,
"SW2HW_MPT failed (%d)\n", err);
495 goto err_out_mailbox;
520 u64 *buffer_list,
int buffer_size_shift,
528 return PTR_ERR(mr->
mtt);
537 total_size, access, mr);
548 key_to_hw_index(dev, lkey));
558 key_to_hw_index(dev, mr->
ibmr.lkey) &
559 (dev->
limits.num_mpts - 1));
561 mthca_warn(dev,
"HW2SW_MPT failed (%d)\n", err);
563 mthca_free_region(dev, mr->
ibmr.lkey);
574 int list_len = mr->
attr.max_pages;
578 if (mr->
attr.page_shift < 12 || mr->
attr.page_shift >= 32)
582 if (mthca_is_memfree(dev) &&
591 key = adjust_key(dev, key);
593 idx = key & (dev->
limits.num_mpts - 1);
594 mr->
ibmr.rkey = mr->
ibmr.lkey = hw_index_to_key(dev, key);
596 if (mthca_is_memfree(dev)) {
599 goto err_out_mpt_free;
607 mr->
mtt = __mthca_alloc_mtt(dev, list_len, dev->
mr_table.fmr_mtt_buddy);
608 if (IS_ERR(mr->
mtt)) {
609 err = PTR_ERR(mr->
mtt);
613 mtt_seg = mr->
mtt->first_seg * dev->
limits.mtt_seg_size;
615 if (mthca_is_memfree(dev)) {
624 if (IS_ERR(mailbox)) {
625 err = PTR_ERR(mailbox);
626 goto err_out_free_mtt;
629 mpt_entry = mailbox->
buf;
649 if ((i + 1) % 4 == 0)
655 key & (dev->
limits.num_mpts - 1));
657 mthca_warn(dev,
"SW2HW_MPT failed (%d)\n", err);
658 goto err_out_mailbox_free;
664 err_out_mailbox_free:
683 mthca_free_region(dev, fmr->
ibmr.lkey);
689 static inline int mthca_check_fmr(
struct mthca_fmr *
fmr,
u64 *page_list,
694 if (list_len > fmr->
attr.max_pages)
697 page_mask = (1 << fmr->
attr.page_shift) - 1;
700 if (iova & page_mask)
706 if (page_list[i] & ~page_mask)
710 if (fmr->
maps >= fmr->
attr.max_maps)
718 int list_len,
u64 iova)
726 err = mthca_check_fmr(fmr, page_list, list_len, iova);
732 key = tavor_key_to_hw_index(fmr->
ibmr.lkey);
733 key += dev->
limits.num_mpts;
734 fmr->
ibmr.lkey = fmr->
ibmr.rkey = tavor_hw_index_to_key(key);
741 mthca_write64_raw(mtt_entry, fmr->
mem.
tavor.mtts + i);
759 int list_len,
u64 iova)
766 err = mthca_check_fmr(fmr, page_list, list_len, iova);
772 key = arbel_key_to_hw_index(fmr->
ibmr.lkey);
776 key += dev->
limits.num_mpts;
777 fmr->
ibmr.lkey = fmr->
ibmr.rkey = arbel_hw_index_to_key(key);
830 int mpts, mtts,
err,
i;
834 ~0, dev->
limits.reserved_mrws);
838 if (!mthca_is_memfree(dev) &&
840 dev->
limits.fmr_reserved_mtts = 0;
845 mthca_dbg(dev,
"Memory key throughput optimization activated.\n");
847 err = mthca_buddy_init(&dev->
mr_table.mtt_buddy,
848 fls(dev->
limits.num_mtt_segs - 1));
856 if (dev->
limits.fmr_reserved_mtts) {
857 i = fls(dev->
limits.fmr_reserved_mtts - 1);
860 mthca_warn(dev,
"Unable to reserve 2^31 FMR MTTs.\n");
864 mpts = mtts = 1 <<
i;
866 mtts = dev->
limits.num_mtt_segs;
867 mpts = dev->
limits.num_mpts;
870 if (!mthca_is_memfree(dev) &&
880 if (!dev->
mr_table.tavor_fmr.mpt_base) {
881 mthca_warn(dev,
"MPT ioremap for FMR failed.\n");
892 if (!dev->
mr_table.tavor_fmr.mtt_base) {
893 mthca_warn(dev,
"MTT ioremap for FMR failed.\n");
899 if (dev->
limits.fmr_reserved_mtts) {
900 err = mthca_buddy_init(&dev->
mr_table.tavor_fmr.mtt_buddy, fls(mtts - 1));
902 goto err_fmr_mtt_buddy;
905 err = mthca_buddy_alloc(&dev->
mr_table.mtt_buddy, fls(mtts - 1));
907 goto err_reserve_fmr;
915 if (dev->
limits.reserved_mtts) {
916 i = fls(dev->
limits.reserved_mtts - 1);
918 if (mthca_alloc_mtt_range(dev, i,
919 dev->
mr_table.fmr_mtt_buddy) == -1) {
920 mthca_warn(dev,
"MTT table of order %d is too small.\n",
921 dev->
mr_table.fmr_mtt_buddy->max_order);
923 goto err_reserve_mtts;
931 if (dev->
limits.fmr_reserved_mtts)
932 mthca_buddy_cleanup(&dev->
mr_table.tavor_fmr.mtt_buddy);
935 if (dev->
mr_table.tavor_fmr.mtt_base)
939 if (dev->
mr_table.tavor_fmr.mpt_base)
943 mthca_buddy_cleanup(&dev->
mr_table.mtt_buddy);
954 if (dev->
limits.fmr_reserved_mtts)
955 mthca_buddy_cleanup(&dev->
mr_table.tavor_fmr.mtt_buddy);
957 mthca_buddy_cleanup(&dev->
mr_table.mtt_buddy);
959 if (dev->
mr_table.tavor_fmr.mtt_base)
961 if (dev->
mr_table.tavor_fmr.mpt_base)