aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBob Copeland <me@bobcopeland.com>2009-12-21 22:26:48 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-12-28 16:13:47 -0500
commit242ab7ad689accafd5e87ffd22b85cf1bf7fbbef (patch)
treec2d2ae7d19ea71a44020260f183150d64ac8d7f2 /drivers
parent2e10d330f8d5f039fa1e00baf59435ab0f11c722 (diff)
ath5k: fix SWI calibration interrupt storm
The calibration period is now invoked by triggering a software interrupt from within the ISR by ath5k_hw_calibration_poll() instead of via a timer. However, the calibration interval isn't initialized before interrupts are enabled, so we can have a situation where an interrupt occurs before the interval is assigned, so the interval is actually negative. As a result, the ISR will arm a software interrupt to schedule the tasklet, and then rearm it when the SWI is processed, and so on, leading to a softlockup at modprobe time. Move the initialization order around so the calibration interval is set before interrupts are active. Another possible fix is to schedule the tasklet directly from the poll routine, but I think there are additional plans for the SWI. Signed-off-by: Bob Copeland <me@bobcopeland.com> Cc: stable@kernel.org Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c7
1 files changed, 3 insertions, 4 deletions
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index a4c086f069b1..2a446a938249 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2381,6 +2381,9 @@ ath5k_init(struct ath5k_softc *sc)
2381 */ 2381 */
2382 ath5k_stop_locked(sc); 2382 ath5k_stop_locked(sc);
2383 2383
2384 /* Set PHY calibration interval */
2385 ah->ah_cal_intval = ath5k_calinterval;
2386
2384 /* 2387 /*
2385 * The basic interface to setting the hardware in a good 2388 * The basic interface to setting the hardware in a good
2386 * state is ``reset''. On return the hardware is known to 2389 * state is ``reset''. On return the hardware is known to
@@ -2408,10 +2411,6 @@ ath5k_init(struct ath5k_softc *sc)
2408 2411
2409 /* Set ack to be sent at low bit-rates */ 2412 /* Set ack to be sent at low bit-rates */
2410 ath5k_hw_set_ack_bitrate_high(ah, false); 2413 ath5k_hw_set_ack_bitrate_high(ah, false);
2411
2412 /* Set PHY calibration inteval */
2413 ah->ah_cal_intval = ath5k_calinterval;
2414
2415 ret = 0; 2414 ret = 0;
2416done: 2415done:
2417 mmiowb(); 2416 mmiowb();