diff options
Diffstat (limited to 'drivers/net/sh_eth.c')
-rw-r--r-- | drivers/net/sh_eth.c | 76 |
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 | */ |
302 | static void read_mac_address(struct net_device *ndev) | 305 | static 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 | ||
314 | struct bb_info { | 321 | struct 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 | ||
1046 | out_free_irq: | 1059 | out_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 | ||
1511 | static 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 | |||
1524 | static 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 | |||
1492 | static struct platform_driver sh_eth_driver = { | 1529 | static 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 | ||