Skip to content

Commit

Permalink
ath9k: never read from the AR_IMR_S2 register
Browse files Browse the repository at this point in the history
The AR_IMR_S2 register sometimes cannot be read correctly.  Instead of a
valid value, 0xdeadbeef is returned.  The driver has been observed
writing that value back to AR_IMR_S2 after changing a few bits.

Cache the register value in ah->imrs2_reg and always write chached value
to the register.

Signed-off-by: Pavel Roskin <proski@gnu.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Pavel Roskin authored and John W. Linville committed Mar 9, 2010
1 parent b4d59a9 commit 74bad5c
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 11 deletions.
16 changes: 7 additions & 9 deletions drivers/net/wireless/ath/ath9k/hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -1151,7 +1151,8 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
ah->mask_reg |= AR_IMR_MIB;

REG_WRITE(ah, AR_IMR, ah->mask_reg);
REG_WRITE(ah, AR_IMR_S2, REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT);
ah->imrs2_reg |= AR_IMR_S2_GTT;
REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);

if (!AR_SREV_9100(ah)) {
REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF);
Expand Down Expand Up @@ -2920,14 +2921,11 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)

ath_print(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask);
REG_WRITE(ah, AR_IMR, mask);
mask = REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM |
AR_IMR_S2_DTIM |
AR_IMR_S2_DTIMSYNC |
AR_IMR_S2_CABEND |
AR_IMR_S2_CABTO |
AR_IMR_S2_TSFOOR |
AR_IMR_S2_GTT | AR_IMR_S2_CST);
REG_WRITE(ah, AR_IMR_S2, mask | mask2);
ah->imrs2_reg &= ~(AR_IMR_S2_TIM | AR_IMR_S2_DTIM | AR_IMR_S2_DTIMSYNC |
AR_IMR_S2_CABEND | AR_IMR_S2_CABTO |
AR_IMR_S2_TSFOOR | AR_IMR_S2_GTT | AR_IMR_S2_CST);
ah->imrs2_reg |= mask2;
REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
ah->mask_reg = ints;

if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/ath/ath9k/hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,7 @@ struct ath_hw {

int16_t curchan_rad_index;
u32 mask_reg;
u32 imrs2_reg;
u32 txok_interrupt_mask;
u32 txerr_interrupt_mask;
u32 txdesc_interrupt_mask;
Expand Down
6 changes: 4 additions & 2 deletions drivers/net/wireless/ath/ath9k/mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@ static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
REG_WRITE(ah, AR_IMR_S1,
SM(ah->txerr_interrupt_mask, AR_IMR_S1_QCU_TXERR)
| SM(ah->txeol_interrupt_mask, AR_IMR_S1_QCU_TXEOL));
REG_RMW_FIELD(ah, AR_IMR_S2,
AR_IMR_S2_QCU_TXURN, ah->txurn_interrupt_mask);

ah->imrs2_reg &= ~AR_IMR_S2_QCU_TXURN;
ah->imrs2_reg |= (ah->txurn_interrupt_mask & AR_IMR_S2_QCU_TXURN);
REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
}

u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
Expand Down

0 comments on commit 74bad5c

Please sign in to comment.