From 398ff859daa5943995a4f8d0cd95920069a42455 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Sun, 7 Dec 2008 06:43:02 +0000 Subject: [PATCH] ag71xx driver: handle TX timout SVN-Revision: 13537 --- .../ar71xx/files/drivers/net/ag71xx/ag71xx.h | 5 ++++- .../files/drivers/net/ag71xx/ag71xx_main.c | 21 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) 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 #include #include +#include #include @@ -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))