diff options
author | Sven Eckelmann <sven@narfation.org> | 2012-09-27 10:41:02 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-09-28 13:54:10 -0400 |
commit | ff9bd2d8d95aedb661714536cb919281540f9772 (patch) | |
tree | 69ebff87dee8e48fd1fb707a07f799e5536f6291 /drivers/net/wireless/ath | |
parent | 6c8c4f7299b89ef369fd332e5f76c2fd23a62abe (diff) |
ath9k_hw: Handle AR_INTR_SYNC_HOST1_(FATAL|PERR) on AR9003
Interrupts with the sync_cause AR_INTR_SYNC_HOST1_FATAL and
AR_INTR_SYNC_HOST1_PERR have to be handled using a chip reset. Otherwise a
interrupt storm with unhandled interrupts will cause a hang or crash of the
machine.
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_mac.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index d5b2e0ecc21c..301bf72c53bf 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c | |||
@@ -182,6 +182,7 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) | |||
182 | struct ath9k_hw_capabilities *pCap = &ah->caps; | 182 | struct ath9k_hw_capabilities *pCap = &ah->caps; |
183 | struct ath_common *common = ath9k_hw_common(ah); | 183 | struct ath_common *common = ath9k_hw_common(ah); |
184 | u32 sync_cause = 0, async_cause, async_mask = AR_INTR_MAC_IRQ; | 184 | u32 sync_cause = 0, async_cause, async_mask = AR_INTR_MAC_IRQ; |
185 | bool fatal_int; | ||
185 | 186 | ||
186 | if (ath9k_hw_mci_is_enabled(ah)) | 187 | if (ath9k_hw_mci_is_enabled(ah)) |
187 | async_mask |= AR_INTR_ASYNC_MASK_MCI; | 188 | async_mask |= AR_INTR_ASYNC_MASK_MCI; |
@@ -310,6 +311,22 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) | |||
310 | 311 | ||
311 | if (sync_cause) { | 312 | if (sync_cause) { |
312 | ath9k_debug_sync_cause(common, sync_cause); | 313 | ath9k_debug_sync_cause(common, sync_cause); |
314 | fatal_int = | ||
315 | (sync_cause & | ||
316 | (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR)) | ||
317 | ? true : false; | ||
318 | |||
319 | if (fatal_int) { | ||
320 | if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) { | ||
321 | ath_dbg(common, ANY, | ||
322 | "received PCI FATAL interrupt\n"); | ||
323 | } | ||
324 | if (sync_cause & AR_INTR_SYNC_HOST1_PERR) { | ||
325 | ath_dbg(common, ANY, | ||
326 | "received PCI PERR interrupt\n"); | ||
327 | } | ||
328 | *masked |= ATH9K_INT_FATAL; | ||
329 | } | ||
313 | 330 | ||
314 | if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) { | 331 | if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) { |
315 | REG_WRITE(ah, AR_RC, AR_RC_HOSTIF); | 332 | REG_WRITE(ah, AR_RC, AR_RC_HOSTIF); |