diff options
-rw-r--r-- | drivers/net/wireless/ath9k/hw.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index 0251e59f2f84..272c75816609 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c | |||
@@ -2526,6 +2526,11 @@ static void ath9k_ani_reset(struct ath_hal *ah) | |||
2526 | } | 2526 | } |
2527 | } | 2527 | } |
2528 | 2528 | ||
2529 | /* | ||
2530 | * Process a MIB interrupt. We may potentially be invoked because | ||
2531 | * any of the MIB counters overflow/trigger so don't assume we're | ||
2532 | * here because a PHY error counter triggered. | ||
2533 | */ | ||
2529 | void ath9k_hw_procmibevent(struct ath_hal *ah, | 2534 | void ath9k_hw_procmibevent(struct ath_hal *ah, |
2530 | const struct ath9k_node_stats *stats) | 2535 | const struct ath9k_node_stats *stats) |
2531 | { | 2536 | { |
@@ -2533,18 +2538,20 @@ void ath9k_hw_procmibevent(struct ath_hal *ah, | |||
2533 | u32 phyCnt1, phyCnt2; | 2538 | u32 phyCnt1, phyCnt2; |
2534 | 2539 | ||
2535 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Processing Mib Intr\n"); | 2540 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Processing Mib Intr\n"); |
2536 | 2541 | /* Reset these counters regardless */ | |
2537 | REG_WRITE(ah, AR_FILT_OFDM, 0); | 2542 | REG_WRITE(ah, AR_FILT_OFDM, 0); |
2538 | REG_WRITE(ah, AR_FILT_CCK, 0); | 2543 | REG_WRITE(ah, AR_FILT_CCK, 0); |
2539 | if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING)) | 2544 | if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING)) |
2540 | REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR); | 2545 | REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR); |
2541 | 2546 | ||
2547 | /* Clear the mib counters and save them in the stats */ | ||
2542 | ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats); | 2548 | ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats); |
2543 | ahp->ah_stats.ast_nodestats = *stats; | 2549 | ahp->ah_stats.ast_nodestats = *stats; |
2544 | 2550 | ||
2545 | if (!DO_ANI(ah)) | 2551 | if (!DO_ANI(ah)) |
2546 | return; | 2552 | return; |
2547 | 2553 | ||
2554 | /* NB: these are not reset-on-read */ | ||
2548 | phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); | 2555 | phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); |
2549 | phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); | 2556 | phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); |
2550 | if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) || | 2557 | if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) || |
@@ -2552,6 +2559,7 @@ void ath9k_hw_procmibevent(struct ath_hal *ah, | |||
2552 | struct ar5416AniState *aniState = ahp->ah_curani; | 2559 | struct ar5416AniState *aniState = ahp->ah_curani; |
2553 | u32 ofdmPhyErrCnt, cckPhyErrCnt; | 2560 | u32 ofdmPhyErrCnt, cckPhyErrCnt; |
2554 | 2561 | ||
2562 | /* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */ | ||
2555 | ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase; | 2563 | ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase; |
2556 | ahp->ah_stats.ast_ani_ofdmerrs += | 2564 | ahp->ah_stats.ast_ani_ofdmerrs += |
2557 | ofdmPhyErrCnt - aniState->ofdmPhyErrCount; | 2565 | ofdmPhyErrCnt - aniState->ofdmPhyErrCount; |
@@ -2562,11 +2570,17 @@ void ath9k_hw_procmibevent(struct ath_hal *ah, | |||
2562 | cckPhyErrCnt - aniState->cckPhyErrCount; | 2570 | cckPhyErrCnt - aniState->cckPhyErrCount; |
2563 | aniState->cckPhyErrCount = cckPhyErrCnt; | 2571 | aniState->cckPhyErrCount = cckPhyErrCnt; |
2564 | 2572 | ||
2573 | /* | ||
2574 | * NB: figure out which counter triggered. If both | ||
2575 | * trigger we'll only deal with one as the processing | ||
2576 | * clobbers the error counter so the trigger threshold | ||
2577 | * check will never be true. | ||
2578 | */ | ||
2565 | if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh) | 2579 | if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh) |
2566 | ath9k_hw_ani_ofdm_err_trigger(ah); | 2580 | ath9k_hw_ani_ofdm_err_trigger(ah); |
2567 | if (aniState->cckPhyErrCount > aniState->cckTrigHigh) | 2581 | if (aniState->cckPhyErrCount > aniState->cckTrigHigh) |
2568 | ath9k_hw_ani_cck_err_trigger(ah); | 2582 | ath9k_hw_ani_cck_err_trigger(ah); |
2569 | 2583 | /* NB: always restart to insure the h/w counters are reset */ | |
2570 | ath9k_ani_restart(ah); | 2584 | ath9k_ani_restart(ah); |
2571 | } | 2585 | } |
2572 | } | 2586 | } |