
From: "Luis R. Rodriguez" <mcgrof@studorgs.rutgers.edu>

2004-03-18	Aurelien Alleaume <slts@free.fr>

- islpci_eth.[c,h] islpci_dev.[c,h] : reset card on tx_timeout.  Patch
  submited by Denis Vlasenko <vda@port.imtp.ilyichevsk.odessa.ua>

Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/drivers/net/wireless/prism54/islpci_dev.c |    6 ++--
 25-akpm/drivers/net/wireless/prism54/islpci_dev.h |    5 ++-
 25-akpm/drivers/net/wireless/prism54/islpci_eth.c |   33 ++++++++++------------
 25-akpm/drivers/net/wireless/prism54/islpci_eth.h |    3 +-
 4 files changed, 26 insertions(+), 21 deletions(-)

diff -puN drivers/net/wireless/prism54/islpci_dev.c~prism54-reset-card-on-tx_timeout drivers/net/wireless/prism54/islpci_dev.c
--- 25/drivers/net/wireless/prism54/islpci_dev.c~prism54-reset-card-on-tx_timeout	Wed May 26 16:16:55 2004
+++ 25-akpm/drivers/net/wireless/prism54/islpci_dev.c	Wed May 26 16:16:55 2004
@@ -1,4 +1,4 @@
-/*  $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_dev.c,v 1.68 2004/02/28 03:06:07 mcgrof Exp $
+/*  $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_dev.c,v 1.71 2004/03/18 11:44:17 ajfa Exp $
  *  
  *  Copyright (C) 2002 Intersil Americas Inc.
  *  Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
@@ -743,9 +743,11 @@ islpci_setup(struct pci_dev *pdev)
 	/* initialize workqueue's */
 	INIT_WORK(&priv->stats_work,
 		  (void (*)(void *)) prism54_update_stats, priv);
-
 	priv->stats_timestamp = 0;
 
+	INIT_WORK(&priv->reset_task, islpci_do_reset_and_wake, priv);
+	priv->reset_task_pending = 0;
+
 	/* allocate various memory areas */
 	if (islpci_alloc_memory(priv))
 		goto do_free_netdev;
diff -puN drivers/net/wireless/prism54/islpci_dev.h~prism54-reset-card-on-tx_timeout drivers/net/wireless/prism54/islpci_dev.h
--- 25/drivers/net/wireless/prism54/islpci_dev.h~prism54-reset-card-on-tx_timeout	Wed May 26 16:16:55 2004
+++ 25-akpm/drivers/net/wireless/prism54/islpci_dev.h	Wed May 26 16:16:55 2004
@@ -1,4 +1,4 @@
-/*  $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_dev.h,v 1.55 2004/03/18 11:16:23 ajfa Exp $
+/*  $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_dev.h,v 1.56 2004/03/18 11:44:17 ajfa Exp $
  *  
  *  Copyright (C) 2002 Intersil Americas Inc. 
  *  Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
@@ -188,6 +188,9 @@ typedef struct {
 	struct list_head bss_wpa_list;
 	int num_bss_wpa;
 	struct semaphore wpa_sem;
+
+	struct work_struct reset_task;
+	int reset_task_pending;
 } islpci_private;
 
 static inline islpci_state_t
diff -puN drivers/net/wireless/prism54/islpci_eth.c~prism54-reset-card-on-tx_timeout drivers/net/wireless/prism54/islpci_eth.c
--- 25/drivers/net/wireless/prism54/islpci_eth.c~prism54-reset-card-on-tx_timeout	Wed May 26 16:16:55 2004
+++ 25-akpm/drivers/net/wireless/prism54/islpci_eth.c	Wed May 26 16:16:55 2004
@@ -1,4 +1,4 @@
-/*  $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_eth.c,v 1.27 2004/01/30 16:24:00 ajfa Exp $
+/*  $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_eth.c,v 1.30 2004/03/18 11:44:17 ajfa Exp $
  *  
  *  Copyright (C) 2002 Intersil Americas Inc.
  *
@@ -319,17 +319,9 @@ islpci_eth_receive(islpci_private *priv)
 		/* The card reports full 802.11 packets but with a 20 bytes
 		 * header and without the FCS. But there a is a bit that
 		 * indicates if the packet is corrupted :-) */
-		/* int i; */
-		if (skb->data[8] & 0x01){
+		if (skb->data[8] & 0x01)
 			/* This one is bad. Drop it !*/
 			discard = 1;
-			/* printk("BAD\n");*/
-		}
-		/*
-		for(i=0;i<50;i++)
-			printk("%2.2X:",skb->data[i]);
-		printk("\n");
-		*/		
 		skb_pull(skb, 20);
 		skb->protocol = htons(ETH_P_802_2);
 		skb->mac.raw = skb->data;
@@ -414,6 +406,15 @@ islpci_eth_receive(islpci_private *priv)
 }
 
 void
+islpci_do_reset_and_wake(void *data)
+{
+       islpci_private *priv = (islpci_private *) data;
+       islpci_reset(priv, 1);
+       netif_wake_queue(priv->ndev);
+       priv->reset_task_pending = 0;
+}
+
+void
 islpci_eth_tx_timeout(struct net_device *ndev)
 {
 	islpci_private *priv = netdev_priv(ndev);
@@ -422,13 +423,11 @@ islpci_eth_tx_timeout(struct net_device 
 	/* increment the transmit error counter */
 	statistics->tx_errors++;
 
-#if 0
-	/* don't do this here! we are not allowed to sleep since we are in interrupt context */
-	if (islpci_reset(priv))
-		printk(KERN_ERR "%s: error on TX timeout card reset!\n",
-		       ndev->name);
-#endif
+	if(!priv->reset_task_pending) {
+		priv->reset_task_pending = 1;
+		netif_stop_queue(ndev);
+		schedule_work(&priv->reset_task);
+	}
 
-	/* netif_wake_queue(ndev); */
 	return;
 }
diff -puN drivers/net/wireless/prism54/islpci_eth.h~prism54-reset-card-on-tx_timeout drivers/net/wireless/prism54/islpci_eth.h
--- 25/drivers/net/wireless/prism54/islpci_eth.h~prism54-reset-card-on-tx_timeout	Wed May 26 16:16:55 2004
+++ 25-akpm/drivers/net/wireless/prism54/islpci_eth.h	Wed May 26 16:16:55 2004
@@ -1,4 +1,4 @@
-/*  $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_eth.h,v 1.5 2004/01/12 22:16:32 jmaurer Exp $
+/*  $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_eth.h,v 1.6 2004/03/18 11:44:17 ajfa Exp $
  *  
  *  Copyright (C) 2002 Intersil Americas Inc.
  *
@@ -27,5 +27,6 @@ void islpci_eth_cleanup_transmit(islpci_
 int islpci_eth_transmit(struct sk_buff *, struct net_device *);
 int islpci_eth_receive(islpci_private *);
 void islpci_eth_tx_timeout(struct net_device *);
+void islpci_do_reset_and_wake(void *data);
 
 #endif				/* _ISL_GEN_H */
_
