aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/myri10ge
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/myri10ge')
-rw-r--r--drivers/net/myri10ge/myri10ge.c121
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
717static int myri10ge_reset(struct myri10ge_priv *mgp) 717static 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
773abort:
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
784static 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 */