diff options
-rw-r--r-- | drivers/net/sunqe.c | 147 | ||||
-rw-r--r-- | drivers/net/sunqe.h | 4 |
2 files changed, 71 insertions, 80 deletions
diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c index 4521972fbf3d..81604cac8e3e 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> |
@@ -25,13 +25,14 @@ | |||
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> | 27 | #include <linux/dma-mapping.h> |
28 | #include <linux/of.h> | ||
29 | #include <linux/of_device.h> | ||
28 | 30 | ||
29 | #include <asm/system.h> | 31 | #include <asm/system.h> |
30 | #include <asm/io.h> | 32 | #include <asm/io.h> |
31 | #include <asm/dma.h> | 33 | #include <asm/dma.h> |
32 | #include <asm/byteorder.h> | 34 | #include <asm/byteorder.h> |
33 | #include <asm/idprom.h> | 35 | #include <asm/idprom.h> |
34 | #include <asm/sbus.h> | ||
35 | #include <asm/openprom.h> | 36 | #include <asm/openprom.h> |
36 | #include <asm/oplib.h> | 37 | #include <asm/oplib.h> |
37 | #include <asm/auxio.h> | 38 | #include <asm/auxio.h> |
@@ -41,8 +42,8 @@ | |||
41 | #include "sunqe.h" | 42 | #include "sunqe.h" |
42 | 43 | ||
43 | #define DRV_NAME "sunqe" | 44 | #define DRV_NAME "sunqe" |
44 | #define DRV_VERSION "4.0" | 45 | #define DRV_VERSION "4.1" |
45 | #define DRV_RELDATE "June 23, 2006" | 46 | #define DRV_RELDATE "August 27, 2008" |
46 | #define DRV_AUTHOR "David S. Miller (davem@davemloft.net)" | 47 | #define DRV_AUTHOR "David S. Miller (davem@davemloft.net)" |
47 | 48 | ||
48 | static char version[] = | 49 | static char version[] = |
@@ -691,12 +692,18 @@ static void qe_set_multicast(struct net_device *dev) | |||
691 | /* Ethtool support... */ | 692 | /* Ethtool support... */ |
692 | 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) |
693 | { | 694 | { |
695 | const struct linux_prom_registers *regs; | ||
694 | struct sunqe *qep = dev->priv; | 696 | struct sunqe *qep = dev->priv; |
697 | struct of_device *op; | ||
695 | 698 | ||
696 | strcpy(info->driver, "sunqe"); | 699 | strcpy(info->driver, "sunqe"); |
697 | strcpy(info->version, "3.0"); | 700 | strcpy(info->version, "3.0"); |
698 | sprintf(info->bus_info, "SBUS:%d", | 701 | |
699 | 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 | |||
700 | } | 707 | } |
701 | 708 | ||
702 | static u32 qe_get_link(struct net_device *dev) | 709 | static u32 qe_get_link(struct net_device *dev) |
@@ -718,7 +725,7 @@ static const struct ethtool_ops qe_ethtool_ops = { | |||
718 | }; | 725 | }; |
719 | 726 | ||
720 | /* 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. */ |
721 | 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) |
722 | { | 729 | { |
723 | u8 bsizes = qecp->qec_bursts; | 730 | u8 bsizes = qecp->qec_bursts; |
724 | 731 | ||
@@ -736,15 +743,15 @@ static inline void qec_init_once(struct sunqec *qecp, struct sbus_dev *qsdev) | |||
736 | sbus_writel(GLOB_PSIZE_2048, qecp->gregs + GLOB_PSIZE); | 743 | sbus_writel(GLOB_PSIZE_2048, qecp->gregs + GLOB_PSIZE); |
737 | 744 | ||
738 | /* 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. */ |
739 | sbus_writel((qsdev->reg_addrs[1].reg_size >> 2), | 746 | sbus_writel((resource_size(&op->resource[1]) >> 2), |
740 | qecp->gregs + GLOB_MSIZE); | 747 | qecp->gregs + GLOB_MSIZE); |
741 | 748 | ||
742 | /* 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 |
743 | * transmitter FIFOs. Basically it is (total / 2 / num_channels). | 750 | * transmitter FIFOs. Basically it is (total / 2 / num_channels). |
744 | */ | 751 | */ |
745 | sbus_writel((qsdev->reg_addrs[1].reg_size >> 2) >> 1, | 752 | sbus_writel((resource_size(&op->resource[1]) >> 2) >> 1, |
746 | qecp->gregs + GLOB_TSIZE); | 753 | qecp->gregs + GLOB_TSIZE); |
747 | sbus_writel((qsdev->reg_addrs[1].reg_size >> 2) >> 1, | 754 | sbus_writel((resource_size(&op->resource[1]) >> 2) >> 1, |
748 | qecp->gregs + GLOB_RSIZE); | 755 | qecp->gregs + GLOB_RSIZE); |
749 | } | 756 | } |
750 | 757 | ||
@@ -768,24 +775,21 @@ static u8 __devinit qec_get_burst(struct device_node *dp) | |||
768 | return bsizes; | 775 | return bsizes; |
769 | } | 776 | } |
770 | 777 | ||
771 | static struct sunqec * __devinit get_qec(struct sbus_dev *child_sdev) | 778 | static struct sunqec * __devinit get_qec(struct of_device *child) |
772 | { | 779 | { |
773 | struct sbus_dev *qec_sdev = child_sdev->parent; | 780 | struct of_device *op = to_of_device(child->dev.parent); |
774 | struct sunqec *qecp; | 781 | struct sunqec *qecp; |
775 | 782 | ||
776 | for (qecp = root_qec_dev; qecp; qecp = qecp->next_module) { | 783 | qecp = dev_get_drvdata(&op->dev); |
777 | if (qecp->qec_sdev == qec_sdev) | ||
778 | break; | ||
779 | } | ||
780 | if (!qecp) { | 784 | if (!qecp) { |
781 | qecp = kzalloc(sizeof(struct sunqec), GFP_KERNEL); | 785 | qecp = kzalloc(sizeof(struct sunqec), GFP_KERNEL); |
782 | if (qecp) { | 786 | if (qecp) { |
783 | u32 ctrl; | 787 | u32 ctrl; |
784 | 788 | ||
785 | qecp->qec_sdev = qec_sdev; | 789 | qecp->op = op; |
786 | qecp->gregs = sbus_ioremap(&qec_sdev->resource[0], 0, | 790 | qecp->gregs = of_ioremap(&op->resource[0], 0, |
787 | GLOB_REG_SIZE, | 791 | GLOB_REG_SIZE, |
788 | "QEC Global Registers"); | 792 | "QEC Global Registers"); |
789 | if (!qecp->gregs) | 793 | if (!qecp->gregs) |
790 | goto fail; | 794 | goto fail; |
791 | 795 | ||
@@ -800,16 +804,18 @@ static struct sunqec * __devinit get_qec(struct sbus_dev *child_sdev) | |||
800 | if (qec_global_reset(qecp->gregs)) | 804 | if (qec_global_reset(qecp->gregs)) |
801 | goto fail; | 805 | goto fail; |
802 | 806 | ||
803 | qecp->qec_bursts = qec_get_burst(qec_sdev->ofdev.node); | 807 | qecp->qec_bursts = qec_get_burst(op->node); |
804 | 808 | ||
805 | qec_init_once(qecp, qec_sdev); | 809 | qec_init_once(qecp, op); |
806 | 810 | ||
807 | if (request_irq(qec_sdev->irqs[0], &qec_interrupt, | 811 | if (request_irq(op->irqs[0], &qec_interrupt, |
808 | IRQF_SHARED, "qec", (void *) qecp)) { | 812 | IRQF_SHARED, "qec", (void *) qecp)) { |
809 | printk(KERN_ERR "qec: Can't register irq.\n"); | 813 | printk(KERN_ERR "qec: Can't register irq.\n"); |
810 | goto fail; | 814 | goto fail; |
811 | } | 815 | } |
812 | 816 | ||
817 | dev_set_drvdata(&op->dev, qecp); | ||
818 | |||
813 | qecp->next_module = root_qec_dev; | 819 | qecp->next_module = root_qec_dev; |
814 | root_qec_dev = qecp; | 820 | root_qec_dev = qecp; |
815 | } | 821 | } |
@@ -819,17 +825,17 @@ static struct sunqec * __devinit get_qec(struct sbus_dev *child_sdev) | |||
819 | 825 | ||
820 | fail: | 826 | fail: |
821 | if (qecp->gregs) | 827 | if (qecp->gregs) |
822 | sbus_iounmap(qecp->gregs, GLOB_REG_SIZE); | 828 | of_iounmap(&op->resource[0], qecp->gregs, GLOB_REG_SIZE); |
823 | kfree(qecp); | 829 | kfree(qecp); |
824 | return NULL; | 830 | return NULL; |
825 | } | 831 | } |
826 | 832 | ||
827 | static int __devinit qec_ether_init(struct sbus_dev *sdev) | 833 | static int __devinit qec_ether_init(struct of_device *op) |
828 | { | 834 | { |
829 | static unsigned version_printed; | 835 | static unsigned version_printed; |
830 | struct net_device *dev; | 836 | struct net_device *dev; |
831 | struct sunqe *qe; | ||
832 | struct sunqec *qecp; | 837 | struct sunqec *qecp; |
838 | struct sunqe *qe; | ||
833 | int i, res; | 839 | int i, res; |
834 | 840 | ||
835 | if (version_printed++ == 0) | 841 | if (version_printed++ == 0) |
@@ -843,48 +849,41 @@ static int __devinit qec_ether_init(struct sbus_dev *sdev) | |||
843 | 849 | ||
844 | qe = netdev_priv(dev); | 850 | qe = netdev_priv(dev); |
845 | 851 | ||
846 | i = of_getintprop_default(sdev->ofdev.node, "channel#", -1); | 852 | res = -ENODEV; |
847 | if (i == -1) { | 853 | |
848 | struct sbus_dev *td = sdev->parent->child; | 854 | i = of_getintprop_default(op->node, "channel#", -1); |
849 | i = 0; | 855 | if (i == -1) |
850 | while (td != sdev) { | 856 | goto fail; |
851 | td = td->next; | ||
852 | i++; | ||
853 | } | ||
854 | } | ||
855 | qe->channel = i; | 857 | qe->channel = i; |
856 | spin_lock_init(&qe->lock); | 858 | spin_lock_init(&qe->lock); |
857 | 859 | ||
858 | res = -ENODEV; | 860 | qecp = get_qec(op); |
859 | qecp = get_qec(sdev); | ||
860 | if (!qecp) | 861 | if (!qecp) |
861 | goto fail; | 862 | goto fail; |
862 | 863 | ||
863 | qecp->qes[qe->channel] = qe; | 864 | qecp->qes[qe->channel] = qe; |
864 | qe->dev = dev; | 865 | qe->dev = dev; |
865 | qe->parent = qecp; | 866 | qe->parent = qecp; |
866 | qe->qe_sdev = sdev; | 867 | qe->op = op; |
867 | 868 | ||
868 | res = -ENOMEM; | 869 | res = -ENOMEM; |
869 | qe->qcregs = sbus_ioremap(&qe->qe_sdev->resource[0], 0, | 870 | qe->qcregs = of_ioremap(&op->resource[0], 0, |
870 | CREG_REG_SIZE, "QEC Channel Registers"); | 871 | CREG_REG_SIZE, "QEC Channel Registers"); |
871 | if (!qe->qcregs) { | 872 | if (!qe->qcregs) { |
872 | printk(KERN_ERR "qe: Cannot map channel registers.\n"); | 873 | printk(KERN_ERR "qe: Cannot map channel registers.\n"); |
873 | goto fail; | 874 | goto fail; |
874 | } | 875 | } |
875 | 876 | ||
876 | qe->mregs = sbus_ioremap(&qe->qe_sdev->resource[1], 0, | 877 | qe->mregs = of_ioremap(&op->resource[1], 0, |
877 | MREGS_REG_SIZE, "QE MACE Registers"); | 878 | MREGS_REG_SIZE, "QE MACE Registers"); |
878 | if (!qe->mregs) { | 879 | if (!qe->mregs) { |
879 | printk(KERN_ERR "qe: Cannot map MACE registers.\n"); | 880 | printk(KERN_ERR "qe: Cannot map MACE registers.\n"); |
880 | goto fail; | 881 | goto fail; |
881 | } | 882 | } |
882 | 883 | ||
883 | qe->qe_block = dma_alloc_coherent(&qe->qe_sdev->ofdev.dev, | 884 | qe->qe_block = dma_alloc_coherent(&op->dev, PAGE_SIZE, |
884 | PAGE_SIZE, | ||
885 | &qe->qblock_dvma, GFP_ATOMIC); | 885 | &qe->qblock_dvma, GFP_ATOMIC); |
886 | qe->buffers = dma_alloc_coherent(&qe->qe_sdev->ofdev.dev, | 886 | qe->buffers = dma_alloc_coherent(&op->dev, sizeof(struct sunqe_buffers), |
887 | sizeof(struct sunqe_buffers), | ||
888 | &qe->buffers_dvma, GFP_ATOMIC); | 887 | &qe->buffers_dvma, GFP_ATOMIC); |
889 | if (qe->qe_block == NULL || qe->qblock_dvma == 0 || | 888 | if (qe->qe_block == NULL || qe->qblock_dvma == 0 || |
890 | qe->buffers == NULL || qe->buffers_dvma == 0) | 889 | qe->buffers == NULL || qe->buffers_dvma == 0) |
@@ -893,7 +892,7 @@ static int __devinit qec_ether_init(struct sbus_dev *sdev) | |||
893 | /* Stop this QE. */ | 892 | /* Stop this QE. */ |
894 | qe_stop(qe); | 893 | qe_stop(qe); |
895 | 894 | ||
896 | SET_NETDEV_DEV(dev, &sdev->ofdev.dev); | 895 | SET_NETDEV_DEV(dev, &op->dev); |
897 | 896 | ||
898 | dev->open = qe_open; | 897 | dev->open = qe_open; |
899 | dev->stop = qe_close; | 898 | dev->stop = qe_close; |
@@ -901,7 +900,7 @@ static int __devinit qec_ether_init(struct sbus_dev *sdev) | |||
901 | dev->set_multicast_list = qe_set_multicast; | 900 | dev->set_multicast_list = qe_set_multicast; |
902 | dev->tx_timeout = qe_tx_timeout; | 901 | dev->tx_timeout = qe_tx_timeout; |
903 | dev->watchdog_timeo = 5*HZ; | 902 | dev->watchdog_timeo = 5*HZ; |
904 | dev->irq = sdev->irqs[0]; | 903 | dev->irq = op->irqs[0]; |
905 | dev->dma = 0; | 904 | dev->dma = 0; |
906 | dev->ethtool_ops = &qe_ethtool_ops; | 905 | dev->ethtool_ops = &qe_ethtool_ops; |
907 | 906 | ||
@@ -909,7 +908,7 @@ static int __devinit qec_ether_init(struct sbus_dev *sdev) | |||
909 | if (res) | 908 | if (res) |
910 | goto fail; | 909 | goto fail; |
911 | 910 | ||
912 | dev_set_drvdata(&sdev->ofdev.dev, qe); | 911 | dev_set_drvdata(&op->dev, qe); |
913 | 912 | ||
914 | printk(KERN_INFO "%s: qe channel[%d] ", dev->name, qe->channel); | 913 | printk(KERN_INFO "%s: qe channel[%d] ", dev->name, qe->channel); |
915 | for (i = 0; i < 6; i++) | 914 | for (i = 0; i < 6; i++) |
@@ -923,16 +922,14 @@ static int __devinit qec_ether_init(struct sbus_dev *sdev) | |||
923 | 922 | ||
924 | fail: | 923 | fail: |
925 | if (qe->qcregs) | 924 | if (qe->qcregs) |
926 | sbus_iounmap(qe->qcregs, CREG_REG_SIZE); | 925 | of_iounmap(&op->resource[0], qe->qcregs, CREG_REG_SIZE); |
927 | if (qe->mregs) | 926 | if (qe->mregs) |
928 | sbus_iounmap(qe->mregs, MREGS_REG_SIZE); | 927 | of_iounmap(&op->resource[1], qe->mregs, MREGS_REG_SIZE); |
929 | if (qe->qe_block) | 928 | if (qe->qe_block) |
930 | dma_free_coherent(&qe->qe_sdev->ofdev.dev, | 929 | dma_free_coherent(&op->dev, PAGE_SIZE, |
931 | PAGE_SIZE, | 930 | qe->qe_block, qe->qblock_dvma); |
932 | qe->qe_block, | ||
933 | qe->qblock_dvma); | ||
934 | if (qe->buffers) | 931 | if (qe->buffers) |
935 | dma_free_coherent(&qe->qe_sdev->ofdev.dev, | 932 | dma_free_coherent(&op->dev, |
936 | sizeof(struct sunqe_buffers), | 933 | sizeof(struct sunqe_buffers), |
937 | qe->buffers, | 934 | qe->buffers, |
938 | qe->buffers_dvma); | 935 | qe->buffers_dvma); |
@@ -942,34 +939,28 @@ fail: | |||
942 | return res; | 939 | return res; |
943 | } | 940 | } |
944 | 941 | ||
945 | 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) |
946 | { | 943 | { |
947 | struct sbus_dev *sdev = to_sbus_device(&dev->dev); | 944 | return qec_ether_init(op); |
948 | |||
949 | return qec_ether_init(sdev); | ||
950 | } | 945 | } |
951 | 946 | ||
952 | static int __devexit qec_sbus_remove(struct of_device *dev) | 947 | static int __devexit qec_sbus_remove(struct of_device *op) |
953 | { | 948 | { |
954 | struct sunqe *qp = dev_get_drvdata(&dev->dev); | 949 | struct sunqe *qp = dev_get_drvdata(&op->dev); |
955 | struct net_device *net_dev = qp->dev; | 950 | struct net_device *net_dev = qp->dev; |
956 | 951 | ||
957 | unregister_netdev(net_dev); | 952 | unregister_netdev(net_dev); |
958 | 953 | ||
959 | sbus_iounmap(qp->qcregs, CREG_REG_SIZE); | 954 | of_iounmap(&op->resource[0], qp->qcregs, CREG_REG_SIZE); |
960 | sbus_iounmap(qp->mregs, MREGS_REG_SIZE); | 955 | of_iounmap(&op->resource[1], qp->mregs, MREGS_REG_SIZE); |
961 | dma_free_coherent(&qp->qe_sdev->ofdev.dev, | 956 | dma_free_coherent(&op->dev, PAGE_SIZE, |
962 | PAGE_SIZE, | 957 | qp->qe_block, qp->qblock_dvma); |
963 | qp->qe_block, | 958 | dma_free_coherent(&op->dev, sizeof(struct sunqe_buffers), |
964 | qp->qblock_dvma); | 959 | qp->buffers, qp->buffers_dvma); |
965 | dma_free_coherent(&qp->qe_sdev->ofdev.dev, | ||
966 | sizeof(struct sunqe_buffers), | ||
967 | qp->buffers, | ||
968 | qp->buffers_dvma); | ||
969 | 960 | ||
970 | free_netdev(net_dev); | 961 | free_netdev(net_dev); |
971 | 962 | ||
972 | dev_set_drvdata(&dev->dev, NULL); | 963 | dev_set_drvdata(&op->dev, NULL); |
973 | 964 | ||
974 | return 0; | 965 | return 0; |
975 | } | 966 | } |
@@ -992,7 +983,7 @@ static struct of_platform_driver qec_sbus_driver = { | |||
992 | 983 | ||
993 | static int __init qec_init(void) | 984 | static int __init qec_init(void) |
994 | { | 985 | { |
995 | return of_register_driver(&qec_sbus_driver, &sbus_bus_type); | 986 | return of_register_driver(&qec_sbus_driver, &of_bus_type); |
996 | } | 987 | } |
997 | 988 | ||
998 | static void __exit qec_exit(void) | 989 | static void __exit qec_exit(void) |
@@ -1001,11 +992,11 @@ static void __exit qec_exit(void) | |||
1001 | 992 | ||
1002 | while (root_qec_dev) { | 993 | while (root_qec_dev) { |
1003 | 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; | ||
1004 | 996 | ||
1005 | free_irq(root_qec_dev->qec_sdev->irqs[0], | 997 | free_irq(op->irqs[0], (void *) root_qec_dev); |
1006 | (void *) root_qec_dev); | 998 | of_iounmap(&op->resource[0], root_qec_dev->gregs, |
1007 | sbus_iounmap(root_qec_dev->gregs, GLOB_REG_SIZE); | 999 | GLOB_REG_SIZE); |
1008 | |||
1009 | kfree(root_qec_dev); | 1000 | kfree(root_qec_dev); |
1010 | 1001 | ||
1011 | root_qec_dev = next; | 1002 | root_qec_dev = next; |
diff --git a/drivers/net/sunqe.h b/drivers/net/sunqe.h index 347c8ddc1592..5813a7b2faa5 100644 --- a/drivers/net/sunqe.h +++ b/drivers/net/sunqe.h | |||
@@ -314,7 +314,7 @@ struct sunqec { | |||
314 | void __iomem *gregs; /* QEC Global Registers */ | 314 | void __iomem *gregs; /* QEC Global Registers */ |
315 | struct sunqe *qes[4]; /* Each child MACE */ | 315 | struct sunqe *qes[4]; /* Each child MACE */ |
316 | unsigned int qec_bursts; /* Support burst sizes */ | 316 | unsigned int qec_bursts; /* Support burst sizes */ |
317 | struct sbus_dev *qec_sdev; /* QEC's SBUS device */ | 317 | struct of_device *op; /* QEC's OF device */ |
318 | struct sunqec *next_module; /* List of all QECs in system */ | 318 | struct sunqec *next_module; /* List of all QECs in system */ |
319 | }; | 319 | }; |
320 | 320 | ||
@@ -342,7 +342,7 @@ struct sunqe { | |||
342 | __u32 buffers_dvma; /* DVMA visible address. */ | 342 | __u32 buffers_dvma; /* DVMA visible address. */ |
343 | struct sunqec *parent; | 343 | struct sunqec *parent; |
344 | u8 mconfig; /* Base MACE mconfig value */ | 344 | u8 mconfig; /* Base MACE mconfig value */ |
345 | struct sbus_dev *qe_sdev; /* QE's SBUS device struct */ | 345 | struct of_device *op; /* QE's OF device struct */ |
346 | struct net_device *dev; /* QE's netdevice struct */ | 346 | struct net_device *dev; /* QE's netdevice struct */ |
347 | int channel; /* Who am I? */ | 347 | int channel; /* Who am I? */ |
348 | }; | 348 | }; |