aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/gianfar.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/gianfar.c')
-rw-r--r--drivers/net/gianfar.c122
1 files changed, 120 insertions, 2 deletions
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,