diff options
Diffstat (limited to 'drivers/net/gianfar.c')
| -rw-r--r-- | drivers/net/gianfar.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index ca6cf6ecb37b..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 | ||
| @@ -631,7 +631,6 @@ static void init_registers(struct net_device *dev) | |||
| 631 | } | 631 | } |
| 632 | 632 | ||
| 633 | 633 | ||
| 634 | #ifdef CONFIG_PM | ||
| 635 | /* Halt the receive and transmit queues */ | 634 | /* Halt the receive and transmit queues */ |
| 636 | static void gfar_halt_nodisable(struct net_device *dev) | 635 | static void gfar_halt_nodisable(struct net_device *dev) |
| 637 | { | 636 | { |
| @@ -657,7 +656,6 @@ static void gfar_halt_nodisable(struct net_device *dev) | |||
| 657 | cpu_relax(); | 656 | cpu_relax(); |
| 658 | } | 657 | } |
| 659 | } | 658 | } |
| 660 | #endif | ||
| 661 | 659 | ||
| 662 | /* Halt the receive and transmit queues */ | 660 | /* Halt the receive and transmit queues */ |
| 663 | void gfar_halt(struct net_device *dev) | 661 | void gfar_halt(struct net_device *dev) |
| @@ -666,6 +664,8 @@ void gfar_halt(struct net_device *dev) | |||
| 666 | struct gfar __iomem *regs = priv->regs; | 664 | struct gfar __iomem *regs = priv->regs; |
| 667 | u32 tempval; | 665 | u32 tempval; |
| 668 | 666 | ||
| 667 | gfar_halt_nodisable(dev); | ||
| 668 | |||
| 669 | /* Disable Rx and Tx */ | 669 | /* Disable Rx and Tx */ |
| 670 | tempval = gfar_read(®s->maccfg1); | 670 | tempval = gfar_read(®s->maccfg1); |
| 671 | tempval &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN); | 671 | tempval &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN); |
| @@ -1214,6 +1214,7 @@ static int gfar_close(struct net_device *dev) | |||
| 1214 | 1214 | ||
| 1215 | napi_disable(&priv->napi); | 1215 | napi_disable(&priv->napi); |
| 1216 | 1216 | ||
| 1217 | cancel_work_sync(&priv->reset_task); | ||
| 1217 | stop_gfar(dev); | 1218 | stop_gfar(dev); |
| 1218 | 1219 | ||
| 1219 | /* Disconnect from the PHY */ | 1220 | /* Disconnect from the PHY */ |
| @@ -1328,13 +1329,16 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu) | |||
| 1328 | return 0; | 1329 | return 0; |
| 1329 | } | 1330 | } |
| 1330 | 1331 | ||
| 1331 | /* gfar_timeout gets called when a packet has not been | 1332 | /* gfar_reset_task gets scheduled when a packet has not been |
| 1332 | * transmitted after a set amount of time. | 1333 | * transmitted after a set amount of time. |
| 1333 | * For now, assume that clearing out all the structures, and | 1334 | * For now, assume that clearing out all the structures, and |
| 1334 | * starting over will fix the problem. */ | 1335 | * starting over will fix the problem. |
| 1335 | static void gfar_timeout(struct net_device *dev) | 1336 | */ |
| 1337 | static void gfar_reset_task(struct work_struct *work) | ||
| 1336 | { | 1338 | { |
| 1337 | 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; | ||
| 1338 | 1342 | ||
| 1339 | if (dev->flags & IFF_UP) { | 1343 | if (dev->flags & IFF_UP) { |
| 1340 | stop_gfar(dev); | 1344 | stop_gfar(dev); |
| @@ -1344,6 +1348,14 @@ static void gfar_timeout(struct net_device *dev) | |||
| 1344 | netif_tx_schedule_all(dev); | 1348 | netif_tx_schedule_all(dev); |
| 1345 | } | 1349 | } |
| 1346 | 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 | |||
| 1347 | /* Interrupt Handler for Transmit complete */ | 1359 | /* Interrupt Handler for Transmit complete */ |
| 1348 | static int gfar_clean_tx_ring(struct net_device *dev) | 1360 | static int gfar_clean_tx_ring(struct net_device *dev) |
| 1349 | { | 1361 | { |
