aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-07-22 16:16:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-22 16:16:01 -0400
commit06b8147c5dbd385b5b97ca74e19f6f3951ebc1cb (patch)
tree6ed9de7ca0ab3a65af6a189a89deb0a36ab35f6b /drivers/net
parent53baaaa9682c230410a057263d1ce2922f43ddc4 (diff)
parent8725f25acc656c1522d48a6746055099efdaca4c (diff)
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (49 commits) powerpc: Fix build bug with binutils < 2.18 and GCC < 4.2 powerpc/eeh: Don't panic when EEH_MAX_FAILS is exceeded fbdev: Teaches offb about palette on radeon r5xx/r6xx powerpc/cell/edac: Log a syndrome code in case of correctable error powerpc/cell: Add DMA_ATTR_WEAK_ORDERING dma attribute and use in Cell IOMMU code powerpc: Indicate which oprofile counters to use while in compat mode powerpc/boot: Change spaces to tabs powerpc: Remove duplicate 6xx option in Kconfig powerpc: Use PPC_LONG and PPC_LONG_ALIGN in lib/string.S powerpc: Use PPC_LONG_ALIGN in uaccess.h powerpc: Add a #define for aligning to a long-sized boundary powerpc: Fix OF parsing of 64 bits PCI addresses powerpc: Use WARN_ON(1) instead of __WARN() powerpc: Fix support for latencytop powerpc/ps3: Update ps3_defconfig powerpc/ps3: Add a sub-match id to ps3_system_bus powerpc: Add a 6xx defconfig powerpc/dma: Use the struct dma_attrs in iommu code powerpc/cell: Add support for power button of future IBM cell blades powerpc/cell: Cleanup sysreset_hack for IBM cell blades ...
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/fs_enet/Makefile5
-rw-r--r--drivers/net/fs_enet/fs_enet-main.c312
-rw-r--r--drivers/net/fs_enet/fs_enet.h4
-rw-r--r--drivers/net/fs_enet/mac-fcc.c67
-rw-r--r--drivers/net/fs_enet/mac-fec.c23
-rw-r--r--drivers/net/fs_enet/mac-scc.c37
-rw-r--r--drivers/net/fs_enet/mii-bitbang.c107
-rw-r--r--drivers/net/fs_enet/mii-fec.c144
-rw-r--r--drivers/net/gianfar.c122
-rw-r--r--drivers/net/gianfar.h12
-rw-r--r--drivers/net/gianfar_ethtool.c41
11 files changed, 175 insertions, 699 deletions
diff --git a/drivers/net/fs_enet/Makefile b/drivers/net/fs_enet/Makefile
index 1ffbe0756a0c..d4a305ee3455 100644
--- a/drivers/net/fs_enet/Makefile
+++ b/drivers/net/fs_enet/Makefile
@@ -8,12 +8,7 @@ fs_enet-$(CONFIG_FS_ENET_HAS_SCC) += mac-scc.o
8fs_enet-$(CONFIG_FS_ENET_HAS_FEC) += mac-fec.o 8fs_enet-$(CONFIG_FS_ENET_HAS_FEC) += mac-fec.o
9fs_enet-$(CONFIG_FS_ENET_HAS_FCC) += mac-fcc.o 9fs_enet-$(CONFIG_FS_ENET_HAS_FCC) += mac-fcc.o
10 10
11ifeq ($(CONFIG_PPC_CPM_NEW_BINDING),y)
12obj-$(CONFIG_FS_ENET_MDIO_FEC) += mii-fec.o 11obj-$(CONFIG_FS_ENET_MDIO_FEC) += mii-fec.o
13obj-$(CONFIG_FS_ENET_MDIO_FCC) += mii-bitbang.o 12obj-$(CONFIG_FS_ENET_MDIO_FCC) += mii-bitbang.o
14else
15fs_enet-$(CONFIG_FS_ENET_MDIO_FEC) += mii-fec.o
16fs_enet-$(CONFIG_FS_ENET_MDIO_FCC) += mii-bitbang.o
17endif
18 13
19fs_enet-objs := fs_enet-main.o $(fs_enet-m) 14fs_enet-objs := fs_enet-main.o $(fs_enet-m)
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index 445763e5648e..92591384afa5 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -36,26 +36,18 @@
36#include <linux/fs.h> 36#include <linux/fs.h>
37#include <linux/platform_device.h> 37#include <linux/platform_device.h>
38#include <linux/phy.h> 38#include <linux/phy.h>
39#include <linux/of_platform.h>
40#include <linux/of_gpio.h>
39 41
40#include <linux/vmalloc.h> 42#include <linux/vmalloc.h>
41#include <asm/pgtable.h> 43#include <asm/pgtable.h>
42#include <asm/irq.h> 44#include <asm/irq.h>
43#include <asm/uaccess.h> 45#include <asm/uaccess.h>
44 46
45#ifdef CONFIG_PPC_CPM_NEW_BINDING
46#include <linux/of_gpio.h>
47#include <linux/of_platform.h>
48#endif
49
50#include "fs_enet.h" 47#include "fs_enet.h"
51 48
52/*************************************************/ 49/*************************************************/
53 50
54#ifndef CONFIG_PPC_CPM_NEW_BINDING
55static char version[] __devinitdata =
56 DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")" "\n";
57#endif
58
59MODULE_AUTHOR("Pantelis Antoniou <panto@intracom.gr>"); 51MODULE_AUTHOR("Pantelis Antoniou <panto@intracom.gr>");
60MODULE_DESCRIPTION("Freescale Ethernet Driver"); 52MODULE_DESCRIPTION("Freescale Ethernet Driver");
61MODULE_LICENSE("GPL"); 53MODULE_LICENSE("GPL");
@@ -958,190 +950,6 @@ static int fs_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
958extern int fs_mii_connect(struct net_device *dev); 950extern int fs_mii_connect(struct net_device *dev);
959extern void fs_mii_disconnect(struct net_device *dev); 951extern void fs_mii_disconnect(struct net_device *dev);
960 952
961#ifndef CONFIG_PPC_CPM_NEW_BINDING
962static struct net_device *fs_init_instance(struct device *dev,
963 struct fs_platform_info *fpi)
964{
965 struct net_device *ndev = NULL;
966 struct fs_enet_private *fep = NULL;
967 int privsize, i, r, err = 0, registered = 0;
968
969 fpi->fs_no = fs_get_id(fpi);
970 /* guard */
971 if ((unsigned int)fpi->fs_no >= FS_MAX_INDEX)
972 return ERR_PTR(-EINVAL);
973
974 privsize = sizeof(*fep) + (sizeof(struct sk_buff **) *
975 (fpi->rx_ring + fpi->tx_ring));
976
977 ndev = alloc_etherdev(privsize);
978 if (!ndev) {
979 err = -ENOMEM;
980 goto err;
981 }
982
983 fep = netdev_priv(ndev);
984
985 fep->dev = dev;
986 dev_set_drvdata(dev, ndev);
987 fep->fpi = fpi;
988 if (fpi->init_ioports)
989 fpi->init_ioports((struct fs_platform_info *)fpi);
990
991#ifdef CONFIG_FS_ENET_HAS_FEC
992 if (fs_get_fec_index(fpi->fs_no) >= 0)
993 fep->ops = &fs_fec_ops;
994#endif
995
996#ifdef CONFIG_FS_ENET_HAS_SCC
997 if (fs_get_scc_index(fpi->fs_no) >=0)
998 fep->ops = &fs_scc_ops;
999#endif
1000
1001#ifdef CONFIG_FS_ENET_HAS_FCC
1002 if (fs_get_fcc_index(fpi->fs_no) >= 0)
1003 fep->ops = &fs_fcc_ops;
1004#endif
1005
1006 if (fep->ops == NULL) {
1007 printk(KERN_ERR DRV_MODULE_NAME
1008 ": %s No matching ops found (%d).\n",
1009 ndev->name, fpi->fs_no);
1010 err = -EINVAL;
1011 goto err;
1012 }
1013
1014 r = (*fep->ops->setup_data)(ndev);
1015 if (r != 0) {
1016 printk(KERN_ERR DRV_MODULE_NAME
1017 ": %s setup_data failed\n",
1018 ndev->name);
1019 err = r;
1020 goto err;
1021 }
1022
1023 /* point rx_skbuff, tx_skbuff */
1024 fep->rx_skbuff = (struct sk_buff **)&fep[1];
1025 fep->tx_skbuff = fep->rx_skbuff + fpi->rx_ring;
1026
1027 /* init locks */
1028 spin_lock_init(&fep->lock);
1029 spin_lock_init(&fep->tx_lock);
1030
1031 /*
1032 * Set the Ethernet address.
1033 */
1034 for (i = 0; i < 6; i++)
1035 ndev->dev_addr[i] = fpi->macaddr[i];
1036
1037 r = (*fep->ops->allocate_bd)(ndev);
1038
1039 if (fep->ring_base == NULL) {
1040 printk(KERN_ERR DRV_MODULE_NAME
1041 ": %s buffer descriptor alloc failed (%d).\n", ndev->name, r);
1042 err = r;
1043 goto err;
1044 }
1045
1046 /*
1047 * Set receive and transmit descriptor base.
1048 */
1049 fep->rx_bd_base = fep->ring_base;
1050 fep->tx_bd_base = fep->rx_bd_base + fpi->rx_ring;
1051
1052 /* initialize ring size variables */
1053 fep->tx_ring = fpi->tx_ring;
1054 fep->rx_ring = fpi->rx_ring;
1055
1056 /*
1057 * The FEC Ethernet specific entries in the device structure.
1058 */
1059 ndev->open = fs_enet_open;
1060 ndev->hard_start_xmit = fs_enet_start_xmit;
1061 ndev->tx_timeout = fs_timeout;
1062 ndev->watchdog_timeo = 2 * HZ;
1063 ndev->stop = fs_enet_close;
1064 ndev->get_stats = fs_enet_get_stats;
1065 ndev->set_multicast_list = fs_set_multicast_list;
1066
1067#ifdef CONFIG_NET_POLL_CONTROLLER
1068 ndev->poll_controller = fs_enet_netpoll;
1069#endif
1070
1071 netif_napi_add(ndev, &fep->napi,
1072 fs_enet_rx_napi, fpi->napi_weight);
1073
1074 ndev->ethtool_ops = &fs_ethtool_ops;
1075 ndev->do_ioctl = fs_ioctl;
1076
1077 init_timer(&fep->phy_timer_list);
1078
1079 netif_carrier_off(ndev);
1080
1081 err = register_netdev(ndev);
1082 if (err != 0) {
1083 printk(KERN_ERR DRV_MODULE_NAME
1084 ": %s register_netdev failed.\n", ndev->name);
1085 goto err;
1086 }
1087 registered = 1;
1088
1089
1090 return ndev;
1091
1092err:
1093 if (ndev != NULL) {
1094 if (registered)
1095 unregister_netdev(ndev);
1096
1097 if (fep && fep->ops) {
1098 (*fep->ops->free_bd)(ndev);
1099 (*fep->ops->cleanup_data)(ndev);
1100 }
1101
1102 free_netdev(ndev);
1103 }
1104
1105 dev_set_drvdata(dev, NULL);
1106
1107 return ERR_PTR(err);
1108}
1109
1110static int fs_cleanup_instance(struct net_device *ndev)
1111{
1112 struct fs_enet_private *fep;
1113 const struct fs_platform_info *fpi;
1114 struct device *dev;
1115
1116 if (ndev == NULL)
1117 return -EINVAL;
1118
1119 fep = netdev_priv(ndev);
1120 if (fep == NULL)
1121 return -EINVAL;
1122
1123 fpi = fep->fpi;
1124
1125 unregister_netdev(ndev);
1126
1127 dma_free_coherent(fep->dev, (fpi->tx_ring + fpi->rx_ring) * sizeof(cbd_t),
1128 (void __force *)fep->ring_base, fep->ring_mem_addr);
1129
1130 /* reset it */
1131 (*fep->ops->cleanup_data)(ndev);
1132
1133 dev = fep->dev;
1134 if (dev != NULL) {
1135 dev_set_drvdata(dev, NULL);
1136 fep->dev = NULL;
1137 }
1138
1139 free_netdev(ndev);
1140
1141 return 0;
1142}
1143#endif
1144
1145/**************************************************************************************/ 953/**************************************************************************************/
1146 954
1147/* handy pointer to the immap */ 955/* handy pointer to the immap */
@@ -1168,7 +976,6 @@ static void cleanup_immap(void)
1168 976
1169/**************************************************************************************/ 977/**************************************************************************************/
1170 978
1171#ifdef CONFIG_PPC_CPM_NEW_BINDING
1172static int __devinit find_phy(struct device_node *np, 979static int __devinit find_phy(struct device_node *np,
1173 struct fs_platform_info *fpi) 980 struct fs_platform_info *fpi)
1174{ 981{
@@ -1408,121 +1215,6 @@ static void __exit fs_cleanup(void)
1408 of_unregister_platform_driver(&fs_enet_driver); 1215 of_unregister_platform_driver(&fs_enet_driver);
1409 cleanup_immap(); 1216 cleanup_immap();
1410} 1217}
1411#else
1412static int __devinit fs_enet_probe(struct device *dev)
1413{
1414 struct net_device *ndev;
1415
1416 /* no fixup - no device */
1417 if (dev->platform_data == NULL) {
1418 printk(KERN_INFO "fs_enet: "
1419 "probe called with no platform data; "
1420 "remove unused devices\n");
1421 return -ENODEV;
1422 }
1423
1424 ndev = fs_init_instance(dev, dev->platform_data);
1425 if (IS_ERR(ndev))
1426 return PTR_ERR(ndev);
1427 return 0;
1428}
1429
1430static int fs_enet_remove(struct device *dev)
1431{
1432 return fs_cleanup_instance(dev_get_drvdata(dev));
1433}
1434
1435static struct device_driver fs_enet_fec_driver = {
1436 .name = "fsl-cpm-fec",
1437 .bus = &platform_bus_type,
1438 .probe = fs_enet_probe,
1439 .remove = fs_enet_remove,
1440#ifdef CONFIG_PM
1441/* .suspend = fs_enet_suspend, TODO */
1442/* .resume = fs_enet_resume, TODO */
1443#endif
1444};
1445
1446static struct device_driver fs_enet_scc_driver = {
1447 .name = "fsl-cpm-scc",
1448 .bus = &platform_bus_type,
1449 .probe = fs_enet_probe,
1450 .remove = fs_enet_remove,
1451#ifdef CONFIG_PM
1452/* .suspend = fs_enet_suspend, TODO */
1453/* .resume = fs_enet_resume, TODO */
1454#endif
1455};
1456
1457static struct device_driver fs_enet_fcc_driver = {
1458 .name = "fsl-cpm-fcc",
1459 .bus = &platform_bus_type,
1460 .probe = fs_enet_probe,
1461 .remove = fs_enet_remove,
1462#ifdef CONFIG_PM
1463/* .suspend = fs_enet_suspend, TODO */
1464/* .resume = fs_enet_resume, TODO */
1465#endif
1466};
1467
1468static int __init fs_init(void)
1469{
1470 int r;
1471
1472 printk(KERN_INFO
1473 "%s", version);
1474
1475 r = setup_immap();
1476 if (r != 0)
1477 return r;
1478
1479#ifdef CONFIG_FS_ENET_HAS_FCC
1480 /* let's insert mii stuff */
1481 r = fs_enet_mdio_bb_init();
1482
1483 if (r != 0) {
1484 printk(KERN_ERR DRV_MODULE_NAME
1485 "BB PHY init failed.\n");
1486 return r;
1487 }
1488 r = driver_register(&fs_enet_fcc_driver);
1489 if (r != 0)
1490 goto err;
1491#endif
1492
1493#ifdef CONFIG_FS_ENET_HAS_FEC
1494 r = fs_enet_mdio_fec_init();
1495 if (r != 0) {
1496 printk(KERN_ERR DRV_MODULE_NAME
1497 "FEC PHY init failed.\n");
1498 return r;
1499 }
1500
1501 r = driver_register(&fs_enet_fec_driver);
1502 if (r != 0)
1503 goto err;
1504#endif
1505
1506#ifdef CONFIG_FS_ENET_HAS_SCC
1507 r = driver_register(&fs_enet_scc_driver);
1508 if (r != 0)
1509 goto err;
1510#endif
1511
1512 return 0;
1513err:
1514 cleanup_immap();
1515 return r;
1516}
1517
1518static void __exit fs_cleanup(void)
1519{
1520 driver_unregister(&fs_enet_fec_driver);
1521 driver_unregister(&fs_enet_fcc_driver);
1522 driver_unregister(&fs_enet_scc_driver);
1523 cleanup_immap();
1524}
1525#endif
1526 1218
1527#ifdef CONFIG_NET_POLL_CONTROLLER 1219#ifdef CONFIG_NET_POLL_CONTROLLER
1528static void fs_enet_netpoll(struct net_device *dev) 1220static void fs_enet_netpoll(struct net_device *dev)
diff --git a/drivers/net/fs_enet/fs_enet.h b/drivers/net/fs_enet/fs_enet.h
index e05389c49bbb..db46d2e72329 100644
--- a/drivers/net/fs_enet/fs_enet.h
+++ b/drivers/net/fs_enet/fs_enet.h
@@ -138,10 +138,6 @@ struct fs_enet_private {
138}; 138};
139 139
140/***************************************************************************/ 140/***************************************************************************/
141#ifndef CONFIG_PPC_CPM_NEW_BINDING
142int fs_enet_mdio_bb_init(void);
143int fs_enet_mdio_fec_init(void);
144#endif
145 141
146void fs_init_bds(struct net_device *dev); 142void fs_init_bds(struct net_device *dev);
147void fs_cleanup_bds(struct net_device *dev); 143void fs_cleanup_bds(struct net_device *dev);
diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c
index 8268b3535b30..0a97fc2d97ec 100644
--- a/drivers/net/fs_enet/mac-fcc.c
+++ b/drivers/net/fs_enet/mac-fcc.c
@@ -33,6 +33,7 @@
33#include <linux/fs.h> 33#include <linux/fs.h>
34#include <linux/platform_device.h> 34#include <linux/platform_device.h>
35#include <linux/phy.h> 35#include <linux/phy.h>
36#include <linux/of_device.h>
36 37
37#include <asm/immap_cpm2.h> 38#include <asm/immap_cpm2.h>
38#include <asm/mpc8260.h> 39#include <asm/mpc8260.h>
@@ -42,10 +43,6 @@
42#include <asm/irq.h> 43#include <asm/irq.h>
43#include <asm/uaccess.h> 44#include <asm/uaccess.h>
44 45
45#ifdef CONFIG_PPC_CPM_NEW_BINDING
46#include <asm/of_device.h>
47#endif
48
49#include "fs_enet.h" 46#include "fs_enet.h"
50 47
51/*************************************************/ 48/*************************************************/
@@ -87,7 +84,6 @@ static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 op)
87 84
88static int do_pd_setup(struct fs_enet_private *fep) 85static int do_pd_setup(struct fs_enet_private *fep)
89{ 86{
90#ifdef CONFIG_PPC_CPM_NEW_BINDING
91 struct of_device *ofdev = to_of_device(fep->dev); 87 struct of_device *ofdev = to_of_device(fep->dev);
92 struct fs_platform_info *fpi = fep->fpi; 88 struct fs_platform_info *fpi = fep->fpi;
93 int ret = -EINVAL; 89 int ret = -EINVAL;
@@ -125,44 +121,6 @@ out_fccp:
125 iounmap(fep->fcc.fccp); 121 iounmap(fep->fcc.fccp);
126out: 122out:
127 return ret; 123 return ret;
128#else
129 struct platform_device *pdev = to_platform_device(fep->dev);
130 struct resource *r;
131
132 /* Fill out IRQ field */
133 fep->interrupt = platform_get_irq(pdev, 0);
134 if (fep->interrupt < 0)
135 return -EINVAL;
136
137 /* Attach the memory for the FCC Parameter RAM */
138 r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_pram");
139 fep->fcc.ep = ioremap(r->start, r->end - r->start + 1);
140 if (fep->fcc.ep == NULL)
141 return -EINVAL;
142
143 r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_regs");
144 fep->fcc.fccp = ioremap(r->start, r->end - r->start + 1);
145 if (fep->fcc.fccp == NULL)
146 return -EINVAL;
147
148 if (fep->fpi->fcc_regs_c) {
149 fep->fcc.fcccp = (void __iomem *)fep->fpi->fcc_regs_c;
150 } else {
151 r = platform_get_resource_byname(pdev, IORESOURCE_MEM,
152 "fcc_regs_c");
153 fep->fcc.fcccp = ioremap(r->start,
154 r->end - r->start + 1);
155 }
156
157 if (fep->fcc.fcccp == NULL)
158 return -EINVAL;
159
160 fep->fcc.mem = (void __iomem *)fep->fpi->mem_offset;
161 if (fep->fcc.mem == NULL)
162 return -EINVAL;
163
164 return 0;
165#endif
166} 124}
167 125
168#define FCC_NAPI_RX_EVENT_MSK (FCC_ENET_RXF | FCC_ENET_RXB) 126#define FCC_NAPI_RX_EVENT_MSK (FCC_ENET_RXF | FCC_ENET_RXB)
@@ -173,17 +131,6 @@ out:
173static int setup_data(struct net_device *dev) 131static int setup_data(struct net_device *dev)
174{ 132{
175 struct fs_enet_private *fep = netdev_priv(dev); 133 struct fs_enet_private *fep = netdev_priv(dev);
176#ifndef CONFIG_PPC_CPM_NEW_BINDING
177 struct fs_platform_info *fpi = fep->fpi;
178
179 fpi->cp_command = (fpi->cp_page << 26) |
180 (fpi->cp_block << 21) |
181 (12 << 6);
182
183 fep->fcc.idx = fs_get_fcc_index(fpi->fs_no);
184 if ((unsigned int)fep->fcc.idx >= 3) /* max 3 FCCs */
185 return -EINVAL;
186#endif
187 134
188 if (do_pd_setup(fep) != 0) 135 if (do_pd_setup(fep) != 0)
189 return -EINVAL; 136 return -EINVAL;
@@ -304,9 +251,6 @@ static void restart(struct net_device *dev)
304 fcc_enet_t __iomem *ep = fep->fcc.ep; 251 fcc_enet_t __iomem *ep = fep->fcc.ep;
305 dma_addr_t rx_bd_base_phys, tx_bd_base_phys; 252 dma_addr_t rx_bd_base_phys, tx_bd_base_phys;
306 u16 paddrh, paddrm, paddrl; 253 u16 paddrh, paddrm, paddrl;
307#ifndef CONFIG_PPC_CPM_NEW_BINDING
308 u16 mem_addr;
309#endif
310 const unsigned char *mac; 254 const unsigned char *mac;
311 int i; 255 int i;
312 256
@@ -338,19 +282,10 @@ static void restart(struct net_device *dev)
338 * this area. 282 * this area.
339 */ 283 */
340 284
341#ifdef CONFIG_PPC_CPM_NEW_BINDING
342 W16(ep, fen_genfcc.fcc_riptr, fpi->dpram_offset); 285 W16(ep, fen_genfcc.fcc_riptr, fpi->dpram_offset);
343 W16(ep, fen_genfcc.fcc_tiptr, fpi->dpram_offset + 32); 286 W16(ep, fen_genfcc.fcc_tiptr, fpi->dpram_offset + 32);
344 287
345 W16(ep, fen_padptr, fpi->dpram_offset + 64); 288 W16(ep, fen_padptr, fpi->dpram_offset + 64);
346#else
347 mem_addr = (u32) fep->fcc.mem; /* de-fixup dpram offset */
348
349 W16(ep, fen_genfcc.fcc_riptr, (mem_addr & 0xffff));
350 W16(ep, fen_genfcc.fcc_tiptr, ((mem_addr + 32) & 0xffff));
351
352 W16(ep, fen_padptr, mem_addr + 64);
353#endif
354 289
355 /* fill with special symbol... */ 290 /* fill with special symbol... */
356 memset_io(fep->fcc.mem + fpi->dpram_offset + 64, 0x88, 32); 291 memset_io(fep->fcc.mem + fpi->dpram_offset + 64, 0x88, 32);
diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c
index 8a311d1e435b..0a7d1c5c6524 100644
--- a/drivers/net/fs_enet/mac-fec.c
+++ b/drivers/net/fs_enet/mac-fec.c
@@ -32,6 +32,7 @@
32#include <linux/bitops.h> 32#include <linux/bitops.h>
33#include <linux/fs.h> 33#include <linux/fs.h>
34#include <linux/platform_device.h> 34#include <linux/platform_device.h>
35#include <linux/of_device.h>
35 36
36#include <asm/irq.h> 37#include <asm/irq.h>
37#include <asm/uaccess.h> 38#include <asm/uaccess.h>
@@ -43,10 +44,6 @@
43#include <asm/cpm1.h> 44#include <asm/cpm1.h>
44#endif 45#endif
45 46
46#ifdef CONFIG_PPC_CPM_NEW_BINDING
47#include <asm/of_device.h>
48#endif
49
50#include "fs_enet.h" 47#include "fs_enet.h"
51#include "fec.h" 48#include "fec.h"
52 49
@@ -99,7 +96,6 @@ static int whack_reset(fec_t __iomem *fecp)
99 96
100static int do_pd_setup(struct fs_enet_private *fep) 97static int do_pd_setup(struct fs_enet_private *fep)
101{ 98{
102#ifdef CONFIG_PPC_CPM_NEW_BINDING
103 struct of_device *ofdev = to_of_device(fep->dev); 99 struct of_device *ofdev = to_of_device(fep->dev);
104 100
105 fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL); 101 fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL);
@@ -111,23 +107,6 @@ static int do_pd_setup(struct fs_enet_private *fep)
111 return -EINVAL; 107 return -EINVAL;
112 108
113 return 0; 109 return 0;
114#else
115 struct platform_device *pdev = to_platform_device(fep->dev);
116 struct resource *r;
117
118 /* Fill out IRQ field */
119 fep->interrupt = platform_get_irq_byname(pdev,"interrupt");
120 if (fep->interrupt < 0)
121 return -EINVAL;
122
123 r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
124 fep->fec.fecp = ioremap(r->start, r->end - r->start + 1);
125
126 if(fep->fec.fecp == NULL)
127 return -EINVAL;
128
129 return 0;
130#endif
131} 110}
132 111
133#define FEC_NAPI_RX_EVENT_MSK (FEC_ENET_RXF | FEC_ENET_RXB) 112#define FEC_NAPI_RX_EVENT_MSK (FEC_ENET_RXF | FEC_ENET_RXB)
diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c
index e3557eca7b6d..029b3c7ef29c 100644
--- a/drivers/net/fs_enet/mac-scc.c
+++ b/drivers/net/fs_enet/mac-scc.c
@@ -32,6 +32,7 @@
32#include <linux/bitops.h> 32#include <linux/bitops.h>
33#include <linux/fs.h> 33#include <linux/fs.h>
34#include <linux/platform_device.h> 34#include <linux/platform_device.h>
35#include <linux/of_platform.h>
35 36
36#include <asm/irq.h> 37#include <asm/irq.h>
37#include <asm/uaccess.h> 38#include <asm/uaccess.h>
@@ -43,10 +44,6 @@
43#include <asm/cpm1.h> 44#include <asm/cpm1.h>
44#endif 45#endif
45 46
46#ifdef CONFIG_PPC_CPM_NEW_BINDING
47#include <linux/of_platform.h>
48#endif
49
50#include "fs_enet.h" 47#include "fs_enet.h"
51 48
52/*************************************************/ 49/*************************************************/
@@ -99,7 +96,6 @@ static inline int scc_cr_cmd(struct fs_enet_private *fep, u32 op)
99 96
100static int do_pd_setup(struct fs_enet_private *fep) 97static int do_pd_setup(struct fs_enet_private *fep)
101{ 98{
102#ifdef CONFIG_PPC_CPM_NEW_BINDING
103 struct of_device *ofdev = to_of_device(fep->dev); 99 struct of_device *ofdev = to_of_device(fep->dev);
104 100
105 fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL); 101 fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL);
@@ -115,27 +111,6 @@ static int do_pd_setup(struct fs_enet_private *fep)
115 iounmap(fep->scc.sccp); 111 iounmap(fep->scc.sccp);
116 return -EINVAL; 112 return -EINVAL;
117 } 113 }
118#else
119 struct platform_device *pdev = to_platform_device(fep->dev);
120 struct resource *r;
121
122 /* Fill out IRQ field */
123 fep->interrupt = platform_get_irq_byname(pdev, "interrupt");
124 if (fep->interrupt < 0)
125 return -EINVAL;
126
127 r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
128 fep->scc.sccp = ioremap(r->start, r->end - r->start + 1);
129
130 if (fep->scc.sccp == NULL)
131 return -EINVAL;
132
133 r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pram");
134 fep->scc.ep = ioremap(r->start, r->end - r->start + 1);
135
136 if (fep->scc.ep == NULL)
137 return -EINVAL;
138#endif
139 114
140 return 0; 115 return 0;
141} 116}
@@ -149,16 +124,6 @@ static int setup_data(struct net_device *dev)
149{ 124{
150 struct fs_enet_private *fep = netdev_priv(dev); 125 struct fs_enet_private *fep = netdev_priv(dev);
151 126
152#ifndef CONFIG_PPC_CPM_NEW_BINDING
153 struct fs_platform_info *fpi = fep->fpi;
154
155 fep->scc.idx = fs_get_scc_index(fpi->fs_no);
156 if ((unsigned int)fep->fcc.idx >= 4) /* max 4 SCCs */
157 return -EINVAL;
158
159 fpi->cp_command = fep->fcc.idx << 6;
160#endif
161
162 do_pd_setup(fep); 127 do_pd_setup(fep);
163 128
164 fep->scc.hthi = 0; 129 fep->scc.hthi = 0;
diff --git a/drivers/net/fs_enet/mii-bitbang.c b/drivers/net/fs_enet/mii-bitbang.c
index 1620030cd33c..be4b72f4f49a 100644
--- a/drivers/net/fs_enet/mii-bitbang.c
+++ b/drivers/net/fs_enet/mii-bitbang.c
@@ -22,10 +22,7 @@
22#include <linux/mii.h> 22#include <linux/mii.h>
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/mdio-bitbang.h> 24#include <linux/mdio-bitbang.h>
25
26#ifdef CONFIG_PPC_CPM_NEW_BINDING
27#include <linux/of_platform.h> 25#include <linux/of_platform.h>
28#endif
29 26
30#include "fs_enet.h" 27#include "fs_enet.h"
31 28
@@ -110,7 +107,6 @@ static struct mdiobb_ops bb_ops = {
110 .get_mdio_data = mdio_read, 107 .get_mdio_data = mdio_read,
111}; 108};
112 109
113#ifdef CONFIG_PPC_CPM_NEW_BINDING
114static int __devinit fs_mii_bitbang_init(struct mii_bus *bus, 110static int __devinit fs_mii_bitbang_init(struct mii_bus *bus,
115 struct device_node *np) 111 struct device_node *np)
116{ 112{
@@ -271,106 +267,3 @@ static void fs_enet_mdio_bb_exit(void)
271 267
272module_init(fs_enet_mdio_bb_init); 268module_init(fs_enet_mdio_bb_init);
273module_exit(fs_enet_mdio_bb_exit); 269module_exit(fs_enet_mdio_bb_exit);
274#else
275static int __devinit fs_mii_bitbang_init(struct bb_info *bitbang,
276 struct fs_mii_bb_platform_info *fmpi)
277{
278 bitbang->dir = (u32 __iomem *)fmpi->mdio_dir.offset;
279 bitbang->dat = (u32 __iomem *)fmpi->mdio_dat.offset;
280 bitbang->mdio_msk = 1U << (31 - fmpi->mdio_dat.bit);
281 bitbang->mdc_msk = 1U << (31 - fmpi->mdc_dat.bit);
282
283 return 0;
284}
285
286static int __devinit fs_enet_mdio_probe(struct device *dev)
287{
288 struct platform_device *pdev = to_platform_device(dev);
289 struct fs_mii_bb_platform_info *pdata;
290 struct mii_bus *new_bus;
291 struct bb_info *bitbang;
292 int err = 0;
293
294 if (NULL == dev)
295 return -EINVAL;
296
297 bitbang = kzalloc(sizeof(struct bb_info), GFP_KERNEL);
298
299 if (NULL == bitbang)
300 return -ENOMEM;
301
302 bitbang->ctrl.ops = &bb_ops;
303
304 new_bus = alloc_mdio_bitbang(&bitbang->ctrl);
305
306 if (NULL == new_bus)
307 return -ENOMEM;
308
309 new_bus->name = "BB MII Bus",
310 snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", pdev->id);
311
312 new_bus->phy_mask = ~0x9;
313 pdata = (struct fs_mii_bb_platform_info *)pdev->dev.platform_data;
314
315 if (NULL == pdata) {
316 printk(KERN_ERR "gfar mdio %d: Missing platform data!\n", pdev->id);
317 return -ENODEV;
318 }
319
320 /*set up workspace*/
321 fs_mii_bitbang_init(bitbang, pdata);
322
323 new_bus->priv = bitbang;
324
325 new_bus->irq = pdata->irq;
326
327 new_bus->dev = dev;
328 dev_set_drvdata(dev, new_bus);
329
330 err = mdiobus_register(new_bus);
331
332 if (0 != err) {
333 printk (KERN_ERR "%s: Cannot register as MDIO bus\n",
334 new_bus->name);
335 goto bus_register_fail;
336 }
337
338 return 0;
339
340bus_register_fail:
341 free_mdio_bitbang(new_bus);
342 kfree(bitbang);
343
344 return err;
345}
346
347static int fs_enet_mdio_remove(struct device *dev)
348{
349 struct mii_bus *bus = dev_get_drvdata(dev);
350
351 mdiobus_unregister(bus);
352
353 dev_set_drvdata(dev, NULL);
354
355 free_mdio_bitbang(bus);
356
357 return 0;
358}
359
360static struct device_driver fs_enet_bb_mdio_driver = {
361 .name = "fsl-bb-mdio",
362 .bus = &platform_bus_type,
363 .probe = fs_enet_mdio_probe,
364 .remove = fs_enet_mdio_remove,
365};
366
367int fs_enet_mdio_bb_init(void)
368{
369 return driver_register(&fs_enet_bb_mdio_driver);
370}
371
372void fs_enet_mdio_bb_exit(void)
373{
374 driver_unregister(&fs_enet_bb_mdio_driver);
375}
376#endif
diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c
index 8f6a43b0e0ff..695f74cc4398 100644
--- a/drivers/net/fs_enet/mii-fec.c
+++ b/drivers/net/fs_enet/mii-fec.c
@@ -31,15 +31,12 @@
31#include <linux/ethtool.h> 31#include <linux/ethtool.h>
32#include <linux/bitops.h> 32#include <linux/bitops.h>
33#include <linux/platform_device.h> 33#include <linux/platform_device.h>
34#include <linux/of_platform.h>
34 35
35#include <asm/pgtable.h> 36#include <asm/pgtable.h>
36#include <asm/irq.h> 37#include <asm/irq.h>
37#include <asm/uaccess.h> 38#include <asm/uaccess.h>
38 39
39#ifdef CONFIG_PPC_CPM_NEW_BINDING
40#include <linux/of_platform.h>
41#endif
42
43#include "fs_enet.h" 40#include "fs_enet.h"
44#include "fec.h" 41#include "fec.h"
45 42
@@ -51,52 +48,6 @@
51 48
52#define FEC_MII_LOOPS 10000 49#define FEC_MII_LOOPS 10000
53 50
54#ifndef CONFIG_PPC_CPM_NEW_BINDING
55static int match_has_phy (struct device *dev, void* data)
56{
57 struct platform_device* pdev = container_of(dev, struct platform_device, dev);
58 struct fs_platform_info* fpi;
59 if(strcmp(pdev->name, (char*)data))
60 {
61 return 0;
62 }
63
64 fpi = pdev->dev.platform_data;
65 if((fpi)&&(fpi->has_phy))
66 return 1;
67 return 0;
68}
69
70static int fs_mii_fec_init(struct fec_info* fec, struct fs_mii_fec_platform_info *fmpi)
71{
72 struct resource *r;
73 fec_t __iomem *fecp;
74 char* name = "fsl-cpm-fec";
75
76 /* we need fec in order to be useful */
77 struct platform_device *fec_pdev =
78 container_of(bus_find_device(&platform_bus_type, NULL, name, match_has_phy),
79 struct platform_device, dev);
80
81 if(fec_pdev == NULL) {
82 printk(KERN_ERR"Unable to find PHY for %s", name);
83 return -ENODEV;
84 }
85
86 r = platform_get_resource_byname(fec_pdev, IORESOURCE_MEM, "regs");
87
88 fec->fecp = fecp = ioremap(r->start,sizeof(fec_t));
89 fec->mii_speed = fmpi->mii_speed;
90
91 setbits32(&fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */
92 setbits32(&fecp->fec_ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN);
93 out_be32(&fecp->fec_ievent, FEC_ENET_MII);
94 out_be32(&fecp->fec_mii_speed, fec->mii_speed);
95
96 return 0;
97}
98#endif
99
100static int fs_enet_fec_mii_read(struct mii_bus *bus , int phy_id, int location) 51static int fs_enet_fec_mii_read(struct mii_bus *bus , int phy_id, int location)
101{ 52{
102 struct fec_info* fec = bus->priv; 53 struct fec_info* fec = bus->priv;
@@ -151,7 +102,6 @@ static int fs_enet_fec_mii_reset(struct mii_bus *bus)
151 return 0; 102 return 0;
152} 103}
153 104
154#ifdef CONFIG_PPC_CPM_NEW_BINDING
155static void __devinit add_phy(struct mii_bus *bus, struct device_node *np) 105static void __devinit add_phy(struct mii_bus *bus, struct device_node *np)
156{ 106{
157 const u32 *data; 107 const u32 *data;
@@ -286,95 +236,3 @@ static void fs_enet_mdio_fec_exit(void)
286 236
287module_init(fs_enet_mdio_fec_init); 237module_init(fs_enet_mdio_fec_init);
288module_exit(fs_enet_mdio_fec_exit); 238module_exit(fs_enet_mdio_fec_exit);
289#else
290static int __devinit fs_enet_fec_mdio_probe(struct device *dev)
291{
292 struct platform_device *pdev = to_platform_device(dev);
293 struct fs_mii_fec_platform_info *pdata;
294 struct mii_bus *new_bus;
295 struct fec_info *fec;
296 int err = 0;
297 if (NULL == dev)
298 return -EINVAL;
299 new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);
300
301 if (NULL == new_bus)
302 return -ENOMEM;
303
304 fec = kzalloc(sizeof(struct fec_info), GFP_KERNEL);
305
306 if (NULL == fec)
307 return -ENOMEM;
308
309 new_bus->name = "FEC MII Bus",
310 new_bus->read = &fs_enet_fec_mii_read,
311 new_bus->write = &fs_enet_fec_mii_write,
312 new_bus->reset = &fs_enet_fec_mii_reset,
313 snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", pdev->id);
314
315 pdata = (struct fs_mii_fec_platform_info *)pdev->dev.platform_data;
316
317 if (NULL == pdata) {
318 printk(KERN_ERR "fs_enet FEC mdio %d: Missing platform data!\n", pdev->id);
319 return -ENODEV;
320 }
321
322 /*set up workspace*/
323
324 fs_mii_fec_init(fec, pdata);
325 new_bus->priv = fec;
326
327 new_bus->irq = pdata->irq;
328
329 new_bus->dev = dev;
330 dev_set_drvdata(dev, new_bus);
331
332 err = mdiobus_register(new_bus);
333
334 if (0 != err) {
335 printk (KERN_ERR "%s: Cannot register as MDIO bus\n",
336 new_bus->name);
337 goto bus_register_fail;
338 }
339
340 return 0;
341
342bus_register_fail:
343 kfree(new_bus);
344
345 return err;
346}
347
348
349static int fs_enet_fec_mdio_remove(struct device *dev)
350{
351 struct mii_bus *bus = dev_get_drvdata(dev);
352
353 mdiobus_unregister(bus);
354
355 dev_set_drvdata(dev, NULL);
356 kfree(bus->priv);
357
358 bus->priv = NULL;
359 kfree(bus);
360
361 return 0;
362}
363
364static struct device_driver fs_enet_fec_mdio_driver = {
365 .name = "fsl-cpm-fec-mdio",
366 .bus = &platform_bus_type,
367 .probe = fs_enet_fec_mdio_probe,
368 .remove = fs_enet_fec_mdio_remove,
369};
370
371int fs_enet_mdio_fec_init(void)
372{
373 return driver_register(&fs_enet_fec_mdio_driver);
374}
375
376void fs_enet_mdio_fec_exit(void)
377{
378 driver_unregister(&fs_enet_fec_mdio_driver);
379}
380#endif
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 39b45e901be6..b8394cf134e8 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -134,6 +134,9 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int l
134static void gfar_vlan_rx_register(struct net_device *netdev, 134static void gfar_vlan_rx_register(struct net_device *netdev,
135 struct vlan_group *grp); 135 struct vlan_group *grp);
136void gfar_halt(struct net_device *dev); 136void gfar_halt(struct net_device *dev);
137#ifdef CONFIG_PM
138static void gfar_halt_nodisable(struct net_device *dev);
139#endif
137void gfar_start(struct net_device *dev); 140void gfar_start(struct net_device *dev);
138static void gfar_clear_exact_match(struct net_device *dev); 141static void gfar_clear_exact_match(struct net_device *dev);
139static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr); 142static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr);
@@ -207,6 +210,7 @@ static int gfar_probe(struct platform_device *pdev)
207 210
208 spin_lock_init(&priv->txlock); 211 spin_lock_init(&priv->txlock);
209 spin_lock_init(&priv->rxlock); 212 spin_lock_init(&priv->rxlock);
213 spin_lock_init(&priv->bflock);
210 214
211 platform_set_drvdata(pdev, dev); 215 platform_set_drvdata(pdev, dev);
212 216
@@ -378,6 +382,103 @@ static int gfar_remove(struct platform_device *pdev)
378 return 0; 382 return 0;
379} 383}
380 384
385#ifdef CONFIG_PM
386static int gfar_suspend(struct platform_device *pdev, pm_message_t state)
387{
388 struct net_device *dev = platform_get_drvdata(pdev);
389 struct gfar_private *priv = netdev_priv(dev);
390 unsigned long flags;
391 u32 tempval;
392
393 int magic_packet = priv->wol_en &&
394 (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
395
396 netif_device_detach(dev);
397
398 if (netif_running(dev)) {
399 spin_lock_irqsave(&priv->txlock, flags);
400 spin_lock(&priv->rxlock);
401
402 gfar_halt_nodisable(dev);
403
404 /* Disable Tx, and Rx if wake-on-LAN is disabled. */
405 tempval = gfar_read(&priv->regs->maccfg1);
406
407 tempval &= ~MACCFG1_TX_EN;
408
409 if (!magic_packet)
410 tempval &= ~MACCFG1_RX_EN;
411
412 gfar_write(&priv->regs->maccfg1, tempval);
413
414 spin_unlock(&priv->rxlock);
415 spin_unlock_irqrestore(&priv->txlock, flags);
416
417#ifdef CONFIG_GFAR_NAPI
418 napi_disable(&priv->napi);
419#endif
420
421 if (magic_packet) {
422 /* Enable interrupt on Magic Packet */
423 gfar_write(&priv->regs->imask, IMASK_MAG);
424
425 /* Enable Magic Packet mode */
426 tempval = gfar_read(&priv->regs->maccfg2);
427 tempval |= MACCFG2_MPEN;
428 gfar_write(&priv->regs->maccfg2, tempval);
429 } else {
430 phy_stop(priv->phydev);
431 }
432 }
433
434 return 0;
435}
436
437static int gfar_resume(struct platform_device *pdev)
438{
439 struct net_device *dev = platform_get_drvdata(pdev);
440 struct gfar_private *priv = netdev_priv(dev);
441 unsigned long flags;
442 u32 tempval;
443 int magic_packet = priv->wol_en &&
444 (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
445
446 if (!netif_running(dev)) {
447 netif_device_attach(dev);
448 return 0;
449 }
450
451 if (!magic_packet && priv->phydev)
452 phy_start(priv->phydev);
453
454 /* Disable Magic Packet mode, in case something
455 * else woke us up.
456 */
457
458 spin_lock_irqsave(&priv->txlock, flags);
459 spin_lock(&priv->rxlock);
460
461 tempval = gfar_read(&priv->regs->maccfg2);
462 tempval &= ~MACCFG2_MPEN;
463 gfar_write(&priv->regs->maccfg2, tempval);
464
465 gfar_start(dev);
466
467 spin_unlock(&priv->rxlock);
468 spin_unlock_irqrestore(&priv->txlock, flags);
469
470 netif_device_attach(dev);
471
472#ifdef CONFIG_GFAR_NAPI
473 napi_enable(&priv->napi);
474#endif
475
476 return 0;
477}
478#else
479#define gfar_suspend NULL
480#define gfar_resume NULL
481#endif
381 482
382/* Reads the controller's registers to determine what interface 483/* Reads the controller's registers to determine what interface
383 * connects it to the PHY. 484 * connects it to the PHY.
@@ -534,8 +635,9 @@ static void init_registers(struct net_device *dev)
534} 635}
535 636
536 637
638#ifdef CONFIG_PM
537/* Halt the receive and transmit queues */ 639/* Halt the receive and transmit queues */
538void gfar_halt(struct net_device *dev) 640static void gfar_halt_nodisable(struct net_device *dev)
539{ 641{
540 struct gfar_private *priv = netdev_priv(dev); 642 struct gfar_private *priv = netdev_priv(dev);
541 struct gfar __iomem *regs = priv->regs; 643 struct gfar __iomem *regs = priv->regs;
@@ -558,6 +660,15 @@ void gfar_halt(struct net_device *dev)
558 (IEVENT_GRSC | IEVENT_GTSC))) 660 (IEVENT_GRSC | IEVENT_GTSC)))
559 cpu_relax(); 661 cpu_relax();
560 } 662 }
663}
664#endif
665
666/* Halt the receive and transmit queues */
667void gfar_halt(struct net_device *dev)
668{
669 struct gfar_private *priv = netdev_priv(dev);
670 struct gfar __iomem *regs = priv->regs;
671 u32 tempval;
561 672
562 /* Disable Rx and Tx */ 673 /* Disable Rx and Tx */
563 tempval = gfar_read(&regs->maccfg1); 674 tempval = gfar_read(&regs->maccfg1);
@@ -1909,7 +2020,12 @@ static irqreturn_t gfar_error(int irq, void *dev_id)
1909 u32 events = gfar_read(&priv->regs->ievent); 2020 u32 events = gfar_read(&priv->regs->ievent);
1910 2021
1911 /* Clear IEVENT */ 2022 /* Clear IEVENT */
1912 gfar_write(&priv->regs->ievent, IEVENT_ERR_MASK); 2023 gfar_write(&priv->regs->ievent, events & IEVENT_ERR_MASK);
2024
2025 /* Magic Packet is not an error. */
2026 if ((priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) &&
2027 (events & IEVENT_MAG))
2028 events &= ~IEVENT_MAG;
1913 2029
1914 /* Hmm... */ 2030 /* Hmm... */
1915 if (netif_msg_rx_err(priv) || netif_msg_tx_err(priv)) 2031 if (netif_msg_rx_err(priv) || netif_msg_tx_err(priv))
@@ -1977,6 +2093,8 @@ MODULE_ALIAS("platform:fsl-gianfar");
1977static struct platform_driver gfar_driver = { 2093static struct platform_driver gfar_driver = {
1978 .probe = gfar_probe, 2094 .probe = gfar_probe,
1979 .remove = gfar_remove, 2095 .remove = gfar_remove,
2096 .suspend = gfar_suspend,
2097 .resume = gfar_resume,
1980 .driver = { 2098 .driver = {
1981 .name = "fsl-gianfar", 2099 .name = "fsl-gianfar",
1982 .owner = THIS_MODULE, 2100 .owner = THIS_MODULE,
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index bead71cb2b16..d59df98bd636 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -157,6 +157,7 @@ extern const char gfar_driver_version[];
157#define MACCFG2_GMII 0x00000200 157#define MACCFG2_GMII 0x00000200
158#define MACCFG2_HUGEFRAME 0x00000020 158#define MACCFG2_HUGEFRAME 0x00000020
159#define MACCFG2_LENGTHCHECK 0x00000010 159#define MACCFG2_LENGTHCHECK 0x00000010
160#define MACCFG2_MPEN 0x00000008
160 161
161#define ECNTRL_INIT_SETTINGS 0x00001000 162#define ECNTRL_INIT_SETTINGS 0x00001000
162#define ECNTRL_TBI_MODE 0x00000020 163#define ECNTRL_TBI_MODE 0x00000020
@@ -229,6 +230,7 @@ extern const char gfar_driver_version[];
229#define IEVENT_CRL 0x00020000 230#define IEVENT_CRL 0x00020000
230#define IEVENT_XFUN 0x00010000 231#define IEVENT_XFUN 0x00010000
231#define IEVENT_RXB0 0x00008000 232#define IEVENT_RXB0 0x00008000
233#define IEVENT_MAG 0x00000800
232#define IEVENT_GRSC 0x00000100 234#define IEVENT_GRSC 0x00000100
233#define IEVENT_RXF0 0x00000080 235#define IEVENT_RXF0 0x00000080
234#define IEVENT_FIR 0x00000008 236#define IEVENT_FIR 0x00000008
@@ -241,7 +243,8 @@ extern const char gfar_driver_version[];
241#define IEVENT_ERR_MASK \ 243#define IEVENT_ERR_MASK \
242(IEVENT_RXC | IEVENT_BSY | IEVENT_EBERR | IEVENT_MSRO | \ 244(IEVENT_RXC | IEVENT_BSY | IEVENT_EBERR | IEVENT_MSRO | \
243 IEVENT_BABT | IEVENT_TXC | IEVENT_TXE | IEVENT_LC \ 245 IEVENT_BABT | IEVENT_TXC | IEVENT_TXE | IEVENT_LC \
244 | IEVENT_CRL | IEVENT_XFUN | IEVENT_DPE | IEVENT_PERR) 246 | IEVENT_CRL | IEVENT_XFUN | IEVENT_DPE | IEVENT_PERR \
247 | IEVENT_MAG)
245 248
246#define IMASK_INIT_CLEAR 0x00000000 249#define IMASK_INIT_CLEAR 0x00000000
247#define IMASK_BABR 0x80000000 250#define IMASK_BABR 0x80000000
@@ -259,6 +262,7 @@ extern const char gfar_driver_version[];
259#define IMASK_CRL 0x00020000 262#define IMASK_CRL 0x00020000
260#define IMASK_XFUN 0x00010000 263#define IMASK_XFUN 0x00010000
261#define IMASK_RXB0 0x00008000 264#define IMASK_RXB0 0x00008000
265#define IMASK_MAG 0x00000800
262#define IMASK_GTSC 0x00000100 266#define IMASK_GTSC 0x00000100
263#define IMASK_RXFEN0 0x00000080 267#define IMASK_RXFEN0 0x00000080
264#define IMASK_FIR 0x00000008 268#define IMASK_FIR 0x00000008
@@ -726,10 +730,14 @@ struct gfar_private {
726 unsigned int fifo_starve; 730 unsigned int fifo_starve;
727 unsigned int fifo_starve_off; 731 unsigned int fifo_starve_off;
728 732
733 /* Bitfield update lock */
734 spinlock_t bflock;
735
729 unsigned char vlan_enable:1, 736 unsigned char vlan_enable:1,
730 rx_csum_enable:1, 737 rx_csum_enable:1,
731 extended_hash:1, 738 extended_hash:1,
732 bd_stash_en:1; 739 bd_stash_en:1,
740 wol_en:1; /* Wake-on-LAN enabled */
733 unsigned short padding; 741 unsigned short padding;
734 742
735 unsigned int interruptTransmit; 743 unsigned int interruptTransmit;
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
index 6007147cc1e9..fb7d3ccc0fdc 100644
--- a/drivers/net/gianfar_ethtool.c
+++ b/drivers/net/gianfar_ethtool.c
@@ -479,14 +479,13 @@ static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rva
479static int gfar_set_rx_csum(struct net_device *dev, uint32_t data) 479static int gfar_set_rx_csum(struct net_device *dev, uint32_t data)
480{ 480{
481 struct gfar_private *priv = netdev_priv(dev); 481 struct gfar_private *priv = netdev_priv(dev);
482 unsigned long flags;
482 int err = 0; 483 int err = 0;
483 484
484 if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM)) 485 if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
485 return -EOPNOTSUPP; 486 return -EOPNOTSUPP;
486 487
487 if (dev->flags & IFF_UP) { 488 if (dev->flags & IFF_UP) {
488 unsigned long flags;
489
490 /* Halt TX and RX, and process the frames which 489 /* Halt TX and RX, and process the frames which
491 * have already been received */ 490 * have already been received */
492 spin_lock_irqsave(&priv->txlock, flags); 491 spin_lock_irqsave(&priv->txlock, flags);
@@ -502,7 +501,9 @@ static int gfar_set_rx_csum(struct net_device *dev, uint32_t data)
502 stop_gfar(dev); 501 stop_gfar(dev);
503 } 502 }
504 503
504 spin_lock_irqsave(&priv->bflock, flags);
505 priv->rx_csum_enable = data; 505 priv->rx_csum_enable = data;
506 spin_unlock_irqrestore(&priv->bflock, flags);
506 507
507 if (dev->flags & IFF_UP) 508 if (dev->flags & IFF_UP)
508 err = startup_gfar(dev); 509 err = startup_gfar(dev);
@@ -564,6 +565,38 @@ static void gfar_set_msglevel(struct net_device *dev, uint32_t data)
564 priv->msg_enable = data; 565 priv->msg_enable = data;
565} 566}
566 567
568#ifdef CONFIG_PM
569static void gfar_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
570{
571 struct gfar_private *priv = netdev_priv(dev);
572
573 if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) {
574 wol->supported = WAKE_MAGIC;
575 wol->wolopts = priv->wol_en ? WAKE_MAGIC : 0;
576 } else {
577 wol->supported = wol->wolopts = 0;
578 }
579}
580
581static int gfar_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
582{
583 struct gfar_private *priv = netdev_priv(dev);
584 unsigned long flags;
585
586 if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) &&
587 wol->wolopts != 0)
588 return -EINVAL;
589
590 if (wol->wolopts & ~WAKE_MAGIC)
591 return -EINVAL;
592
593 spin_lock_irqsave(&priv->bflock, flags);
594 priv->wol_en = wol->wolopts & WAKE_MAGIC ? 1 : 0;
595 spin_unlock_irqrestore(&priv->bflock, flags);
596
597 return 0;
598}
599#endif
567 600
568const struct ethtool_ops gfar_ethtool_ops = { 601const struct ethtool_ops gfar_ethtool_ops = {
569 .get_settings = gfar_gsettings, 602 .get_settings = gfar_gsettings,
@@ -585,4 +618,8 @@ const struct ethtool_ops gfar_ethtool_ops = {
585 .set_tx_csum = gfar_set_tx_csum, 618 .set_tx_csum = gfar_set_tx_csum,
586 .get_msglevel = gfar_get_msglevel, 619 .get_msglevel = gfar_get_msglevel,
587 .set_msglevel = gfar_set_msglevel, 620 .set_msglevel = gfar_set_msglevel,
621#ifdef CONFIG_PM
622 .get_wol = gfar_get_wol,
623 .set_wol = gfar_set_wol,
624#endif
588}; 625};