aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c38
-rw-r--r--drivers/net/wireless/ath/ath5k/base.h3
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.c2
3 files changed, 24 insertions, 19 deletions
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 20328bdd138b..b290cc6c600f 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -388,7 +388,7 @@ static int ath5k_init(struct ath5k_softc *sc);
388static int ath5k_stop_locked(struct ath5k_softc *sc); 388static int ath5k_stop_locked(struct ath5k_softc *sc);
389static int ath5k_stop_hw(struct ath5k_softc *sc); 389static int ath5k_stop_hw(struct ath5k_softc *sc);
390static irqreturn_t ath5k_intr(int irq, void *dev_id); 390static irqreturn_t ath5k_intr(int irq, void *dev_id);
391static void ath5k_tasklet_reset(unsigned long data); 391static void ath5k_reset_work(struct work_struct *work);
392 392
393static void ath5k_tasklet_calibrate(unsigned long data); 393static void ath5k_tasklet_calibrate(unsigned long data);
394 394
@@ -831,11 +831,12 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
831 831
832 tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc); 832 tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc);
833 tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc); 833 tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc);
834 tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc);
835 tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc); 834 tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc);
836 tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc); 835 tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc);
837 tasklet_init(&sc->ani_tasklet, ath5k_tasklet_ani, (unsigned long)sc); 836 tasklet_init(&sc->ani_tasklet, ath5k_tasklet_ani, (unsigned long)sc);
838 837
838 INIT_WORK(&sc->reset_work, ath5k_reset_work);
839
839 ret = ath5k_eeprom_read_mac(ah, mac); 840 ret = ath5k_eeprom_read_mac(ah, mac);
840 if (ret) { 841 if (ret) {
841 ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n", 842 ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n",
@@ -2294,8 +2295,8 @@ err_unmap:
2294 * frame contents are done as needed and the slot time is 2295 * frame contents are done as needed and the slot time is
2295 * also adjusted based on current state. 2296 * also adjusted based on current state.
2296 * 2297 *
2297 * This is called from software irq context (beacontq or restq 2298 * This is called from software irq context (beacontq tasklets)
2298 * tasklets) or user context from ath5k_beacon_config. 2299 * or user context from ath5k_beacon_config.
2299 */ 2300 */
2300static void 2301static void
2301ath5k_beacon_send(struct ath5k_softc *sc) 2302ath5k_beacon_send(struct ath5k_softc *sc)
@@ -2328,7 +2329,7 @@ ath5k_beacon_send(struct ath5k_softc *sc)
2328 sc->bmisscount); 2329 sc->bmisscount);
2329 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, 2330 ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
2330 "stuck beacon, resetting\n"); 2331 "stuck beacon, resetting\n");
2331 tasklet_schedule(&sc->restq); 2332 ieee80211_queue_work(sc->hw, &sc->reset_work);
2332 } 2333 }
2333 return; 2334 return;
2334 } 2335 }
@@ -2684,7 +2685,6 @@ ath5k_stop_hw(struct ath5k_softc *sc)
2684 2685
2685 tasklet_kill(&sc->rxtq); 2686 tasklet_kill(&sc->rxtq);
2686 tasklet_kill(&sc->txtq); 2687 tasklet_kill(&sc->txtq);
2687 tasklet_kill(&sc->restq);
2688 tasklet_kill(&sc->calib); 2688 tasklet_kill(&sc->calib);
2689 tasklet_kill(&sc->beacontq); 2689 tasklet_kill(&sc->beacontq);
2690 tasklet_kill(&sc->ani_tasklet); 2690 tasklet_kill(&sc->ani_tasklet);
@@ -2737,7 +2737,7 @@ ath5k_intr(int irq, void *dev_id)
2737 */ 2737 */
2738 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, 2738 ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
2739 "fatal int, resetting\n"); 2739 "fatal int, resetting\n");
2740 tasklet_schedule(&sc->restq); 2740 ieee80211_queue_work(sc->hw, &sc->reset_work);
2741 } else if (unlikely(status & AR5K_INT_RXORN)) { 2741 } else if (unlikely(status & AR5K_INT_RXORN)) {
2742 /* 2742 /*
2743 * Receive buffers are full. Either the bus is busy or 2743 * Receive buffers are full. Either the bus is busy or
@@ -2752,7 +2752,7 @@ ath5k_intr(int irq, void *dev_id)
2752 if (ah->ah_mac_srev < AR5K_SREV_AR5212) { 2752 if (ah->ah_mac_srev < AR5K_SREV_AR5212) {
2753 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, 2753 ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
2754 "rx overrun, resetting\n"); 2754 "rx overrun, resetting\n");
2755 tasklet_schedule(&sc->restq); 2755 ieee80211_queue_work(sc->hw, &sc->reset_work);
2756 } 2756 }
2757 else 2757 else
2758 tasklet_schedule(&sc->rxtq); 2758 tasklet_schedule(&sc->rxtq);
@@ -2799,14 +2799,6 @@ ath5k_intr(int irq, void *dev_id)
2799 return IRQ_HANDLED; 2799 return IRQ_HANDLED;
2800} 2800}
2801 2801
2802static void
2803ath5k_tasklet_reset(unsigned long data)
2804{
2805 struct ath5k_softc *sc = (void *)data;
2806
2807 ath5k_reset(sc, sc->curchan);
2808}
2809
2810/* 2802/*
2811 * Periodically recalibrate the PHY to account 2803 * Periodically recalibrate the PHY to account
2812 * for temperature/environment changes. 2804 * for temperature/environment changes.
@@ -2830,7 +2822,7 @@ ath5k_tasklet_calibrate(unsigned long data)
2830 * to load new gain values. 2822 * to load new gain values.
2831 */ 2823 */
2832 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "calibration, resetting\n"); 2824 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "calibration, resetting\n");
2833 ath5k_reset(sc, sc->curchan); 2825 ieee80211_queue_work(sc->hw, &sc->reset_work);
2834 } 2826 }
2835 if (ath5k_hw_phy_calibrate(ah, sc->curchan)) 2827 if (ath5k_hw_phy_calibrate(ah, sc->curchan))
2836 ATH5K_ERR(sc, "calibration of channel %u failed\n", 2828 ATH5K_ERR(sc, "calibration of channel %u failed\n",
@@ -2934,6 +2926,8 @@ drop_packet:
2934/* 2926/*
2935 * Reset the hardware. If chan is not NULL, then also pause rx/tx 2927 * Reset the hardware. If chan is not NULL, then also pause rx/tx
2936 * and change to the given channel. 2928 * and change to the given channel.
2929 *
2930 * This should be called with sc->lock.
2937 */ 2931 */
2938static int 2932static int
2939ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan) 2933ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan)
@@ -2990,6 +2984,16 @@ err:
2990 return ret; 2984 return ret;
2991} 2985}
2992 2986
2987static void ath5k_reset_work(struct work_struct *work)
2988{
2989 struct ath5k_softc *sc = container_of(work, struct ath5k_softc,
2990 reset_work);
2991
2992 mutex_lock(&sc->lock);
2993 ath5k_reset(sc, sc->curchan);
2994 mutex_unlock(&sc->lock);
2995}
2996
2993static int ath5k_start(struct ieee80211_hw *hw) 2997static int ath5k_start(struct ieee80211_hw *hw)
2994{ 2998{
2995 return ath5k_init(hw->priv); 2999 return ath5k_init(hw->priv);
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index 56221bc7c8cd..86c90f471b74 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -47,6 +47,7 @@
47#include <linux/if_ether.h> 47#include <linux/if_ether.h>
48#include <linux/leds.h> 48#include <linux/leds.h>
49#include <linux/rfkill.h> 49#include <linux/rfkill.h>
50#include <linux/workqueue.h>
50 51
51#include "ath5k.h" 52#include "ath5k.h"
52#include "debug.h" 53#include "debug.h"
@@ -189,7 +190,7 @@ struct ath5k_softc {
189 unsigned int led_pin, /* GPIO pin for driving LED */ 190 unsigned int led_pin, /* GPIO pin for driving LED */
190 led_on; /* pin setting for LED on */ 191 led_on; /* pin setting for LED on */
191 192
192 struct tasklet_struct restq; /* reset tasklet */ 193 struct work_struct reset_work; /* deferred chip reset */
193 194
194 unsigned int rxbufsize; /* rx size based on mtu */ 195 unsigned int rxbufsize; /* rx size based on mtu */
195 struct list_head rxbuf; /* receive buffer */ 196 struct list_head rxbuf; /* receive buffer */
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
index 8c638865c712..ebb9c237a0d5 100644
--- a/drivers/net/wireless/ath/ath5k/debug.c
+++ b/drivers/net/wireless/ath/ath5k/debug.c
@@ -279,7 +279,7 @@ static ssize_t write_file_reset(struct file *file,
279{ 279{
280 struct ath5k_softc *sc = file->private_data; 280 struct ath5k_softc *sc = file->private_data;
281 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "debug file triggered reset\n"); 281 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "debug file triggered reset\n");
282 tasklet_schedule(&sc->restq); 282 ieee80211_queue_work(sc->hw, &sc->reset_work);
283 return count; 283 return count;
284} 284}
285 285