aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath9k/hw.c18
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 */
2529void ath9k_hw_procmibevent(struct ath_hal *ah, 2534void 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}