diff options
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/core/packer.c | 4 | ||||
-rw-r--r-- | drivers/infiniband/core/sa_query.c | 18 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_av.c | 1 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_cmd.c | 531 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_cmd.h | 48 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_cq.c | 101 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_dev.h | 12 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_doorbell.h | 1 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_eq.c | 58 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_main.c | 32 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_mcg.c | 63 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_memfree.c | 10 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_mr.c | 367 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_provider.c | 4 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_provider.h | 14 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_qp.c | 139 |
16 files changed, 712 insertions, 691 deletions
diff --git a/drivers/infiniband/core/packer.c b/drivers/infiniband/core/packer.c index 5f15feffeae2..eb5ff54c10d7 100644 --- a/drivers/infiniband/core/packer.c +++ b/drivers/infiniband/core/packer.c | |||
@@ -96,7 +96,7 @@ void ib_pack(const struct ib_field *desc, | |||
96 | else | 96 | else |
97 | val = 0; | 97 | val = 0; |
98 | 98 | ||
99 | mask = cpu_to_be64(((1ull << desc[i].size_bits) - 1) << shift); | 99 | mask = cpu_to_be64((~0ull >> (64 - desc[i].size_bits)) << shift); |
100 | addr = (__be64 *) ((__be32 *) buf + desc[i].offset_words); | 100 | addr = (__be64 *) ((__be32 *) buf + desc[i].offset_words); |
101 | *addr = (*addr & ~mask) | (cpu_to_be64(val) & mask); | 101 | *addr = (*addr & ~mask) | (cpu_to_be64(val) & mask); |
102 | } else { | 102 | } else { |
@@ -176,7 +176,7 @@ void ib_unpack(const struct ib_field *desc, | |||
176 | __be64 *addr; | 176 | __be64 *addr; |
177 | 177 | ||
178 | shift = 64 - desc[i].offset_bits - desc[i].size_bits; | 178 | shift = 64 - desc[i].offset_bits - desc[i].size_bits; |
179 | mask = ((1ull << desc[i].size_bits) - 1) << shift; | 179 | mask = (~0ull >> (64 - desc[i].size_bits)) << shift; |
180 | addr = (__be64 *) buf + desc[i].offset_words; | 180 | addr = (__be64 *) buf + desc[i].offset_words; |
181 | val = (be64_to_cpup(addr) & mask) >> shift; | 181 | val = (be64_to_cpup(addr) & mask) >> shift; |
182 | value_write(desc[i].struct_offset_bytes, | 182 | value_write(desc[i].struct_offset_bytes, |
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 276e1a53010d..5a08e81fa827 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c | |||
@@ -507,7 +507,13 @@ retry: | |||
507 | spin_unlock_irqrestore(&idr_lock, flags); | 507 | spin_unlock_irqrestore(&idr_lock, flags); |
508 | } | 508 | } |
509 | 509 | ||
510 | return ret; | 510 | /* |
511 | * It's not safe to dereference query any more, because the | ||
512 | * send may already have completed and freed the query in | ||
513 | * another context. So use wr.wr_id, which has a copy of the | ||
514 | * query's id. | ||
515 | */ | ||
516 | return ret ? ret : wr.wr_id; | ||
511 | } | 517 | } |
512 | 518 | ||
513 | static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query, | 519 | static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query, |
@@ -598,14 +604,15 @@ int ib_sa_path_rec_get(struct ib_device *device, u8 port_num, | |||
598 | rec, query->sa_query.mad->data); | 604 | rec, query->sa_query.mad->data); |
599 | 605 | ||
600 | *sa_query = &query->sa_query; | 606 | *sa_query = &query->sa_query; |
607 | |||
601 | ret = send_mad(&query->sa_query, timeout_ms); | 608 | ret = send_mad(&query->sa_query, timeout_ms); |
602 | if (ret) { | 609 | if (ret < 0) { |
603 | *sa_query = NULL; | 610 | *sa_query = NULL; |
604 | kfree(query->sa_query.mad); | 611 | kfree(query->sa_query.mad); |
605 | kfree(query); | 612 | kfree(query); |
606 | } | 613 | } |
607 | 614 | ||
608 | return ret ? ret : query->sa_query.id; | 615 | return ret; |
609 | } | 616 | } |
610 | EXPORT_SYMBOL(ib_sa_path_rec_get); | 617 | EXPORT_SYMBOL(ib_sa_path_rec_get); |
611 | 618 | ||
@@ -674,14 +681,15 @@ int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num, | |||
674 | rec, query->sa_query.mad->data); | 681 | rec, query->sa_query.mad->data); |
675 | 682 | ||
676 | *sa_query = &query->sa_query; | 683 | *sa_query = &query->sa_query; |
684 | |||
677 | ret = send_mad(&query->sa_query, timeout_ms); | 685 | ret = send_mad(&query->sa_query, timeout_ms); |
678 | if (ret) { | 686 | if (ret < 0) { |
679 | *sa_query = NULL; | 687 | *sa_query = NULL; |
680 | kfree(query->sa_query.mad); | 688 | kfree(query->sa_query.mad); |
681 | kfree(query); | 689 | kfree(query); |
682 | } | 690 | } |
683 | 691 | ||
684 | return ret ? ret : query->sa_query.id; | 692 | return ret; |
685 | } | 693 | } |
686 | EXPORT_SYMBOL(ib_sa_mcmember_rec_query); | 694 | EXPORT_SYMBOL(ib_sa_mcmember_rec_query); |
687 | 695 | ||
diff --git a/drivers/infiniband/hw/mthca/mthca_av.c b/drivers/infiniband/hw/mthca/mthca_av.c index 085baf393ca4..d58dcbe66488 100644 --- a/drivers/infiniband/hw/mthca/mthca_av.c +++ b/drivers/infiniband/hw/mthca/mthca_av.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004 Topspin Communications. All rights reserved. | 2 | * Copyright (c) 2004 Topspin Communications. All rights reserved. |
3 | * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. | ||
3 | * | 4 | * |
4 | * This software is available to you under a choice of one of two | 5 | * This software is available to you under a choice of one of two |
5 | * licenses. You may choose to be licensed under the terms of the GNU | 6 | * licenses. You may choose to be licensed under the terms of the GNU |
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index cd9ed958d92f..1557a522d831 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c | |||
@@ -431,6 +431,36 @@ static int mthca_cmd_imm(struct mthca_dev *dev, | |||
431 | timeout, status); | 431 | timeout, status); |
432 | } | 432 | } |
433 | 433 | ||
434 | int mthca_cmd_init(struct mthca_dev *dev) | ||
435 | { | ||
436 | sema_init(&dev->cmd.hcr_sem, 1); | ||
437 | sema_init(&dev->cmd.poll_sem, 1); | ||
438 | dev->cmd.use_events = 0; | ||
439 | |||
440 | dev->hcr = ioremap(pci_resource_start(dev->pdev, 0) + MTHCA_HCR_BASE, | ||
441 | MTHCA_HCR_SIZE); | ||
442 | if (!dev->hcr) { | ||
443 | mthca_err(dev, "Couldn't map command register."); | ||
444 | return -ENOMEM; | ||
445 | } | ||
446 | |||
447 | dev->cmd.pool = pci_pool_create("mthca_cmd", dev->pdev, | ||
448 | MTHCA_MAILBOX_SIZE, | ||
449 | MTHCA_MAILBOX_SIZE, 0); | ||
450 | if (!dev->cmd.pool) { | ||
451 | iounmap(dev->hcr); | ||
452 | return -ENOMEM; | ||
453 | } | ||
454 | |||
455 | return 0; | ||
456 | } | ||
457 | |||
458 | void mthca_cmd_cleanup(struct mthca_dev *dev) | ||
459 | { | ||
460 | pci_pool_destroy(dev->cmd.pool); | ||
461 | iounmap(dev->hcr); | ||
462 | } | ||
463 | |||
434 | /* | 464 | /* |
435 | * Switch to using events to issue FW commands (should be called after | 465 | * Switch to using events to issue FW commands (should be called after |
436 | * event queue to command events has been initialized). | 466 | * event queue to command events has been initialized). |
@@ -489,6 +519,33 @@ void mthca_cmd_use_polling(struct mthca_dev *dev) | |||
489 | up(&dev->cmd.poll_sem); | 519 | up(&dev->cmd.poll_sem); |
490 | } | 520 | } |
491 | 521 | ||
522 | struct mthca_mailbox *mthca_alloc_mailbox(struct mthca_dev *dev, | ||
523 | unsigned int gfp_mask) | ||
524 | { | ||
525 | struct mthca_mailbox *mailbox; | ||
526 | |||
527 | mailbox = kmalloc(sizeof *mailbox, gfp_mask); | ||
528 | if (!mailbox) | ||
529 | return ERR_PTR(-ENOMEM); | ||
530 | |||
531 | mailbox->buf = pci_pool_alloc(dev->cmd.pool, gfp_mask, &mailbox->dma); | ||
532 | if (!mailbox->buf) { | ||
533 | kfree(mailbox); | ||
534 | return ERR_PTR(-ENOMEM); | ||
535 | } | ||
536 | |||
537 | return mailbox; | ||
538 | } | ||
539 | |||
540 | void mthca_free_mailbox(struct mthca_dev *dev, struct mthca_mailbox *mailbox) | ||
541 | { | ||
542 | if (!mailbox) | ||
543 | return; | ||
544 | |||
545 | pci_pool_free(dev->cmd.pool, mailbox->buf, mailbox->dma); | ||
546 | kfree(mailbox); | ||
547 | } | ||
548 | |||
492 | int mthca_SYS_EN(struct mthca_dev *dev, u8 *status) | 549 | int mthca_SYS_EN(struct mthca_dev *dev, u8 *status) |
493 | { | 550 | { |
494 | u64 out; | 551 | u64 out; |
@@ -513,20 +570,20 @@ int mthca_SYS_DIS(struct mthca_dev *dev, u8 *status) | |||
513 | static int mthca_map_cmd(struct mthca_dev *dev, u16 op, struct mthca_icm *icm, | 570 | static int mthca_map_cmd(struct mthca_dev *dev, u16 op, struct mthca_icm *icm, |
514 | u64 virt, u8 *status) | 571 | u64 virt, u8 *status) |
515 | { | 572 | { |
516 | u32 *inbox; | 573 | struct mthca_mailbox *mailbox; |
517 | dma_addr_t indma; | ||
518 | struct mthca_icm_iter iter; | 574 | struct mthca_icm_iter iter; |
575 | __be64 *pages; | ||
519 | int lg; | 576 | int lg; |
520 | int nent = 0; | 577 | int nent = 0; |
521 | int i; | 578 | int i; |
522 | int err = 0; | 579 | int err = 0; |
523 | int ts = 0, tc = 0; | 580 | int ts = 0, tc = 0; |
524 | 581 | ||
525 | inbox = pci_alloc_consistent(dev->pdev, PAGE_SIZE, &indma); | 582 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); |
526 | if (!inbox) | 583 | if (IS_ERR(mailbox)) |
527 | return -ENOMEM; | 584 | return PTR_ERR(mailbox); |
528 | 585 | memset(mailbox->buf, 0, MTHCA_MAILBOX_SIZE); | |
529 | memset(inbox, 0, PAGE_SIZE); | 586 | pages = mailbox->buf; |
530 | 587 | ||
531 | for (mthca_icm_first(icm, &iter); | 588 | for (mthca_icm_first(icm, &iter); |
532 | !mthca_icm_last(&iter); | 589 | !mthca_icm_last(&iter); |
@@ -546,19 +603,17 @@ static int mthca_map_cmd(struct mthca_dev *dev, u16 op, struct mthca_icm *icm, | |||
546 | } | 603 | } |
547 | for (i = 0; i < mthca_icm_size(&iter) / (1 << lg); ++i, ++nent) { | 604 | for (i = 0; i < mthca_icm_size(&iter) / (1 << lg); ++i, ++nent) { |
548 | if (virt != -1) { | 605 | if (virt != -1) { |
549 | *((__be64 *) (inbox + nent * 4)) = | 606 | pages[nent * 2] = cpu_to_be64(virt); |
550 | cpu_to_be64(virt); | ||
551 | virt += 1 << lg; | 607 | virt += 1 << lg; |
552 | } | 608 | } |
553 | 609 | ||
554 | *((__be64 *) (inbox + nent * 4 + 2)) = | 610 | pages[nent * 2 + 1] = cpu_to_be64((mthca_icm_addr(&iter) + |
555 | cpu_to_be64((mthca_icm_addr(&iter) + | 611 | (i << lg)) | (lg - 12)); |
556 | (i << lg)) | (lg - 12)); | ||
557 | ts += 1 << (lg - 10); | 612 | ts += 1 << (lg - 10); |
558 | ++tc; | 613 | ++tc; |
559 | 614 | ||
560 | if (nent == PAGE_SIZE / 16) { | 615 | if (nent == MTHCA_MAILBOX_SIZE / 16) { |
561 | err = mthca_cmd(dev, indma, nent, 0, op, | 616 | err = mthca_cmd(dev, mailbox->dma, nent, 0, op, |
562 | CMD_TIME_CLASS_B, status); | 617 | CMD_TIME_CLASS_B, status); |
563 | if (err || *status) | 618 | if (err || *status) |
564 | goto out; | 619 | goto out; |
@@ -568,7 +623,7 @@ static int mthca_map_cmd(struct mthca_dev *dev, u16 op, struct mthca_icm *icm, | |||
568 | } | 623 | } |
569 | 624 | ||
570 | if (nent) | 625 | if (nent) |
571 | err = mthca_cmd(dev, indma, nent, 0, op, | 626 | err = mthca_cmd(dev, mailbox->dma, nent, 0, op, |
572 | CMD_TIME_CLASS_B, status); | 627 | CMD_TIME_CLASS_B, status); |
573 | 628 | ||
574 | switch (op) { | 629 | switch (op) { |
@@ -585,7 +640,7 @@ static int mthca_map_cmd(struct mthca_dev *dev, u16 op, struct mthca_icm *icm, | |||
585 | } | 640 | } |
586 | 641 | ||
587 | out: | 642 | out: |
588 | pci_free_consistent(dev->pdev, PAGE_SIZE, inbox, indma); | 643 | mthca_free_mailbox(dev, mailbox); |
589 | return err; | 644 | return err; |
590 | } | 645 | } |
591 | 646 | ||
@@ -606,8 +661,8 @@ int mthca_RUN_FW(struct mthca_dev *dev, u8 *status) | |||
606 | 661 | ||
607 | int mthca_QUERY_FW(struct mthca_dev *dev, u8 *status) | 662 | int mthca_QUERY_FW(struct mthca_dev *dev, u8 *status) |
608 | { | 663 | { |
664 | struct mthca_mailbox *mailbox; | ||
609 | u32 *outbox; | 665 | u32 *outbox; |
610 | dma_addr_t outdma; | ||
611 | int err = 0; | 666 | int err = 0; |
612 | u8 lg; | 667 | u8 lg; |
613 | 668 | ||
@@ -625,12 +680,12 @@ int mthca_QUERY_FW(struct mthca_dev *dev, u8 *status) | |||
625 | #define QUERY_FW_EQ_ARM_BASE_OFFSET 0x40 | 680 | #define QUERY_FW_EQ_ARM_BASE_OFFSET 0x40 |
626 | #define QUERY_FW_EQ_SET_CI_BASE_OFFSET 0x48 | 681 | #define QUERY_FW_EQ_SET_CI_BASE_OFFSET 0x48 |
627 | 682 | ||
628 | outbox = pci_alloc_consistent(dev->pdev, QUERY_FW_OUT_SIZE, &outdma); | 683 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); |
629 | if (!outbox) { | 684 | if (IS_ERR(mailbox)) |
630 | return -ENOMEM; | 685 | return PTR_ERR(mailbox); |
631 | } | 686 | outbox = mailbox->buf; |
632 | 687 | ||
633 | err = mthca_cmd_box(dev, 0, outdma, 0, 0, CMD_QUERY_FW, | 688 | err = mthca_cmd_box(dev, 0, mailbox->dma, 0, 0, CMD_QUERY_FW, |
634 | CMD_TIME_CLASS_A, status); | 689 | CMD_TIME_CLASS_A, status); |
635 | 690 | ||
636 | if (err) | 691 | if (err) |
@@ -681,15 +736,15 @@ int mthca_QUERY_FW(struct mthca_dev *dev, u8 *status) | |||
681 | } | 736 | } |
682 | 737 | ||
683 | out: | 738 | out: |
684 | pci_free_consistent(dev->pdev, QUERY_FW_OUT_SIZE, outbox, outdma); | 739 | mthca_free_mailbox(dev, mailbox); |
685 | return err; | 740 | return err; |
686 | } | 741 | } |
687 | 742 | ||
688 | int mthca_ENABLE_LAM(struct mthca_dev *dev, u8 *status) | 743 | int mthca_ENABLE_LAM(struct mthca_dev *dev, u8 *status) |
689 | { | 744 | { |
745 | struct mthca_mailbox *mailbox; | ||
690 | u8 info; | 746 | u8 info; |
691 | u32 *outbox; | 747 | u32 *outbox; |
692 | dma_addr_t outdma; | ||
693 | int err = 0; | 748 | int err = 0; |
694 | 749 | ||
695 | #define ENABLE_LAM_OUT_SIZE 0x100 | 750 | #define ENABLE_LAM_OUT_SIZE 0x100 |
@@ -700,11 +755,12 @@ int mthca_ENABLE_LAM(struct mthca_dev *dev, u8 *status) | |||
700 | #define ENABLE_LAM_INFO_HIDDEN_FLAG (1 << 4) | 755 | #define ENABLE_LAM_INFO_HIDDEN_FLAG (1 << 4) |
701 | #define ENABLE_LAM_INFO_ECC_MASK 0x3 | 756 | #define ENABLE_LAM_INFO_ECC_MASK 0x3 |
702 | 757 | ||
703 | outbox = pci_alloc_consistent(dev->pdev, ENABLE_LAM_OUT_SIZE, &outdma); | 758 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); |
704 | if (!outbox) | 759 | if (IS_ERR(mailbox)) |
705 | return -ENOMEM; | 760 | return PTR_ERR(mailbox); |
761 | outbox = mailbox->buf; | ||
706 | 762 | ||
707 | err = mthca_cmd_box(dev, 0, outdma, 0, 0, CMD_ENABLE_LAM, | 763 | err = mthca_cmd_box(dev, 0, mailbox->dma, 0, 0, CMD_ENABLE_LAM, |
708 | CMD_TIME_CLASS_C, status); | 764 | CMD_TIME_CLASS_C, status); |
709 | 765 | ||
710 | if (err) | 766 | if (err) |
@@ -733,7 +789,7 @@ int mthca_ENABLE_LAM(struct mthca_dev *dev, u8 *status) | |||
733 | (unsigned long long) dev->ddr_end); | 789 | (unsigned long long) dev->ddr_end); |
734 | 790 | ||
735 | out: | 791 | out: |
736 | pci_free_consistent(dev->pdev, ENABLE_LAM_OUT_SIZE, outbox, outdma); | 792 | mthca_free_mailbox(dev, mailbox); |
737 | return err; | 793 | return err; |
738 | } | 794 | } |
739 | 795 | ||
@@ -744,9 +800,9 @@ int mthca_DISABLE_LAM(struct mthca_dev *dev, u8 *status) | |||
744 | 800 | ||
745 | int mthca_QUERY_DDR(struct mthca_dev *dev, u8 *status) | 801 | int mthca_QUERY_DDR(struct mthca_dev *dev, u8 *status) |
746 | { | 802 | { |
803 | struct mthca_mailbox *mailbox; | ||
747 | u8 info; | 804 | u8 info; |
748 | u32 *outbox; | 805 | u32 *outbox; |
749 | dma_addr_t outdma; | ||
750 | int err = 0; | 806 | int err = 0; |
751 | 807 | ||
752 | #define QUERY_DDR_OUT_SIZE 0x100 | 808 | #define QUERY_DDR_OUT_SIZE 0x100 |
@@ -757,11 +813,12 @@ int mthca_QUERY_DDR(struct mthca_dev *dev, u8 *status) | |||
757 | #define QUERY_DDR_INFO_HIDDEN_FLAG (1 << 4) | 813 | #define QUERY_DDR_INFO_HIDDEN_FLAG (1 << 4) |
758 | #define QUERY_DDR_INFO_ECC_MASK 0x3 | 814 | #define QUERY_DDR_INFO_ECC_MASK 0x3 |
759 | 815 | ||
760 | outbox = pci_alloc_consistent(dev->pdev, QUERY_DDR_OUT_SIZE, &outdma); | 816 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); |
761 | if (!outbox) | 817 | if (IS_ERR(mailbox)) |
762 | return -ENOMEM; | 818 | return PTR_ERR(mailbox); |
819 | outbox = mailbox->buf; | ||
763 | 820 | ||
764 | err = mthca_cmd_box(dev, 0, outdma, 0, 0, CMD_QUERY_DDR, | 821 | err = mthca_cmd_box(dev, 0, mailbox->dma, 0, 0, CMD_QUERY_DDR, |
765 | CMD_TIME_CLASS_A, status); | 822 | CMD_TIME_CLASS_A, status); |
766 | 823 | ||
767 | if (err) | 824 | if (err) |
@@ -787,15 +844,15 @@ int mthca_QUERY_DDR(struct mthca_dev *dev, u8 *status) | |||
787 | (unsigned long long) dev->ddr_end); | 844 | (unsigned long long) dev->ddr_end); |
788 | 845 | ||
789 | out: | 846 | out: |
790 | pci_free_consistent(dev->pdev, QUERY_DDR_OUT_SIZE, outbox, outdma); | 847 | mthca_free_mailbox(dev, mailbox); |
791 | return err; | 848 | return err; |
792 | } | 849 | } |
793 | 850 | ||
794 | int mthca_QUERY_DEV_LIM(struct mthca_dev *dev, | 851 | int mthca_QUERY_DEV_LIM(struct mthca_dev *dev, |
795 | struct mthca_dev_lim *dev_lim, u8 *status) | 852 | struct mthca_dev_lim *dev_lim, u8 *status) |
796 | { | 853 | { |
854 | struct mthca_mailbox *mailbox; | ||
797 | u32 *outbox; | 855 | u32 *outbox; |
798 | dma_addr_t outdma; | ||
799 | u8 field; | 856 | u8 field; |
800 | u16 size; | 857 | u16 size; |
801 | int err; | 858 | int err; |
@@ -860,11 +917,12 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev, | |||
860 | #define QUERY_DEV_LIM_LAMR_OFFSET 0x9f | 917 | #define QUERY_DEV_LIM_LAMR_OFFSET 0x9f |
861 | #define QUERY_DEV_LIM_MAX_ICM_SZ_OFFSET 0xa0 | 918 | #define QUERY_DEV_LIM_MAX_ICM_SZ_OFFSET 0xa0 |
862 | 919 | ||
863 | outbox = pci_alloc_consistent(dev->pdev, QUERY_DEV_LIM_OUT_SIZE, &outdma); | 920 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); |
864 | if (!outbox) | 921 | if (IS_ERR(mailbox)) |
865 | return -ENOMEM; | 922 | return PTR_ERR(mailbox); |
923 | outbox = mailbox->buf; | ||
866 | 924 | ||
867 | err = mthca_cmd_box(dev, 0, outdma, 0, 0, CMD_QUERY_DEV_LIM, | 925 | err = mthca_cmd_box(dev, 0, mailbox->dma, 0, 0, CMD_QUERY_DEV_LIM, |
868 | CMD_TIME_CLASS_A, status); | 926 | CMD_TIME_CLASS_A, status); |
869 | 927 | ||
870 | if (err) | 928 | if (err) |
@@ -1020,15 +1078,15 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev, | |||
1020 | } | 1078 | } |
1021 | 1079 | ||
1022 | out: | 1080 | out: |
1023 | pci_free_consistent(dev->pdev, QUERY_DEV_LIM_OUT_SIZE, outbox, outdma); | 1081 | mthca_free_mailbox(dev, mailbox); |
1024 | return err; | 1082 | return err; |
1025 | } | 1083 | } |
1026 | 1084 | ||
1027 | int mthca_QUERY_ADAPTER(struct mthca_dev *dev, | 1085 | int mthca_QUERY_ADAPTER(struct mthca_dev *dev, |
1028 | struct mthca_adapter *adapter, u8 *status) | 1086 | struct mthca_adapter *adapter, u8 *status) |
1029 | { | 1087 | { |
1088 | struct mthca_mailbox *mailbox; | ||
1030 | u32 *outbox; | 1089 | u32 *outbox; |
1031 | dma_addr_t outdma; | ||
1032 | int err; | 1090 | int err; |
1033 | 1091 | ||
1034 | #define QUERY_ADAPTER_OUT_SIZE 0x100 | 1092 | #define QUERY_ADAPTER_OUT_SIZE 0x100 |
@@ -1037,23 +1095,24 @@ int mthca_QUERY_ADAPTER(struct mthca_dev *dev, | |||
1037 | #define QUERY_ADAPTER_REVISION_ID_OFFSET 0x08 | 1095 | #define QUERY_ADAPTER_REVISION_ID_OFFSET 0x08 |
1038 | #define QUERY_ADAPTER_INTA_PIN_OFFSET 0x10 | 1096 | #define QUERY_ADAPTER_INTA_PIN_OFFSET 0x10 |
1039 | 1097 | ||
1040 | outbox = pci_alloc_consistent(dev->pdev, QUERY_ADAPTER_OUT_SIZE, &outdma); | 1098 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); |
1041 | if (!outbox) | 1099 | if (IS_ERR(mailbox)) |
1042 | return -ENOMEM; | 1100 | return PTR_ERR(mailbox); |
1101 | outbox = mailbox->buf; | ||
1043 | 1102 | ||
1044 | err = mthca_cmd_box(dev, 0, outdma, 0, 0, CMD_QUERY_ADAPTER, | 1103 | err = mthca_cmd_box(dev, 0, mailbox->dma, 0, 0, CMD_QUERY_ADAPTER, |
1045 | CMD_TIME_CLASS_A, status); | 1104 | CMD_TIME_CLASS_A, status); |
1046 | 1105 | ||
1047 | if (err) | 1106 | if (err) |
1048 | goto out; | 1107 | goto out; |
1049 | 1108 | ||
1050 | MTHCA_GET(adapter->vendor_id, outbox, QUERY_ADAPTER_VENDOR_ID_OFFSET); | 1109 | MTHCA_GET(adapter->vendor_id, outbox, QUERY_ADAPTER_VENDOR_ID_OFFSET); |
1051 | MTHCA_GET(adapter->device_id, outbox, QUERY_ADAPTER_DEVICE_ID_OFFSET); | 1110 | MTHCA_GET(adapter->device_id, outbox, QUERY_ADAPTER_DEVICE_ID_OFFSET); |
1052 | MTHCA_GET(adapter->revision_id, outbox, QUERY_ADAPTER_REVISION_ID_OFFSET); | 1111 | MTHCA_GET(adapter->revision_id, outbox, QUERY_ADAPTER_REVISION_ID_OFFSET); |
1053 | MTHCA_GET(adapter->inta_pin, outbox, QUERY_ADAPTER_INTA_PIN_OFFSET); | 1112 | MTHCA_GET(adapter->inta_pin, outbox, QUERY_ADAPTER_INTA_PIN_OFFSET); |
1054 | 1113 | ||
1055 | out: | 1114 | out: |
1056 | pci_free_consistent(dev->pdev, QUERY_DEV_LIM_OUT_SIZE, outbox, outdma); | 1115 | mthca_free_mailbox(dev, mailbox); |
1057 | return err; | 1116 | return err; |
1058 | } | 1117 | } |
1059 | 1118 | ||
@@ -1061,8 +1120,8 @@ int mthca_INIT_HCA(struct mthca_dev *dev, | |||
1061 | struct mthca_init_hca_param *param, | 1120 | struct mthca_init_hca_param *param, |
1062 | u8 *status) | 1121 | u8 *status) |
1063 | { | 1122 | { |
1123 | struct mthca_mailbox *mailbox; | ||
1064 | u32 *inbox; | 1124 | u32 *inbox; |
1065 | dma_addr_t indma; | ||
1066 | int err; | 1125 | int err; |
1067 | 1126 | ||
1068 | #define INIT_HCA_IN_SIZE 0x200 | 1127 | #define INIT_HCA_IN_SIZE 0x200 |
@@ -1102,9 +1161,10 @@ int mthca_INIT_HCA(struct mthca_dev *dev, | |||
1102 | #define INIT_HCA_UAR_SCATCH_BASE_OFFSET (INIT_HCA_UAR_OFFSET + 0x10) | 1161 | #define INIT_HCA_UAR_SCATCH_BASE_OFFSET (INIT_HCA_UAR_OFFSET + 0x10) |
1103 | #define INIT_HCA_UAR_CTX_BASE_OFFSET (INIT_HCA_UAR_OFFSET + 0x18) | 1162 | #define INIT_HCA_UAR_CTX_BASE_OFFSET (INIT_HCA_UAR_OFFSET + 0x18) |
1104 | 1163 | ||
1105 | inbox = pci_alloc_consistent(dev->pdev, INIT_HCA_IN_SIZE, &indma); | 1164 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); |
1106 | if (!inbox) | 1165 | if (IS_ERR(mailbox)) |
1107 | return -ENOMEM; | 1166 | return PTR_ERR(mailbox); |
1167 | inbox = mailbox->buf; | ||
1108 | 1168 | ||
1109 | memset(inbox, 0, INIT_HCA_IN_SIZE); | 1169 | memset(inbox, 0, INIT_HCA_IN_SIZE); |
1110 | 1170 | ||
@@ -1167,10 +1227,9 @@ int mthca_INIT_HCA(struct mthca_dev *dev, | |||
1167 | MTHCA_PUT(inbox, param->uarc_base, INIT_HCA_UAR_CTX_BASE_OFFSET); | 1227 | MTHCA_PUT(inbox, param->uarc_base, INIT_HCA_UAR_CTX_BASE_OFFSET); |
1168 | } | 1228 | } |
1169 | 1229 | ||
1170 | err = mthca_cmd(dev, indma, 0, 0, CMD_INIT_HCA, | 1230 | err = mthca_cmd(dev, mailbox->dma, 0, 0, CMD_INIT_HCA, HZ, status); |
1171 | HZ, status); | ||
1172 | 1231 | ||
1173 | pci_free_consistent(dev->pdev, INIT_HCA_IN_SIZE, inbox, indma); | 1232 | mthca_free_mailbox(dev, mailbox); |
1174 | return err; | 1233 | return err; |
1175 | } | 1234 | } |
1176 | 1235 | ||
@@ -1178,8 +1237,8 @@ int mthca_INIT_IB(struct mthca_dev *dev, | |||
1178 | struct mthca_init_ib_param *param, | 1237 | struct mthca_init_ib_param *param, |
1179 | int port, u8 *status) | 1238 | int port, u8 *status) |
1180 | { | 1239 | { |
1240 | struct mthca_mailbox *mailbox; | ||
1181 | u32 *inbox; | 1241 | u32 *inbox; |
1182 | dma_addr_t indma; | ||
1183 | int err; | 1242 | int err; |
1184 | u32 flags; | 1243 | u32 flags; |
1185 | 1244 | ||
@@ -1199,9 +1258,10 @@ int mthca_INIT_IB(struct mthca_dev *dev, | |||
1199 | #define INIT_IB_NODE_GUID_OFFSET 0x18 | 1258 | #define INIT_IB_NODE_GUID_OFFSET 0x18 |
1200 | #define INIT_IB_SI_GUID_OFFSET 0x20 | 1259 | #define INIT_IB_SI_GUID_OFFSET 0x20 |
1201 | 1260 | ||
1202 | inbox = pci_alloc_consistent(dev->pdev, INIT_IB_IN_SIZE, &indma); | 1261 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); |
1203 | if (!inbox) | 1262 | if (IS_ERR(mailbox)) |
1204 | return -ENOMEM; | 1263 | return PTR_ERR(mailbox); |
1264 | inbox = mailbox->buf; | ||
1205 | 1265 | ||
1206 | memset(inbox, 0, INIT_IB_IN_SIZE); | 1266 | memset(inbox, 0, INIT_IB_IN_SIZE); |
1207 | 1267 | ||
@@ -1221,10 +1281,10 @@ int mthca_INIT_IB(struct mthca_dev *dev, | |||
1221 | MTHCA_PUT(inbox, param->node_guid, INIT_IB_NODE_GUID_OFFSET); | 1281 | MTHCA_PUT(inbox, param->node_guid, INIT_IB_NODE_GUID_OFFSET); |
1222 | MTHCA_PUT(inbox, param->si_guid, INIT_IB_SI_GUID_OFFSET); | 1282 | MTHCA_PUT(inbox, param->si_guid, INIT_IB_SI_GUID_OFFSET); |
1223 | 1283 | ||
1224 | err = mthca_cmd(dev, indma, port, 0, CMD_INIT_IB, | 1284 | err = mthca_cmd(dev, mailbox->dma, port, 0, CMD_INIT_IB, |
1225 | CMD_TIME_CLASS_A, status); | 1285 | CMD_TIME_CLASS_A, status); |
1226 | 1286 | ||
1227 | pci_free_consistent(dev->pdev, INIT_HCA_IN_SIZE, inbox, indma); | 1287 | mthca_free_mailbox(dev, mailbox); |
1228 | return err; | 1288 | return err; |
1229 | } | 1289 | } |
1230 | 1290 | ||
@@ -1241,8 +1301,8 @@ int mthca_CLOSE_HCA(struct mthca_dev *dev, int panic, u8 *status) | |||
1241 | int mthca_SET_IB(struct mthca_dev *dev, struct mthca_set_ib_param *param, | 1301 | int mthca_SET_IB(struct mthca_dev *dev, struct mthca_set_ib_param *param, |
1242 | int port, u8 *status) | 1302 | int port, u8 *status) |
1243 | { | 1303 | { |
1304 | struct mthca_mailbox *mailbox; | ||
1244 | u32 *inbox; | 1305 | u32 *inbox; |
1245 | dma_addr_t indma; | ||
1246 | int err; | 1306 | int err; |
1247 | u32 flags = 0; | 1307 | u32 flags = 0; |
1248 | 1308 | ||
@@ -1253,9 +1313,10 @@ int mthca_SET_IB(struct mthca_dev *dev, struct mthca_set_ib_param *param, | |||
1253 | #define SET_IB_CAP_MASK_OFFSET 0x04 | 1313 | #define SET_IB_CAP_MASK_OFFSET 0x04 |
1254 | #define SET_IB_SI_GUID_OFFSET 0x08 | 1314 | #define SET_IB_SI_GUID_OFFSET 0x08 |
1255 | 1315 | ||
1256 | inbox = pci_alloc_consistent(dev->pdev, SET_IB_IN_SIZE, &indma); | 1316 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); |
1257 | if (!inbox) | 1317 | if (IS_ERR(mailbox)) |
1258 | return -ENOMEM; | 1318 | return PTR_ERR(mailbox); |
1319 | inbox = mailbox->buf; | ||
1259 | 1320 | ||
1260 | memset(inbox, 0, SET_IB_IN_SIZE); | 1321 | memset(inbox, 0, SET_IB_IN_SIZE); |
1261 | 1322 | ||
@@ -1266,10 +1327,10 @@ int mthca_SET_IB(struct mthca_dev *dev, struct mthca_set_ib_param *param, | |||
1266 | MTHCA_PUT(inbox, param->cap_mask, SET_IB_CAP_MASK_OFFSET); | 1327 | MTHCA_PUT(inbox, param->cap_mask, SET_IB_CAP_MASK_OFFSET); |
1267 | MTHCA_PUT(inbox, param->si_guid, SET_IB_SI_GUID_OFFSET); | 1328 | MTHCA_PUT(inbox, param->si_guid, SET_IB_SI_GUID_OFFSET); |
1268 | 1329 | ||
1269 | err = mthca_cmd(dev, indma, port, 0, CMD_SET_IB, | 1330 | err = mthca_cmd(dev, mailbox->dma, port, 0, CMD_SET_IB, |
1270 | CMD_TIME_CLASS_B, status); | 1331 | CMD_TIME_CLASS_B, status); |
1271 | 1332 | ||
1272 | pci_free_consistent(dev->pdev, INIT_HCA_IN_SIZE, inbox, indma); | 1333 | mthca_free_mailbox(dev, mailbox); |
1273 | return err; | 1334 | return err; |
1274 | } | 1335 | } |
1275 | 1336 | ||
@@ -1280,20 +1341,22 @@ int mthca_MAP_ICM(struct mthca_dev *dev, struct mthca_icm *icm, u64 virt, u8 *st | |||
1280 | 1341 | ||
1281 | int mthca_MAP_ICM_page(struct mthca_dev *dev, u64 dma_addr, u64 virt, u8 *status) | 1342 | int mthca_MAP_ICM_page(struct mthca_dev *dev, u64 dma_addr, u64 virt, u8 *status) |
1282 | { | 1343 | { |
1344 | struct mthca_mailbox *mailbox; | ||
1283 | u64 *inbox; | 1345 | u64 *inbox; |
1284 | dma_addr_t indma; | ||
1285 | int err; | 1346 | int err; |
1286 | 1347 | ||
1287 | inbox = pci_alloc_consistent(dev->pdev, 16, &indma); | 1348 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); |
1288 | if (!inbox) | 1349 | if (IS_ERR(mailbox)) |
1289 | return -ENOMEM; | 1350 | return PTR_ERR(mailbox); |
1351 | inbox = mailbox->buf; | ||
1290 | 1352 | ||
1291 | inbox[0] = cpu_to_be64(virt); | 1353 | inbox[0] = cpu_to_be64(virt); |
1292 | inbox[1] = cpu_to_be64(dma_addr); | 1354 | inbox[1] = cpu_to_be64(dma_addr); |
1293 | 1355 | ||
1294 | err = mthca_cmd(dev, indma, 1, 0, CMD_MAP_ICM, CMD_TIME_CLASS_B, status); | 1356 | err = mthca_cmd(dev, mailbox->dma, 1, 0, CMD_MAP_ICM, |
1357 | CMD_TIME_CLASS_B, status); | ||
1295 | 1358 | ||
1296 | pci_free_consistent(dev->pdev, 16, inbox, indma); | 1359 | mthca_free_mailbox(dev, mailbox); |
1297 | 1360 | ||
1298 | if (!err) | 1361 | if (!err) |
1299 | mthca_dbg(dev, "Mapped page at %llx to %llx for ICM.\n", | 1362 | mthca_dbg(dev, "Mapped page at %llx to %llx for ICM.\n", |
@@ -1338,69 +1401,26 @@ int mthca_SET_ICM_SIZE(struct mthca_dev *dev, u64 icm_size, u64 *aux_pages, | |||
1338 | return 0; | 1401 | return 0; |
1339 | } | 1402 | } |
1340 | 1403 | ||
1341 | int mthca_SW2HW_MPT(struct mthca_dev *dev, void *mpt_entry, | 1404 | int mthca_SW2HW_MPT(struct mthca_dev *dev, struct mthca_mailbox *mailbox, |
1342 | int mpt_index, u8 *status) | 1405 | int mpt_index, u8 *status) |
1343 | { | 1406 | { |
1344 | dma_addr_t indma; | 1407 | return mthca_cmd(dev, mailbox->dma, mpt_index, 0, CMD_SW2HW_MPT, |
1345 | int err; | 1408 | CMD_TIME_CLASS_B, status); |
1346 | |||
1347 | indma = pci_map_single(dev->pdev, mpt_entry, | ||
1348 | MTHCA_MPT_ENTRY_SIZE, | ||
1349 | PCI_DMA_TODEVICE); | ||
1350 | if (pci_dma_mapping_error(indma)) | ||
1351 | return -ENOMEM; | ||
1352 | |||
1353 | err = mthca_cmd(dev, indma, mpt_index, 0, CMD_SW2HW_MPT, | ||
1354 | CMD_TIME_CLASS_B, status); | ||
1355 | |||
1356 | pci_unmap_single(dev->pdev, indma, | ||
1357 | MTHCA_MPT_ENTRY_SIZE, PCI_DMA_TODEVICE); | ||
1358 | return err; | ||
1359 | } | 1409 | } |
1360 | 1410 | ||
1361 | int mthca_HW2SW_MPT(struct mthca_dev *dev, void *mpt_entry, | 1411 | int mthca_HW2SW_MPT(struct mthca_dev *dev, struct mthca_mailbox *mailbox, |
1362 | int mpt_index, u8 *status) | 1412 | int mpt_index, u8 *status) |
1363 | { | 1413 | { |
1364 | dma_addr_t outdma = 0; | 1414 | return mthca_cmd_box(dev, 0, mailbox ? mailbox->dma : 0, mpt_index, |
1365 | int err; | 1415 | !mailbox, CMD_HW2SW_MPT, |
1366 | 1416 | CMD_TIME_CLASS_B, status); | |
1367 | if (mpt_entry) { | ||
1368 | outdma = pci_map_single(dev->pdev, mpt_entry, | ||
1369 | MTHCA_MPT_ENTRY_SIZE, | ||
1370 | PCI_DMA_FROMDEVICE); | ||
1371 | if (pci_dma_mapping_error(outdma)) | ||
1372 | return -ENOMEM; | ||
1373 | } | ||
1374 | |||
1375 | err = mthca_cmd_box(dev, 0, outdma, mpt_index, !mpt_entry, | ||
1376 | CMD_HW2SW_MPT, | ||
1377 | CMD_TIME_CLASS_B, status); | ||
1378 | |||
1379 | if (mpt_entry) | ||
1380 | pci_unmap_single(dev->pdev, outdma, | ||
1381 | MTHCA_MPT_ENTRY_SIZE, | ||
1382 | PCI_DMA_FROMDEVICE); | ||
1383 | return err; | ||
1384 | } | 1417 | } |
1385 | 1418 | ||
1386 | int mthca_WRITE_MTT(struct mthca_dev *dev, u64 *mtt_entry, | 1419 | int mthca_WRITE_MTT(struct mthca_dev *dev, struct mthca_mailbox *mailbox, |
1387 | int num_mtt, u8 *status) | 1420 | int num_mtt, u8 *status) |
1388 | { | 1421 | { |
1389 | dma_addr_t indma; | 1422 | return mthca_cmd(dev, mailbox->dma, num_mtt, 0, CMD_WRITE_MTT, |
1390 | int err; | 1423 | CMD_TIME_CLASS_B, status); |
1391 | |||
1392 | indma = pci_map_single(dev->pdev, mtt_entry, | ||
1393 | (num_mtt + 2) * 8, | ||
1394 | PCI_DMA_TODEVICE); | ||
1395 | if (pci_dma_mapping_error(indma)) | ||
1396 | return -ENOMEM; | ||
1397 | |||
1398 | err = mthca_cmd(dev, indma, num_mtt, 0, CMD_WRITE_MTT, | ||
1399 | CMD_TIME_CLASS_B, status); | ||
1400 | |||
1401 | pci_unmap_single(dev->pdev, indma, | ||
1402 | (num_mtt + 2) * 8, PCI_DMA_TODEVICE); | ||
1403 | return err; | ||
1404 | } | 1424 | } |
1405 | 1425 | ||
1406 | int mthca_SYNC_TPT(struct mthca_dev *dev, u8 *status) | 1426 | int mthca_SYNC_TPT(struct mthca_dev *dev, u8 *status) |
@@ -1418,92 +1438,38 @@ int mthca_MAP_EQ(struct mthca_dev *dev, u64 event_mask, int unmap, | |||
1418 | 0, CMD_MAP_EQ, CMD_TIME_CLASS_B, status); | 1438 | 0, CMD_MAP_EQ, CMD_TIME_CLASS_B, status); |
1419 | } | 1439 | } |
1420 | 1440 | ||
1421 | int mthca_SW2HW_EQ(struct mthca_dev *dev, void *eq_context, | 1441 | int mthca_SW2HW_EQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox, |
1422 | int eq_num, u8 *status) | 1442 | int eq_num, u8 *status) |
1423 | { | 1443 | { |
1424 | dma_addr_t indma; | 1444 | return mthca_cmd(dev, mailbox->dma, eq_num, 0, CMD_SW2HW_EQ, |
1425 | int err; | 1445 | CMD_TIME_CLASS_A, status); |
1426 | |||
1427 | indma = pci_map_single(dev->pdev, eq_context, | ||
1428 | MTHCA_EQ_CONTEXT_SIZE, | ||
1429 | PCI_DMA_TODEVICE); | ||
1430 | if (pci_dma_mapping_error(indma)) | ||
1431 | return -ENOMEM; | ||
1432 | |||
1433 | err = mthca_cmd(dev, indma, eq_num, 0, CMD_SW2HW_EQ, | ||
1434 | CMD_TIME_CLASS_A, status); | ||
1435 | |||
1436 | pci_unmap_single(dev->pdev, indma, | ||
1437 | MTHCA_EQ_CONTEXT_SIZE, PCI_DMA_TODEVICE); | ||
1438 | return err; | ||
1439 | } | 1446 | } |
1440 | 1447 | ||
1441 | int mthca_HW2SW_EQ(struct mthca_dev *dev, void *eq_context, | 1448 | int mthca_HW2SW_EQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox, |
1442 | int eq_num, u8 *status) | 1449 | int eq_num, u8 *status) |
1443 | { | 1450 | { |
1444 | dma_addr_t outdma = 0; | 1451 | return mthca_cmd_box(dev, 0, mailbox->dma, eq_num, 0, |
1445 | int err; | 1452 | CMD_HW2SW_EQ, |
1446 | 1453 | CMD_TIME_CLASS_A, status); | |
1447 | outdma = pci_map_single(dev->pdev, eq_context, | ||
1448 | MTHCA_EQ_CONTEXT_SIZE, | ||
1449 | PCI_DMA_FROMDEVICE); | ||
1450 | if (pci_dma_mapping_error(outdma)) | ||
1451 | return -ENOMEM; | ||
1452 | |||
1453 | err = mthca_cmd_box(dev, 0, outdma, eq_num, 0, | ||
1454 | CMD_HW2SW_EQ, | ||
1455 | CMD_TIME_CLASS_A, status); | ||
1456 | |||
1457 | pci_unmap_single(dev->pdev, outdma, | ||
1458 | MTHCA_EQ_CONTEXT_SIZE, | ||
1459 | PCI_DMA_FROMDEVICE); | ||
1460 | return err; | ||
1461 | } | 1454 | } |
1462 | 1455 | ||
1463 | int mthca_SW2HW_CQ(struct mthca_dev *dev, void *cq_context, | 1456 | int mthca_SW2HW_CQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox, |
1464 | int cq_num, u8 *status) | 1457 | int cq_num, u8 *status) |
1465 | { | 1458 | { |
1466 | dma_addr_t indma; | 1459 | return mthca_cmd(dev, mailbox->dma, cq_num, 0, CMD_SW2HW_CQ, |
1467 | int err; | ||
1468 | |||
1469 | indma = pci_map_single(dev->pdev, cq_context, | ||
1470 | MTHCA_CQ_CONTEXT_SIZE, | ||
1471 | PCI_DMA_TODEVICE); | ||
1472 | if (pci_dma_mapping_error(indma)) | ||
1473 | return -ENOMEM; | ||
1474 | |||
1475 | err = mthca_cmd(dev, indma, cq_num, 0, CMD_SW2HW_CQ, | ||
1476 | CMD_TIME_CLASS_A, status); | 1460 | CMD_TIME_CLASS_A, status); |
1477 | |||
1478 | pci_unmap_single(dev->pdev, indma, | ||
1479 | MTHCA_CQ_CONTEXT_SIZE, PCI_DMA_TODEVICE); | ||
1480 | return err; | ||
1481 | } | 1461 | } |
1482 | 1462 | ||
1483 | int mthca_HW2SW_CQ(struct mthca_dev *dev, void *cq_context, | 1463 | int mthca_HW2SW_CQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox, |
1484 | int cq_num, u8 *status) | 1464 | int cq_num, u8 *status) |
1485 | { | 1465 | { |
1486 | dma_addr_t outdma = 0; | 1466 | return mthca_cmd_box(dev, 0, mailbox->dma, cq_num, 0, |
1487 | int err; | 1467 | CMD_HW2SW_CQ, |
1488 | 1468 | CMD_TIME_CLASS_A, status); | |
1489 | outdma = pci_map_single(dev->pdev, cq_context, | ||
1490 | MTHCA_CQ_CONTEXT_SIZE, | ||
1491 | PCI_DMA_FROMDEVICE); | ||
1492 | if (pci_dma_mapping_error(outdma)) | ||
1493 | return -ENOMEM; | ||
1494 | |||
1495 | err = mthca_cmd_box(dev, 0, outdma, cq_num, 0, | ||
1496 | CMD_HW2SW_CQ, | ||
1497 | CMD_TIME_CLASS_A, status); | ||
1498 | |||
1499 | pci_unmap_single(dev->pdev, outdma, | ||
1500 | MTHCA_CQ_CONTEXT_SIZE, | ||
1501 | PCI_DMA_FROMDEVICE); | ||
1502 | return err; | ||
1503 | } | 1469 | } |
1504 | 1470 | ||
1505 | int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num, | 1471 | int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num, |
1506 | int is_ee, void *qp_context, u32 optmask, | 1472 | int is_ee, struct mthca_mailbox *mailbox, u32 optmask, |
1507 | u8 *status) | 1473 | u8 *status) |
1508 | { | 1474 | { |
1509 | static const u16 op[] = { | 1475 | static const u16 op[] = { |
@@ -1520,36 +1486,34 @@ int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num, | |||
1520 | [MTHCA_TRANS_ANY2RST] = CMD_ERR2RST_QPEE | 1486 | [MTHCA_TRANS_ANY2RST] = CMD_ERR2RST_QPEE |
1521 | }; | 1487 | }; |
1522 | u8 op_mod = 0; | 1488 | u8 op_mod = 0; |
1523 | 1489 | int my_mailbox = 0; | |
1524 | dma_addr_t indma; | ||
1525 | int err; | 1490 | int err; |
1526 | 1491 | ||
1527 | if (trans < 0 || trans >= ARRAY_SIZE(op)) | 1492 | if (trans < 0 || trans >= ARRAY_SIZE(op)) |
1528 | return -EINVAL; | 1493 | return -EINVAL; |
1529 | 1494 | ||
1530 | if (trans == MTHCA_TRANS_ANY2RST) { | 1495 | if (trans == MTHCA_TRANS_ANY2RST) { |
1531 | indma = 0; | ||
1532 | op_mod = 3; /* don't write outbox, any->reset */ | 1496 | op_mod = 3; /* don't write outbox, any->reset */ |
1533 | 1497 | ||
1534 | /* For debugging */ | 1498 | /* For debugging */ |
1535 | qp_context = pci_alloc_consistent(dev->pdev, MTHCA_QP_CONTEXT_SIZE, | 1499 | if (!mailbox) { |
1536 | &indma); | 1500 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); |
1537 | op_mod = 2; /* write outbox, any->reset */ | 1501 | if (!IS_ERR(mailbox)) { |
1502 | my_mailbox = 1; | ||
1503 | op_mod = 2; /* write outbox, any->reset */ | ||
1504 | } else | ||
1505 | mailbox = NULL; | ||
1506 | } | ||
1538 | } else { | 1507 | } else { |
1539 | indma = pci_map_single(dev->pdev, qp_context, | ||
1540 | MTHCA_QP_CONTEXT_SIZE, | ||
1541 | PCI_DMA_TODEVICE); | ||
1542 | if (pci_dma_mapping_error(indma)) | ||
1543 | return -ENOMEM; | ||
1544 | |||
1545 | if (0) { | 1508 | if (0) { |
1546 | int i; | 1509 | int i; |
1547 | mthca_dbg(dev, "Dumping QP context:\n"); | 1510 | mthca_dbg(dev, "Dumping QP context:\n"); |
1548 | printk(" opt param mask: %08x\n", be32_to_cpup(qp_context)); | 1511 | printk(" opt param mask: %08x\n", be32_to_cpup(mailbox->buf)); |
1549 | for (i = 0; i < 0x100 / 4; ++i) { | 1512 | for (i = 0; i < 0x100 / 4; ++i) { |
1550 | if (i % 8 == 0) | 1513 | if (i % 8 == 0) |
1551 | printk(" [%02x] ", i * 4); | 1514 | printk(" [%02x] ", i * 4); |
1552 | printk(" %08x", be32_to_cpu(((u32 *) qp_context)[i + 2])); | 1515 | printk(" %08x", |
1516 | be32_to_cpu(((u32 *) mailbox->buf)[i + 2])); | ||
1553 | if ((i + 1) % 8 == 0) | 1517 | if ((i + 1) % 8 == 0) |
1554 | printk("\n"); | 1518 | printk("\n"); |
1555 | } | 1519 | } |
@@ -1557,55 +1521,39 @@ int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num, | |||
1557 | } | 1521 | } |
1558 | 1522 | ||
1559 | if (trans == MTHCA_TRANS_ANY2RST) { | 1523 | if (trans == MTHCA_TRANS_ANY2RST) { |
1560 | err = mthca_cmd_box(dev, 0, indma, (!!is_ee << 24) | num, | 1524 | err = mthca_cmd_box(dev, 0, mailbox ? mailbox->dma : 0, |
1561 | op_mod, op[trans], CMD_TIME_CLASS_C, status); | 1525 | (!!is_ee << 24) | num, op_mod, |
1526 | op[trans], CMD_TIME_CLASS_C, status); | ||
1562 | 1527 | ||
1563 | if (0) { | 1528 | if (0 && mailbox) { |
1564 | int i; | 1529 | int i; |
1565 | mthca_dbg(dev, "Dumping QP context:\n"); | 1530 | mthca_dbg(dev, "Dumping QP context:\n"); |
1566 | printk(" %08x\n", be32_to_cpup(qp_context)); | 1531 | printk(" %08x\n", be32_to_cpup(mailbox->buf)); |
1567 | for (i = 0; i < 0x100 / 4; ++i) { | 1532 | for (i = 0; i < 0x100 / 4; ++i) { |
1568 | if (i % 8 == 0) | 1533 | if (i % 8 == 0) |
1569 | printk("[%02x] ", i * 4); | 1534 | printk("[%02x] ", i * 4); |
1570 | printk(" %08x", be32_to_cpu(((u32 *) qp_context)[i + 2])); | 1535 | printk(" %08x", |
1536 | be32_to_cpu(((u32 *) mailbox->buf)[i + 2])); | ||
1571 | if ((i + 1) % 8 == 0) | 1537 | if ((i + 1) % 8 == 0) |
1572 | printk("\n"); | 1538 | printk("\n"); |
1573 | } | 1539 | } |
1574 | } | 1540 | } |
1575 | 1541 | ||
1576 | } else | 1542 | } else |
1577 | err = mthca_cmd(dev, indma, (!!is_ee << 24) | num, | 1543 | err = mthca_cmd(dev, mailbox->dma, (!!is_ee << 24) | num, |
1578 | op_mod, op[trans], CMD_TIME_CLASS_C, status); | 1544 | op_mod, op[trans], CMD_TIME_CLASS_C, status); |
1579 | 1545 | ||
1580 | if (trans != MTHCA_TRANS_ANY2RST) | 1546 | if (my_mailbox) |
1581 | pci_unmap_single(dev->pdev, indma, | 1547 | mthca_free_mailbox(dev, mailbox); |
1582 | MTHCA_QP_CONTEXT_SIZE, PCI_DMA_TODEVICE); | 1548 | |
1583 | else | ||
1584 | pci_free_consistent(dev->pdev, MTHCA_QP_CONTEXT_SIZE, | ||
1585 | qp_context, indma); | ||
1586 | return err; | 1549 | return err; |
1587 | } | 1550 | } |
1588 | 1551 | ||
1589 | int mthca_QUERY_QP(struct mthca_dev *dev, u32 num, int is_ee, | 1552 | int mthca_QUERY_QP(struct mthca_dev *dev, u32 num, int is_ee, |
1590 | void *qp_context, u8 *status) | 1553 | struct mthca_mailbox *mailbox, u8 *status) |
1591 | { | 1554 | { |
1592 | dma_addr_t outdma = 0; | 1555 | return mthca_cmd_box(dev, 0, mailbox->dma, (!!is_ee << 24) | num, 0, |
1593 | int err; | 1556 | CMD_QUERY_QPEE, CMD_TIME_CLASS_A, status); |
1594 | |||
1595 | outdma = pci_map_single(dev->pdev, qp_context, | ||
1596 | MTHCA_QP_CONTEXT_SIZE, | ||
1597 | PCI_DMA_FROMDEVICE); | ||
1598 | if (pci_dma_mapping_error(outdma)) | ||
1599 | return -ENOMEM; | ||
1600 | |||
1601 | err = mthca_cmd_box(dev, 0, outdma, (!!is_ee << 24) | num, 0, | ||
1602 | CMD_QUERY_QPEE, | ||
1603 | CMD_TIME_CLASS_A, status); | ||
1604 | |||
1605 | pci_unmap_single(dev->pdev, outdma, | ||
1606 | MTHCA_QP_CONTEXT_SIZE, | ||
1607 | PCI_DMA_FROMDEVICE); | ||
1608 | return err; | ||
1609 | } | 1557 | } |
1610 | 1558 | ||
1611 | int mthca_CONF_SPECIAL_QP(struct mthca_dev *dev, int type, u32 qpn, | 1559 | int mthca_CONF_SPECIAL_QP(struct mthca_dev *dev, int type, u32 qpn, |
@@ -1635,11 +1583,11 @@ int mthca_CONF_SPECIAL_QP(struct mthca_dev *dev, int type, u32 qpn, | |||
1635 | } | 1583 | } |
1636 | 1584 | ||
1637 | int mthca_MAD_IFC(struct mthca_dev *dev, int ignore_mkey, int ignore_bkey, | 1585 | int mthca_MAD_IFC(struct mthca_dev *dev, int ignore_mkey, int ignore_bkey, |
1638 | int port, struct ib_wc* in_wc, struct ib_grh* in_grh, | 1586 | int port, struct ib_wc *in_wc, struct ib_grh *in_grh, |
1639 | void *in_mad, void *response_mad, u8 *status) | 1587 | void *in_mad, void *response_mad, u8 *status) |
1640 | { | 1588 | { |
1641 | void *box; | 1589 | struct mthca_mailbox *inmailbox, *outmailbox; |
1642 | dma_addr_t dma; | 1590 | void *inbox; |
1643 | int err; | 1591 | int err; |
1644 | u32 in_modifier = port; | 1592 | u32 in_modifier = port; |
1645 | u8 op_modifier = 0; | 1593 | u8 op_modifier = 0; |
@@ -1653,11 +1601,18 @@ int mthca_MAD_IFC(struct mthca_dev *dev, int ignore_mkey, int ignore_bkey, | |||
1653 | #define MAD_IFC_PKEY_OFFSET 0x10e | 1601 | #define MAD_IFC_PKEY_OFFSET 0x10e |
1654 | #define MAD_IFC_GRH_OFFSET 0x140 | 1602 | #define MAD_IFC_GRH_OFFSET 0x140 |
1655 | 1603 | ||
1656 | box = pci_alloc_consistent(dev->pdev, MAD_IFC_BOX_SIZE, &dma); | 1604 | inmailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); |
1657 | if (!box) | 1605 | if (IS_ERR(inmailbox)) |
1658 | return -ENOMEM; | 1606 | return PTR_ERR(inmailbox); |
1607 | inbox = inmailbox->buf; | ||
1659 | 1608 | ||
1660 | memcpy(box, in_mad, 256); | 1609 | outmailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); |
1610 | if (IS_ERR(outmailbox)) { | ||
1611 | mthca_free_mailbox(dev, inmailbox); | ||
1612 | return PTR_ERR(outmailbox); | ||
1613 | } | ||
1614 | |||
1615 | memcpy(inbox, in_mad, 256); | ||
1661 | 1616 | ||
1662 | /* | 1617 | /* |
1663 | * Key check traps can't be generated unless we have in_wc to | 1618 | * Key check traps can't be generated unless we have in_wc to |
@@ -1671,97 +1626,65 @@ int mthca_MAD_IFC(struct mthca_dev *dev, int ignore_mkey, int ignore_bkey, | |||
1671 | if (in_wc) { | 1626 | if (in_wc) { |
1672 | u8 val; | 1627 | u8 val; |
1673 | 1628 | ||
1674 | memset(box + 256, 0, 256); | 1629 | memset(inbox + 256, 0, 256); |
1675 | 1630 | ||
1676 | MTHCA_PUT(box, in_wc->qp_num, MAD_IFC_MY_QPN_OFFSET); | 1631 | MTHCA_PUT(inbox, in_wc->qp_num, MAD_IFC_MY_QPN_OFFSET); |
1677 | MTHCA_PUT(box, in_wc->src_qp, MAD_IFC_RQPN_OFFSET); | 1632 | MTHCA_PUT(inbox, in_wc->src_qp, MAD_IFC_RQPN_OFFSET); |
1678 | 1633 | ||
1679 | val = in_wc->sl << 4; | 1634 | val = in_wc->sl << 4; |
1680 | MTHCA_PUT(box, val, MAD_IFC_SL_OFFSET); | 1635 | MTHCA_PUT(inbox, val, MAD_IFC_SL_OFFSET); |
1681 | 1636 | ||
1682 | val = in_wc->dlid_path_bits | | 1637 | val = in_wc->dlid_path_bits | |
1683 | (in_wc->wc_flags & IB_WC_GRH ? 0x80 : 0); | 1638 | (in_wc->wc_flags & IB_WC_GRH ? 0x80 : 0); |
1684 | MTHCA_PUT(box, val, MAD_IFC_GRH_OFFSET); | 1639 | MTHCA_PUT(inbox, val, MAD_IFC_GRH_OFFSET); |
1685 | 1640 | ||
1686 | MTHCA_PUT(box, in_wc->slid, MAD_IFC_RLID_OFFSET); | 1641 | MTHCA_PUT(inbox, in_wc->slid, MAD_IFC_RLID_OFFSET); |
1687 | MTHCA_PUT(box, in_wc->pkey_index, MAD_IFC_PKEY_OFFSET); | 1642 | MTHCA_PUT(inbox, in_wc->pkey_index, MAD_IFC_PKEY_OFFSET); |
1688 | 1643 | ||
1689 | if (in_grh) | 1644 | if (in_grh) |
1690 | memcpy((u8 *) box + MAD_IFC_GRH_OFFSET, in_grh, 40); | 1645 | memcpy(inbox + MAD_IFC_GRH_OFFSET, in_grh, 40); |
1691 | 1646 | ||
1692 | op_modifier |= 0x10; | 1647 | op_modifier |= 0x10; |
1693 | 1648 | ||
1694 | in_modifier |= in_wc->slid << 16; | 1649 | in_modifier |= in_wc->slid << 16; |
1695 | } | 1650 | } |
1696 | 1651 | ||
1697 | err = mthca_cmd_box(dev, dma, dma + 512, in_modifier, op_modifier, | 1652 | err = mthca_cmd_box(dev, inmailbox->dma, outmailbox->dma, |
1653 | in_modifier, op_modifier, | ||
1698 | CMD_MAD_IFC, CMD_TIME_CLASS_C, status); | 1654 | CMD_MAD_IFC, CMD_TIME_CLASS_C, status); |
1699 | 1655 | ||
1700 | if (!err && !*status) | 1656 | if (!err && !*status) |
1701 | memcpy(response_mad, box + 512, 256); | 1657 | memcpy(response_mad, outmailbox->buf, 256); |
1702 | 1658 | ||
1703 | pci_free_consistent(dev->pdev, MAD_IFC_BOX_SIZE, box, dma); | 1659 | mthca_free_mailbox(dev, inmailbox); |
1660 | mthca_free_mailbox(dev, outmailbox); | ||
1704 | return err; | 1661 | return err; |
1705 | } | 1662 | } |
1706 | 1663 | ||
1707 | int mthca_READ_MGM(struct mthca_dev *dev, int index, void *mgm, | 1664 | int mthca_READ_MGM(struct mthca_dev *dev, int index, |
1708 | u8 *status) | 1665 | struct mthca_mailbox *mailbox, u8 *status) |
1709 | { | 1666 | { |
1710 | dma_addr_t outdma = 0; | 1667 | return mthca_cmd_box(dev, 0, mailbox->dma, index, 0, |
1711 | int err; | 1668 | CMD_READ_MGM, CMD_TIME_CLASS_A, status); |
1712 | |||
1713 | outdma = pci_map_single(dev->pdev, mgm, | ||
1714 | MTHCA_MGM_ENTRY_SIZE, | ||
1715 | PCI_DMA_FROMDEVICE); | ||
1716 | if (pci_dma_mapping_error(outdma)) | ||
1717 | return -ENOMEM; | ||
1718 | |||
1719 | err = mthca_cmd_box(dev, 0, outdma, index, 0, | ||
1720 | CMD_READ_MGM, | ||
1721 | CMD_TIME_CLASS_A, status); | ||
1722 | |||
1723 | pci_unmap_single(dev->pdev, outdma, | ||
1724 | MTHCA_MGM_ENTRY_SIZE, | ||
1725 | PCI_DMA_FROMDEVICE); | ||
1726 | return err; | ||
1727 | } | 1669 | } |
1728 | 1670 | ||
1729 | int mthca_WRITE_MGM(struct mthca_dev *dev, int index, void *mgm, | 1671 | int mthca_WRITE_MGM(struct mthca_dev *dev, int index, |
1730 | u8 *status) | 1672 | struct mthca_mailbox *mailbox, u8 *status) |
1731 | { | 1673 | { |
1732 | dma_addr_t indma; | 1674 | return mthca_cmd(dev, mailbox->dma, index, 0, CMD_WRITE_MGM, |
1733 | int err; | 1675 | CMD_TIME_CLASS_A, status); |
1734 | |||
1735 | indma = pci_map_single(dev->pdev, mgm, | ||
1736 | MTHCA_MGM_ENTRY_SIZE, | ||
1737 | PCI_DMA_TODEVICE); | ||
1738 | if (pci_dma_mapping_error(indma)) | ||
1739 | return -ENOMEM; | ||
1740 | |||
1741 | err = mthca_cmd(dev, indma, index, 0, CMD_WRITE_MGM, | ||
1742 | CMD_TIME_CLASS_A, status); | ||
1743 | |||
1744 | pci_unmap_single(dev->pdev, indma, | ||
1745 | MTHCA_MGM_ENTRY_SIZE, PCI_DMA_TODEVICE); | ||
1746 | return err; | ||
1747 | } | 1676 | } |
1748 | 1677 | ||
1749 | int mthca_MGID_HASH(struct mthca_dev *dev, void *gid, u16 *hash, | 1678 | int mthca_MGID_HASH(struct mthca_dev *dev, struct mthca_mailbox *mailbox, |
1750 | u8 *status) | 1679 | u16 *hash, u8 *status) |
1751 | { | 1680 | { |
1752 | dma_addr_t indma; | ||
1753 | u64 imm; | 1681 | u64 imm; |
1754 | int err; | 1682 | int err; |
1755 | 1683 | ||
1756 | indma = pci_map_single(dev->pdev, gid, 16, PCI_DMA_TODEVICE); | 1684 | err = mthca_cmd_imm(dev, mailbox->dma, &imm, 0, 0, CMD_MGID_HASH, |
1757 | if (pci_dma_mapping_error(indma)) | ||
1758 | return -ENOMEM; | ||
1759 | |||
1760 | err = mthca_cmd_imm(dev, indma, &imm, 0, 0, CMD_MGID_HASH, | ||
1761 | CMD_TIME_CLASS_A, status); | 1685 | CMD_TIME_CLASS_A, status); |
1762 | *hash = imm; | ||
1763 | 1686 | ||
1764 | pci_unmap_single(dev->pdev, indma, 16, PCI_DMA_TODEVICE); | 1687 | *hash = imm; |
1765 | return err; | 1688 | return err; |
1766 | } | 1689 | } |
1767 | 1690 | ||
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.h b/drivers/infiniband/hw/mthca/mthca_cmd.h index adf039b3c540..ed517f175dd6 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.h +++ b/drivers/infiniband/hw/mthca/mthca_cmd.h | |||
@@ -37,8 +37,7 @@ | |||
37 | 37 | ||
38 | #include <ib_verbs.h> | 38 | #include <ib_verbs.h> |
39 | 39 | ||
40 | #define MTHCA_CMD_MAILBOX_ALIGN 16UL | 40 | #define MTHCA_MAILBOX_SIZE 4096 |
41 | #define MTHCA_CMD_MAILBOX_EXTRA (MTHCA_CMD_MAILBOX_ALIGN - 1) | ||
42 | 41 | ||
43 | enum { | 42 | enum { |
44 | /* command completed successfully: */ | 43 | /* command completed successfully: */ |
@@ -112,6 +111,11 @@ enum { | |||
112 | DEV_LIM_FLAG_UD_MULTI = 1 << 21, | 111 | DEV_LIM_FLAG_UD_MULTI = 1 << 21, |
113 | }; | 112 | }; |
114 | 113 | ||
114 | struct mthca_mailbox { | ||
115 | dma_addr_t dma; | ||
116 | void *buf; | ||
117 | }; | ||
118 | |||
115 | struct mthca_dev_lim { | 119 | struct mthca_dev_lim { |
116 | int max_srq_sz; | 120 | int max_srq_sz; |
117 | int max_qp_sz; | 121 | int max_qp_sz; |
@@ -235,11 +239,17 @@ struct mthca_set_ib_param { | |||
235 | u32 cap_mask; | 239 | u32 cap_mask; |
236 | }; | 240 | }; |
237 | 241 | ||
242 | int mthca_cmd_init(struct mthca_dev *dev); | ||
243 | void mthca_cmd_cleanup(struct mthca_dev *dev); | ||
238 | int mthca_cmd_use_events(struct mthca_dev *dev); | 244 | int mthca_cmd_use_events(struct mthca_dev *dev); |
239 | void mthca_cmd_use_polling(struct mthca_dev *dev); | 245 | void mthca_cmd_use_polling(struct mthca_dev *dev); |
240 | void mthca_cmd_event(struct mthca_dev *dev, u16 token, | 246 | void mthca_cmd_event(struct mthca_dev *dev, u16 token, |
241 | u8 status, u64 out_param); | 247 | u8 status, u64 out_param); |
242 | 248 | ||
249 | struct mthca_mailbox *mthca_alloc_mailbox(struct mthca_dev *dev, | ||
250 | unsigned int gfp_mask); | ||
251 | void mthca_free_mailbox(struct mthca_dev *dev, struct mthca_mailbox *mailbox); | ||
252 | |||
243 | int mthca_SYS_EN(struct mthca_dev *dev, u8 *status); | 253 | int mthca_SYS_EN(struct mthca_dev *dev, u8 *status); |
244 | int mthca_SYS_DIS(struct mthca_dev *dev, u8 *status); | 254 | int mthca_SYS_DIS(struct mthca_dev *dev, u8 *status); |
245 | int mthca_MAP_FA(struct mthca_dev *dev, struct mthca_icm *icm, u8 *status); | 255 | int mthca_MAP_FA(struct mthca_dev *dev, struct mthca_icm *icm, u8 *status); |
@@ -270,41 +280,39 @@ int mthca_MAP_ICM_AUX(struct mthca_dev *dev, struct mthca_icm *icm, u8 *status); | |||
270 | int mthca_UNMAP_ICM_AUX(struct mthca_dev *dev, u8 *status); | 280 | int mthca_UNMAP_ICM_AUX(struct mthca_dev *dev, u8 *status); |
271 | int mthca_SET_ICM_SIZE(struct mthca_dev *dev, u64 icm_size, u64 *aux_pages, | 281 | int mthca_SET_ICM_SIZE(struct mthca_dev *dev, u64 icm_size, u64 *aux_pages, |
272 | u8 *status); | 282 | u8 *status); |
273 | int mthca_SW2HW_MPT(struct mthca_dev *dev, void *mpt_entry, | 283 | int mthca_SW2HW_MPT(struct mthca_dev *dev, struct mthca_mailbox *mailbox, |
274 | int mpt_index, u8 *status); | 284 | int mpt_index, u8 *status); |
275 | int mthca_HW2SW_MPT(struct mthca_dev *dev, void *mpt_entry, | 285 | int mthca_HW2SW_MPT(struct mthca_dev *dev, struct mthca_mailbox *mailbox, |
276 | int mpt_index, u8 *status); | 286 | int mpt_index, u8 *status); |
277 | int mthca_WRITE_MTT(struct mthca_dev *dev, u64 *mtt_entry, | 287 | int mthca_WRITE_MTT(struct mthca_dev *dev, struct mthca_mailbox *mailbox, |
278 | int num_mtt, u8 *status); | 288 | int num_mtt, u8 *status); |
279 | int mthca_SYNC_TPT(struct mthca_dev *dev, u8 *status); | 289 | int mthca_SYNC_TPT(struct mthca_dev *dev, u8 *status); |
280 | int mthca_MAP_EQ(struct mthca_dev *dev, u64 event_mask, int unmap, | 290 | int mthca_MAP_EQ(struct mthca_dev *dev, u64 event_mask, int unmap, |
281 | int eq_num, u8 *status); | 291 | int eq_num, u8 *status); |
282 | int mthca_SW2HW_EQ(struct mthca_dev *dev, void *eq_context, | 292 | int mthca_SW2HW_EQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox, |
283 | int eq_num, u8 *status); | 293 | int eq_num, u8 *status); |
284 | int mthca_HW2SW_EQ(struct mthca_dev *dev, void *eq_context, | 294 | int mthca_HW2SW_EQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox, |
285 | int eq_num, u8 *status); | 295 | int eq_num, u8 *status); |
286 | int mthca_SW2HW_CQ(struct mthca_dev *dev, void *cq_context, | 296 | int mthca_SW2HW_CQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox, |
287 | int cq_num, u8 *status); | 297 | int cq_num, u8 *status); |
288 | int mthca_HW2SW_CQ(struct mthca_dev *dev, void *cq_context, | 298 | int mthca_HW2SW_CQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox, |
289 | int cq_num, u8 *status); | 299 | int cq_num, u8 *status); |
290 | int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num, | 300 | int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num, |
291 | int is_ee, void *qp_context, u32 optmask, | 301 | int is_ee, struct mthca_mailbox *mailbox, u32 optmask, |
292 | u8 *status); | 302 | u8 *status); |
293 | int mthca_QUERY_QP(struct mthca_dev *dev, u32 num, int is_ee, | 303 | int mthca_QUERY_QP(struct mthca_dev *dev, u32 num, int is_ee, |
294 | void *qp_context, u8 *status); | 304 | struct mthca_mailbox *mailbox, u8 *status); |
295 | int mthca_CONF_SPECIAL_QP(struct mthca_dev *dev, int type, u32 qpn, | 305 | int mthca_CONF_SPECIAL_QP(struct mthca_dev *dev, int type, u32 qpn, |
296 | u8 *status); | 306 | u8 *status); |
297 | int mthca_MAD_IFC(struct mthca_dev *dev, int ignore_mkey, int ignore_bkey, | 307 | int mthca_MAD_IFC(struct mthca_dev *dev, int ignore_mkey, int ignore_bkey, |
298 | int port, struct ib_wc* in_wc, struct ib_grh* in_grh, | 308 | int port, struct ib_wc *in_wc, struct ib_grh *in_grh, |
299 | void *in_mad, void *response_mad, u8 *status); | 309 | void *in_mad, void *response_mad, u8 *status); |
300 | int mthca_READ_MGM(struct mthca_dev *dev, int index, void *mgm, | 310 | int mthca_READ_MGM(struct mthca_dev *dev, int index, |
301 | u8 *status); | 311 | struct mthca_mailbox *mailbox, u8 *status); |
302 | int mthca_WRITE_MGM(struct mthca_dev *dev, int index, void *mgm, | 312 | int mthca_WRITE_MGM(struct mthca_dev *dev, int index, |
303 | u8 *status); | 313 | struct mthca_mailbox *mailbox, u8 *status); |
304 | int mthca_MGID_HASH(struct mthca_dev *dev, void *gid, u16 *hash, | 314 | int mthca_MGID_HASH(struct mthca_dev *dev, struct mthca_mailbox *mailbox, |
305 | u8 *status); | 315 | u16 *hash, u8 *status); |
306 | int mthca_NOP(struct mthca_dev *dev, u8 *status); | 316 | int mthca_NOP(struct mthca_dev *dev, u8 *status); |
307 | 317 | ||
308 | #define MAILBOX_ALIGN(x) ((void *) ALIGN((unsigned long) (x), MTHCA_CMD_MAILBOX_ALIGN)) | ||
309 | |||
310 | #endif /* MTHCA_CMD_H */ | 318 | #endif /* MTHCA_CMD_H */ |
diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c index 2bf347b84c31..766e9031ec45 100644 --- a/drivers/infiniband/hw/mthca/mthca_cq.c +++ b/drivers/infiniband/hw/mthca/mthca_cq.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. | 2 | * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. |
3 | * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. | ||
3 | * | 4 | * |
4 | * This software is available to you under a choice of one of two | 5 | * This software is available to you under a choice of one of two |
5 | * licenses. You may choose to be licensed under the terms of the GNU | 6 | * licenses. You may choose to be licensed under the terms of the GNU |
@@ -171,6 +172,17 @@ static inline void set_cqe_hw(struct mthca_cqe *cqe) | |||
171 | cqe->owner = MTHCA_CQ_ENTRY_OWNER_HW; | 172 | cqe->owner = MTHCA_CQ_ENTRY_OWNER_HW; |
172 | } | 173 | } |
173 | 174 | ||
175 | static void dump_cqe(struct mthca_dev *dev, void *cqe_ptr) | ||
176 | { | ||
177 | __be32 *cqe = cqe_ptr; | ||
178 | |||
179 | (void) cqe; /* avoid warning if mthca_dbg compiled away... */ | ||
180 | mthca_dbg(dev, "CQE contents %08x %08x %08x %08x %08x %08x %08x %08x\n", | ||
181 | be32_to_cpu(cqe[0]), be32_to_cpu(cqe[1]), be32_to_cpu(cqe[2]), | ||
182 | be32_to_cpu(cqe[3]), be32_to_cpu(cqe[4]), be32_to_cpu(cqe[5]), | ||
183 | be32_to_cpu(cqe[6]), be32_to_cpu(cqe[7])); | ||
184 | } | ||
185 | |||
174 | /* | 186 | /* |
175 | * incr is ignored in native Arbel (mem-free) mode, so cq->cons_index | 187 | * incr is ignored in native Arbel (mem-free) mode, so cq->cons_index |
176 | * should be correct before calling update_cons_index(). | 188 | * should be correct before calling update_cons_index(). |
@@ -280,16 +292,12 @@ static int handle_error_cqe(struct mthca_dev *dev, struct mthca_cq *cq, | |||
280 | int dbd; | 292 | int dbd; |
281 | u32 new_wqe; | 293 | u32 new_wqe; |
282 | 294 | ||
283 | if (1 && cqe->syndrome != SYNDROME_WR_FLUSH_ERR) { | 295 | if (cqe->syndrome == SYNDROME_LOCAL_QP_OP_ERR) { |
284 | int j; | 296 | mthca_dbg(dev, "local QP operation err " |
285 | 297 | "(QPN %06x, WQE @ %08x, CQN %06x, index %d)\n", | |
286 | mthca_dbg(dev, "%x/%d: error CQE -> QPN %06x, WQE @ %08x\n", | 298 | be32_to_cpu(cqe->my_qpn), be32_to_cpu(cqe->wqe), |
287 | cq->cqn, cq->cons_index, be32_to_cpu(cqe->my_qpn), | 299 | cq->cqn, cq->cons_index); |
288 | be32_to_cpu(cqe->wqe)); | 300 | dump_cqe(dev, cqe); |
289 | |||
290 | for (j = 0; j < 8; ++j) | ||
291 | printk(KERN_DEBUG " [%2x] %08x\n", | ||
292 | j * 4, be32_to_cpu(((u32 *) cqe)[j])); | ||
293 | } | 301 | } |
294 | 302 | ||
295 | /* | 303 | /* |
@@ -377,15 +385,6 @@ static int handle_error_cqe(struct mthca_dev *dev, struct mthca_cq *cq, | |||
377 | return 0; | 385 | return 0; |
378 | } | 386 | } |
379 | 387 | ||
380 | static void dump_cqe(struct mthca_cqe *cqe) | ||
381 | { | ||
382 | int j; | ||
383 | |||
384 | for (j = 0; j < 8; ++j) | ||
385 | printk(KERN_DEBUG " [%2x] %08x\n", | ||
386 | j * 4, be32_to_cpu(((u32 *) cqe)[j])); | ||
387 | } | ||
388 | |||
389 | static inline int mthca_poll_one(struct mthca_dev *dev, | 388 | static inline int mthca_poll_one(struct mthca_dev *dev, |
390 | struct mthca_cq *cq, | 389 | struct mthca_cq *cq, |
391 | struct mthca_qp **cur_qp, | 390 | struct mthca_qp **cur_qp, |
@@ -414,8 +413,7 @@ static inline int mthca_poll_one(struct mthca_dev *dev, | |||
414 | mthca_dbg(dev, "%x/%d: CQE -> QPN %06x, WQE @ %08x\n", | 413 | mthca_dbg(dev, "%x/%d: CQE -> QPN %06x, WQE @ %08x\n", |
415 | cq->cqn, cq->cons_index, be32_to_cpu(cqe->my_qpn), | 414 | cq->cqn, cq->cons_index, be32_to_cpu(cqe->my_qpn), |
416 | be32_to_cpu(cqe->wqe)); | 415 | be32_to_cpu(cqe->wqe)); |
417 | 416 | dump_cqe(dev, cqe); | |
418 | dump_cqe(cqe); | ||
419 | } | 417 | } |
420 | 418 | ||
421 | is_error = (cqe->opcode & MTHCA_ERROR_CQE_OPCODE_MASK) == | 419 | is_error = (cqe->opcode & MTHCA_ERROR_CQE_OPCODE_MASK) == |
@@ -638,19 +636,19 @@ static void mthca_free_cq_buf(struct mthca_dev *dev, struct mthca_cq *cq) | |||
638 | int size; | 636 | int size; |
639 | 637 | ||
640 | if (cq->is_direct) | 638 | if (cq->is_direct) |
641 | pci_free_consistent(dev->pdev, | 639 | dma_free_coherent(&dev->pdev->dev, |
642 | (cq->ibcq.cqe + 1) * MTHCA_CQ_ENTRY_SIZE, | 640 | (cq->ibcq.cqe + 1) * MTHCA_CQ_ENTRY_SIZE, |
643 | cq->queue.direct.buf, | 641 | cq->queue.direct.buf, |
644 | pci_unmap_addr(&cq->queue.direct, | 642 | pci_unmap_addr(&cq->queue.direct, |
645 | mapping)); | 643 | mapping)); |
646 | else { | 644 | else { |
647 | size = (cq->ibcq.cqe + 1) * MTHCA_CQ_ENTRY_SIZE; | 645 | size = (cq->ibcq.cqe + 1) * MTHCA_CQ_ENTRY_SIZE; |
648 | for (i = 0; i < (size + PAGE_SIZE - 1) / PAGE_SIZE; ++i) | 646 | for (i = 0; i < (size + PAGE_SIZE - 1) / PAGE_SIZE; ++i) |
649 | if (cq->queue.page_list[i].buf) | 647 | if (cq->queue.page_list[i].buf) |
650 | pci_free_consistent(dev->pdev, PAGE_SIZE, | 648 | dma_free_coherent(&dev->pdev->dev, PAGE_SIZE, |
651 | cq->queue.page_list[i].buf, | 649 | cq->queue.page_list[i].buf, |
652 | pci_unmap_addr(&cq->queue.page_list[i], | 650 | pci_unmap_addr(&cq->queue.page_list[i], |
653 | mapping)); | 651 | mapping)); |
654 | 652 | ||
655 | kfree(cq->queue.page_list); | 653 | kfree(cq->queue.page_list); |
656 | } | 654 | } |
@@ -670,8 +668,8 @@ static int mthca_alloc_cq_buf(struct mthca_dev *dev, int size, | |||
670 | npages = 1; | 668 | npages = 1; |
671 | shift = get_order(size) + PAGE_SHIFT; | 669 | shift = get_order(size) + PAGE_SHIFT; |
672 | 670 | ||
673 | cq->queue.direct.buf = pci_alloc_consistent(dev->pdev, | 671 | cq->queue.direct.buf = dma_alloc_coherent(&dev->pdev->dev, |
674 | size, &t); | 672 | size, &t, GFP_KERNEL); |
675 | if (!cq->queue.direct.buf) | 673 | if (!cq->queue.direct.buf) |
676 | return -ENOMEM; | 674 | return -ENOMEM; |
677 | 675 | ||
@@ -709,7 +707,8 @@ static int mthca_alloc_cq_buf(struct mthca_dev *dev, int size, | |||
709 | 707 | ||
710 | for (i = 0; i < npages; ++i) { | 708 | for (i = 0; i < npages; ++i) { |
711 | cq->queue.page_list[i].buf = | 709 | cq->queue.page_list[i].buf = |
712 | pci_alloc_consistent(dev->pdev, PAGE_SIZE, &t); | 710 | dma_alloc_coherent(&dev->pdev->dev, PAGE_SIZE, |
711 | &t, GFP_KERNEL); | ||
713 | if (!cq->queue.page_list[i].buf) | 712 | if (!cq->queue.page_list[i].buf) |
714 | goto err_free; | 713 | goto err_free; |
715 | 714 | ||
@@ -746,7 +745,7 @@ int mthca_init_cq(struct mthca_dev *dev, int nent, | |||
746 | struct mthca_cq *cq) | 745 | struct mthca_cq *cq) |
747 | { | 746 | { |
748 | int size = nent * MTHCA_CQ_ENTRY_SIZE; | 747 | int size = nent * MTHCA_CQ_ENTRY_SIZE; |
749 | void *mailbox = NULL; | 748 | struct mthca_mailbox *mailbox; |
750 | struct mthca_cq_context *cq_context; | 749 | struct mthca_cq_context *cq_context; |
751 | int err = -ENOMEM; | 750 | int err = -ENOMEM; |
752 | u8 status; | 751 | u8 status; |
@@ -780,12 +779,11 @@ int mthca_init_cq(struct mthca_dev *dev, int nent, | |||
780 | goto err_out_ci; | 779 | goto err_out_ci; |
781 | } | 780 | } |
782 | 781 | ||
783 | mailbox = kmalloc(sizeof (struct mthca_cq_context) + MTHCA_CMD_MAILBOX_EXTRA, | 782 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); |
784 | GFP_KERNEL); | 783 | if (IS_ERR(mailbox)) |
785 | if (!mailbox) | 784 | goto err_out_arm; |
786 | goto err_out_mailbox; | ||
787 | 785 | ||
788 | cq_context = MAILBOX_ALIGN(mailbox); | 786 | cq_context = mailbox->buf; |
789 | 787 | ||
790 | err = mthca_alloc_cq_buf(dev, size, cq); | 788 | err = mthca_alloc_cq_buf(dev, size, cq); |
791 | if (err) | 789 | if (err) |
@@ -816,7 +814,7 @@ int mthca_init_cq(struct mthca_dev *dev, int nent, | |||
816 | cq_context->state_db = cpu_to_be32(cq->arm_db_index); | 814 | cq_context->state_db = cpu_to_be32(cq->arm_db_index); |
817 | } | 815 | } |
818 | 816 | ||
819 | err = mthca_SW2HW_CQ(dev, cq_context, cq->cqn, &status); | 817 | err = mthca_SW2HW_CQ(dev, mailbox, cq->cqn, &status); |
820 | if (err) { | 818 | if (err) { |
821 | mthca_warn(dev, "SW2HW_CQ failed (%d)\n", err); | 819 | mthca_warn(dev, "SW2HW_CQ failed (%d)\n", err); |
822 | goto err_out_free_mr; | 820 | goto err_out_free_mr; |
@@ -840,7 +838,7 @@ int mthca_init_cq(struct mthca_dev *dev, int nent, | |||
840 | 838 | ||
841 | cq->cons_index = 0; | 839 | cq->cons_index = 0; |
842 | 840 | ||
843 | kfree(mailbox); | 841 | mthca_free_mailbox(dev, mailbox); |
844 | 842 | ||
845 | return 0; | 843 | return 0; |
846 | 844 | ||
@@ -849,8 +847,9 @@ err_out_free_mr: | |||
849 | mthca_free_cq_buf(dev, cq); | 847 | mthca_free_cq_buf(dev, cq); |
850 | 848 | ||
851 | err_out_mailbox: | 849 | err_out_mailbox: |
852 | kfree(mailbox); | 850 | mthca_free_mailbox(dev, mailbox); |
853 | 851 | ||
852 | err_out_arm: | ||
854 | if (mthca_is_memfree(dev)) | 853 | if (mthca_is_memfree(dev)) |
855 | mthca_free_db(dev, MTHCA_DB_TYPE_CQ_ARM, cq->arm_db_index); | 854 | mthca_free_db(dev, MTHCA_DB_TYPE_CQ_ARM, cq->arm_db_index); |
856 | 855 | ||
@@ -870,28 +869,26 @@ err_out: | |||
870 | void mthca_free_cq(struct mthca_dev *dev, | 869 | void mthca_free_cq(struct mthca_dev *dev, |
871 | struct mthca_cq *cq) | 870 | struct mthca_cq *cq) |
872 | { | 871 | { |
873 | void *mailbox; | 872 | struct mthca_mailbox *mailbox; |
874 | int err; | 873 | int err; |
875 | u8 status; | 874 | u8 status; |
876 | 875 | ||
877 | might_sleep(); | 876 | might_sleep(); |
878 | 877 | ||
879 | mailbox = kmalloc(sizeof (struct mthca_cq_context) + MTHCA_CMD_MAILBOX_EXTRA, | 878 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); |
880 | GFP_KERNEL); | 879 | if (IS_ERR(mailbox)) { |
881 | if (!mailbox) { | ||
882 | mthca_warn(dev, "No memory for mailbox to free CQ.\n"); | 880 | mthca_warn(dev, "No memory for mailbox to free CQ.\n"); |
883 | return; | 881 | return; |
884 | } | 882 | } |
885 | 883 | ||
886 | err = mthca_HW2SW_CQ(dev, MAILBOX_ALIGN(mailbox), cq->cqn, &status); | 884 | err = mthca_HW2SW_CQ(dev, mailbox, cq->cqn, &status); |
887 | if (err) | 885 | if (err) |
888 | mthca_warn(dev, "HW2SW_CQ failed (%d)\n", err); | 886 | mthca_warn(dev, "HW2SW_CQ failed (%d)\n", err); |
889 | else if (status) | 887 | else if (status) |
890 | mthca_warn(dev, "HW2SW_CQ returned status 0x%02x\n", | 888 | mthca_warn(dev, "HW2SW_CQ returned status 0x%02x\n", status); |
891 | status); | ||
892 | 889 | ||
893 | if (0) { | 890 | if (0) { |
894 | u32 *ctx = MAILBOX_ALIGN(mailbox); | 891 | u32 *ctx = mailbox->buf; |
895 | int j; | 892 | int j; |
896 | 893 | ||
897 | printk(KERN_ERR "context for CQN %x (cons index %x, next sw %d)\n", | 894 | printk(KERN_ERR "context for CQN %x (cons index %x, next sw %d)\n", |
@@ -919,11 +916,11 @@ void mthca_free_cq(struct mthca_dev *dev, | |||
919 | if (mthca_is_memfree(dev)) { | 916 | if (mthca_is_memfree(dev)) { |
920 | mthca_free_db(dev, MTHCA_DB_TYPE_CQ_ARM, cq->arm_db_index); | 917 | mthca_free_db(dev, MTHCA_DB_TYPE_CQ_ARM, cq->arm_db_index); |
921 | mthca_free_db(dev, MTHCA_DB_TYPE_CQ_SET_CI, cq->set_ci_db_index); | 918 | mthca_free_db(dev, MTHCA_DB_TYPE_CQ_SET_CI, cq->set_ci_db_index); |
922 | mthca_table_put(dev, dev->cq_table.table, cq->cqn); | ||
923 | } | 919 | } |
924 | 920 | ||
921 | mthca_table_put(dev, dev->cq_table.table, cq->cqn); | ||
925 | mthca_free(&dev->cq_table.alloc, cq->cqn); | 922 | mthca_free(&dev->cq_table.alloc, cq->cqn); |
926 | kfree(mailbox); | 923 | mthca_free_mailbox(dev, mailbox); |
927 | } | 924 | } |
928 | 925 | ||
929 | int __devinit mthca_init_cq_table(struct mthca_dev *dev) | 926 | int __devinit mthca_init_cq_table(struct mthca_dev *dev) |
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h index e3d79e267dc9..4127f09dc5ec 100644 --- a/drivers/infiniband/hw/mthca/mthca_dev.h +++ b/drivers/infiniband/hw/mthca/mthca_dev.h | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. | 2 | * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. |
3 | * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. | ||
3 | * | 4 | * |
4 | * This software is available to you under a choice of one of two | 5 | * This software is available to you under a choice of one of two |
5 | * licenses. You may choose to be licensed under the terms of the GNU | 6 | * licenses. You may choose to be licensed under the terms of the GNU |
@@ -46,8 +47,8 @@ | |||
46 | 47 | ||
47 | #define DRV_NAME "ib_mthca" | 48 | #define DRV_NAME "ib_mthca" |
48 | #define PFX DRV_NAME ": " | 49 | #define PFX DRV_NAME ": " |
49 | #define DRV_VERSION "0.06-pre" | 50 | #define DRV_VERSION "0.06" |
50 | #define DRV_RELDATE "November 8, 2004" | 51 | #define DRV_RELDATE "June 23, 2005" |
51 | 52 | ||
52 | enum { | 53 | enum { |
53 | MTHCA_FLAG_DDR_HIDDEN = 1 << 1, | 54 | MTHCA_FLAG_DDR_HIDDEN = 1 << 1, |
@@ -98,6 +99,7 @@ enum { | |||
98 | }; | 99 | }; |
99 | 100 | ||
100 | struct mthca_cmd { | 101 | struct mthca_cmd { |
102 | struct pci_pool *pool; | ||
101 | int use_events; | 103 | int use_events; |
102 | struct semaphore hcr_sem; | 104 | struct semaphore hcr_sem; |
103 | struct semaphore poll_sem; | 105 | struct semaphore poll_sem; |
@@ -379,6 +381,12 @@ void mthca_uar_free(struct mthca_dev *dev, struct mthca_uar *uar); | |||
379 | int mthca_pd_alloc(struct mthca_dev *dev, struct mthca_pd *pd); | 381 | int mthca_pd_alloc(struct mthca_dev *dev, struct mthca_pd *pd); |
380 | void mthca_pd_free(struct mthca_dev *dev, struct mthca_pd *pd); | 382 | void mthca_pd_free(struct mthca_dev *dev, struct mthca_pd *pd); |
381 | 383 | ||
384 | struct mthca_mtt *mthca_alloc_mtt(struct mthca_dev *dev, int size); | ||
385 | void mthca_free_mtt(struct mthca_dev *dev, struct mthca_mtt *mtt); | ||
386 | int mthca_write_mtt(struct mthca_dev *dev, struct mthca_mtt *mtt, | ||
387 | int start_index, u64 *buffer_list, int list_len); | ||
388 | int mthca_mr_alloc(struct mthca_dev *dev, u32 pd, int buffer_size_shift, | ||
389 | u64 iova, u64 total_size, u32 access, struct mthca_mr *mr); | ||
382 | int mthca_mr_alloc_notrans(struct mthca_dev *dev, u32 pd, | 390 | int mthca_mr_alloc_notrans(struct mthca_dev *dev, u32 pd, |
383 | u32 access, struct mthca_mr *mr); | 391 | u32 access, struct mthca_mr *mr); |
384 | int mthca_mr_alloc_phys(struct mthca_dev *dev, u32 pd, | 392 | int mthca_mr_alloc_phys(struct mthca_dev *dev, u32 pd, |
diff --git a/drivers/infiniband/hw/mthca/mthca_doorbell.h b/drivers/infiniband/hw/mthca/mthca_doorbell.h index 821039a49049..535fad7710fb 100644 --- a/drivers/infiniband/hw/mthca/mthca_doorbell.h +++ b/drivers/infiniband/hw/mthca/mthca_doorbell.h | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004 Topspin Communications. All rights reserved. | 2 | * Copyright (c) 2004 Topspin Communications. All rights reserved. |
3 | * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. | ||
3 | * | 4 | * |
4 | * This software is available to you under a choice of one of two | 5 | * This software is available to you under a choice of one of two |
5 | * licenses. You may choose to be licensed under the terms of the GNU | 6 | * licenses. You may choose to be licensed under the terms of the GNU |
diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c index f46d615d396f..cbcf2b4722e4 100644 --- a/drivers/infiniband/hw/mthca/mthca_eq.c +++ b/drivers/infiniband/hw/mthca/mthca_eq.c | |||
@@ -469,7 +469,7 @@ static int __devinit mthca_create_eq(struct mthca_dev *dev, | |||
469 | PAGE_SIZE; | 469 | PAGE_SIZE; |
470 | u64 *dma_list = NULL; | 470 | u64 *dma_list = NULL; |
471 | dma_addr_t t; | 471 | dma_addr_t t; |
472 | void *mailbox = NULL; | 472 | struct mthca_mailbox *mailbox; |
473 | struct mthca_eq_context *eq_context; | 473 | struct mthca_eq_context *eq_context; |
474 | int err = -ENOMEM; | 474 | int err = -ENOMEM; |
475 | int i; | 475 | int i; |
@@ -494,17 +494,16 @@ static int __devinit mthca_create_eq(struct mthca_dev *dev, | |||
494 | if (!dma_list) | 494 | if (!dma_list) |
495 | goto err_out_free; | 495 | goto err_out_free; |
496 | 496 | ||
497 | mailbox = kmalloc(sizeof *eq_context + MTHCA_CMD_MAILBOX_EXTRA, | 497 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); |
498 | GFP_KERNEL); | 498 | if (IS_ERR(mailbox)) |
499 | if (!mailbox) | ||
500 | goto err_out_free; | 499 | goto err_out_free; |
501 | eq_context = MAILBOX_ALIGN(mailbox); | 500 | eq_context = mailbox->buf; |
502 | 501 | ||
503 | for (i = 0; i < npages; ++i) { | 502 | for (i = 0; i < npages; ++i) { |
504 | eq->page_list[i].buf = pci_alloc_consistent(dev->pdev, | 503 | eq->page_list[i].buf = dma_alloc_coherent(&dev->pdev->dev, |
505 | PAGE_SIZE, &t); | 504 | PAGE_SIZE, &t, GFP_KERNEL); |
506 | if (!eq->page_list[i].buf) | 505 | if (!eq->page_list[i].buf) |
507 | goto err_out_free; | 506 | goto err_out_free_pages; |
508 | 507 | ||
509 | dma_list[i] = t; | 508 | dma_list[i] = t; |
510 | pci_unmap_addr_set(&eq->page_list[i], mapping, t); | 509 | pci_unmap_addr_set(&eq->page_list[i], mapping, t); |
@@ -517,7 +516,7 @@ static int __devinit mthca_create_eq(struct mthca_dev *dev, | |||
517 | 516 | ||
518 | eq->eqn = mthca_alloc(&dev->eq_table.alloc); | 517 | eq->eqn = mthca_alloc(&dev->eq_table.alloc); |
519 | if (eq->eqn == -1) | 518 | if (eq->eqn == -1) |
520 | goto err_out_free; | 519 | goto err_out_free_pages; |
521 | 520 | ||
522 | err = mthca_mr_alloc_phys(dev, dev->driver_pd.pd_num, | 521 | err = mthca_mr_alloc_phys(dev, dev->driver_pd.pd_num, |
523 | dma_list, PAGE_SHIFT, npages, | 522 | dma_list, PAGE_SHIFT, npages, |
@@ -548,7 +547,7 @@ static int __devinit mthca_create_eq(struct mthca_dev *dev, | |||
548 | eq_context->intr = intr; | 547 | eq_context->intr = intr; |
549 | eq_context->lkey = cpu_to_be32(eq->mr.ibmr.lkey); | 548 | eq_context->lkey = cpu_to_be32(eq->mr.ibmr.lkey); |
550 | 549 | ||
551 | err = mthca_SW2HW_EQ(dev, eq_context, eq->eqn, &status); | 550 | err = mthca_SW2HW_EQ(dev, mailbox, eq->eqn, &status); |
552 | if (err) { | 551 | if (err) { |
553 | mthca_warn(dev, "SW2HW_EQ failed (%d)\n", err); | 552 | mthca_warn(dev, "SW2HW_EQ failed (%d)\n", err); |
554 | goto err_out_free_mr; | 553 | goto err_out_free_mr; |
@@ -561,7 +560,7 @@ static int __devinit mthca_create_eq(struct mthca_dev *dev, | |||
561 | } | 560 | } |
562 | 561 | ||
563 | kfree(dma_list); | 562 | kfree(dma_list); |
564 | kfree(mailbox); | 563 | mthca_free_mailbox(dev, mailbox); |
565 | 564 | ||
566 | eq->eqn_mask = swab32(1 << eq->eqn); | 565 | eq->eqn_mask = swab32(1 << eq->eqn); |
567 | eq->cons_index = 0; | 566 | eq->cons_index = 0; |
@@ -579,17 +578,19 @@ static int __devinit mthca_create_eq(struct mthca_dev *dev, | |||
579 | err_out_free_eq: | 578 | err_out_free_eq: |
580 | mthca_free(&dev->eq_table.alloc, eq->eqn); | 579 | mthca_free(&dev->eq_table.alloc, eq->eqn); |
581 | 580 | ||
582 | err_out_free: | 581 | err_out_free_pages: |
583 | for (i = 0; i < npages; ++i) | 582 | for (i = 0; i < npages; ++i) |
584 | if (eq->page_list[i].buf) | 583 | if (eq->page_list[i].buf) |
585 | pci_free_consistent(dev->pdev, PAGE_SIZE, | 584 | dma_free_coherent(&dev->pdev->dev, PAGE_SIZE, |
586 | eq->page_list[i].buf, | 585 | eq->page_list[i].buf, |
587 | pci_unmap_addr(&eq->page_list[i], | 586 | pci_unmap_addr(&eq->page_list[i], |
588 | mapping)); | 587 | mapping)); |
588 | |||
589 | mthca_free_mailbox(dev, mailbox); | ||
589 | 590 | ||
591 | err_out_free: | ||
590 | kfree(eq->page_list); | 592 | kfree(eq->page_list); |
591 | kfree(dma_list); | 593 | kfree(dma_list); |
592 | kfree(mailbox); | ||
593 | 594 | ||
594 | err_out: | 595 | err_out: |
595 | return err; | 596 | return err; |
@@ -598,25 +599,22 @@ static int __devinit mthca_create_eq(struct mthca_dev *dev, | |||
598 | static void mthca_free_eq(struct mthca_dev *dev, | 599 | static void mthca_free_eq(struct mthca_dev *dev, |
599 | struct mthca_eq *eq) | 600 | struct mthca_eq *eq) |
600 | { | 601 | { |
601 | void *mailbox = NULL; | 602 | struct mthca_mailbox *mailbox; |
602 | int err; | 603 | int err; |
603 | u8 status; | 604 | u8 status; |
604 | int npages = (eq->nent * MTHCA_EQ_ENTRY_SIZE + PAGE_SIZE - 1) / | 605 | int npages = (eq->nent * MTHCA_EQ_ENTRY_SIZE + PAGE_SIZE - 1) / |
605 | PAGE_SIZE; | 606 | PAGE_SIZE; |
606 | int i; | 607 | int i; |
607 | 608 | ||
608 | mailbox = kmalloc(sizeof (struct mthca_eq_context) + MTHCA_CMD_MAILBOX_EXTRA, | 609 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); |
609 | GFP_KERNEL); | 610 | if (IS_ERR(mailbox)) |
610 | if (!mailbox) | ||
611 | return; | 611 | return; |
612 | 612 | ||
613 | err = mthca_HW2SW_EQ(dev, MAILBOX_ALIGN(mailbox), | 613 | err = mthca_HW2SW_EQ(dev, mailbox, eq->eqn, &status); |
614 | eq->eqn, &status); | ||
615 | if (err) | 614 | if (err) |
616 | mthca_warn(dev, "HW2SW_EQ failed (%d)\n", err); | 615 | mthca_warn(dev, "HW2SW_EQ failed (%d)\n", err); |
617 | if (status) | 616 | if (status) |
618 | mthca_warn(dev, "HW2SW_EQ returned status 0x%02x\n", | 617 | mthca_warn(dev, "HW2SW_EQ returned status 0x%02x\n", status); |
619 | status); | ||
620 | 618 | ||
621 | dev->eq_table.arm_mask &= ~eq->eqn_mask; | 619 | dev->eq_table.arm_mask &= ~eq->eqn_mask; |
622 | 620 | ||
@@ -625,7 +623,7 @@ static void mthca_free_eq(struct mthca_dev *dev, | |||
625 | for (i = 0; i < sizeof (struct mthca_eq_context) / 4; ++i) { | 623 | for (i = 0; i < sizeof (struct mthca_eq_context) / 4; ++i) { |
626 | if (i % 4 == 0) | 624 | if (i % 4 == 0) |
627 | printk("[%02x] ", i * 4); | 625 | printk("[%02x] ", i * 4); |
628 | printk(" %08x", be32_to_cpup(MAILBOX_ALIGN(mailbox) + i * 4)); | 626 | printk(" %08x", be32_to_cpup(mailbox->buf + i * 4)); |
629 | if ((i + 1) % 4 == 0) | 627 | if ((i + 1) % 4 == 0) |
630 | printk("\n"); | 628 | printk("\n"); |
631 | } | 629 | } |
@@ -638,7 +636,7 @@ static void mthca_free_eq(struct mthca_dev *dev, | |||
638 | pci_unmap_addr(&eq->page_list[i], mapping)); | 636 | pci_unmap_addr(&eq->page_list[i], mapping)); |
639 | 637 | ||
640 | kfree(eq->page_list); | 638 | kfree(eq->page_list); |
641 | kfree(mailbox); | 639 | mthca_free_mailbox(dev, mailbox); |
642 | } | 640 | } |
643 | 641 | ||
644 | static void mthca_free_irqs(struct mthca_dev *dev) | 642 | static void mthca_free_irqs(struct mthca_dev *dev) |
@@ -709,8 +707,7 @@ static int __devinit mthca_map_eq_regs(struct mthca_dev *dev) | |||
709 | if (mthca_map_reg(dev, ((pci_resource_len(dev->pdev, 0) - 1) & | 707 | if (mthca_map_reg(dev, ((pci_resource_len(dev->pdev, 0) - 1) & |
710 | dev->fw.arbel.eq_arm_base) + 4, 4, | 708 | dev->fw.arbel.eq_arm_base) + 4, 4, |
711 | &dev->eq_regs.arbel.eq_arm)) { | 709 | &dev->eq_regs.arbel.eq_arm)) { |
712 | mthca_err(dev, "Couldn't map interrupt clear register, " | 710 | mthca_err(dev, "Couldn't map EQ arm register, aborting.\n"); |
713 | "aborting.\n"); | ||
714 | mthca_unmap_reg(dev, (pci_resource_len(dev->pdev, 0) - 1) & | 711 | mthca_unmap_reg(dev, (pci_resource_len(dev->pdev, 0) - 1) & |
715 | dev->fw.arbel.clr_int_base, MTHCA_CLR_INT_SIZE, | 712 | dev->fw.arbel.clr_int_base, MTHCA_CLR_INT_SIZE, |
716 | dev->clr_base); | 713 | dev->clr_base); |
@@ -721,8 +718,7 @@ static int __devinit mthca_map_eq_regs(struct mthca_dev *dev) | |||
721 | dev->fw.arbel.eq_set_ci_base, | 718 | dev->fw.arbel.eq_set_ci_base, |
722 | MTHCA_EQ_SET_CI_SIZE, | 719 | MTHCA_EQ_SET_CI_SIZE, |
723 | &dev->eq_regs.arbel.eq_set_ci_base)) { | 720 | &dev->eq_regs.arbel.eq_set_ci_base)) { |
724 | mthca_err(dev, "Couldn't map interrupt clear register, " | 721 | mthca_err(dev, "Couldn't map EQ CI register, aborting.\n"); |
725 | "aborting.\n"); | ||
726 | mthca_unmap_reg(dev, ((pci_resource_len(dev->pdev, 0) - 1) & | 722 | mthca_unmap_reg(dev, ((pci_resource_len(dev->pdev, 0) - 1) & |
727 | dev->fw.arbel.eq_arm_base) + 4, 4, | 723 | dev->fw.arbel.eq_arm_base) + 4, 4, |
728 | dev->eq_regs.arbel.eq_arm); | 724 | dev->eq_regs.arbel.eq_arm); |
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c index d40590356df8..09519b604c08 100644 --- a/drivers/infiniband/hw/mthca/mthca_main.c +++ b/drivers/infiniband/hw/mthca/mthca_main.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. | 2 | * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. |
3 | * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. | ||
3 | * | 4 | * |
4 | * This software is available to you under a choice of one of two | 5 | * This software is available to you under a choice of one of two |
5 | * licenses. You may choose to be licensed under the terms of the GNU | 6 | * licenses. You may choose to be licensed under the terms of the GNU |
@@ -69,7 +70,7 @@ MODULE_PARM_DESC(msi, "attempt to use MSI if nonzero"); | |||
69 | #endif /* CONFIG_PCI_MSI */ | 70 | #endif /* CONFIG_PCI_MSI */ |
70 | 71 | ||
71 | static const char mthca_version[] __devinitdata = | 72 | static const char mthca_version[] __devinitdata = |
72 | "ib_mthca: Mellanox InfiniBand HCA driver v" | 73 | DRV_NAME ": Mellanox InfiniBand HCA driver v" |
73 | DRV_VERSION " (" DRV_RELDATE ")\n"; | 74 | DRV_VERSION " (" DRV_RELDATE ")\n"; |
74 | 75 | ||
75 | static struct mthca_profile default_profile = { | 76 | static struct mthca_profile default_profile = { |
@@ -927,13 +928,13 @@ static int __devinit mthca_init_one(struct pci_dev *pdev, | |||
927 | */ | 928 | */ |
928 | if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM) || | 929 | if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM) || |
929 | pci_resource_len(pdev, 0) != 1 << 20) { | 930 | pci_resource_len(pdev, 0) != 1 << 20) { |
930 | dev_err(&pdev->dev, "Missing DCS, aborting."); | 931 | dev_err(&pdev->dev, "Missing DCS, aborting.\n"); |
931 | err = -ENODEV; | 932 | err = -ENODEV; |
932 | goto err_disable_pdev; | 933 | goto err_disable_pdev; |
933 | } | 934 | } |
934 | if (!(pci_resource_flags(pdev, 2) & IORESOURCE_MEM) || | 935 | if (!(pci_resource_flags(pdev, 2) & IORESOURCE_MEM) || |
935 | pci_resource_len(pdev, 2) != 1 << 23) { | 936 | pci_resource_len(pdev, 2) != 1 << 23) { |
936 | dev_err(&pdev->dev, "Missing UAR, aborting."); | 937 | dev_err(&pdev->dev, "Missing UAR, aborting.\n"); |
937 | err = -ENODEV; | 938 | err = -ENODEV; |
938 | goto err_disable_pdev; | 939 | goto err_disable_pdev; |
939 | } | 940 | } |
@@ -1004,25 +1005,18 @@ static int __devinit mthca_init_one(struct pci_dev *pdev, | |||
1004 | !pci_enable_msi(pdev)) | 1005 | !pci_enable_msi(pdev)) |
1005 | mdev->mthca_flags |= MTHCA_FLAG_MSI; | 1006 | mdev->mthca_flags |= MTHCA_FLAG_MSI; |
1006 | 1007 | ||
1007 | sema_init(&mdev->cmd.hcr_sem, 1); | 1008 | if (mthca_cmd_init(mdev)) { |
1008 | sema_init(&mdev->cmd.poll_sem, 1); | 1009 | mthca_err(mdev, "Failed to init command interface, aborting.\n"); |
1009 | mdev->cmd.use_events = 0; | ||
1010 | |||
1011 | mdev->hcr = ioremap(pci_resource_start(pdev, 0) + MTHCA_HCR_BASE, MTHCA_HCR_SIZE); | ||
1012 | if (!mdev->hcr) { | ||
1013 | mthca_err(mdev, "Couldn't map command register, " | ||
1014 | "aborting.\n"); | ||
1015 | err = -ENOMEM; | ||
1016 | goto err_free_dev; | 1010 | goto err_free_dev; |
1017 | } | 1011 | } |
1018 | 1012 | ||
1019 | err = mthca_tune_pci(mdev); | 1013 | err = mthca_tune_pci(mdev); |
1020 | if (err) | 1014 | if (err) |
1021 | goto err_iounmap; | 1015 | goto err_cmd; |
1022 | 1016 | ||
1023 | err = mthca_init_hca(mdev); | 1017 | err = mthca_init_hca(mdev); |
1024 | if (err) | 1018 | if (err) |
1025 | goto err_iounmap; | 1019 | goto err_cmd; |
1026 | 1020 | ||
1027 | if (mdev->fw_ver < mthca_hca_table[id->driver_data].latest_fw) { | 1021 | if (mdev->fw_ver < mthca_hca_table[id->driver_data].latest_fw) { |
1028 | mthca_warn(mdev, "HCA FW version %x.%x.%x is old (%x.%x.%x is current).\n", | 1022 | mthca_warn(mdev, "HCA FW version %x.%x.%x is old (%x.%x.%x is current).\n", |
@@ -1070,8 +1064,8 @@ err_cleanup: | |||
1070 | err_close: | 1064 | err_close: |
1071 | mthca_close_hca(mdev); | 1065 | mthca_close_hca(mdev); |
1072 | 1066 | ||
1073 | err_iounmap: | 1067 | err_cmd: |
1074 | iounmap(mdev->hcr); | 1068 | mthca_cmd_cleanup(mdev); |
1075 | 1069 | ||
1076 | err_free_dev: | 1070 | err_free_dev: |
1077 | if (mdev->mthca_flags & MTHCA_FLAG_MSI_X) | 1071 | if (mdev->mthca_flags & MTHCA_FLAG_MSI_X) |
@@ -1118,10 +1112,8 @@ static void __devexit mthca_remove_one(struct pci_dev *pdev) | |||
1118 | iounmap(mdev->kar); | 1112 | iounmap(mdev->kar); |
1119 | mthca_uar_free(mdev, &mdev->driver_uar); | 1113 | mthca_uar_free(mdev, &mdev->driver_uar); |
1120 | mthca_cleanup_uar_table(mdev); | 1114 | mthca_cleanup_uar_table(mdev); |
1121 | |||
1122 | mthca_close_hca(mdev); | 1115 | mthca_close_hca(mdev); |
1123 | 1116 | mthca_cmd_cleanup(mdev); | |
1124 | iounmap(mdev->hcr); | ||
1125 | 1117 | ||
1126 | if (mdev->mthca_flags & MTHCA_FLAG_MSI_X) | 1118 | if (mdev->mthca_flags & MTHCA_FLAG_MSI_X) |
1127 | pci_disable_msix(pdev); | 1119 | pci_disable_msix(pdev); |
@@ -1163,7 +1155,7 @@ static struct pci_device_id mthca_pci_table[] = { | |||
1163 | MODULE_DEVICE_TABLE(pci, mthca_pci_table); | 1155 | MODULE_DEVICE_TABLE(pci, mthca_pci_table); |
1164 | 1156 | ||
1165 | static struct pci_driver mthca_driver = { | 1157 | static struct pci_driver mthca_driver = { |
1166 | .name = "ib_mthca", | 1158 | .name = DRV_NAME, |
1167 | .id_table = mthca_pci_table, | 1159 | .id_table = mthca_pci_table, |
1168 | .probe = mthca_init_one, | 1160 | .probe = mthca_init_one, |
1169 | .remove = __devexit_p(mthca_remove_one) | 1161 | .remove = __devexit_p(mthca_remove_one) |
diff --git a/drivers/infiniband/hw/mthca/mthca_mcg.c b/drivers/infiniband/hw/mthca/mthca_mcg.c index 70a6553a588e..5be7d949dbf6 100644 --- a/drivers/infiniband/hw/mthca/mthca_mcg.c +++ b/drivers/infiniband/hw/mthca/mthca_mcg.c | |||
@@ -66,22 +66,23 @@ static const u8 zero_gid[16]; /* automatically initialized to 0 */ | |||
66 | * entry in hash chain and *mgm holds end of hash chain. | 66 | * entry in hash chain and *mgm holds end of hash chain. |
67 | */ | 67 | */ |
68 | static int find_mgm(struct mthca_dev *dev, | 68 | static int find_mgm(struct mthca_dev *dev, |
69 | u8 *gid, struct mthca_mgm *mgm, | 69 | u8 *gid, struct mthca_mailbox *mgm_mailbox, |
70 | u16 *hash, int *prev, int *index) | 70 | u16 *hash, int *prev, int *index) |
71 | { | 71 | { |
72 | void *mailbox; | 72 | struct mthca_mailbox *mailbox; |
73 | struct mthca_mgm *mgm = mgm_mailbox->buf; | ||
73 | u8 *mgid; | 74 | u8 *mgid; |
74 | int err; | 75 | int err; |
75 | u8 status; | 76 | u8 status; |
76 | 77 | ||
77 | mailbox = kmalloc(16 + MTHCA_CMD_MAILBOX_EXTRA, GFP_KERNEL); | 78 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); |
78 | if (!mailbox) | 79 | if (IS_ERR(mailbox)) |
79 | return -ENOMEM; | 80 | return -ENOMEM; |
80 | mgid = MAILBOX_ALIGN(mailbox); | 81 | mgid = mailbox->buf; |
81 | 82 | ||
82 | memcpy(mgid, gid, 16); | 83 | memcpy(mgid, gid, 16); |
83 | 84 | ||
84 | err = mthca_MGID_HASH(dev, mgid, hash, &status); | 85 | err = mthca_MGID_HASH(dev, mailbox, hash, &status); |
85 | if (err) | 86 | if (err) |
86 | goto out; | 87 | goto out; |
87 | if (status) { | 88 | if (status) { |
@@ -103,7 +104,7 @@ static int find_mgm(struct mthca_dev *dev, | |||
103 | *prev = -1; | 104 | *prev = -1; |
104 | 105 | ||
105 | do { | 106 | do { |
106 | err = mthca_READ_MGM(dev, *index, mgm, &status); | 107 | err = mthca_READ_MGM(dev, *index, mgm_mailbox, &status); |
107 | if (err) | 108 | if (err) |
108 | goto out; | 109 | goto out; |
109 | if (status) { | 110 | if (status) { |
@@ -129,14 +130,14 @@ static int find_mgm(struct mthca_dev *dev, | |||
129 | *index = -1; | 130 | *index = -1; |
130 | 131 | ||
131 | out: | 132 | out: |
132 | kfree(mailbox); | 133 | mthca_free_mailbox(dev, mailbox); |
133 | return err; | 134 | return err; |
134 | } | 135 | } |
135 | 136 | ||
136 | int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | 137 | int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) |
137 | { | 138 | { |
138 | struct mthca_dev *dev = to_mdev(ibqp->device); | 139 | struct mthca_dev *dev = to_mdev(ibqp->device); |
139 | void *mailbox; | 140 | struct mthca_mailbox *mailbox; |
140 | struct mthca_mgm *mgm; | 141 | struct mthca_mgm *mgm; |
141 | u16 hash; | 142 | u16 hash; |
142 | int index, prev; | 143 | int index, prev; |
@@ -145,15 +146,15 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | |||
145 | int err; | 146 | int err; |
146 | u8 status; | 147 | u8 status; |
147 | 148 | ||
148 | mailbox = kmalloc(sizeof *mgm + MTHCA_CMD_MAILBOX_EXTRA, GFP_KERNEL); | 149 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); |
149 | if (!mailbox) | 150 | if (IS_ERR(mailbox)) |
150 | return -ENOMEM; | 151 | return PTR_ERR(mailbox); |
151 | mgm = MAILBOX_ALIGN(mailbox); | 152 | mgm = mailbox->buf; |
152 | 153 | ||
153 | if (down_interruptible(&dev->mcg_table.sem)) | 154 | if (down_interruptible(&dev->mcg_table.sem)) |
154 | return -EINTR; | 155 | return -EINTR; |
155 | 156 | ||
156 | err = find_mgm(dev, gid->raw, mgm, &hash, &prev, &index); | 157 | err = find_mgm(dev, gid->raw, mailbox, &hash, &prev, &index); |
157 | if (err) | 158 | if (err) |
158 | goto out; | 159 | goto out; |
159 | 160 | ||
@@ -170,7 +171,7 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | |||
170 | goto out; | 171 | goto out; |
171 | } | 172 | } |
172 | 173 | ||
173 | err = mthca_READ_MGM(dev, index, mgm, &status); | 174 | err = mthca_READ_MGM(dev, index, mailbox, &status); |
174 | if (err) | 175 | if (err) |
175 | goto out; | 176 | goto out; |
176 | if (status) { | 177 | if (status) { |
@@ -195,7 +196,7 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | |||
195 | goto out; | 196 | goto out; |
196 | } | 197 | } |
197 | 198 | ||
198 | err = mthca_WRITE_MGM(dev, index, mgm, &status); | 199 | err = mthca_WRITE_MGM(dev, index, mailbox, &status); |
199 | if (err) | 200 | if (err) |
200 | goto out; | 201 | goto out; |
201 | if (status) { | 202 | if (status) { |
@@ -206,7 +207,7 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | |||
206 | if (!link) | 207 | if (!link) |
207 | goto out; | 208 | goto out; |
208 | 209 | ||
209 | err = mthca_READ_MGM(dev, prev, mgm, &status); | 210 | err = mthca_READ_MGM(dev, prev, mailbox, &status); |
210 | if (err) | 211 | if (err) |
211 | goto out; | 212 | goto out; |
212 | if (status) { | 213 | if (status) { |
@@ -217,7 +218,7 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | |||
217 | 218 | ||
218 | mgm->next_gid_index = cpu_to_be32(index << 5); | 219 | mgm->next_gid_index = cpu_to_be32(index << 5); |
219 | 220 | ||
220 | err = mthca_WRITE_MGM(dev, prev, mgm, &status); | 221 | err = mthca_WRITE_MGM(dev, prev, mailbox, &status); |
221 | if (err) | 222 | if (err) |
222 | goto out; | 223 | goto out; |
223 | if (status) { | 224 | if (status) { |
@@ -227,14 +228,14 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | |||
227 | 228 | ||
228 | out: | 229 | out: |
229 | up(&dev->mcg_table.sem); | 230 | up(&dev->mcg_table.sem); |
230 | kfree(mailbox); | 231 | mthca_free_mailbox(dev, mailbox); |
231 | return err; | 232 | return err; |
232 | } | 233 | } |
233 | 234 | ||
234 | int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | 235 | int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) |
235 | { | 236 | { |
236 | struct mthca_dev *dev = to_mdev(ibqp->device); | 237 | struct mthca_dev *dev = to_mdev(ibqp->device); |
237 | void *mailbox; | 238 | struct mthca_mailbox *mailbox; |
238 | struct mthca_mgm *mgm; | 239 | struct mthca_mgm *mgm; |
239 | u16 hash; | 240 | u16 hash; |
240 | int prev, index; | 241 | int prev, index; |
@@ -242,15 +243,15 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | |||
242 | int err; | 243 | int err; |
243 | u8 status; | 244 | u8 status; |
244 | 245 | ||
245 | mailbox = kmalloc(sizeof *mgm + MTHCA_CMD_MAILBOX_EXTRA, GFP_KERNEL); | 246 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); |
246 | if (!mailbox) | 247 | if (IS_ERR(mailbox)) |
247 | return -ENOMEM; | 248 | return PTR_ERR(mailbox); |
248 | mgm = MAILBOX_ALIGN(mailbox); | 249 | mgm = mailbox->buf; |
249 | 250 | ||
250 | if (down_interruptible(&dev->mcg_table.sem)) | 251 | if (down_interruptible(&dev->mcg_table.sem)) |
251 | return -EINTR; | 252 | return -EINTR; |
252 | 253 | ||
253 | err = find_mgm(dev, gid->raw, mgm, &hash, &prev, &index); | 254 | err = find_mgm(dev, gid->raw, mailbox, &hash, &prev, &index); |
254 | if (err) | 255 | if (err) |
255 | goto out; | 256 | goto out; |
256 | 257 | ||
@@ -285,7 +286,7 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | |||
285 | mgm->qp[loc] = mgm->qp[i - 1]; | 286 | mgm->qp[loc] = mgm->qp[i - 1]; |
286 | mgm->qp[i - 1] = 0; | 287 | mgm->qp[i - 1] = 0; |
287 | 288 | ||
288 | err = mthca_WRITE_MGM(dev, index, mgm, &status); | 289 | err = mthca_WRITE_MGM(dev, index, mailbox, &status); |
289 | if (err) | 290 | if (err) |
290 | goto out; | 291 | goto out; |
291 | if (status) { | 292 | if (status) { |
@@ -304,7 +305,7 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | |||
304 | if (be32_to_cpu(mgm->next_gid_index) >> 5) { | 305 | if (be32_to_cpu(mgm->next_gid_index) >> 5) { |
305 | err = mthca_READ_MGM(dev, | 306 | err = mthca_READ_MGM(dev, |
306 | be32_to_cpu(mgm->next_gid_index) >> 5, | 307 | be32_to_cpu(mgm->next_gid_index) >> 5, |
307 | mgm, &status); | 308 | mailbox, &status); |
308 | if (err) | 309 | if (err) |
309 | goto out; | 310 | goto out; |
310 | if (status) { | 311 | if (status) { |
@@ -316,7 +317,7 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | |||
316 | } else | 317 | } else |
317 | memset(mgm->gid, 0, 16); | 318 | memset(mgm->gid, 0, 16); |
318 | 319 | ||
319 | err = mthca_WRITE_MGM(dev, index, mgm, &status); | 320 | err = mthca_WRITE_MGM(dev, index, mailbox, &status); |
320 | if (err) | 321 | if (err) |
321 | goto out; | 322 | goto out; |
322 | if (status) { | 323 | if (status) { |
@@ -327,7 +328,7 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | |||
327 | } else { | 328 | } else { |
328 | /* Remove entry from AMGM */ | 329 | /* Remove entry from AMGM */ |
329 | index = be32_to_cpu(mgm->next_gid_index) >> 5; | 330 | index = be32_to_cpu(mgm->next_gid_index) >> 5; |
330 | err = mthca_READ_MGM(dev, prev, mgm, &status); | 331 | err = mthca_READ_MGM(dev, prev, mailbox, &status); |
331 | if (err) | 332 | if (err) |
332 | goto out; | 333 | goto out; |
333 | if (status) { | 334 | if (status) { |
@@ -338,7 +339,7 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | |||
338 | 339 | ||
339 | mgm->next_gid_index = cpu_to_be32(index << 5); | 340 | mgm->next_gid_index = cpu_to_be32(index << 5); |
340 | 341 | ||
341 | err = mthca_WRITE_MGM(dev, prev, mgm, &status); | 342 | err = mthca_WRITE_MGM(dev, prev, mailbox, &status); |
342 | if (err) | 343 | if (err) |
343 | goto out; | 344 | goto out; |
344 | if (status) { | 345 | if (status) { |
@@ -350,7 +351,7 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | |||
350 | 351 | ||
351 | out: | 352 | out: |
352 | up(&dev->mcg_table.sem); | 353 | up(&dev->mcg_table.sem); |
353 | kfree(mailbox); | 354 | mthca_free_mailbox(dev, mailbox); |
354 | return err; | 355 | return err; |
355 | } | 356 | } |
356 | 357 | ||
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c index 637b30e35592..6d3b05dd9e3f 100644 --- a/drivers/infiniband/hw/mthca/mthca_memfree.c +++ b/drivers/infiniband/hw/mthca/mthca_memfree.c | |||
@@ -179,9 +179,14 @@ out: | |||
179 | 179 | ||
180 | void mthca_table_put(struct mthca_dev *dev, struct mthca_icm_table *table, int obj) | 180 | void mthca_table_put(struct mthca_dev *dev, struct mthca_icm_table *table, int obj) |
181 | { | 181 | { |
182 | int i = (obj & (table->num_obj - 1)) * table->obj_size / MTHCA_TABLE_CHUNK_SIZE; | 182 | int i; |
183 | u8 status; | 183 | u8 status; |
184 | 184 | ||
185 | if (!mthca_is_memfree(dev)) | ||
186 | return; | ||
187 | |||
188 | i = (obj & (table->num_obj - 1)) * table->obj_size / MTHCA_TABLE_CHUNK_SIZE; | ||
189 | |||
185 | down(&table->mutex); | 190 | down(&table->mutex); |
186 | 191 | ||
187 | if (--table->icm[i]->refcount == 0) { | 192 | if (--table->icm[i]->refcount == 0) { |
@@ -256,6 +261,9 @@ void mthca_table_put_range(struct mthca_dev *dev, struct mthca_icm_table *table, | |||
256 | { | 261 | { |
257 | int i; | 262 | int i; |
258 | 263 | ||
264 | if (!mthca_is_memfree(dev)) | ||
265 | return; | ||
266 | |||
259 | for (i = start; i <= end; i += MTHCA_TABLE_CHUNK_SIZE / table->obj_size) | 267 | for (i = start; i <= end; i += MTHCA_TABLE_CHUNK_SIZE / table->obj_size) |
260 | mthca_table_put(dev, table, i); | 268 | mthca_table_put(dev, table, i); |
261 | } | 269 | } |
diff --git a/drivers/infiniband/hw/mthca/mthca_mr.c b/drivers/infiniband/hw/mthca/mthca_mr.c index 8960fc2306be..cbe50feaf680 100644 --- a/drivers/infiniband/hw/mthca/mthca_mr.c +++ b/drivers/infiniband/hw/mthca/mthca_mr.c | |||
@@ -40,6 +40,12 @@ | |||
40 | #include "mthca_cmd.h" | 40 | #include "mthca_cmd.h" |
41 | #include "mthca_memfree.h" | 41 | #include "mthca_memfree.h" |
42 | 42 | ||
43 | struct mthca_mtt { | ||
44 | struct mthca_buddy *buddy; | ||
45 | int order; | ||
46 | u32 first_seg; | ||
47 | }; | ||
48 | |||
43 | /* | 49 | /* |
44 | * Must be packed because mtt_seg is 64 bits but only aligned to 32 bits. | 50 | * Must be packed because mtt_seg is 64 bits but only aligned to 32 bits. |
45 | */ | 51 | */ |
@@ -173,8 +179,8 @@ static void __devexit mthca_buddy_cleanup(struct mthca_buddy *buddy) | |||
173 | kfree(buddy->bits); | 179 | kfree(buddy->bits); |
174 | } | 180 | } |
175 | 181 | ||
176 | static u32 mthca_alloc_mtt(struct mthca_dev *dev, int order, | 182 | static u32 mthca_alloc_mtt_range(struct mthca_dev *dev, int order, |
177 | struct mthca_buddy *buddy) | 183 | struct mthca_buddy *buddy) |
178 | { | 184 | { |
179 | u32 seg = mthca_buddy_alloc(buddy, order); | 185 | u32 seg = mthca_buddy_alloc(buddy, order); |
180 | 186 | ||
@@ -191,14 +197,102 @@ static u32 mthca_alloc_mtt(struct mthca_dev *dev, int order, | |||
191 | return seg; | 197 | return seg; |
192 | } | 198 | } |
193 | 199 | ||
194 | static void mthca_free_mtt(struct mthca_dev *dev, u32 seg, int order, | 200 | static struct mthca_mtt *__mthca_alloc_mtt(struct mthca_dev *dev, int size, |
195 | struct mthca_buddy* buddy) | 201 | struct mthca_buddy *buddy) |
196 | { | 202 | { |
197 | mthca_buddy_free(buddy, seg, order); | 203 | struct mthca_mtt *mtt; |
204 | int i; | ||
198 | 205 | ||
199 | if (mthca_is_memfree(dev)) | 206 | if (size <= 0) |
200 | mthca_table_put_range(dev, dev->mr_table.mtt_table, seg, | 207 | return ERR_PTR(-EINVAL); |
201 | seg + (1 << order) - 1); | 208 | |
209 | mtt = kmalloc(sizeof *mtt, GFP_KERNEL); | ||
210 | if (!mtt) | ||
211 | return ERR_PTR(-ENOMEM); | ||
212 | |||
213 | mtt->buddy = buddy; | ||
214 | mtt->order = 0; | ||
215 | for (i = MTHCA_MTT_SEG_SIZE / 8; i < size; i <<= 1) | ||
216 | ++mtt->order; | ||
217 | |||
218 | mtt->first_seg = mthca_alloc_mtt_range(dev, mtt->order, buddy); | ||
219 | if (mtt->first_seg == -1) { | ||
220 | kfree(mtt); | ||
221 | return ERR_PTR(-ENOMEM); | ||
222 | } | ||
223 | |||
224 | return mtt; | ||
225 | } | ||
226 | |||
227 | struct mthca_mtt *mthca_alloc_mtt(struct mthca_dev *dev, int size) | ||
228 | { | ||
229 | return __mthca_alloc_mtt(dev, size, &dev->mr_table.mtt_buddy); | ||
230 | } | ||
231 | |||
232 | void mthca_free_mtt(struct mthca_dev *dev, struct mthca_mtt *mtt) | ||
233 | { | ||
234 | if (!mtt) | ||
235 | return; | ||
236 | |||
237 | mthca_buddy_free(mtt->buddy, mtt->first_seg, mtt->order); | ||
238 | |||
239 | mthca_table_put_range(dev, dev->mr_table.mtt_table, | ||
240 | mtt->first_seg, | ||
241 | mtt->first_seg + (1 << mtt->order) - 1); | ||
242 | |||
243 | kfree(mtt); | ||
244 | } | ||
245 | |||
246 | int mthca_write_mtt(struct mthca_dev *dev, struct mthca_mtt *mtt, | ||
247 | int start_index, u64 *buffer_list, int list_len) | ||
248 | { | ||
249 | struct mthca_mailbox *mailbox; | ||
250 | u64 *mtt_entry; | ||
251 | int err = 0; | ||
252 | u8 status; | ||
253 | int i; | ||
254 | |||
255 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); | ||
256 | if (IS_ERR(mailbox)) | ||
257 | return PTR_ERR(mailbox); | ||
258 | mtt_entry = mailbox->buf; | ||
259 | |||
260 | while (list_len > 0) { | ||
261 | mtt_entry[0] = cpu_to_be64(dev->mr_table.mtt_base + | ||
262 | mtt->first_seg * MTHCA_MTT_SEG_SIZE + | ||
263 | start_index * 8); | ||
264 | mtt_entry[1] = 0; | ||
265 | for (i = 0; i < list_len && i < MTHCA_MAILBOX_SIZE / 8 - 2; ++i) | ||
266 | mtt_entry[i + 2] = cpu_to_be64(buffer_list[i] | | ||
267 | MTHCA_MTT_FLAG_PRESENT); | ||
268 | |||
269 | /* | ||
270 | * If we have an odd number of entries to write, add | ||
271 | * one more dummy entry for firmware efficiency. | ||
272 | */ | ||
273 | if (i & 1) | ||
274 | mtt_entry[i + 2] = 0; | ||
275 | |||
276 | err = mthca_WRITE_MTT(dev, mailbox, (i + 1) & ~1, &status); | ||
277 | if (err) { | ||
278 | mthca_warn(dev, "WRITE_MTT failed (%d)\n", err); | ||
279 | goto out; | ||
280 | } | ||
281 | if (status) { | ||
282 | mthca_warn(dev, "WRITE_MTT returned status 0x%02x\n", | ||
283 | status); | ||
284 | err = -EINVAL; | ||
285 | goto out; | ||
286 | } | ||
287 | |||
288 | list_len -= i; | ||
289 | start_index += i; | ||
290 | buffer_list += i; | ||
291 | } | ||
292 | |||
293 | out: | ||
294 | mthca_free_mailbox(dev, mailbox); | ||
295 | return err; | ||
202 | } | 296 | } |
203 | 297 | ||
204 | static inline u32 tavor_hw_index_to_key(u32 ind) | 298 | static inline u32 tavor_hw_index_to_key(u32 ind) |
@@ -237,91 +331,18 @@ static inline u32 key_to_hw_index(struct mthca_dev *dev, u32 key) | |||
237 | return tavor_key_to_hw_index(key); | 331 | return tavor_key_to_hw_index(key); |
238 | } | 332 | } |
239 | 333 | ||
240 | int mthca_mr_alloc_notrans(struct mthca_dev *dev, u32 pd, | 334 | int mthca_mr_alloc(struct mthca_dev *dev, u32 pd, int buffer_size_shift, |
241 | u32 access, struct mthca_mr *mr) | 335 | u64 iova, u64 total_size, u32 access, struct mthca_mr *mr) |
242 | { | 336 | { |
243 | void *mailbox = NULL; | 337 | struct mthca_mailbox *mailbox; |
244 | struct mthca_mpt_entry *mpt_entry; | 338 | struct mthca_mpt_entry *mpt_entry; |
245 | u32 key; | 339 | u32 key; |
340 | int i; | ||
246 | int err; | 341 | int err; |
247 | u8 status; | 342 | u8 status; |
248 | 343 | ||
249 | might_sleep(); | 344 | might_sleep(); |
250 | 345 | ||
251 | mr->order = -1; | ||
252 | key = mthca_alloc(&dev->mr_table.mpt_alloc); | ||
253 | if (key == -1) | ||
254 | return -ENOMEM; | ||
255 | mr->ibmr.rkey = mr->ibmr.lkey = hw_index_to_key(dev, key); | ||
256 | |||
257 | if (mthca_is_memfree(dev)) { | ||
258 | err = mthca_table_get(dev, dev->mr_table.mpt_table, key); | ||
259 | if (err) | ||
260 | goto err_out_mpt_free; | ||
261 | } | ||
262 | |||
263 | mailbox = kmalloc(sizeof *mpt_entry + MTHCA_CMD_MAILBOX_EXTRA, | ||
264 | GFP_KERNEL); | ||
265 | if (!mailbox) { | ||
266 | err = -ENOMEM; | ||
267 | goto err_out_table; | ||
268 | } | ||
269 | mpt_entry = MAILBOX_ALIGN(mailbox); | ||
270 | |||
271 | mpt_entry->flags = cpu_to_be32(MTHCA_MPT_FLAG_SW_OWNS | | ||
272 | MTHCA_MPT_FLAG_MIO | | ||
273 | MTHCA_MPT_FLAG_PHYSICAL | | ||
274 | MTHCA_MPT_FLAG_REGION | | ||
275 | access); | ||
276 | mpt_entry->page_size = 0; | ||
277 | mpt_entry->key = cpu_to_be32(key); | ||
278 | mpt_entry->pd = cpu_to_be32(pd); | ||
279 | mpt_entry->start = 0; | ||
280 | mpt_entry->length = ~0ULL; | ||
281 | |||
282 | memset(&mpt_entry->lkey, 0, | ||
283 | sizeof *mpt_entry - offsetof(struct mthca_mpt_entry, lkey)); | ||
284 | |||
285 | err = mthca_SW2HW_MPT(dev, mpt_entry, | ||
286 | key & (dev->limits.num_mpts - 1), | ||
287 | &status); | ||
288 | if (err) { | ||
289 | mthca_warn(dev, "SW2HW_MPT failed (%d)\n", err); | ||
290 | goto err_out_table; | ||
291 | } else if (status) { | ||
292 | mthca_warn(dev, "SW2HW_MPT returned status 0x%02x\n", | ||
293 | status); | ||
294 | err = -EINVAL; | ||
295 | goto err_out_table; | ||
296 | } | ||
297 | |||
298 | kfree(mailbox); | ||
299 | return err; | ||
300 | |||
301 | err_out_table: | ||
302 | if (mthca_is_memfree(dev)) | ||
303 | mthca_table_put(dev, dev->mr_table.mpt_table, key); | ||
304 | |||
305 | err_out_mpt_free: | ||
306 | mthca_free(&dev->mr_table.mpt_alloc, key); | ||
307 | kfree(mailbox); | ||
308 | return err; | ||
309 | } | ||
310 | |||
311 | int mthca_mr_alloc_phys(struct mthca_dev *dev, u32 pd, | ||
312 | u64 *buffer_list, int buffer_size_shift, | ||
313 | int list_len, u64 iova, u64 total_size, | ||
314 | u32 access, struct mthca_mr *mr) | ||
315 | { | ||
316 | void *mailbox; | ||
317 | u64 *mtt_entry; | ||
318 | struct mthca_mpt_entry *mpt_entry; | ||
319 | u32 key; | ||
320 | int err = -ENOMEM; | ||
321 | u8 status; | ||
322 | int i; | ||
323 | |||
324 | might_sleep(); | ||
325 | WARN_ON(buffer_size_shift >= 32); | 346 | WARN_ON(buffer_size_shift >= 32); |
326 | 347 | ||
327 | key = mthca_alloc(&dev->mr_table.mpt_alloc); | 348 | key = mthca_alloc(&dev->mr_table.mpt_alloc); |
@@ -335,75 +356,33 @@ int mthca_mr_alloc_phys(struct mthca_dev *dev, u32 pd, | |||
335 | goto err_out_mpt_free; | 356 | goto err_out_mpt_free; |
336 | } | 357 | } |
337 | 358 | ||
338 | for (i = MTHCA_MTT_SEG_SIZE / 8, mr->order = 0; | 359 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); |
339 | i < list_len; | 360 | if (IS_ERR(mailbox)) { |
340 | i <<= 1, ++mr->order) | 361 | err = PTR_ERR(mailbox); |
341 | ; /* nothing */ | ||
342 | |||
343 | mr->first_seg = mthca_alloc_mtt(dev, mr->order, | ||
344 | &dev->mr_table.mtt_buddy); | ||
345 | if (mr->first_seg == -1) | ||
346 | goto err_out_table; | 362 | goto err_out_table; |
347 | |||
348 | /* | ||
349 | * If list_len is odd, we add one more dummy entry for | ||
350 | * firmware efficiency. | ||
351 | */ | ||
352 | mailbox = kmalloc(max(sizeof *mpt_entry, | ||
353 | (size_t) 8 * (list_len + (list_len & 1) + 2)) + | ||
354 | MTHCA_CMD_MAILBOX_EXTRA, | ||
355 | GFP_KERNEL); | ||
356 | if (!mailbox) | ||
357 | goto err_out_free_mtt; | ||
358 | |||
359 | mtt_entry = MAILBOX_ALIGN(mailbox); | ||
360 | |||
361 | mtt_entry[0] = cpu_to_be64(dev->mr_table.mtt_base + | ||
362 | mr->first_seg * MTHCA_MTT_SEG_SIZE); | ||
363 | mtt_entry[1] = 0; | ||
364 | for (i = 0; i < list_len; ++i) | ||
365 | mtt_entry[i + 2] = cpu_to_be64(buffer_list[i] | | ||
366 | MTHCA_MTT_FLAG_PRESENT); | ||
367 | if (list_len & 1) { | ||
368 | mtt_entry[i + 2] = 0; | ||
369 | ++list_len; | ||
370 | } | ||
371 | |||
372 | if (0) { | ||
373 | mthca_dbg(dev, "Dumping MPT entry\n"); | ||
374 | for (i = 0; i < list_len + 2; ++i) | ||
375 | printk(KERN_ERR "[%2d] %016llx\n", | ||
376 | i, (unsigned long long) be64_to_cpu(mtt_entry[i])); | ||
377 | } | ||
378 | |||
379 | err = mthca_WRITE_MTT(dev, mtt_entry, list_len, &status); | ||
380 | if (err) { | ||
381 | mthca_warn(dev, "WRITE_MTT failed (%d)\n", err); | ||
382 | goto err_out_mailbox_free; | ||
383 | } | ||
384 | if (status) { | ||
385 | mthca_warn(dev, "WRITE_MTT returned status 0x%02x\n", | ||
386 | status); | ||
387 | err = -EINVAL; | ||
388 | goto err_out_mailbox_free; | ||
389 | } | 363 | } |
390 | 364 | mpt_entry = mailbox->buf; | |
391 | mpt_entry = MAILBOX_ALIGN(mailbox); | ||
392 | 365 | ||
393 | mpt_entry->flags = cpu_to_be32(MTHCA_MPT_FLAG_SW_OWNS | | 366 | mpt_entry->flags = cpu_to_be32(MTHCA_MPT_FLAG_SW_OWNS | |
394 | MTHCA_MPT_FLAG_MIO | | 367 | MTHCA_MPT_FLAG_MIO | |
395 | MTHCA_MPT_FLAG_REGION | | 368 | MTHCA_MPT_FLAG_REGION | |
396 | access); | 369 | access); |
370 | if (!mr->mtt) | ||
371 | mpt_entry->flags |= cpu_to_be32(MTHCA_MPT_FLAG_PHYSICAL); | ||
397 | 372 | ||
398 | mpt_entry->page_size = cpu_to_be32(buffer_size_shift - 12); | 373 | mpt_entry->page_size = cpu_to_be32(buffer_size_shift - 12); |
399 | mpt_entry->key = cpu_to_be32(key); | 374 | mpt_entry->key = cpu_to_be32(key); |
400 | mpt_entry->pd = cpu_to_be32(pd); | 375 | mpt_entry->pd = cpu_to_be32(pd); |
401 | mpt_entry->start = cpu_to_be64(iova); | 376 | mpt_entry->start = cpu_to_be64(iova); |
402 | mpt_entry->length = cpu_to_be64(total_size); | 377 | mpt_entry->length = cpu_to_be64(total_size); |
378 | |||
403 | memset(&mpt_entry->lkey, 0, | 379 | memset(&mpt_entry->lkey, 0, |
404 | sizeof *mpt_entry - offsetof(struct mthca_mpt_entry, lkey)); | 380 | sizeof *mpt_entry - offsetof(struct mthca_mpt_entry, lkey)); |
405 | mpt_entry->mtt_seg = cpu_to_be64(dev->mr_table.mtt_base + | 381 | |
406 | mr->first_seg * MTHCA_MTT_SEG_SIZE); | 382 | if (mr->mtt) |
383 | mpt_entry->mtt_seg = | ||
384 | cpu_to_be64(dev->mr_table.mtt_base + | ||
385 | mr->mtt->first_seg * MTHCA_MTT_SEG_SIZE); | ||
407 | 386 | ||
408 | if (0) { | 387 | if (0) { |
409 | mthca_dbg(dev, "Dumping MPT entry %08x:\n", mr->ibmr.lkey); | 388 | mthca_dbg(dev, "Dumping MPT entry %08x:\n", mr->ibmr.lkey); |
@@ -416,45 +395,70 @@ int mthca_mr_alloc_phys(struct mthca_dev *dev, u32 pd, | |||
416 | } | 395 | } |
417 | } | 396 | } |
418 | 397 | ||
419 | err = mthca_SW2HW_MPT(dev, mpt_entry, | 398 | err = mthca_SW2HW_MPT(dev, mailbox, |
420 | key & (dev->limits.num_mpts - 1), | 399 | key & (dev->limits.num_mpts - 1), |
421 | &status); | 400 | &status); |
422 | if (err) | 401 | if (err) { |
423 | mthca_warn(dev, "SW2HW_MPT failed (%d)\n", err); | 402 | mthca_warn(dev, "SW2HW_MPT failed (%d)\n", err); |
424 | else if (status) { | 403 | goto err_out_mailbox; |
404 | } else if (status) { | ||
425 | mthca_warn(dev, "SW2HW_MPT returned status 0x%02x\n", | 405 | mthca_warn(dev, "SW2HW_MPT returned status 0x%02x\n", |
426 | status); | 406 | status); |
427 | err = -EINVAL; | 407 | err = -EINVAL; |
408 | goto err_out_mailbox; | ||
428 | } | 409 | } |
429 | 410 | ||
430 | kfree(mailbox); | 411 | mthca_free_mailbox(dev, mailbox); |
431 | return err; | 412 | return err; |
432 | 413 | ||
433 | err_out_mailbox_free: | 414 | err_out_mailbox: |
434 | kfree(mailbox); | 415 | mthca_free_mailbox(dev, mailbox); |
435 | |||
436 | err_out_free_mtt: | ||
437 | mthca_free_mtt(dev, mr->first_seg, mr->order, &dev->mr_table.mtt_buddy); | ||
438 | 416 | ||
439 | err_out_table: | 417 | err_out_table: |
440 | if (mthca_is_memfree(dev)) | 418 | mthca_table_put(dev, dev->mr_table.mpt_table, key); |
441 | mthca_table_put(dev, dev->mr_table.mpt_table, key); | ||
442 | 419 | ||
443 | err_out_mpt_free: | 420 | err_out_mpt_free: |
444 | mthca_free(&dev->mr_table.mpt_alloc, key); | 421 | mthca_free(&dev->mr_table.mpt_alloc, key); |
445 | return err; | 422 | return err; |
446 | } | 423 | } |
447 | 424 | ||
448 | /* Free mr or fmr */ | 425 | int mthca_mr_alloc_notrans(struct mthca_dev *dev, u32 pd, |
449 | static void mthca_free_region(struct mthca_dev *dev, u32 lkey, int order, | 426 | u32 access, struct mthca_mr *mr) |
450 | u32 first_seg, struct mthca_buddy *buddy) | ||
451 | { | 427 | { |
452 | if (order >= 0) | 428 | mr->mtt = NULL; |
453 | mthca_free_mtt(dev, first_seg, order, buddy); | 429 | return mthca_mr_alloc(dev, pd, 12, 0, ~0ULL, access, mr); |
430 | } | ||
454 | 431 | ||
455 | if (mthca_is_memfree(dev)) | 432 | int mthca_mr_alloc_phys(struct mthca_dev *dev, u32 pd, |
456 | mthca_table_put(dev, dev->mr_table.mpt_table, | 433 | u64 *buffer_list, int buffer_size_shift, |
457 | arbel_key_to_hw_index(lkey)); | 434 | int list_len, u64 iova, u64 total_size, |
435 | u32 access, struct mthca_mr *mr) | ||
436 | { | ||
437 | int err; | ||
438 | |||
439 | mr->mtt = mthca_alloc_mtt(dev, list_len); | ||
440 | if (IS_ERR(mr->mtt)) | ||
441 | return PTR_ERR(mr->mtt); | ||
442 | |||
443 | err = mthca_write_mtt(dev, mr->mtt, 0, buffer_list, list_len); | ||
444 | if (err) { | ||
445 | mthca_free_mtt(dev, mr->mtt); | ||
446 | return err; | ||
447 | } | ||
448 | |||
449 | err = mthca_mr_alloc(dev, pd, buffer_size_shift, iova, | ||
450 | total_size, access, mr); | ||
451 | if (err) | ||
452 | mthca_free_mtt(dev, mr->mtt); | ||
453 | |||
454 | return err; | ||
455 | } | ||
456 | |||
457 | /* Free mr or fmr */ | ||
458 | static void mthca_free_region(struct mthca_dev *dev, u32 lkey) | ||
459 | { | ||
460 | mthca_table_put(dev, dev->mr_table.mpt_table, | ||
461 | arbel_key_to_hw_index(lkey)); | ||
458 | 462 | ||
459 | mthca_free(&dev->mr_table.mpt_alloc, key_to_hw_index(dev, lkey)); | 463 | mthca_free(&dev->mr_table.mpt_alloc, key_to_hw_index(dev, lkey)); |
460 | } | 464 | } |
@@ -476,15 +480,15 @@ void mthca_free_mr(struct mthca_dev *dev, struct mthca_mr *mr) | |||
476 | mthca_warn(dev, "HW2SW_MPT returned status 0x%02x\n", | 480 | mthca_warn(dev, "HW2SW_MPT returned status 0x%02x\n", |
477 | status); | 481 | status); |
478 | 482 | ||
479 | mthca_free_region(dev, mr->ibmr.lkey, mr->order, mr->first_seg, | 483 | mthca_free_region(dev, mr->ibmr.lkey); |
480 | &dev->mr_table.mtt_buddy); | 484 | mthca_free_mtt(dev, mr->mtt); |
481 | } | 485 | } |
482 | 486 | ||
483 | int mthca_fmr_alloc(struct mthca_dev *dev, u32 pd, | 487 | int mthca_fmr_alloc(struct mthca_dev *dev, u32 pd, |
484 | u32 access, struct mthca_fmr *mr) | 488 | u32 access, struct mthca_fmr *mr) |
485 | { | 489 | { |
486 | struct mthca_mpt_entry *mpt_entry; | 490 | struct mthca_mpt_entry *mpt_entry; |
487 | void *mailbox; | 491 | struct mthca_mailbox *mailbox; |
488 | u64 mtt_seg; | 492 | u64 mtt_seg; |
489 | u32 key, idx; | 493 | u32 key, idx; |
490 | u8 status; | 494 | u8 status; |
@@ -522,31 +526,24 @@ int mthca_fmr_alloc(struct mthca_dev *dev, u32 pd, | |||
522 | mr->mem.tavor.mpt = dev->mr_table.tavor_fmr.mpt_base + | 526 | mr->mem.tavor.mpt = dev->mr_table.tavor_fmr.mpt_base + |
523 | sizeof *(mr->mem.tavor.mpt) * idx; | 527 | sizeof *(mr->mem.tavor.mpt) * idx; |
524 | 528 | ||
525 | for (i = MTHCA_MTT_SEG_SIZE / 8, mr->order = 0; | 529 | mr->mtt = __mthca_alloc_mtt(dev, list_len, dev->mr_table.fmr_mtt_buddy); |
526 | i < list_len; | 530 | if (IS_ERR(mr->mtt)) |
527 | i <<= 1, ++mr->order) | ||
528 | ; /* nothing */ | ||
529 | |||
530 | mr->first_seg = mthca_alloc_mtt(dev, mr->order, | ||
531 | dev->mr_table.fmr_mtt_buddy); | ||
532 | if (mr->first_seg == -1) | ||
533 | goto err_out_table; | 531 | goto err_out_table; |
534 | 532 | ||
535 | mtt_seg = mr->first_seg * MTHCA_MTT_SEG_SIZE; | 533 | mtt_seg = mr->mtt->first_seg * MTHCA_MTT_SEG_SIZE; |
536 | 534 | ||
537 | if (mthca_is_memfree(dev)) { | 535 | if (mthca_is_memfree(dev)) { |
538 | mr->mem.arbel.mtts = mthca_table_find(dev->mr_table.mtt_table, | 536 | mr->mem.arbel.mtts = mthca_table_find(dev->mr_table.mtt_table, |
539 | mr->first_seg); | 537 | mr->mtt->first_seg); |
540 | BUG_ON(!mr->mem.arbel.mtts); | 538 | BUG_ON(!mr->mem.arbel.mtts); |
541 | } else | 539 | } else |
542 | mr->mem.tavor.mtts = dev->mr_table.tavor_fmr.mtt_base + mtt_seg; | 540 | mr->mem.tavor.mtts = dev->mr_table.tavor_fmr.mtt_base + mtt_seg; |
543 | 541 | ||
544 | mailbox = kmalloc(sizeof *mpt_entry + MTHCA_CMD_MAILBOX_EXTRA, | 542 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); |
545 | GFP_KERNEL); | 543 | if (IS_ERR(mailbox)) |
546 | if (!mailbox) | ||
547 | goto err_out_free_mtt; | 544 | goto err_out_free_mtt; |
548 | 545 | ||
549 | mpt_entry = MAILBOX_ALIGN(mailbox); | 546 | mpt_entry = mailbox->buf; |
550 | 547 | ||
551 | mpt_entry->flags = cpu_to_be32(MTHCA_MPT_FLAG_SW_OWNS | | 548 | mpt_entry->flags = cpu_to_be32(MTHCA_MPT_FLAG_SW_OWNS | |
552 | MTHCA_MPT_FLAG_MIO | | 549 | MTHCA_MPT_FLAG_MIO | |
@@ -571,7 +568,7 @@ int mthca_fmr_alloc(struct mthca_dev *dev, u32 pd, | |||
571 | } | 568 | } |
572 | } | 569 | } |
573 | 570 | ||
574 | err = mthca_SW2HW_MPT(dev, mpt_entry, | 571 | err = mthca_SW2HW_MPT(dev, mailbox, |
575 | key & (dev->limits.num_mpts - 1), | 572 | key & (dev->limits.num_mpts - 1), |
576 | &status); | 573 | &status); |
577 | if (err) { | 574 | if (err) { |
@@ -585,19 +582,17 @@ int mthca_fmr_alloc(struct mthca_dev *dev, u32 pd, | |||
585 | goto err_out_mailbox_free; | 582 | goto err_out_mailbox_free; |
586 | } | 583 | } |
587 | 584 | ||
588 | kfree(mailbox); | 585 | mthca_free_mailbox(dev, mailbox); |
589 | return 0; | 586 | return 0; |
590 | 587 | ||
591 | err_out_mailbox_free: | 588 | err_out_mailbox_free: |
592 | kfree(mailbox); | 589 | mthca_free_mailbox(dev, mailbox); |
593 | 590 | ||
594 | err_out_free_mtt: | 591 | err_out_free_mtt: |
595 | mthca_free_mtt(dev, mr->first_seg, mr->order, | 592 | mthca_free_mtt(dev, mr->mtt); |
596 | dev->mr_table.fmr_mtt_buddy); | ||
597 | 593 | ||
598 | err_out_table: | 594 | err_out_table: |
599 | if (mthca_is_memfree(dev)) | 595 | mthca_table_put(dev, dev->mr_table.mpt_table, key); |
600 | mthca_table_put(dev, dev->mr_table.mpt_table, key); | ||
601 | 596 | ||
602 | err_out_mpt_free: | 597 | err_out_mpt_free: |
603 | mthca_free(&dev->mr_table.mpt_alloc, mr->ibmr.lkey); | 598 | mthca_free(&dev->mr_table.mpt_alloc, mr->ibmr.lkey); |
@@ -609,8 +604,9 @@ int mthca_free_fmr(struct mthca_dev *dev, struct mthca_fmr *fmr) | |||
609 | if (fmr->maps) | 604 | if (fmr->maps) |
610 | return -EBUSY; | 605 | return -EBUSY; |
611 | 606 | ||
612 | mthca_free_region(dev, fmr->ibmr.lkey, fmr->order, fmr->first_seg, | 607 | mthca_free_region(dev, fmr->ibmr.lkey); |
613 | dev->mr_table.fmr_mtt_buddy); | 608 | mthca_free_mtt(dev, fmr->mtt); |
609 | |||
614 | return 0; | 610 | return 0; |
615 | } | 611 | } |
616 | 612 | ||
@@ -826,7 +822,8 @@ int __devinit mthca_init_mr_table(struct mthca_dev *dev) | |||
826 | if (dev->limits.reserved_mtts) { | 822 | if (dev->limits.reserved_mtts) { |
827 | i = fls(dev->limits.reserved_mtts - 1); | 823 | i = fls(dev->limits.reserved_mtts - 1); |
828 | 824 | ||
829 | if (mthca_alloc_mtt(dev, i, dev->mr_table.fmr_mtt_buddy) == -1) { | 825 | if (mthca_alloc_mtt_range(dev, i, |
826 | dev->mr_table.fmr_mtt_buddy) == -1) { | ||
830 | mthca_warn(dev, "MTT table of order %d is too small.\n", | 827 | mthca_warn(dev, "MTT table of order %d is too small.\n", |
831 | dev->mr_table.fmr_mtt_buddy->max_order); | 828 | dev->mr_table.fmr_mtt_buddy->max_order); |
832 | err = -ENOMEM; | 829 | err = -ENOMEM; |
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index 159f4e6c312d..0b5adfd91597 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. | 2 | * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. |
3 | * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. | ||
3 | * | 4 | * |
4 | * This software is available to you under a choice of one of two | 5 | * This software is available to you under a choice of one of two |
5 | * licenses. You may choose to be licensed under the terms of the GNU | 6 | * licenses. You may choose to be licensed under the terms of the GNU |
@@ -52,7 +53,7 @@ static int mthca_query_device(struct ib_device *ibdev, | |||
52 | if (!in_mad || !out_mad) | 53 | if (!in_mad || !out_mad) |
53 | goto out; | 54 | goto out; |
54 | 55 | ||
55 | memset(props, 0, sizeof props); | 56 | memset(props, 0, sizeof *props); |
56 | 57 | ||
57 | props->fw_ver = mdev->fw_ver; | 58 | props->fw_ver = mdev->fw_ver; |
58 | 59 | ||
@@ -558,6 +559,7 @@ static struct ib_mr *mthca_reg_phys_mr(struct ib_pd *pd, | |||
558 | convert_access(acc), mr); | 559 | convert_access(acc), mr); |
559 | 560 | ||
560 | if (err) { | 561 | if (err) { |
562 | kfree(page_list); | ||
561 | kfree(mr); | 563 | kfree(mr); |
562 | return ERR_PTR(err); | 564 | return ERR_PTR(err); |
563 | } | 565 | } |
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.h b/drivers/infiniband/hw/mthca/mthca_provider.h index 619710f95a87..4d976cccb1a8 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.h +++ b/drivers/infiniband/hw/mthca/mthca_provider.h | |||
@@ -54,18 +54,18 @@ struct mthca_uar { | |||
54 | int index; | 54 | int index; |
55 | }; | 55 | }; |
56 | 56 | ||
57 | struct mthca_mtt; | ||
58 | |||
57 | struct mthca_mr { | 59 | struct mthca_mr { |
58 | struct ib_mr ibmr; | 60 | struct ib_mr ibmr; |
59 | int order; | 61 | struct mthca_mtt *mtt; |
60 | u32 first_seg; | ||
61 | }; | 62 | }; |
62 | 63 | ||
63 | struct mthca_fmr { | 64 | struct mthca_fmr { |
64 | struct ib_fmr ibmr; | 65 | struct ib_fmr ibmr; |
65 | struct ib_fmr_attr attr; | 66 | struct ib_fmr_attr attr; |
66 | int order; | 67 | struct mthca_mtt *mtt; |
67 | u32 first_seg; | 68 | int maps; |
68 | int maps; | ||
69 | union { | 69 | union { |
70 | struct { | 70 | struct { |
71 | struct mthca_mpt_entry __iomem *mpt; | 71 | struct mthca_mpt_entry __iomem *mpt; |
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c index ca73bab11a02..163a8ef4186f 100644 --- a/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/drivers/infiniband/hw/mthca/mthca_qp.c | |||
@@ -357,6 +357,9 @@ static const struct { | |||
357 | [UD] = (IB_QP_PKEY_INDEX | | 357 | [UD] = (IB_QP_PKEY_INDEX | |
358 | IB_QP_PORT | | 358 | IB_QP_PORT | |
359 | IB_QP_QKEY), | 359 | IB_QP_QKEY), |
360 | [UC] = (IB_QP_PKEY_INDEX | | ||
361 | IB_QP_PORT | | ||
362 | IB_QP_ACCESS_FLAGS), | ||
360 | [RC] = (IB_QP_PKEY_INDEX | | 363 | [RC] = (IB_QP_PKEY_INDEX | |
361 | IB_QP_PORT | | 364 | IB_QP_PORT | |
362 | IB_QP_ACCESS_FLAGS), | 365 | IB_QP_ACCESS_FLAGS), |
@@ -378,6 +381,9 @@ static const struct { | |||
378 | [UD] = (IB_QP_PKEY_INDEX | | 381 | [UD] = (IB_QP_PKEY_INDEX | |
379 | IB_QP_PORT | | 382 | IB_QP_PORT | |
380 | IB_QP_QKEY), | 383 | IB_QP_QKEY), |
384 | [UC] = (IB_QP_PKEY_INDEX | | ||
385 | IB_QP_PORT | | ||
386 | IB_QP_ACCESS_FLAGS), | ||
381 | [RC] = (IB_QP_PKEY_INDEX | | 387 | [RC] = (IB_QP_PKEY_INDEX | |
382 | IB_QP_PORT | | 388 | IB_QP_PORT | |
383 | IB_QP_ACCESS_FLAGS), | 389 | IB_QP_ACCESS_FLAGS), |
@@ -388,6 +394,11 @@ static const struct { | |||
388 | [IB_QPS_RTR] = { | 394 | [IB_QPS_RTR] = { |
389 | .trans = MTHCA_TRANS_INIT2RTR, | 395 | .trans = MTHCA_TRANS_INIT2RTR, |
390 | .req_param = { | 396 | .req_param = { |
397 | [UC] = (IB_QP_AV | | ||
398 | IB_QP_PATH_MTU | | ||
399 | IB_QP_DEST_QPN | | ||
400 | IB_QP_RQ_PSN | | ||
401 | IB_QP_MAX_DEST_RD_ATOMIC), | ||
391 | [RC] = (IB_QP_AV | | 402 | [RC] = (IB_QP_AV | |
392 | IB_QP_PATH_MTU | | 403 | IB_QP_PATH_MTU | |
393 | IB_QP_DEST_QPN | | 404 | IB_QP_DEST_QPN | |
@@ -398,6 +409,9 @@ static const struct { | |||
398 | .opt_param = { | 409 | .opt_param = { |
399 | [UD] = (IB_QP_PKEY_INDEX | | 410 | [UD] = (IB_QP_PKEY_INDEX | |
400 | IB_QP_QKEY), | 411 | IB_QP_QKEY), |
412 | [UC] = (IB_QP_ALT_PATH | | ||
413 | IB_QP_ACCESS_FLAGS | | ||
414 | IB_QP_PKEY_INDEX), | ||
401 | [RC] = (IB_QP_ALT_PATH | | 415 | [RC] = (IB_QP_ALT_PATH | |
402 | IB_QP_ACCESS_FLAGS | | 416 | IB_QP_ACCESS_FLAGS | |
403 | IB_QP_PKEY_INDEX), | 417 | IB_QP_PKEY_INDEX), |
@@ -413,6 +427,8 @@ static const struct { | |||
413 | .trans = MTHCA_TRANS_RTR2RTS, | 427 | .trans = MTHCA_TRANS_RTR2RTS, |
414 | .req_param = { | 428 | .req_param = { |
415 | [UD] = IB_QP_SQ_PSN, | 429 | [UD] = IB_QP_SQ_PSN, |
430 | [UC] = (IB_QP_SQ_PSN | | ||
431 | IB_QP_MAX_QP_RD_ATOMIC), | ||
416 | [RC] = (IB_QP_TIMEOUT | | 432 | [RC] = (IB_QP_TIMEOUT | |
417 | IB_QP_RETRY_CNT | | 433 | IB_QP_RETRY_CNT | |
418 | IB_QP_RNR_RETRY | | 434 | IB_QP_RNR_RETRY | |
@@ -423,6 +439,11 @@ static const struct { | |||
423 | .opt_param = { | 439 | .opt_param = { |
424 | [UD] = (IB_QP_CUR_STATE | | 440 | [UD] = (IB_QP_CUR_STATE | |
425 | IB_QP_QKEY), | 441 | IB_QP_QKEY), |
442 | [UC] = (IB_QP_CUR_STATE | | ||
443 | IB_QP_ALT_PATH | | ||
444 | IB_QP_ACCESS_FLAGS | | ||
445 | IB_QP_PKEY_INDEX | | ||
446 | IB_QP_PATH_MIG_STATE), | ||
426 | [RC] = (IB_QP_CUR_STATE | | 447 | [RC] = (IB_QP_CUR_STATE | |
427 | IB_QP_ALT_PATH | | 448 | IB_QP_ALT_PATH | |
428 | IB_QP_ACCESS_FLAGS | | 449 | IB_QP_ACCESS_FLAGS | |
@@ -442,6 +463,9 @@ static const struct { | |||
442 | .opt_param = { | 463 | .opt_param = { |
443 | [UD] = (IB_QP_CUR_STATE | | 464 | [UD] = (IB_QP_CUR_STATE | |
444 | IB_QP_QKEY), | 465 | IB_QP_QKEY), |
466 | [UC] = (IB_QP_ACCESS_FLAGS | | ||
467 | IB_QP_ALT_PATH | | ||
468 | IB_QP_PATH_MIG_STATE), | ||
445 | [RC] = (IB_QP_ACCESS_FLAGS | | 469 | [RC] = (IB_QP_ACCESS_FLAGS | |
446 | IB_QP_ALT_PATH | | 470 | IB_QP_ALT_PATH | |
447 | IB_QP_PATH_MIG_STATE | | 471 | IB_QP_PATH_MIG_STATE | |
@@ -462,6 +486,10 @@ static const struct { | |||
462 | .opt_param = { | 486 | .opt_param = { |
463 | [UD] = (IB_QP_CUR_STATE | | 487 | [UD] = (IB_QP_CUR_STATE | |
464 | IB_QP_QKEY), | 488 | IB_QP_QKEY), |
489 | [UC] = (IB_QP_CUR_STATE | | ||
490 | IB_QP_ALT_PATH | | ||
491 | IB_QP_ACCESS_FLAGS | | ||
492 | IB_QP_PATH_MIG_STATE), | ||
465 | [RC] = (IB_QP_CUR_STATE | | 493 | [RC] = (IB_QP_CUR_STATE | |
466 | IB_QP_ALT_PATH | | 494 | IB_QP_ALT_PATH | |
467 | IB_QP_ACCESS_FLAGS | | 495 | IB_QP_ACCESS_FLAGS | |
@@ -476,6 +504,14 @@ static const struct { | |||
476 | .opt_param = { | 504 | .opt_param = { |
477 | [UD] = (IB_QP_PKEY_INDEX | | 505 | [UD] = (IB_QP_PKEY_INDEX | |
478 | IB_QP_QKEY), | 506 | IB_QP_QKEY), |
507 | [UC] = (IB_QP_AV | | ||
508 | IB_QP_MAX_QP_RD_ATOMIC | | ||
509 | IB_QP_MAX_DEST_RD_ATOMIC | | ||
510 | IB_QP_CUR_STATE | | ||
511 | IB_QP_ALT_PATH | | ||
512 | IB_QP_ACCESS_FLAGS | | ||
513 | IB_QP_PKEY_INDEX | | ||
514 | IB_QP_PATH_MIG_STATE), | ||
479 | [RC] = (IB_QP_AV | | 515 | [RC] = (IB_QP_AV | |
480 | IB_QP_TIMEOUT | | 516 | IB_QP_TIMEOUT | |
481 | IB_QP_RETRY_CNT | | 517 | IB_QP_RETRY_CNT | |
@@ -501,6 +537,7 @@ static const struct { | |||
501 | .opt_param = { | 537 | .opt_param = { |
502 | [UD] = (IB_QP_CUR_STATE | | 538 | [UD] = (IB_QP_CUR_STATE | |
503 | IB_QP_QKEY), | 539 | IB_QP_QKEY), |
540 | [UC] = (IB_QP_CUR_STATE), | ||
504 | [RC] = (IB_QP_CUR_STATE | | 541 | [RC] = (IB_QP_CUR_STATE | |
505 | IB_QP_MIN_RNR_TIMER), | 542 | IB_QP_MIN_RNR_TIMER), |
506 | [MLX] = (IB_QP_CUR_STATE | | 543 | [MLX] = (IB_QP_CUR_STATE | |
@@ -552,7 +589,7 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | |||
552 | struct mthca_dev *dev = to_mdev(ibqp->device); | 589 | struct mthca_dev *dev = to_mdev(ibqp->device); |
553 | struct mthca_qp *qp = to_mqp(ibqp); | 590 | struct mthca_qp *qp = to_mqp(ibqp); |
554 | enum ib_qp_state cur_state, new_state; | 591 | enum ib_qp_state cur_state, new_state; |
555 | void *mailbox = NULL; | 592 | struct mthca_mailbox *mailbox; |
556 | struct mthca_qp_param *qp_param; | 593 | struct mthca_qp_param *qp_param; |
557 | struct mthca_qp_context *qp_context; | 594 | struct mthca_qp_context *qp_context; |
558 | u32 req_param, opt_param; | 595 | u32 req_param, opt_param; |
@@ -609,10 +646,10 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | |||
609 | return -EINVAL; | 646 | return -EINVAL; |
610 | } | 647 | } |
611 | 648 | ||
612 | mailbox = kmalloc(sizeof (*qp_param) + MTHCA_CMD_MAILBOX_EXTRA, GFP_KERNEL); | 649 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); |
613 | if (!mailbox) | 650 | if (IS_ERR(mailbox)) |
614 | return -ENOMEM; | 651 | return PTR_ERR(mailbox); |
615 | qp_param = MAILBOX_ALIGN(mailbox); | 652 | qp_param = mailbox->buf; |
616 | qp_context = &qp_param->context; | 653 | qp_context = &qp_param->context; |
617 | memset(qp_param, 0, sizeof *qp_param); | 654 | memset(qp_param, 0, sizeof *qp_param); |
618 | 655 | ||
@@ -683,7 +720,7 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | |||
683 | if (attr_mask & IB_QP_AV) { | 720 | if (attr_mask & IB_QP_AV) { |
684 | qp_context->pri_path.g_mylmc = attr->ah_attr.src_path_bits & 0x7f; | 721 | qp_context->pri_path.g_mylmc = attr->ah_attr.src_path_bits & 0x7f; |
685 | qp_context->pri_path.rlid = cpu_to_be16(attr->ah_attr.dlid); | 722 | qp_context->pri_path.rlid = cpu_to_be16(attr->ah_attr.dlid); |
686 | qp_context->pri_path.static_rate = (!!attr->ah_attr.static_rate) << 3; | 723 | qp_context->pri_path.static_rate = !!attr->ah_attr.static_rate; |
687 | if (attr->ah_attr.ah_flags & IB_AH_GRH) { | 724 | if (attr->ah_attr.ah_flags & IB_AH_GRH) { |
688 | qp_context->pri_path.g_mylmc |= 1 << 7; | 725 | qp_context->pri_path.g_mylmc |= 1 << 7; |
689 | qp_context->pri_path.mgid_index = attr->ah_attr.grh.sgid_index; | 726 | qp_context->pri_path.mgid_index = attr->ah_attr.grh.sgid_index; |
@@ -724,9 +761,9 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | |||
724 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RETRY_COUNT); | 761 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RETRY_COUNT); |
725 | } | 762 | } |
726 | 763 | ||
727 | if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) { | 764 | if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC) { |
728 | qp_context->params1 |= cpu_to_be32(min(attr->max_dest_rd_atomic ? | 765 | qp_context->params1 |= cpu_to_be32(min(attr->max_rd_atomic ? |
729 | ffs(attr->max_dest_rd_atomic) - 1 : 0, | 766 | ffs(attr->max_rd_atomic) - 1 : 0, |
730 | 7) << 21); | 767 | 7) << 21); |
731 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_SRA_MAX); | 768 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_SRA_MAX); |
732 | } | 769 | } |
@@ -764,10 +801,10 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | |||
764 | qp->atomic_rd_en = attr->qp_access_flags; | 801 | qp->atomic_rd_en = attr->qp_access_flags; |
765 | } | 802 | } |
766 | 803 | ||
767 | if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC) { | 804 | if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) { |
768 | u8 rra_max; | 805 | u8 rra_max; |
769 | 806 | ||
770 | if (qp->resp_depth && !attr->max_rd_atomic) { | 807 | if (qp->resp_depth && !attr->max_dest_rd_atomic) { |
771 | /* | 808 | /* |
772 | * Lowering our responder resources to zero. | 809 | * Lowering our responder resources to zero. |
773 | * Turn off RDMA/atomics as responder. | 810 | * Turn off RDMA/atomics as responder. |
@@ -778,7 +815,7 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | |||
778 | MTHCA_QP_OPTPAR_RAE); | 815 | MTHCA_QP_OPTPAR_RAE); |
779 | } | 816 | } |
780 | 817 | ||
781 | if (!qp->resp_depth && attr->max_rd_atomic) { | 818 | if (!qp->resp_depth && attr->max_dest_rd_atomic) { |
782 | /* | 819 | /* |
783 | * Increasing our responder resources from | 820 | * Increasing our responder resources from |
784 | * zero. Turn on RDMA/atomics as appropriate. | 821 | * zero. Turn on RDMA/atomics as appropriate. |
@@ -799,7 +836,7 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | |||
799 | } | 836 | } |
800 | 837 | ||
801 | for (rra_max = 0; | 838 | for (rra_max = 0; |
802 | 1 << rra_max < attr->max_rd_atomic && | 839 | 1 << rra_max < attr->max_dest_rd_atomic && |
803 | rra_max < dev->qp_table.rdb_shift; | 840 | rra_max < dev->qp_table.rdb_shift; |
804 | ++rra_max) | 841 | ++rra_max) |
805 | ; /* nothing */ | 842 | ; /* nothing */ |
@@ -807,7 +844,7 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | |||
807 | qp_context->params2 |= cpu_to_be32(rra_max << 21); | 844 | qp_context->params2 |= cpu_to_be32(rra_max << 21); |
808 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRA_MAX); | 845 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRA_MAX); |
809 | 846 | ||
810 | qp->resp_depth = attr->max_rd_atomic; | 847 | qp->resp_depth = attr->max_dest_rd_atomic; |
811 | } | 848 | } |
812 | 849 | ||
813 | qp_context->params2 |= cpu_to_be32(MTHCA_QP_BIT_RSC); | 850 | qp_context->params2 |= cpu_to_be32(MTHCA_QP_BIT_RSC); |
@@ -835,7 +872,7 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | |||
835 | } | 872 | } |
836 | 873 | ||
837 | err = mthca_MODIFY_QP(dev, state_table[cur_state][new_state].trans, | 874 | err = mthca_MODIFY_QP(dev, state_table[cur_state][new_state].trans, |
838 | qp->qpn, 0, qp_param, 0, &status); | 875 | qp->qpn, 0, mailbox, 0, &status); |
839 | if (status) { | 876 | if (status) { |
840 | mthca_warn(dev, "modify QP %d returned status %02x.\n", | 877 | mthca_warn(dev, "modify QP %d returned status %02x.\n", |
841 | state_table[cur_state][new_state].trans, status); | 878 | state_table[cur_state][new_state].trans, status); |
@@ -845,7 +882,7 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | |||
845 | if (!err) | 882 | if (!err) |
846 | qp->state = new_state; | 883 | qp->state = new_state; |
847 | 884 | ||
848 | kfree(mailbox); | 885 | mthca_free_mailbox(dev, mailbox); |
849 | 886 | ||
850 | if (is_sqp(dev, qp)) | 887 | if (is_sqp(dev, qp)) |
851 | store_attrs(to_msqp(qp), attr, attr_mask); | 888 | store_attrs(to_msqp(qp), attr, attr_mask); |
@@ -934,7 +971,8 @@ static int mthca_alloc_wqe_buf(struct mthca_dev *dev, | |||
934 | mthca_dbg(dev, "Creating direct QP of size %d (shift %d)\n", | 971 | mthca_dbg(dev, "Creating direct QP of size %d (shift %d)\n", |
935 | size, shift); | 972 | size, shift); |
936 | 973 | ||
937 | qp->queue.direct.buf = pci_alloc_consistent(dev->pdev, size, &t); | 974 | qp->queue.direct.buf = dma_alloc_coherent(&dev->pdev->dev, size, |
975 | &t, GFP_KERNEL); | ||
938 | if (!qp->queue.direct.buf) | 976 | if (!qp->queue.direct.buf) |
939 | goto err_out; | 977 | goto err_out; |
940 | 978 | ||
@@ -973,7 +1011,8 @@ static int mthca_alloc_wqe_buf(struct mthca_dev *dev, | |||
973 | 1011 | ||
974 | for (i = 0; i < npages; ++i) { | 1012 | for (i = 0; i < npages; ++i) { |
975 | qp->queue.page_list[i].buf = | 1013 | qp->queue.page_list[i].buf = |
976 | pci_alloc_consistent(dev->pdev, PAGE_SIZE, &t); | 1014 | dma_alloc_coherent(&dev->pdev->dev, PAGE_SIZE, |
1015 | &t, GFP_KERNEL); | ||
977 | if (!qp->queue.page_list[i].buf) | 1016 | if (!qp->queue.page_list[i].buf) |
978 | goto err_out_free; | 1017 | goto err_out_free; |
979 | 1018 | ||
@@ -996,16 +1035,15 @@ static int mthca_alloc_wqe_buf(struct mthca_dev *dev, | |||
996 | 1035 | ||
997 | err_out_free: | 1036 | err_out_free: |
998 | if (qp->is_direct) { | 1037 | if (qp->is_direct) { |
999 | pci_free_consistent(dev->pdev, size, | 1038 | dma_free_coherent(&dev->pdev->dev, size, qp->queue.direct.buf, |
1000 | qp->queue.direct.buf, | 1039 | pci_unmap_addr(&qp->queue.direct, mapping)); |
1001 | pci_unmap_addr(&qp->queue.direct, mapping)); | ||
1002 | } else | 1040 | } else |
1003 | for (i = 0; i < npages; ++i) { | 1041 | for (i = 0; i < npages; ++i) { |
1004 | if (qp->queue.page_list[i].buf) | 1042 | if (qp->queue.page_list[i].buf) |
1005 | pci_free_consistent(dev->pdev, PAGE_SIZE, | 1043 | dma_free_coherent(&dev->pdev->dev, PAGE_SIZE, |
1006 | qp->queue.page_list[i].buf, | 1044 | qp->queue.page_list[i].buf, |
1007 | pci_unmap_addr(&qp->queue.page_list[i], | 1045 | pci_unmap_addr(&qp->queue.page_list[i], |
1008 | mapping)); | 1046 | mapping)); |
1009 | 1047 | ||
1010 | } | 1048 | } |
1011 | 1049 | ||
@@ -1073,11 +1111,12 @@ static void mthca_free_memfree(struct mthca_dev *dev, | |||
1073 | if (mthca_is_memfree(dev)) { | 1111 | if (mthca_is_memfree(dev)) { |
1074 | mthca_free_db(dev, MTHCA_DB_TYPE_SQ, qp->sq.db_index); | 1112 | mthca_free_db(dev, MTHCA_DB_TYPE_SQ, qp->sq.db_index); |
1075 | mthca_free_db(dev, MTHCA_DB_TYPE_RQ, qp->rq.db_index); | 1113 | mthca_free_db(dev, MTHCA_DB_TYPE_RQ, qp->rq.db_index); |
1076 | mthca_table_put(dev, dev->qp_table.rdb_table, | ||
1077 | qp->qpn << dev->qp_table.rdb_shift); | ||
1078 | mthca_table_put(dev, dev->qp_table.eqp_table, qp->qpn); | ||
1079 | mthca_table_put(dev, dev->qp_table.qp_table, qp->qpn); | ||
1080 | } | 1114 | } |
1115 | |||
1116 | mthca_table_put(dev, dev->qp_table.rdb_table, | ||
1117 | qp->qpn << dev->qp_table.rdb_shift); | ||
1118 | mthca_table_put(dev, dev->qp_table.eqp_table, qp->qpn); | ||
1119 | mthca_table_put(dev, dev->qp_table.qp_table, qp->qpn); | ||
1081 | } | 1120 | } |
1082 | 1121 | ||
1083 | static void mthca_wq_init(struct mthca_wq* wq) | 1122 | static void mthca_wq_init(struct mthca_wq* wq) |
@@ -1529,6 +1568,26 @@ int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
1529 | 1568 | ||
1530 | break; | 1569 | break; |
1531 | 1570 | ||
1571 | case UC: | ||
1572 | switch (wr->opcode) { | ||
1573 | case IB_WR_RDMA_WRITE: | ||
1574 | case IB_WR_RDMA_WRITE_WITH_IMM: | ||
1575 | ((struct mthca_raddr_seg *) wqe)->raddr = | ||
1576 | cpu_to_be64(wr->wr.rdma.remote_addr); | ||
1577 | ((struct mthca_raddr_seg *) wqe)->rkey = | ||
1578 | cpu_to_be32(wr->wr.rdma.rkey); | ||
1579 | ((struct mthca_raddr_seg *) wqe)->reserved = 0; | ||
1580 | wqe += sizeof (struct mthca_raddr_seg); | ||
1581 | size += sizeof (struct mthca_raddr_seg) / 16; | ||
1582 | break; | ||
1583 | |||
1584 | default: | ||
1585 | /* No extra segments required for sends */ | ||
1586 | break; | ||
1587 | } | ||
1588 | |||
1589 | break; | ||
1590 | |||
1532 | case UD: | 1591 | case UD: |
1533 | ((struct mthca_tavor_ud_seg *) wqe)->lkey = | 1592 | ((struct mthca_tavor_ud_seg *) wqe)->lkey = |
1534 | cpu_to_be32(to_mah(wr->wr.ud.ah)->key); | 1593 | cpu_to_be32(to_mah(wr->wr.ud.ah)->key); |
@@ -1814,9 +1873,29 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
1814 | sizeof (struct mthca_atomic_seg); | 1873 | sizeof (struct mthca_atomic_seg); |
1815 | break; | 1874 | break; |
1816 | 1875 | ||
1876 | case IB_WR_RDMA_READ: | ||
1877 | case IB_WR_RDMA_WRITE: | ||
1878 | case IB_WR_RDMA_WRITE_WITH_IMM: | ||
1879 | ((struct mthca_raddr_seg *) wqe)->raddr = | ||
1880 | cpu_to_be64(wr->wr.rdma.remote_addr); | ||
1881 | ((struct mthca_raddr_seg *) wqe)->rkey = | ||
1882 | cpu_to_be32(wr->wr.rdma.rkey); | ||
1883 | ((struct mthca_raddr_seg *) wqe)->reserved = 0; | ||
1884 | wqe += sizeof (struct mthca_raddr_seg); | ||
1885 | size += sizeof (struct mthca_raddr_seg) / 16; | ||
1886 | break; | ||
1887 | |||
1888 | default: | ||
1889 | /* No extra segments required for sends */ | ||
1890 | break; | ||
1891 | } | ||
1892 | |||
1893 | break; | ||
1894 | |||
1895 | case UC: | ||
1896 | switch (wr->opcode) { | ||
1817 | case IB_WR_RDMA_WRITE: | 1897 | case IB_WR_RDMA_WRITE: |
1818 | case IB_WR_RDMA_WRITE_WITH_IMM: | 1898 | case IB_WR_RDMA_WRITE_WITH_IMM: |
1819 | case IB_WR_RDMA_READ: | ||
1820 | ((struct mthca_raddr_seg *) wqe)->raddr = | 1899 | ((struct mthca_raddr_seg *) wqe)->raddr = |
1821 | cpu_to_be64(wr->wr.rdma.remote_addr); | 1900 | cpu_to_be64(wr->wr.rdma.remote_addr); |
1822 | ((struct mthca_raddr_seg *) wqe)->rkey = | 1901 | ((struct mthca_raddr_seg *) wqe)->rkey = |