]>
Commit | Line | Data |
---|---|---|
c06f7f46 GKH |
1 | From f119da3015712dc32bdf1c311652479e02dcb49a Mon Sep 17 00:00:00 2001 |
2 | From: Vasanthakumar Thiagarajan <vasanth@atheros.com> | |
3 | Date: Thu, 4 Nov 2010 17:41:25 -0700 | |
4 | Subject: ath9k_hw: Fix AR9280 surprise removal during frequent idle on/off | |
5 | ||
6 | From: Vasanthakumar Thiagarajan <vasanth@atheros.com> | |
7 | ||
8 | commit f119da3015712dc32bdf1c311652479e02dcb49a upstream. | |
9 | ||
10 | Bit 22 of AR_WA should be set to fix the situation where chip reset | |
11 | is asynchronous to clock of analog shift registers, such that when | |
12 | reset is released, it could mess up the values of analog shift registers | |
13 | and cause some hw issue on AR9280. | |
14 | ||
15 | This bit is write only, but the driver does a read-modify-write | |
16 | on AR_WA without setting bit 22 in ar9002_hw_configpcipowersave() | |
17 | during radio disable. This causes surprise removal of hw. It can | |
18 | never recover from this state and the hw will become usable only | |
19 | after a power on/off cycle, and sometimes only during a cold reboot. | |
20 | ||
21 | This issue can be triggered by doing frequent roaming with the | |
22 | simple/test-roam script available from the wifi-test project [1] | |
23 | when roaming between APs quickly. When roaming there is a is a high | |
24 | possibility that the device being put into idle (radio disable) state | |
25 | by mac80211 during AUTH->ASSOC. A device hardware reset would fail | |
26 | and the kernel would output: | |
27 | ||
28 | [40251.363799] ath: AWAKE -> FULL-SLEEP | |
29 | [40251.363815] ieee80211 phy17: device no longer idle - working | |
30 | [40251.363817] ath: Marking phy17 as not-idle | |
31 | [40251.363819] ath: FULL-SLEEP -> AWAKE | |
32 | [40251.415978] pciehp 0000:00:1c.3:pcie04: Card not present on Slot(3) | |
33 | [40251.419896] ath: ah->misc_mode 0x4 | |
34 | [40251.428138] pciehp 0000:00:1c.3:pcie04: Card present on Slot(3) | |
35 | [40251.532247] ath: timeout (100000 us) on reg 0x9860: 0xffffffff & 0x00000001 != 0x00000000 | |
36 | [40251.532250] ath: Unable to reset channel (2462 MHz), reset status -5 | |
37 | [40251.532422] ath: Set channel: 5745 MHz | |
38 | [40251.540639] ath: Failed to stop TX DMA in 100 msec after killing last frame | |
39 | [40251.548826] ath: Failed to stop TX DMA in 100 msec after killing last frame | |
40 | [40251.557023] ath: Failed to stop TX DMA in 100 msec after killing last frame | |
41 | [40251.565211] ath: Failed to stop TX DMA in 100 msec after killing last frame | |
42 | [40251.573415] ath: Failed to stop TX DMA in 100 msec after killing last frame | |
43 | [40251.581603] ath: Failed to stop TX DMA in 100 msec after killing last frame | |
44 | [40251.581606] ath: Failed to stop TX DMA. Resetting hardware! | |
45 | [40251.592679] ath: DMA failed to stop in 10 ms AR_CR=0xffffffff AR_DIAG_SW=0xffffffff | |
46 | [40251.703330] ath: timeout (100000 us) on reg 0x7000: 0xffffffff & 0x00000003 != 0x00000000 | |
47 | [40251.703333] ath: RTC stuck in MAC reset | |
48 | [40251.703334] ath: Chip reset failed | |
49 | [40251.703335] ath: Unable to reset hardware; reset status -22 | |
50 | ||
51 | This is currently only reproducible with some HB92 (Half Mini-PCIE) | |
52 | cards but the fix applies to all AR9280 cards. This patch fixes this | |
53 | issue by setting bit 22 during radio disable. | |
54 | ||
55 | This patch has fixes for all kernels that has ath9k. | |
56 | ||
57 | [1] http://wireless.kernel.org/en/developers/Testing/wifi-test | |
58 | ||
59 | Cc: kyungwan.nam@atheros.com | |
60 | Cc: amod.bodas@atheros.com | |
61 | Cc: david.quan@atheros.com | |
62 | Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com> | |
63 | Signed-off-by: John W. Linville <linville@tuxdriver.com> | |
64 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
65 | ||
66 | --- | |
67 | drivers/net/wireless/ath/ath9k/ar9002_hw.c | 3 +++ | |
68 | drivers/net/wireless/ath/ath9k/reg.h | 1 + | |
69 | 2 files changed, 4 insertions(+) | |
70 | ||
71 | --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c | |
72 | +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c | |
73 | @@ -411,6 +411,9 @@ static void ar9002_hw_configpcipowersave | |
74 | val &= ~(AR_WA_BIT6 | AR_WA_BIT7); | |
75 | } | |
76 | ||
77 | + if (AR_SREV_9280(ah)) | |
78 | + val |= AR_WA_BIT22; | |
79 | + | |
80 | if (AR_SREV_9285E_20(ah)) | |
81 | val |= AR_WA_BIT23; | |
82 | ||
83 | --- a/drivers/net/wireless/ath/ath9k/reg.h | |
84 | +++ b/drivers/net/wireless/ath/ath9k/reg.h | |
85 | @@ -709,6 +709,7 @@ | |
86 | #define AR_WA_RESET_EN (1 << 18) /* Sw Control to enable PCI-Reset to POR (bit 15) */ | |
87 | #define AR_WA_ANALOG_SHIFT (1 << 20) | |
88 | #define AR_WA_POR_SHORT (1 << 21) /* PCI-E Phy reset control */ | |
89 | +#define AR_WA_BIT22 (1 << 22) | |
90 | #define AR9285_WA_DEFAULT 0x004a050b | |
91 | #define AR9280_WA_DEFAULT 0x0040073b | |
92 | #define AR_WA_DEFAULT 0x0000073f |