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.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 999d69168277..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
106static int gfar_enet_open(struct net_device *dev); 106static int gfar_enet_open(struct net_device *dev);
107static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev); 107static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev);
108static void gfar_reset_task(struct work_struct *work);
108static void gfar_timeout(struct net_device *dev); 109static void gfar_timeout(struct net_device *dev);
109static int gfar_close(struct net_device *dev); 110static int gfar_close(struct net_device *dev);
110struct sk_buff *gfar_new_skb(struct net_device *dev); 111struct sk_buff *gfar_new_skb(struct net_device *dev);
@@ -209,6 +210,7 @@ static int gfar_probe(struct platform_device *pdev)
209 spin_lock_init(&priv->txlock); 210 spin_lock_init(&priv->txlock);
210 spin_lock_init(&priv->rxlock); 211 spin_lock_init(&priv->rxlock);
211 spin_lock_init(&priv->bflock); 212 spin_lock_init(&priv->bflock);
213 INIT_WORK(&priv->reset_task, gfar_reset_task);
212 214
213 platform_set_drvdata(pdev, dev); 215 platform_set_drvdata(pdev, dev);
214 216
@@ -1212,6 +1214,7 @@ static int gfar_close(struct net_device *dev)
1212 1214
1213 napi_disable(&priv->napi); 1215 napi_disable(&priv->napi);
1214 1216
1217 cancel_work_sync(&priv->reset_task);
1215 stop_gfar(dev); 1218 stop_gfar(dev);
1216 1219
1217 /* Disconnect from the PHY */ 1220 /* Disconnect from the PHY */
@@ -1326,13 +1329,16 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu)
1326 return 0; 1329 return 0;
1327} 1330}
1328 1331
1329/* gfar_timeout gets called when a packet has not been 1332/* gfar_reset_task gets scheduled when a packet has not been
1330 * transmitted after a set amount of time. 1333 * transmitted after a set amount of time.
1331 * For now, assume that clearing out all the structures, and 1334 * For now, assume that clearing out all the structures, and
1332 * starting over will fix the problem. */ 1335 * starting over will fix the problem.
1333static void gfar_timeout(struct net_device *dev) 1336 */
1337static void gfar_reset_task(struct work_struct *work)
1334{ 1338{
1335 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;
1336 1342
1337 if (dev->flags & IFF_UP) { 1343 if (dev->flags & IFF_UP) {
1338 stop_gfar(dev); 1344 stop_gfar(dev);
@@ -1342,6 +1348,14 @@ static void gfar_timeout(struct net_device *dev)
1342 netif_tx_schedule_all(dev); 1348 netif_tx_schedule_all(dev);
1343} 1349}
1344 1350
1351static 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
1345/* Interrupt Handler for Transmit complete */ 1359/* Interrupt Handler for Transmit complete */
1346static int gfar_clean_tx_ring(struct net_device *dev) 1360static int gfar_clean_tx_ring(struct net_device *dev)
1347{ 1361{