aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGabor Juhos <juhosg@openwrt.org>2008-12-07 06:43:02 +0000
committerGabor Juhos <juhosg@openwrt.org>2008-12-07 06:43:02 +0000
commit398ff859daa5943995a4f8d0cd95920069a42455 (patch)
tree4040222e5160d575fc14b46a3766cc8c839f31df
parentcd02dc5ead3eb959f6ee508df81944eedcda79b8 (diff)
downloadupstream-398ff859daa5943995a4f8d0cd95920069a42455.tar.gz
upstream-398ff859daa5943995a4f8d0cd95920069a42455.tar.bz2
upstream-398ff859daa5943995a4f8d0cd95920069a42455.zip
ag71xx driver: handle TX timout
SVN-Revision: 13537
-rw-r--r--target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx.h5
-rw-r--r--target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c21
2 files changed, 25 insertions, 1 deletions
diff --git a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx.h b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx.h
index 7e3da8178e..d5f7743d4c 100644
--- a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx.h
+++ b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx.h
@@ -28,6 +28,7 @@
#include <linux/phy.h>
#include <linux/skbuff.h>
#include <linux/dma-mapping.h>
+#include <linux/workqueue.h>
#include <linux/bitops.h>
@@ -37,7 +38,7 @@
#define ETH_FCS_LEN 4
#define AG71XX_DRV_NAME "ag71xx"
-#define AG71XX_DRV_VERSION "0.5.10"
+#define AG71XX_DRV_VERSION "0.5.11"
#define AG71XX_NAPI_WEIGHT 64
@@ -124,6 +125,8 @@ struct ag71xx {
unsigned int link;
unsigned int speed;
int duplex;
+
+ struct work_struct restart_work;
};
extern struct ethtool_ops ag71xx_ethtool_ops;
diff --git a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c
index 87f83d0cd1..7818969355 100644
--- a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c
+++ b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c
@@ -551,6 +551,24 @@ static int ag71xx_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return -EOPNOTSUPP;
}
+static void ag71xx_tx_timeout(struct net_device *dev)
+{
+ struct ag71xx *ag = netdev_priv(dev);
+
+ if (netif_msg_tx_err(ag))
+ printk(KERN_DEBUG "%s: tx timeout\n", ag->dev->name);
+
+ schedule_work(&ag->restart_work);
+}
+
+static void ag71xx_restart_work_func(struct work_struct *work)
+{
+ struct ag71xx *ag = container_of(work, struct ag71xx, restart_work);
+
+ ag71xx_stop(ag->dev);
+ ag71xx_open(ag->dev);
+}
+
static void ag71xx_tx_packets(struct ag71xx *ag)
{
struct ag71xx_ring *ring = &ag->tx_ring;
@@ -824,6 +842,9 @@ static int __init ag71xx_probe(struct platform_device *pdev)
dev->do_ioctl = ag71xx_do_ioctl;
dev->ethtool_ops = &ag71xx_ethtool_ops;
+ dev->tx_timeout = ag71xx_tx_timeout;
+ INIT_WORK(&ag->restart_work, ag71xx_restart_work_func);
+
netif_napi_add(dev, &ag->napi, ag71xx_poll, AG71XX_NAPI_WEIGHT);
if (is_valid_ether_addr(pdata->mac_addr))