diff options
Diffstat (limited to 'drivers/net/gianfar.c')
-rw-r--r-- | drivers/net/gianfar.c | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index b8394cf134e8..4320a983a588 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c | |||
@@ -105,6 +105,7 @@ const char gfar_driver_version[] = "1.3"; | |||
105 | 105 | ||
106 | static int gfar_enet_open(struct net_device *dev); | 106 | static int gfar_enet_open(struct net_device *dev); |
107 | static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev); | 107 | static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev); |
108 | static void gfar_reset_task(struct work_struct *work); | ||
108 | static void gfar_timeout(struct net_device *dev); | 109 | static void gfar_timeout(struct net_device *dev); |
109 | static int gfar_close(struct net_device *dev); | 110 | static int gfar_close(struct net_device *dev); |
110 | struct sk_buff *gfar_new_skb(struct net_device *dev); | 111 | struct sk_buff *gfar_new_skb(struct net_device *dev); |
@@ -134,9 +135,7 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int l | |||
134 | static void gfar_vlan_rx_register(struct net_device *netdev, | 135 | static void gfar_vlan_rx_register(struct net_device *netdev, |
135 | struct vlan_group *grp); | 136 | struct vlan_group *grp); |
136 | void gfar_halt(struct net_device *dev); | 137 | void gfar_halt(struct net_device *dev); |
137 | #ifdef CONFIG_PM | ||
138 | static void gfar_halt_nodisable(struct net_device *dev); | 138 | static void gfar_halt_nodisable(struct net_device *dev); |
139 | #endif | ||
140 | void gfar_start(struct net_device *dev); | 139 | void gfar_start(struct net_device *dev); |
141 | static void gfar_clear_exact_match(struct net_device *dev); | 140 | static void gfar_clear_exact_match(struct net_device *dev); |
142 | static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr); | 141 | static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr); |
@@ -211,6 +210,7 @@ static int gfar_probe(struct platform_device *pdev) | |||
211 | spin_lock_init(&priv->txlock); | 210 | spin_lock_init(&priv->txlock); |
212 | spin_lock_init(&priv->rxlock); | 211 | spin_lock_init(&priv->rxlock); |
213 | spin_lock_init(&priv->bflock); | 212 | spin_lock_init(&priv->bflock); |
213 | INIT_WORK(&priv->reset_task, gfar_reset_task); | ||
214 | 214 | ||
215 | platform_set_drvdata(pdev, dev); | 215 | platform_set_drvdata(pdev, dev); |
216 | 216 | ||
@@ -414,9 +414,7 @@ static int gfar_suspend(struct platform_device *pdev, pm_message_t state) | |||
414 | spin_unlock(&priv->rxlock); | 414 | spin_unlock(&priv->rxlock); |
415 | spin_unlock_irqrestore(&priv->txlock, flags); | 415 | spin_unlock_irqrestore(&priv->txlock, flags); |
416 | 416 | ||
417 | #ifdef CONFIG_GFAR_NAPI | ||
418 | napi_disable(&priv->napi); | 417 | napi_disable(&priv->napi); |
419 | #endif | ||
420 | 418 | ||
421 | if (magic_packet) { | 419 | if (magic_packet) { |
422 | /* Enable interrupt on Magic Packet */ | 420 | /* Enable interrupt on Magic Packet */ |
@@ -469,9 +467,7 @@ static int gfar_resume(struct platform_device *pdev) | |||
469 | 467 | ||
470 | netif_device_attach(dev); | 468 | netif_device_attach(dev); |
471 | 469 | ||
472 | #ifdef CONFIG_GFAR_NAPI | ||
473 | napi_enable(&priv->napi); | 470 | napi_enable(&priv->napi); |
474 | #endif | ||
475 | 471 | ||
476 | return 0; | 472 | return 0; |
477 | } | 473 | } |
@@ -635,7 +631,6 @@ static void init_registers(struct net_device *dev) | |||
635 | } | 631 | } |
636 | 632 | ||
637 | 633 | ||
638 | #ifdef CONFIG_PM | ||
639 | /* Halt the receive and transmit queues */ | 634 | /* Halt the receive and transmit queues */ |
640 | static void gfar_halt_nodisable(struct net_device *dev) | 635 | static void gfar_halt_nodisable(struct net_device *dev) |
641 | { | 636 | { |
@@ -661,7 +656,6 @@ static void gfar_halt_nodisable(struct net_device *dev) | |||
661 | cpu_relax(); | 656 | cpu_relax(); |
662 | } | 657 | } |
663 | } | 658 | } |
664 | #endif | ||
665 | 659 | ||
666 | /* Halt the receive and transmit queues */ | 660 | /* Halt the receive and transmit queues */ |
667 | void gfar_halt(struct net_device *dev) | 661 | void gfar_halt(struct net_device *dev) |
@@ -670,6 +664,8 @@ void gfar_halt(struct net_device *dev) | |||
670 | struct gfar __iomem *regs = priv->regs; | 664 | struct gfar __iomem *regs = priv->regs; |
671 | u32 tempval; | 665 | u32 tempval; |
672 | 666 | ||
667 | gfar_halt_nodisable(dev); | ||
668 | |||
673 | /* Disable Rx and Tx */ | 669 | /* Disable Rx and Tx */ |
674 | tempval = gfar_read(®s->maccfg1); | 670 | tempval = gfar_read(®s->maccfg1); |
675 | tempval &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN); | 671 | tempval &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN); |
@@ -1218,6 +1214,7 @@ static int gfar_close(struct net_device *dev) | |||
1218 | 1214 | ||
1219 | napi_disable(&priv->napi); | 1215 | napi_disable(&priv->napi); |
1220 | 1216 | ||
1217 | cancel_work_sync(&priv->reset_task); | ||
1221 | stop_gfar(dev); | 1218 | stop_gfar(dev); |
1222 | 1219 | ||
1223 | /* Disconnect from the PHY */ | 1220 | /* Disconnect from the PHY */ |
@@ -1332,13 +1329,16 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu) | |||
1332 | return 0; | 1329 | return 0; |
1333 | } | 1330 | } |
1334 | 1331 | ||
1335 | /* gfar_timeout gets called when a packet has not been | 1332 | /* gfar_reset_task gets scheduled when a packet has not been |
1336 | * transmitted after a set amount of time. | 1333 | * transmitted after a set amount of time. |
1337 | * For now, assume that clearing out all the structures, and | 1334 | * For now, assume that clearing out all the structures, and |
1338 | * starting over will fix the problem. */ | 1335 | * starting over will fix the problem. |
1339 | static void gfar_timeout(struct net_device *dev) | 1336 | */ |
1337 | static void gfar_reset_task(struct work_struct *work) | ||
1340 | { | 1338 | { |
1341 | dev->stats.tx_errors++; | 1339 | struct gfar_private *priv = container_of(work, struct gfar_private, |
1340 | reset_task); | ||
1341 | struct net_device *dev = priv->dev; | ||
1342 | 1342 | ||
1343 | if (dev->flags & IFF_UP) { | 1343 | if (dev->flags & IFF_UP) { |
1344 | stop_gfar(dev); | 1344 | stop_gfar(dev); |
@@ -1348,6 +1348,14 @@ static void gfar_timeout(struct net_device *dev) | |||
1348 | netif_tx_schedule_all(dev); | 1348 | netif_tx_schedule_all(dev); |
1349 | } | 1349 | } |
1350 | 1350 | ||
1351 | static void gfar_timeout(struct net_device *dev) | ||
1352 | { | ||
1353 | struct gfar_private *priv = netdev_priv(dev); | ||
1354 | |||
1355 | dev->stats.tx_errors++; | ||
1356 | schedule_work(&priv->reset_task); | ||
1357 | } | ||
1358 | |||
1351 | /* Interrupt Handler for Transmit complete */ | 1359 | /* Interrupt Handler for Transmit complete */ |
1352 | static int gfar_clean_tx_ring(struct net_device *dev) | 1360 | static int gfar_clean_tx_ring(struct net_device *dev) |
1353 | { | 1361 | { |