diff options
Diffstat (limited to 'drivers/net/myri10ge')
-rw-r--r-- | drivers/net/myri10ge/myri10ge.c | 121 |
1 files changed, 68 insertions, 53 deletions
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 3245357a06f2..f53b0dad65ab 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c | |||
@@ -714,14 +714,78 @@ myri10ge_change_promisc(struct myri10ge_priv *mgp, int promisc, int atomic) | |||
714 | mgp->dev->name); | 714 | mgp->dev->name); |
715 | } | 715 | } |
716 | 716 | ||
717 | static int myri10ge_reset(struct myri10ge_priv *mgp) | 717 | static int myri10ge_dma_test(struct myri10ge_priv *mgp, int test_type) |
718 | { | 718 | { |
719 | struct myri10ge_cmd cmd; | 719 | struct myri10ge_cmd cmd; |
720 | int status; | 720 | int status; |
721 | size_t bytes; | ||
722 | u32 len; | 721 | u32 len; |
723 | struct page *dmatest_page; | 722 | struct page *dmatest_page; |
724 | dma_addr_t dmatest_bus; | 723 | dma_addr_t dmatest_bus; |
724 | char *test = " "; | ||
725 | |||
726 | dmatest_page = alloc_page(GFP_KERNEL); | ||
727 | if (!dmatest_page) | ||
728 | return -ENOMEM; | ||
729 | dmatest_bus = pci_map_page(mgp->pdev, dmatest_page, 0, PAGE_SIZE, | ||
730 | DMA_BIDIRECTIONAL); | ||
731 | |||
732 | /* Run a small DMA test. | ||
733 | * The magic multipliers to the length tell the firmware | ||
734 | * to do DMA read, write, or read+write tests. The | ||
735 | * results are returned in cmd.data0. The upper 16 | ||
736 | * bits or the return is the number of transfers completed. | ||
737 | * The lower 16 bits is the time in 0.5us ticks that the | ||
738 | * transfers took to complete. | ||
739 | */ | ||
740 | |||
741 | len = mgp->tx.boundary; | ||
742 | |||
743 | cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus); | ||
744 | cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus); | ||
745 | cmd.data2 = len * 0x10000; | ||
746 | status = myri10ge_send_cmd(mgp, test_type, &cmd, 0); | ||
747 | if (status != 0) { | ||
748 | test = "read"; | ||
749 | goto abort; | ||
750 | } | ||
751 | mgp->read_dma = ((cmd.data0 >> 16) * len * 2) / (cmd.data0 & 0xffff); | ||
752 | cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus); | ||
753 | cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus); | ||
754 | cmd.data2 = len * 0x1; | ||
755 | status = myri10ge_send_cmd(mgp, test_type, &cmd, 0); | ||
756 | if (status != 0) { | ||
757 | test = "write"; | ||
758 | goto abort; | ||
759 | } | ||
760 | mgp->write_dma = ((cmd.data0 >> 16) * len * 2) / (cmd.data0 & 0xffff); | ||
761 | |||
762 | cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus); | ||
763 | cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus); | ||
764 | cmd.data2 = len * 0x10001; | ||
765 | status = myri10ge_send_cmd(mgp, test_type, &cmd, 0); | ||
766 | if (status != 0) { | ||
767 | test = "read/write"; | ||
768 | goto abort; | ||
769 | } | ||
770 | mgp->read_write_dma = ((cmd.data0 >> 16) * len * 2 * 2) / | ||
771 | (cmd.data0 & 0xffff); | ||
772 | |||
773 | abort: | ||
774 | pci_unmap_page(mgp->pdev, dmatest_bus, PAGE_SIZE, DMA_BIDIRECTIONAL); | ||
775 | put_page(dmatest_page); | ||
776 | |||
777 | if (status != 0 && test_type != MXGEFW_CMD_UNALIGNED_TEST) | ||
778 | dev_warn(&mgp->pdev->dev, "DMA %s benchmark failed: %d\n", | ||
779 | test, status); | ||
780 | |||
781 | return status; | ||
782 | } | ||
783 | |||
784 | static int myri10ge_reset(struct myri10ge_priv *mgp) | ||
785 | { | ||
786 | struct myri10ge_cmd cmd; | ||
787 | int status; | ||
788 | size_t bytes; | ||
725 | 789 | ||
726 | /* try to send a reset command to the card to see if it | 790 | /* try to send a reset command to the card to see if it |
727 | * is alive */ | 791 | * is alive */ |
@@ -731,11 +795,8 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) | |||
731 | dev_err(&mgp->pdev->dev, "failed reset\n"); | 795 | dev_err(&mgp->pdev->dev, "failed reset\n"); |
732 | return -ENXIO; | 796 | return -ENXIO; |
733 | } | 797 | } |
734 | dmatest_page = alloc_page(GFP_KERNEL); | 798 | |
735 | if (!dmatest_page) | 799 | (void)myri10ge_dma_test(mgp, MXGEFW_DMA_TEST); |
736 | return -ENOMEM; | ||
737 | dmatest_bus = pci_map_page(mgp->pdev, dmatest_page, 0, PAGE_SIZE, | ||
738 | DMA_BIDIRECTIONAL); | ||
739 | 800 | ||
740 | /* Now exchange information about interrupts */ | 801 | /* Now exchange information about interrupts */ |
741 | 802 | ||
@@ -763,52 +824,6 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) | |||
763 | } | 824 | } |
764 | put_be32(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr); | 825 | put_be32(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr); |
765 | 826 | ||
766 | /* Run a small DMA test. | ||
767 | * The magic multipliers to the length tell the firmware | ||
768 | * to do DMA read, write, or read+write tests. The | ||
769 | * results are returned in cmd.data0. The upper 16 | ||
770 | * bits or the return is the number of transfers completed. | ||
771 | * The lower 16 bits is the time in 0.5us ticks that the | ||
772 | * transfers took to complete. | ||
773 | */ | ||
774 | |||
775 | len = mgp->tx.boundary; | ||
776 | |||
777 | cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus); | ||
778 | cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus); | ||
779 | cmd.data2 = len * 0x10000; | ||
780 | status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0); | ||
781 | if (status == 0) | ||
782 | mgp->read_dma = ((cmd.data0 >> 16) * len * 2) / | ||
783 | (cmd.data0 & 0xffff); | ||
784 | else | ||
785 | dev_warn(&mgp->pdev->dev, "DMA read benchmark failed: %d\n", | ||
786 | status); | ||
787 | cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus); | ||
788 | cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus); | ||
789 | cmd.data2 = len * 0x1; | ||
790 | status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0); | ||
791 | if (status == 0) | ||
792 | mgp->write_dma = ((cmd.data0 >> 16) * len * 2) / | ||
793 | (cmd.data0 & 0xffff); | ||
794 | else | ||
795 | dev_warn(&mgp->pdev->dev, "DMA write benchmark failed: %d\n", | ||
796 | status); | ||
797 | |||
798 | cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus); | ||
799 | cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus); | ||
800 | cmd.data2 = len * 0x10001; | ||
801 | status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0); | ||
802 | if (status == 0) | ||
803 | mgp->read_write_dma = ((cmd.data0 >> 16) * len * 2 * 2) / | ||
804 | (cmd.data0 & 0xffff); | ||
805 | else | ||
806 | dev_warn(&mgp->pdev->dev, | ||
807 | "DMA read/write benchmark failed: %d\n", status); | ||
808 | |||
809 | pci_unmap_page(mgp->pdev, dmatest_bus, PAGE_SIZE, DMA_BIDIRECTIONAL); | ||
810 | put_page(dmatest_page); | ||
811 | |||
812 | memset(mgp->rx_done.entry, 0, bytes); | 827 | memset(mgp->rx_done.entry, 0, bytes); |
813 | 828 | ||
814 | /* reset mcp/driver shared state back to 0 */ | 829 | /* reset mcp/driver shared state back to 0 */ |