diff options
| author | juhosg <juhosg@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2008-12-07 06:43:02 +0000 | 
|---|---|---|
| committer | juhosg <juhosg@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2008-12-07 06:43:02 +0000 | 
| commit | 032445afeec0a2729bd2859138a1d3ef7a0958f4 (patch) | |
| tree | 0a1d734fbaa1dd8103bea26114aa47c5ef7e51cd | |
| parent | 3460b30f36ac4455da0a40e90781d46f3c4f204f (diff) | |
[ar71xx] ag71xx driver: handle TX timout
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@13537 3c298f89-4303-0410-b956-a3cf2f4a3e73
| -rw-r--r-- | target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx.h | 5 | ||||
| -rw-r--r-- | target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c | 21 | 
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 7e3da8178..d5f7743d4 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 87f83d0cd..781896935 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)) | 
