From 1f5b3aa4e04765ca22584e1d53cca4c32b2297f7 Mon Sep 17 00:00:00 2001 From: Sebastian Siewior Date: Tue, 19 Aug 2008 21:12:45 +0200 Subject: [PATCH] --- yaml --- r: 109270 b: refs/heads/master c: ab9399059bb85a94758f42fb25607e440e926cc6 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/net/gianfar.c | 22 ++++++++++++++++++---- trunk/drivers/net/gianfar.h | 1 + 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/[refs] b/[refs] index e2b220d47148..96f96441c074 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: edcfe5f7e307846e578fb88d69fa27051fded0ab +refs/heads/master: ab9399059bb85a94758f42fb25607e440e926cc6 diff --git a/trunk/drivers/net/gianfar.c b/trunk/drivers/net/gianfar.c index 999d69168277..4320a983a588 100644 --- a/trunk/drivers/net/gianfar.c +++ b/trunk/drivers/net/gianfar.c @@ -105,6 +105,7 @@ const char gfar_driver_version[] = "1.3"; static int gfar_enet_open(struct net_device *dev); static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev); +static void gfar_reset_task(struct work_struct *work); static void gfar_timeout(struct net_device *dev); static int gfar_close(struct net_device *dev); struct sk_buff *gfar_new_skb(struct net_device *dev); @@ -209,6 +210,7 @@ static int gfar_probe(struct platform_device *pdev) spin_lock_init(&priv->txlock); spin_lock_init(&priv->rxlock); spin_lock_init(&priv->bflock); + INIT_WORK(&priv->reset_task, gfar_reset_task); platform_set_drvdata(pdev, dev); @@ -1212,6 +1214,7 @@ static int gfar_close(struct net_device *dev) napi_disable(&priv->napi); + cancel_work_sync(&priv->reset_task); stop_gfar(dev); /* Disconnect from the PHY */ @@ -1326,13 +1329,16 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu) return 0; } -/* gfar_timeout gets called when a packet has not been +/* gfar_reset_task gets scheduled when a packet has not been * transmitted after a set amount of time. * For now, assume that clearing out all the structures, and - * starting over will fix the problem. */ -static void gfar_timeout(struct net_device *dev) + * starting over will fix the problem. + */ +static void gfar_reset_task(struct work_struct *work) { - dev->stats.tx_errors++; + struct gfar_private *priv = container_of(work, struct gfar_private, + reset_task); + struct net_device *dev = priv->dev; if (dev->flags & IFF_UP) { stop_gfar(dev); @@ -1342,6 +1348,14 @@ static void gfar_timeout(struct net_device *dev) netif_tx_schedule_all(dev); } +static void gfar_timeout(struct net_device *dev) +{ + struct gfar_private *priv = netdev_priv(dev); + + dev->stats.tx_errors++; + schedule_work(&priv->reset_task); +} + /* Interrupt Handler for Transmit complete */ static int gfar_clean_tx_ring(struct net_device *dev) { diff --git a/trunk/drivers/net/gianfar.h b/trunk/drivers/net/gianfar.h index d59df98bd636..f46e9b63af13 100644 --- a/trunk/drivers/net/gianfar.h +++ b/trunk/drivers/net/gianfar.h @@ -756,6 +756,7 @@ struct gfar_private { uint32_t msg_enable; + struct work_struct reset_task; /* Network Statistics */ struct gfar_extra_stats extra_stats; };