diff options
author | Sven Eckelmann <sven@narfation.org> | 2012-09-27 18:41:02 +0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-09-28 21:54:10 +0400 |
commit | ff9bd2d8d95aedb661714536cb919281540f9772 (patch) | |
tree | 69ebff87dee8e48fd1fb707a07f799e5536f6291 /drivers/net/wireless/ath | |
parent | 6c8c4f7299b89ef369fd332e5f76c2fd23a62abe (diff) | |
download | linux-ff9bd2d8d95aedb661714536cb919281540f9772.tar.xz |
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) struct ath9k_hw_capabilities *pCap = &ah->caps; struct ath_common *common = ath9k_hw_common(ah); u32 sync_cause = 0, async_cause, async_mask = AR_INTR_MAC_IRQ; + bool fatal_int; if (ath9k_hw_mci_is_enabled(ah)) 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) if (sync_cause) { ath9k_debug_sync_cause(common, sync_cause); + fatal_int = + (sync_cause & + (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR)) + ? true : false; + + if (fatal_int) { + if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) { + ath_dbg(common, ANY, + "received PCI FATAL interrupt\n"); + } + if (sync_cause & AR_INTR_SYNC_HOST1_PERR) { + ath_dbg(common, ANY, + "received PCI PERR interrupt\n"); + } + *masked |= ATH9K_INT_FATAL; + } if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) { REG_WRITE(ah, AR_RC, AR_RC_HOSTIF); |