]>
Commit | Line | Data |
---|---|---|
80e6ae8f GKH |
1 | From 242ab7ad689accafd5e87ffd22b85cf1bf7fbbef Mon Sep 17 00:00:00 2001 |
2 | From: Bob Copeland <me@bobcopeland.com> | |
3 | Date: Mon, 21 Dec 2009 22:26:48 -0500 | |
4 | Subject: ath5k: fix SWI calibration interrupt storm | |
5 | ||
6 | From: Bob Copeland <me@bobcopeland.com> | |
7 | ||
8 | commit 242ab7ad689accafd5e87ffd22b85cf1bf7fbbef upstream. | |
9 | ||
10 | The calibration period is now invoked by triggering a software | |
11 | interrupt from within the ISR by ath5k_hw_calibration_poll() | |
12 | instead of via a timer. | |
13 | ||
14 | However, the calibration interval isn't initialized before | |
15 | interrupts are enabled, so we can have a situation where an | |
16 | interrupt occurs before the interval is assigned, so the | |
17 | interval is actually negative. As a result, the ISR will | |
18 | arm a software interrupt to schedule the tasklet, and then | |
19 | rearm it when the SWI is processed, and so on, leading to a | |
20 | softlockup at modprobe time. | |
21 | ||
22 | Move the initialization order around so the calibration interval | |
23 | is set before interrupts are active. Another possible fix | |
24 | is to schedule the tasklet directly from the poll routine, | |
25 | but I think there are additional plans for the SWI. | |
26 | ||
27 | Signed-off-by: Bob Copeland <me@bobcopeland.com> | |
28 | Signed-off-by: John W. Linville <linville@tuxdriver.com> | |
29 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
30 | ||
31 | --- | |
32 | drivers/net/wireless/ath/ath5k/base.c | 7 +++---- | |
33 | 1 file changed, 3 insertions(+), 4 deletions(-) | |
34 | ||
35 | --- a/drivers/net/wireless/ath/ath5k/base.c | |
36 | +++ b/drivers/net/wireless/ath/ath5k/base.c | |
37 | @@ -2349,6 +2349,9 @@ ath5k_init(struct ath5k_softc *sc) | |
38 | */ | |
39 | ath5k_stop_locked(sc); | |
40 | ||
41 | + /* Set PHY calibration interval */ | |
42 | + ah->ah_cal_intval = ath5k_calinterval; | |
43 | + | |
44 | /* | |
45 | * The basic interface to setting the hardware in a good | |
46 | * state is ``reset''. On return the hardware is known to | |
47 | @@ -2376,10 +2379,6 @@ ath5k_init(struct ath5k_softc *sc) | |
48 | ||
49 | /* Set ack to be sent at low bit-rates */ | |
50 | ath5k_hw_set_ack_bitrate_high(ah, false); | |
51 | - | |
52 | - /* Set PHY calibration inteval */ | |
53 | - ah->ah_cal_intval = ath5k_calinterval; | |
54 | - | |
55 | ret = 0; | |
56 | done: | |
57 | mmiowb(); |