aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sh_eth.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/net/sh_eth.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/net/sh_eth.c')
-rw-r--r--drivers/net/sh_eth.c76
1 files changed, 57 insertions, 19 deletions
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 528b912a4b0d..6242b85d5d15 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -30,6 +30,8 @@
30#include <linux/phy.h> 30#include <linux/phy.h>
31#include <linux/cache.h> 31#include <linux/cache.h>
32#include <linux/io.h> 32#include <linux/io.h>
33#include <linux/pm_runtime.h>
34#include <linux/slab.h>
33#include <asm/cacheflush.h> 35#include <asm/cacheflush.h>
34 36
35#include "sh_eth.h" 37#include "sh_eth.h"
@@ -83,6 +85,8 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
83 .mpr = 1, 85 .mpr = 1,
84 .tpauser = 1, 86 .tpauser = 1,
85 .hw_swap = 1, 87 .hw_swap = 1,
88 .rpadir = 1,
89 .rpadir_value = 0x00020000, /* NET_IP_ALIGN assumed to be 2 */
86}; 90};
87 91
88#elif defined(CONFIG_CPU_SUBTYPE_SH7763) 92#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
@@ -107,7 +111,7 @@ static void sh_eth_reset(struct net_device *ndev)
107 mdelay(1); 111 mdelay(1);
108 cnt--; 112 cnt--;
109 } 113 }
110 if (cnt < 0) 114 if (cnt == 0)
111 printk(KERN_ERR "Device reset fail\n"); 115 printk(KERN_ERR "Device reset fail\n");
112 116
113 /* Table Init */ 117 /* Table Init */
@@ -174,7 +178,6 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
174 .tpauser = 1, 178 .tpauser = 1,
175 .bculr = 1, 179 .bculr = 1,
176 .hw_swap = 1, 180 .hw_swap = 1,
177 .rpadir = 1,
178 .no_trimd = 1, 181 .no_trimd = 1,
179 .no_ade = 1, 182 .no_ade = 1,
180}; 183};
@@ -299,16 +302,20 @@ static void update_mac_address(struct net_device *ndev)
299 * When you want use this device, you must set MAC address in bootloader. 302 * When you want use this device, you must set MAC address in bootloader.
300 * 303 *
301 */ 304 */
302static void read_mac_address(struct net_device *ndev) 305static void read_mac_address(struct net_device *ndev, unsigned char *mac)
303{ 306{
304 u32 ioaddr = ndev->base_addr; 307 u32 ioaddr = ndev->base_addr;
305 308
306 ndev->dev_addr[0] = (ctrl_inl(ioaddr + MAHR) >> 24); 309 if (mac[0] || mac[1] || mac[2] || mac[3] || mac[4] || mac[5]) {
307 ndev->dev_addr[1] = (ctrl_inl(ioaddr + MAHR) >> 16) & 0xFF; 310 memcpy(ndev->dev_addr, mac, 6);
308 ndev->dev_addr[2] = (ctrl_inl(ioaddr + MAHR) >> 8) & 0xFF; 311 } else {
309 ndev->dev_addr[3] = (ctrl_inl(ioaddr + MAHR) & 0xFF); 312 ndev->dev_addr[0] = (ctrl_inl(ioaddr + MAHR) >> 24);
310 ndev->dev_addr[4] = (ctrl_inl(ioaddr + MALR) >> 8) & 0xFF; 313 ndev->dev_addr[1] = (ctrl_inl(ioaddr + MAHR) >> 16) & 0xFF;
311 ndev->dev_addr[5] = (ctrl_inl(ioaddr + MALR) & 0xFF); 314 ndev->dev_addr[2] = (ctrl_inl(ioaddr + MAHR) >> 8) & 0xFF;
315 ndev->dev_addr[3] = (ctrl_inl(ioaddr + MAHR) & 0xFF);
316 ndev->dev_addr[4] = (ctrl_inl(ioaddr + MALR) >> 8) & 0xFF;
317 ndev->dev_addr[5] = (ctrl_inl(ioaddr + MALR) & 0xFF);
318 }
312} 319}
313 320
314struct bb_info { 321struct bb_info {
@@ -496,6 +503,8 @@ static int sh_eth_ring_init(struct net_device *ndev)
496 */ 503 */
497 mdp->rx_buf_sz = (ndev->mtu <= 1492 ? PKT_BUF_SZ : 504 mdp->rx_buf_sz = (ndev->mtu <= 1492 ? PKT_BUF_SZ :
498 (((ndev->mtu + 26 + 7) & ~7) + 2 + 16)); 505 (((ndev->mtu + 26 + 7) & ~7) + 2 + 16));
506 if (mdp->cd->rpadir)
507 mdp->rx_buf_sz += NET_IP_ALIGN;
499 508
500 /* Allocate RX and TX skb rings */ 509 /* Allocate RX and TX skb rings */
501 mdp->rx_skbuff = kmalloc(sizeof(*mdp->rx_skbuff) * RX_RING_SIZE, 510 mdp->rx_skbuff = kmalloc(sizeof(*mdp->rx_skbuff) * RX_RING_SIZE,
@@ -710,6 +719,8 @@ static int sh_eth_rx(struct net_device *ndev)
710 pkt_len + 2); 719 pkt_len + 2);
711 skb = mdp->rx_skbuff[entry]; 720 skb = mdp->rx_skbuff[entry];
712 mdp->rx_skbuff[entry] = NULL; 721 mdp->rx_skbuff[entry] = NULL;
722 if (mdp->cd->rpadir)
723 skb_reserve(skb, NET_IP_ALIGN);
713 skb_put(skb, pkt_len); 724 skb_put(skb, pkt_len);
714 skb->protocol = eth_type_trans(skb, ndev); 725 skb->protocol = eth_type_trans(skb, ndev);
715 netif_rx(skb); 726 netif_rx(skb);
@@ -1009,7 +1020,9 @@ static int sh_eth_open(struct net_device *ndev)
1009 int ret = 0; 1020 int ret = 0;
1010 struct sh_eth_private *mdp = netdev_priv(ndev); 1021 struct sh_eth_private *mdp = netdev_priv(ndev);
1011 1022
1012 ret = request_irq(ndev->irq, &sh_eth_interrupt, 1023 pm_runtime_get_sync(&mdp->pdev->dev);
1024
1025 ret = request_irq(ndev->irq, sh_eth_interrupt,
1013#if defined(CONFIG_CPU_SUBTYPE_SH7763) || defined(CONFIG_CPU_SUBTYPE_SH7764) 1026#if defined(CONFIG_CPU_SUBTYPE_SH7763) || defined(CONFIG_CPU_SUBTYPE_SH7764)
1014 IRQF_SHARED, 1027 IRQF_SHARED,
1015#else 1028#else
@@ -1045,6 +1058,7 @@ static int sh_eth_open(struct net_device *ndev)
1045 1058
1046out_free_irq: 1059out_free_irq:
1047 free_irq(ndev->irq, ndev); 1060 free_irq(ndev->irq, ndev);
1061 pm_runtime_put_sync(&mdp->pdev->dev);
1048 return ret; 1062 return ret;
1049} 1063}
1050 1064
@@ -1176,6 +1190,8 @@ static int sh_eth_close(struct net_device *ndev)
1176 ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE; 1190 ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE;
1177 dma_free_coherent(NULL, ringsize, mdp->tx_ring, mdp->tx_desc_dma); 1191 dma_free_coherent(NULL, ringsize, mdp->tx_ring, mdp->tx_desc_dma);
1178 1192
1193 pm_runtime_put_sync(&mdp->pdev->dev);
1194
1179 return 0; 1195 return 0;
1180} 1196}
1181 1197
@@ -1184,6 +1200,8 @@ static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev)
1184 struct sh_eth_private *mdp = netdev_priv(ndev); 1200 struct sh_eth_private *mdp = netdev_priv(ndev);
1185 u32 ioaddr = ndev->base_addr; 1201 u32 ioaddr = ndev->base_addr;
1186 1202
1203 pm_runtime_get_sync(&mdp->pdev->dev);
1204
1187 mdp->stats.tx_dropped += ctrl_inl(ioaddr + TROCR); 1205 mdp->stats.tx_dropped += ctrl_inl(ioaddr + TROCR);
1188 ctrl_outl(0, ioaddr + TROCR); /* (write clear) */ 1206 ctrl_outl(0, ioaddr + TROCR); /* (write clear) */
1189 mdp->stats.collisions += ctrl_inl(ioaddr + CDCR); 1207 mdp->stats.collisions += ctrl_inl(ioaddr + CDCR);
@@ -1199,6 +1217,8 @@ static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev)
1199 mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CNDCR); 1217 mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CNDCR);
1200 ctrl_outl(0, ioaddr + CNDCR); /* (write clear) */ 1218 ctrl_outl(0, ioaddr + CNDCR); /* (write clear) */
1201#endif 1219#endif
1220 pm_runtime_put_sync(&mdp->pdev->dev);
1221
1202 return &mdp->stats; 1222 return &mdp->stats;
1203} 1223}
1204 1224
@@ -1407,6 +1427,9 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
1407 1427
1408 mdp = netdev_priv(ndev); 1428 mdp = netdev_priv(ndev);
1409 spin_lock_init(&mdp->lock); 1429 spin_lock_init(&mdp->lock);
1430 mdp->pdev = pdev;
1431 pm_runtime_enable(&pdev->dev);
1432 pm_runtime_resume(&pdev->dev);
1410 1433
1411 pd = (struct sh_eth_plat_data *)(pdev->dev.platform_data); 1434 pd = (struct sh_eth_plat_data *)(pdev->dev.platform_data);
1412 /* get PHY ID */ 1435 /* get PHY ID */
@@ -1428,7 +1451,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
1428 mdp->post_fw = POST_FW >> (devno << 1); 1451 mdp->post_fw = POST_FW >> (devno << 1);
1429 1452
1430 /* read and set MAC address */ 1453 /* read and set MAC address */
1431 read_mac_address(ndev); 1454 read_mac_address(ndev, pd->mac_addr);
1432 1455
1433 /* First device only init */ 1456 /* First device only init */
1434 if (!devno) { 1457 if (!devno) {
@@ -1451,13 +1474,9 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
1451 if (ret) 1474 if (ret)
1452 goto out_unregister; 1475 goto out_unregister;
1453 1476
1454 /* pritnt device infomation */ 1477 /* print device infomation */
1455 pr_info("Base address at 0x%x, ", 1478 pr_info("Base address at 0x%x, %pM, IRQ %d.\n",
1456 (u32)ndev->base_addr); 1479 (u32)ndev->base_addr, ndev->dev_addr, ndev->irq);
1457
1458 for (i = 0; i < 5; i++)
1459 printk("%02X:", ndev->dev_addr[i]);
1460 printk("%02X, IRQ %d.\n", ndev->dev_addr[i], ndev->irq);
1461 1480
1462 platform_set_drvdata(pdev, ndev); 1481 platform_set_drvdata(pdev, ndev);
1463 1482
@@ -1482,18 +1501,37 @@ static int sh_eth_drv_remove(struct platform_device *pdev)
1482 sh_mdio_release(ndev); 1501 sh_mdio_release(ndev);
1483 unregister_netdev(ndev); 1502 unregister_netdev(ndev);
1484 flush_scheduled_work(); 1503 flush_scheduled_work();
1485 1504 pm_runtime_disable(&pdev->dev);
1486 free_netdev(ndev); 1505 free_netdev(ndev);
1487 platform_set_drvdata(pdev, NULL); 1506 platform_set_drvdata(pdev, NULL);
1488 1507
1489 return 0; 1508 return 0;
1490} 1509}
1491 1510
1511static int sh_eth_runtime_nop(struct device *dev)
1512{
1513 /*
1514 * Runtime PM callback shared between ->runtime_suspend()
1515 * and ->runtime_resume(). Simply returns success.
1516 *
1517 * This driver re-initializes all registers after
1518 * pm_runtime_get_sync() anyway so there is no need
1519 * to save and restore registers here.
1520 */
1521 return 0;
1522}
1523
1524static struct dev_pm_ops sh_eth_dev_pm_ops = {
1525 .runtime_suspend = sh_eth_runtime_nop,
1526 .runtime_resume = sh_eth_runtime_nop,
1527};
1528
1492static struct platform_driver sh_eth_driver = { 1529static struct platform_driver sh_eth_driver = {
1493 .probe = sh_eth_drv_probe, 1530 .probe = sh_eth_drv_probe,
1494 .remove = sh_eth_drv_remove, 1531 .remove = sh_eth_drv_remove,
1495 .driver = { 1532 .driver = {
1496 .name = CARDNAME, 1533 .name = CARDNAME,
1534 .pm = &sh_eth_dev_pm_ops,
1497 }, 1535 },
1498}; 1536};
1499 1537