From a266161bebbd553afe1f3cda8207229a378c8b4a Mon Sep 17 00:00:00 2001 From: Margit Schubert-While Date: Wed, 2 Jun 2004 07:54:42 -0400 Subject: [PATCH] [PATCH] prism54: Reset card on tx timeout * islpci_eth.[c,h] islpci_dev.[c,h] : reset card on tx_timeout. Patch submited by Denis Vlasenko --- drivers/net/wireless/prism54/islpci_dev.c | 4 ++- drivers/net/wireless/prism54/islpci_dev.h | 3 +++ drivers/net/wireless/prism54/islpci_eth.c | 31 +++++++++++------------ drivers/net/wireless/prism54/islpci_eth.h | 1 + 4 files changed, 22 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c index 850b72bf45c7e..acc5fbd87b3ee 100644 --- a/drivers/net/wireless/prism54/islpci_dev.c +++ b/drivers/net/wireless/prism54/islpci_dev.c @@ -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 --git a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h index a163a48428655..f7fa3f8f37441 100644 --- a/drivers/net/wireless/prism54/islpci_dev.h +++ b/drivers/net/wireless/prism54/islpci_dev.h @@ -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 --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c index afaff46ff9ece..0e13239f5b08c 100644 --- a/drivers/net/wireless/prism54/islpci_eth.c +++ b/drivers/net/wireless/prism54/islpci_eth.c @@ -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; @@ -413,6 +405,15 @@ islpci_eth_receive(islpci_private *priv) return 0; } +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) { @@ -422,13 +423,11 @@ islpci_eth_tx_timeout(struct net_device *ndev) /* 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 --git a/drivers/net/wireless/prism54/islpci_eth.h b/drivers/net/wireless/prism54/islpci_eth.h index b349c7aad3e8a..c99bb2bb623a5 100644 --- a/drivers/net/wireless/prism54/islpci_eth.h +++ b/drivers/net/wireless/prism54/islpci_eth.h @@ -27,5 +27,6 @@ void islpci_eth_cleanup_transmit(islpci_private *, isl38xx_control_block *); 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 */ -- 2.53.0