diff options
Diffstat (limited to 'drivers/net/sunqe.c')
-rw-r--r-- | drivers/net/sunqe.c | 162 |
1 files changed, 77 insertions, 85 deletions
diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c index e811331d4608..f63644744ff9 100644 --- a/drivers/net/sunqe.c +++ b/drivers/net/sunqe.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * controller out there can be most efficiently programmed | 3 | * controller out there can be most efficiently programmed |
4 | * if you make it look like a LANCE. | 4 | * if you make it look like a LANCE. |
5 | * | 5 | * |
6 | * Copyright (C) 1996, 1999, 2003, 2006 David S. Miller (davem@davemloft.net) | 6 | * Copyright (C) 1996, 1999, 2003, 2006, 2008 David S. Miller (davem@davemloft.net) |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
@@ -24,13 +24,15 @@ | |||
24 | #include <linux/skbuff.h> | 24 | #include <linux/skbuff.h> |
25 | #include <linux/ethtool.h> | 25 | #include <linux/ethtool.h> |
26 | #include <linux/bitops.h> | 26 | #include <linux/bitops.h> |
27 | #include <linux/dma-mapping.h> | ||
28 | #include <linux/of.h> | ||
29 | #include <linux/of_device.h> | ||
27 | 30 | ||
28 | #include <asm/system.h> | 31 | #include <asm/system.h> |
29 | #include <asm/io.h> | 32 | #include <asm/io.h> |
30 | #include <asm/dma.h> | 33 | #include <asm/dma.h> |
31 | #include <asm/byteorder.h> | 34 | #include <asm/byteorder.h> |
32 | #include <asm/idprom.h> | 35 | #include <asm/idprom.h> |
33 | #include <asm/sbus.h> | ||
34 | #include <asm/openprom.h> | 36 | #include <asm/openprom.h> |
35 | #include <asm/oplib.h> | 37 | #include <asm/oplib.h> |
36 | #include <asm/auxio.h> | 38 | #include <asm/auxio.h> |
@@ -40,8 +42,8 @@ | |||
40 | #include "sunqe.h" | 42 | #include "sunqe.h" |
41 | 43 | ||
42 | #define DRV_NAME "sunqe" | 44 | #define DRV_NAME "sunqe" |
43 | #define DRV_VERSION "4.0" | 45 | #define DRV_VERSION "4.1" |
44 | #define DRV_RELDATE "June 23, 2006" | 46 | #define DRV_RELDATE "August 27, 2008" |
45 | #define DRV_AUTHOR "David S. Miller (davem@davemloft.net)" | 47 | #define DRV_AUTHOR "David S. Miller (davem@davemloft.net)" |
46 | 48 | ||
47 | static char version[] = | 49 | static char version[] = |
@@ -690,12 +692,18 @@ static void qe_set_multicast(struct net_device *dev) | |||
690 | /* Ethtool support... */ | 692 | /* Ethtool support... */ |
691 | static void qe_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | 693 | static void qe_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) |
692 | { | 694 | { |
695 | const struct linux_prom_registers *regs; | ||
693 | struct sunqe *qep = dev->priv; | 696 | struct sunqe *qep = dev->priv; |
697 | struct of_device *op; | ||
694 | 698 | ||
695 | strcpy(info->driver, "sunqe"); | 699 | strcpy(info->driver, "sunqe"); |
696 | strcpy(info->version, "3.0"); | 700 | strcpy(info->version, "3.0"); |
697 | sprintf(info->bus_info, "SBUS:%d", | 701 | |
698 | qep->qe_sdev->slot); | 702 | op = qep->op; |
703 | regs = of_get_property(op->node, "reg", NULL); | ||
704 | if (regs) | ||
705 | sprintf(info->bus_info, "SBUS:%d", regs->which_io); | ||
706 | |||
699 | } | 707 | } |
700 | 708 | ||
701 | static u32 qe_get_link(struct net_device *dev) | 709 | static u32 qe_get_link(struct net_device *dev) |
@@ -717,11 +725,11 @@ static const struct ethtool_ops qe_ethtool_ops = { | |||
717 | }; | 725 | }; |
718 | 726 | ||
719 | /* This is only called once at boot time for each card probed. */ | 727 | /* This is only called once at boot time for each card probed. */ |
720 | static inline void qec_init_once(struct sunqec *qecp, struct sbus_dev *qsdev) | 728 | static void qec_init_once(struct sunqec *qecp, struct of_device *op) |
721 | { | 729 | { |
722 | u8 bsizes = qecp->qec_bursts; | 730 | u8 bsizes = qecp->qec_bursts; |
723 | 731 | ||
724 | if (sbus_can_burst64(qsdev) && (bsizes & DMA_BURST64)) { | 732 | if (sbus_can_burst64() && (bsizes & DMA_BURST64)) { |
725 | sbus_writel(GLOB_CTRL_B64, qecp->gregs + GLOB_CTRL); | 733 | sbus_writel(GLOB_CTRL_B64, qecp->gregs + GLOB_CTRL); |
726 | } else if (bsizes & DMA_BURST32) { | 734 | } else if (bsizes & DMA_BURST32) { |
727 | sbus_writel(GLOB_CTRL_B32, qecp->gregs + GLOB_CTRL); | 735 | sbus_writel(GLOB_CTRL_B32, qecp->gregs + GLOB_CTRL); |
@@ -735,15 +743,15 @@ static inline void qec_init_once(struct sunqec *qecp, struct sbus_dev *qsdev) | |||
735 | sbus_writel(GLOB_PSIZE_2048, qecp->gregs + GLOB_PSIZE); | 743 | sbus_writel(GLOB_PSIZE_2048, qecp->gregs + GLOB_PSIZE); |
736 | 744 | ||
737 | /* Set the local memsize register, divided up to one piece per QE channel. */ | 745 | /* Set the local memsize register, divided up to one piece per QE channel. */ |
738 | sbus_writel((qsdev->reg_addrs[1].reg_size >> 2), | 746 | sbus_writel((resource_size(&op->resource[1]) >> 2), |
739 | qecp->gregs + GLOB_MSIZE); | 747 | qecp->gregs + GLOB_MSIZE); |
740 | 748 | ||
741 | /* Divide up the local QEC memory amongst the 4 QE receiver and | 749 | /* Divide up the local QEC memory amongst the 4 QE receiver and |
742 | * transmitter FIFOs. Basically it is (total / 2 / num_channels). | 750 | * transmitter FIFOs. Basically it is (total / 2 / num_channels). |
743 | */ | 751 | */ |
744 | sbus_writel((qsdev->reg_addrs[1].reg_size >> 2) >> 1, | 752 | sbus_writel((resource_size(&op->resource[1]) >> 2) >> 1, |
745 | qecp->gregs + GLOB_TSIZE); | 753 | qecp->gregs + GLOB_TSIZE); |
746 | sbus_writel((qsdev->reg_addrs[1].reg_size >> 2) >> 1, | 754 | sbus_writel((resource_size(&op->resource[1]) >> 2) >> 1, |
747 | qecp->gregs + GLOB_RSIZE); | 755 | qecp->gregs + GLOB_RSIZE); |
748 | } | 756 | } |
749 | 757 | ||
@@ -767,24 +775,21 @@ static u8 __devinit qec_get_burst(struct device_node *dp) | |||
767 | return bsizes; | 775 | return bsizes; |
768 | } | 776 | } |
769 | 777 | ||
770 | static struct sunqec * __devinit get_qec(struct sbus_dev *child_sdev) | 778 | static struct sunqec * __devinit get_qec(struct of_device *child) |
771 | { | 779 | { |
772 | struct sbus_dev *qec_sdev = child_sdev->parent; | 780 | struct of_device *op = to_of_device(child->dev.parent); |
773 | struct sunqec *qecp; | 781 | struct sunqec *qecp; |
774 | 782 | ||
775 | for (qecp = root_qec_dev; qecp; qecp = qecp->next_module) { | 783 | qecp = dev_get_drvdata(&op->dev); |
776 | if (qecp->qec_sdev == qec_sdev) | ||
777 | break; | ||
778 | } | ||
779 | if (!qecp) { | 784 | if (!qecp) { |
780 | qecp = kzalloc(sizeof(struct sunqec), GFP_KERNEL); | 785 | qecp = kzalloc(sizeof(struct sunqec), GFP_KERNEL); |
781 | if (qecp) { | 786 | if (qecp) { |
782 | u32 ctrl; | 787 | u32 ctrl; |
783 | 788 | ||
784 | qecp->qec_sdev = qec_sdev; | 789 | qecp->op = op; |
785 | qecp->gregs = sbus_ioremap(&qec_sdev->resource[0], 0, | 790 | qecp->gregs = of_ioremap(&op->resource[0], 0, |
786 | GLOB_REG_SIZE, | 791 | GLOB_REG_SIZE, |
787 | "QEC Global Registers"); | 792 | "QEC Global Registers"); |
788 | if (!qecp->gregs) | 793 | if (!qecp->gregs) |
789 | goto fail; | 794 | goto fail; |
790 | 795 | ||
@@ -799,16 +804,18 @@ static struct sunqec * __devinit get_qec(struct sbus_dev *child_sdev) | |||
799 | if (qec_global_reset(qecp->gregs)) | 804 | if (qec_global_reset(qecp->gregs)) |
800 | goto fail; | 805 | goto fail; |
801 | 806 | ||
802 | qecp->qec_bursts = qec_get_burst(qec_sdev->ofdev.node); | 807 | qecp->qec_bursts = qec_get_burst(op->node); |
803 | 808 | ||
804 | qec_init_once(qecp, qec_sdev); | 809 | qec_init_once(qecp, op); |
805 | 810 | ||
806 | if (request_irq(qec_sdev->irqs[0], &qec_interrupt, | 811 | if (request_irq(op->irqs[0], &qec_interrupt, |
807 | IRQF_SHARED, "qec", (void *) qecp)) { | 812 | IRQF_SHARED, "qec", (void *) qecp)) { |
808 | printk(KERN_ERR "qec: Can't register irq.\n"); | 813 | printk(KERN_ERR "qec: Can't register irq.\n"); |
809 | goto fail; | 814 | goto fail; |
810 | } | 815 | } |
811 | 816 | ||
817 | dev_set_drvdata(&op->dev, qecp); | ||
818 | |||
812 | qecp->next_module = root_qec_dev; | 819 | qecp->next_module = root_qec_dev; |
813 | root_qec_dev = qecp; | 820 | root_qec_dev = qecp; |
814 | } | 821 | } |
@@ -818,17 +825,17 @@ static struct sunqec * __devinit get_qec(struct sbus_dev *child_sdev) | |||
818 | 825 | ||
819 | fail: | 826 | fail: |
820 | if (qecp->gregs) | 827 | if (qecp->gregs) |
821 | sbus_iounmap(qecp->gregs, GLOB_REG_SIZE); | 828 | of_iounmap(&op->resource[0], qecp->gregs, GLOB_REG_SIZE); |
822 | kfree(qecp); | 829 | kfree(qecp); |
823 | return NULL; | 830 | return NULL; |
824 | } | 831 | } |
825 | 832 | ||
826 | static int __devinit qec_ether_init(struct sbus_dev *sdev) | 833 | static int __devinit qec_ether_init(struct of_device *op) |
827 | { | 834 | { |
828 | static unsigned version_printed; | 835 | static unsigned version_printed; |
829 | struct net_device *dev; | 836 | struct net_device *dev; |
830 | struct sunqe *qe; | ||
831 | struct sunqec *qecp; | 837 | struct sunqec *qecp; |
838 | struct sunqe *qe; | ||
832 | int i, res; | 839 | int i, res; |
833 | 840 | ||
834 | if (version_printed++ == 0) | 841 | if (version_printed++ == 0) |
@@ -842,49 +849,42 @@ static int __devinit qec_ether_init(struct sbus_dev *sdev) | |||
842 | 849 | ||
843 | qe = netdev_priv(dev); | 850 | qe = netdev_priv(dev); |
844 | 851 | ||
845 | i = of_getintprop_default(sdev->ofdev.node, "channel#", -1); | 852 | res = -ENODEV; |
846 | if (i == -1) { | 853 | |
847 | struct sbus_dev *td = sdev->parent->child; | 854 | i = of_getintprop_default(op->node, "channel#", -1); |
848 | i = 0; | 855 | if (i == -1) |
849 | while (td != sdev) { | 856 | goto fail; |
850 | td = td->next; | ||
851 | i++; | ||
852 | } | ||
853 | } | ||
854 | qe->channel = i; | 857 | qe->channel = i; |
855 | spin_lock_init(&qe->lock); | 858 | spin_lock_init(&qe->lock); |
856 | 859 | ||
857 | res = -ENODEV; | 860 | qecp = get_qec(op); |
858 | qecp = get_qec(sdev); | ||
859 | if (!qecp) | 861 | if (!qecp) |
860 | goto fail; | 862 | goto fail; |
861 | 863 | ||
862 | qecp->qes[qe->channel] = qe; | 864 | qecp->qes[qe->channel] = qe; |
863 | qe->dev = dev; | 865 | qe->dev = dev; |
864 | qe->parent = qecp; | 866 | qe->parent = qecp; |
865 | qe->qe_sdev = sdev; | 867 | qe->op = op; |
866 | 868 | ||
867 | res = -ENOMEM; | 869 | res = -ENOMEM; |
868 | qe->qcregs = sbus_ioremap(&qe->qe_sdev->resource[0], 0, | 870 | qe->qcregs = of_ioremap(&op->resource[0], 0, |
869 | CREG_REG_SIZE, "QEC Channel Registers"); | 871 | CREG_REG_SIZE, "QEC Channel Registers"); |
870 | if (!qe->qcregs) { | 872 | if (!qe->qcregs) { |
871 | printk(KERN_ERR "qe: Cannot map channel registers.\n"); | 873 | printk(KERN_ERR "qe: Cannot map channel registers.\n"); |
872 | goto fail; | 874 | goto fail; |
873 | } | 875 | } |
874 | 876 | ||
875 | qe->mregs = sbus_ioremap(&qe->qe_sdev->resource[1], 0, | 877 | qe->mregs = of_ioremap(&op->resource[1], 0, |
876 | MREGS_REG_SIZE, "QE MACE Registers"); | 878 | MREGS_REG_SIZE, "QE MACE Registers"); |
877 | if (!qe->mregs) { | 879 | if (!qe->mregs) { |
878 | printk(KERN_ERR "qe: Cannot map MACE registers.\n"); | 880 | printk(KERN_ERR "qe: Cannot map MACE registers.\n"); |
879 | goto fail; | 881 | goto fail; |
880 | } | 882 | } |
881 | 883 | ||
882 | qe->qe_block = sbus_alloc_consistent(qe->qe_sdev, | 884 | qe->qe_block = dma_alloc_coherent(&op->dev, PAGE_SIZE, |
883 | PAGE_SIZE, | 885 | &qe->qblock_dvma, GFP_ATOMIC); |
884 | &qe->qblock_dvma); | 886 | qe->buffers = dma_alloc_coherent(&op->dev, sizeof(struct sunqe_buffers), |
885 | qe->buffers = sbus_alloc_consistent(qe->qe_sdev, | 887 | &qe->buffers_dvma, GFP_ATOMIC); |
886 | sizeof(struct sunqe_buffers), | ||
887 | &qe->buffers_dvma); | ||
888 | if (qe->qe_block == NULL || qe->qblock_dvma == 0 || | 888 | if (qe->qe_block == NULL || qe->qblock_dvma == 0 || |
889 | qe->buffers == NULL || qe->buffers_dvma == 0) | 889 | qe->buffers == NULL || qe->buffers_dvma == 0) |
890 | goto fail; | 890 | goto fail; |
@@ -892,7 +892,7 @@ static int __devinit qec_ether_init(struct sbus_dev *sdev) | |||
892 | /* Stop this QE. */ | 892 | /* Stop this QE. */ |
893 | qe_stop(qe); | 893 | qe_stop(qe); |
894 | 894 | ||
895 | SET_NETDEV_DEV(dev, &sdev->ofdev.dev); | 895 | SET_NETDEV_DEV(dev, &op->dev); |
896 | 896 | ||
897 | dev->open = qe_open; | 897 | dev->open = qe_open; |
898 | dev->stop = qe_close; | 898 | dev->stop = qe_close; |
@@ -900,7 +900,7 @@ static int __devinit qec_ether_init(struct sbus_dev *sdev) | |||
900 | dev->set_multicast_list = qe_set_multicast; | 900 | dev->set_multicast_list = qe_set_multicast; |
901 | dev->tx_timeout = qe_tx_timeout; | 901 | dev->tx_timeout = qe_tx_timeout; |
902 | dev->watchdog_timeo = 5*HZ; | 902 | dev->watchdog_timeo = 5*HZ; |
903 | dev->irq = sdev->irqs[0]; | 903 | dev->irq = op->irqs[0]; |
904 | dev->dma = 0; | 904 | dev->dma = 0; |
905 | dev->ethtool_ops = &qe_ethtool_ops; | 905 | dev->ethtool_ops = &qe_ethtool_ops; |
906 | 906 | ||
@@ -908,7 +908,7 @@ static int __devinit qec_ether_init(struct sbus_dev *sdev) | |||
908 | if (res) | 908 | if (res) |
909 | goto fail; | 909 | goto fail; |
910 | 910 | ||
911 | dev_set_drvdata(&sdev->ofdev.dev, qe); | 911 | dev_set_drvdata(&op->dev, qe); |
912 | 912 | ||
913 | printk(KERN_INFO "%s: qe channel[%d] ", dev->name, qe->channel); | 913 | printk(KERN_INFO "%s: qe channel[%d] ", dev->name, qe->channel); |
914 | for (i = 0; i < 6; i++) | 914 | for (i = 0; i < 6; i++) |
@@ -922,58 +922,50 @@ static int __devinit qec_ether_init(struct sbus_dev *sdev) | |||
922 | 922 | ||
923 | fail: | 923 | fail: |
924 | if (qe->qcregs) | 924 | if (qe->qcregs) |
925 | sbus_iounmap(qe->qcregs, CREG_REG_SIZE); | 925 | of_iounmap(&op->resource[0], qe->qcregs, CREG_REG_SIZE); |
926 | if (qe->mregs) | 926 | if (qe->mregs) |
927 | sbus_iounmap(qe->mregs, MREGS_REG_SIZE); | 927 | of_iounmap(&op->resource[1], qe->mregs, MREGS_REG_SIZE); |
928 | if (qe->qe_block) | 928 | if (qe->qe_block) |
929 | sbus_free_consistent(qe->qe_sdev, | 929 | dma_free_coherent(&op->dev, PAGE_SIZE, |
930 | PAGE_SIZE, | 930 | qe->qe_block, qe->qblock_dvma); |
931 | qe->qe_block, | ||
932 | qe->qblock_dvma); | ||
933 | if (qe->buffers) | 931 | if (qe->buffers) |
934 | sbus_free_consistent(qe->qe_sdev, | 932 | dma_free_coherent(&op->dev, |
935 | sizeof(struct sunqe_buffers), | 933 | sizeof(struct sunqe_buffers), |
936 | qe->buffers, | 934 | qe->buffers, |
937 | qe->buffers_dvma); | 935 | qe->buffers_dvma); |
938 | 936 | ||
939 | free_netdev(dev); | 937 | free_netdev(dev); |
940 | 938 | ||
941 | return res; | 939 | return res; |
942 | } | 940 | } |
943 | 941 | ||
944 | static int __devinit qec_sbus_probe(struct of_device *dev, const struct of_device_id *match) | 942 | static int __devinit qec_sbus_probe(struct of_device *op, const struct of_device_id *match) |
945 | { | 943 | { |
946 | struct sbus_dev *sdev = to_sbus_device(&dev->dev); | 944 | return qec_ether_init(op); |
947 | |||
948 | return qec_ether_init(sdev); | ||
949 | } | 945 | } |
950 | 946 | ||
951 | static int __devexit qec_sbus_remove(struct of_device *dev) | 947 | static int __devexit qec_sbus_remove(struct of_device *op) |
952 | { | 948 | { |
953 | struct sunqe *qp = dev_get_drvdata(&dev->dev); | 949 | struct sunqe *qp = dev_get_drvdata(&op->dev); |
954 | struct net_device *net_dev = qp->dev; | 950 | struct net_device *net_dev = qp->dev; |
955 | 951 | ||
956 | unregister_netdev(net_dev); | 952 | unregister_netdev(net_dev); |
957 | 953 | ||
958 | sbus_iounmap(qp->qcregs, CREG_REG_SIZE); | 954 | of_iounmap(&op->resource[0], qp->qcregs, CREG_REG_SIZE); |
959 | sbus_iounmap(qp->mregs, MREGS_REG_SIZE); | 955 | of_iounmap(&op->resource[1], qp->mregs, MREGS_REG_SIZE); |
960 | sbus_free_consistent(qp->qe_sdev, | 956 | dma_free_coherent(&op->dev, PAGE_SIZE, |
961 | PAGE_SIZE, | 957 | qp->qe_block, qp->qblock_dvma); |
962 | qp->qe_block, | 958 | dma_free_coherent(&op->dev, sizeof(struct sunqe_buffers), |
963 | qp->qblock_dvma); | 959 | qp->buffers, qp->buffers_dvma); |
964 | sbus_free_consistent(qp->qe_sdev, | ||
965 | sizeof(struct sunqe_buffers), | ||
966 | qp->buffers, | ||
967 | qp->buffers_dvma); | ||
968 | 960 | ||
969 | free_netdev(net_dev); | 961 | free_netdev(net_dev); |
970 | 962 | ||
971 | dev_set_drvdata(&dev->dev, NULL); | 963 | dev_set_drvdata(&op->dev, NULL); |
972 | 964 | ||
973 | return 0; | 965 | return 0; |
974 | } | 966 | } |
975 | 967 | ||
976 | static struct of_device_id qec_sbus_match[] = { | 968 | static const struct of_device_id qec_sbus_match[] = { |
977 | { | 969 | { |
978 | .name = "qe", | 970 | .name = "qe", |
979 | }, | 971 | }, |
@@ -991,7 +983,7 @@ static struct of_platform_driver qec_sbus_driver = { | |||
991 | 983 | ||
992 | static int __init qec_init(void) | 984 | static int __init qec_init(void) |
993 | { | 985 | { |
994 | return of_register_driver(&qec_sbus_driver, &sbus_bus_type); | 986 | return of_register_driver(&qec_sbus_driver, &of_bus_type); |
995 | } | 987 | } |
996 | 988 | ||
997 | static void __exit qec_exit(void) | 989 | static void __exit qec_exit(void) |
@@ -1000,11 +992,11 @@ static void __exit qec_exit(void) | |||
1000 | 992 | ||
1001 | while (root_qec_dev) { | 993 | while (root_qec_dev) { |
1002 | struct sunqec *next = root_qec_dev->next_module; | 994 | struct sunqec *next = root_qec_dev->next_module; |
995 | struct of_device *op = root_qec_dev->op; | ||
1003 | 996 | ||
1004 | free_irq(root_qec_dev->qec_sdev->irqs[0], | 997 | free_irq(op->irqs[0], (void *) root_qec_dev); |
1005 | (void *) root_qec_dev); | 998 | of_iounmap(&op->resource[0], root_qec_dev->gregs, |
1006 | sbus_iounmap(root_qec_dev->gregs, GLOB_REG_SIZE); | 999 | GLOB_REG_SIZE); |
1007 | |||
1008 | kfree(root_qec_dev); | 1000 | kfree(root_qec_dev); |
1009 | 1001 | ||
1010 | root_qec_dev = next; | 1002 | root_qec_dev = next; |