1*dd1de374Slin wang - Sun Microsystems - Beijing China /* 2*dd1de374Slin wang - Sun Microsystems - Beijing China * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 3*dd1de374Slin wang - Sun Microsystems - Beijing China * Use is subject to license terms. 4*dd1de374Slin wang - Sun Microsystems - Beijing China */ 5*dd1de374Slin wang - Sun Microsystems - Beijing China 6*dd1de374Slin wang - Sun Microsystems - Beijing China /* 7*dd1de374Slin wang - Sun Microsystems - Beijing China * Copyright (c) 2008 Atheros Communications Inc. 8*dd1de374Slin wang - Sun Microsystems - Beijing China * 9*dd1de374Slin wang - Sun Microsystems - Beijing China * Permission to use, copy, modify, and/or distribute this software for any 10*dd1de374Slin wang - Sun Microsystems - Beijing China * purpose with or without fee is hereby granted, provided that the above 11*dd1de374Slin wang - Sun Microsystems - Beijing China * copyright notice and this permission notice appear in all copies. 12*dd1de374Slin wang - Sun Microsystems - Beijing China * 13*dd1de374Slin wang - Sun Microsystems - Beijing China * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 14*dd1de374Slin wang - Sun Microsystems - Beijing China * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15*dd1de374Slin wang - Sun Microsystems - Beijing China * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 16*dd1de374Slin wang - Sun Microsystems - Beijing China * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17*dd1de374Slin wang - Sun Microsystems - Beijing China * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18*dd1de374Slin wang - Sun Microsystems - Beijing China * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19*dd1de374Slin wang - Sun Microsystems - Beijing China * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20*dd1de374Slin wang - Sun Microsystems - Beijing China */ 21*dd1de374Slin wang - Sun Microsystems - Beijing China 22*dd1de374Slin wang - Sun Microsystems - Beijing China #include "arn_core.h" 23*dd1de374Slin wang - Sun Microsystems - Beijing China #include "arn_hw.h" 24*dd1de374Slin wang - Sun Microsystems - Beijing China #include "arn_reg.h" 25*dd1de374Slin wang - Sun Microsystems - Beijing China #include "arn_phy.h" 26*dd1de374Slin wang - Sun Microsystems - Beijing China 27*dd1de374Slin wang - Sun Microsystems - Beijing China static int 28*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_get_ani_channel_idx(struct ath_hal *ah, struct ath9k_channel *chan) 29*dd1de374Slin wang - Sun Microsystems - Beijing China { 30*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal_5416 *ahp = AH5416(ah); 31*dd1de374Slin wang - Sun Microsystems - Beijing China int i; 32*dd1de374Slin wang - Sun Microsystems - Beijing China 33*dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < ARRAY_SIZE(ahp->ah_ani); i++) { 34*dd1de374Slin wang - Sun Microsystems - Beijing China if (ahp->ah_ani[i].c.channel == chan->channel) 35*dd1de374Slin wang - Sun Microsystems - Beijing China return (i); 36*dd1de374Slin wang - Sun Microsystems - Beijing China if (ahp->ah_ani[i].c.channel == 0) { 37*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_ani[i].c.channel = chan->channel; 38*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_ani[i].c.channelFlags = chan->channelFlags; 39*dd1de374Slin wang - Sun Microsystems - Beijing China return (i); 40*dd1de374Slin wang - Sun Microsystems - Beijing China } 41*dd1de374Slin wang - Sun Microsystems - Beijing China } 42*dd1de374Slin wang - Sun Microsystems - Beijing China 43*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_ANI, "arn: ath9k_hw_get_ani_channel_idx(): " 44*dd1de374Slin wang - Sun Microsystems - Beijing China "No more channel states left. Using channel 0\n")); 45*dd1de374Slin wang - Sun Microsystems - Beijing China 46*dd1de374Slin wang - Sun Microsystems - Beijing China return (0); 47*dd1de374Slin wang - Sun Microsystems - Beijing China } 48*dd1de374Slin wang - Sun Microsystems - Beijing China 49*dd1de374Slin wang - Sun Microsystems - Beijing China static boolean_t 50*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_ani_control(struct ath_hal *ah, enum ath9k_ani_cmd cmd, int param) 51*dd1de374Slin wang - Sun Microsystems - Beijing China { 52*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal_5416 *ahp = AH5416(ah); 53*dd1de374Slin wang - Sun Microsystems - Beijing China struct ar5416AniState *aniState = ahp->ah_curani; 54*dd1de374Slin wang - Sun Microsystems - Beijing China 55*dd1de374Slin wang - Sun Microsystems - Beijing China switch (cmd & ahp->ah_ani_function) { 56*dd1de374Slin wang - Sun Microsystems - Beijing China case ATH9K_ANI_NOISE_IMMUNITY_LEVEL: { 57*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t level = param; 58*dd1de374Slin wang - Sun Microsystems - Beijing China 59*dd1de374Slin wang - Sun Microsystems - Beijing China if (level >= ARRAY_SIZE(ahp->ah_totalSizeDesired)) { 60*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_ANI, "arn: " 61*dd1de374Slin wang - Sun Microsystems - Beijing China "ah->ah_sc, ATH_DBG_ANI", 62*dd1de374Slin wang - Sun Microsystems - Beijing China "%s: level out of range (%u > %u)\n", 63*dd1de374Slin wang - Sun Microsystems - Beijing China __func__, level, 64*dd1de374Slin wang - Sun Microsystems - Beijing China (unsigned)ARRAY_SIZE(ahp->ah_totalSizeDesired))); 65*dd1de374Slin wang - Sun Microsystems - Beijing China 66*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 67*dd1de374Slin wang - Sun Microsystems - Beijing China } 68*dd1de374Slin wang - Sun Microsystems - Beijing China 69*dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, 70*dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_DESIRED_SZ_TOT_DES, 71*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_totalSizeDesired[level]); 72*dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1, 73*dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_AGC_CTL1_COARSE_LOW, 74*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_coarseLow[level]); 75*dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1, 76*dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_AGC_CTL1_COARSE_HIGH, 77*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_coarseHigh[level]); 78*dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, 79*dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_FIND_SIG_FIRPWR, 80*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_firpwr[level]); 81*dd1de374Slin wang - Sun Microsystems - Beijing China 82*dd1de374Slin wang - Sun Microsystems - Beijing China if (level > aniState->noiseImmunityLevel) 83*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_stats.ast_ani_niup++; 84*dd1de374Slin wang - Sun Microsystems - Beijing China else if (level < aniState->noiseImmunityLevel) 85*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_stats.ast_ani_nidown++; 86*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->noiseImmunityLevel = (uint8_t)level; /* LINT */ 87*dd1de374Slin wang - Sun Microsystems - Beijing China break; 88*dd1de374Slin wang - Sun Microsystems - Beijing China } 89*dd1de374Slin wang - Sun Microsystems - Beijing China case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION: { 90*dd1de374Slin wang - Sun Microsystems - Beijing China const int m1ThreshLow[] = { 127, 50 }; 91*dd1de374Slin wang - Sun Microsystems - Beijing China const int m2ThreshLow[] = { 127, 40 }; 92*dd1de374Slin wang - Sun Microsystems - Beijing China const int m1Thresh[] = { 127, 0x4d }; 93*dd1de374Slin wang - Sun Microsystems - Beijing China const int m2Thresh[] = { 127, 0x40 }; 94*dd1de374Slin wang - Sun Microsystems - Beijing China const int m2CountThr[] = { 31, 16 }; 95*dd1de374Slin wang - Sun Microsystems - Beijing China const int m2CountThrLow[] = { 63, 48 }; 96*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t on = param ? 1 : 0; 97*dd1de374Slin wang - Sun Microsystems - Beijing China 98*dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, 99*dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_SFCORR_LOW_M1_THRESH_LOW, 100*dd1de374Slin wang - Sun Microsystems - Beijing China m1ThreshLow[on]); 101*dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, 102*dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_SFCORR_LOW_M2_THRESH_LOW, 103*dd1de374Slin wang - Sun Microsystems - Beijing China m2ThreshLow[on]); 104*dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR_PHY_SFCORR, 105*dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_SFCORR_M1_THRESH, 106*dd1de374Slin wang - Sun Microsystems - Beijing China m1Thresh[on]); 107*dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR_PHY_SFCORR, 108*dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_SFCORR_M2_THRESH, 109*dd1de374Slin wang - Sun Microsystems - Beijing China m2Thresh[on]); 110*dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR_PHY_SFCORR, 111*dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_SFCORR_M2COUNT_THR, 112*dd1de374Slin wang - Sun Microsystems - Beijing China m2CountThr[on]); 113*dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, 114*dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, 115*dd1de374Slin wang - Sun Microsystems - Beijing China m2CountThrLow[on]); 116*dd1de374Slin wang - Sun Microsystems - Beijing China 117*dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 118*dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_SFCORR_EXT_M1_THRESH_LOW, 119*dd1de374Slin wang - Sun Microsystems - Beijing China m1ThreshLow[on]); 120*dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 121*dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_SFCORR_EXT_M2_THRESH_LOW, 122*dd1de374Slin wang - Sun Microsystems - Beijing China m2ThreshLow[on]); 123*dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 124*dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_SFCORR_EXT_M1_THRESH, 125*dd1de374Slin wang - Sun Microsystems - Beijing China m1Thresh[on]); 126*dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 127*dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_SFCORR_EXT_M2_THRESH, 128*dd1de374Slin wang - Sun Microsystems - Beijing China m2Thresh[on]); 129*dd1de374Slin wang - Sun Microsystems - Beijing China 130*dd1de374Slin wang - Sun Microsystems - Beijing China if (on) 131*dd1de374Slin wang - Sun Microsystems - Beijing China REG_SET_BIT(ah, AR_PHY_SFCORR_LOW, 132*dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); 133*dd1de374Slin wang - Sun Microsystems - Beijing China else 134*dd1de374Slin wang - Sun Microsystems - Beijing China REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW, 135*dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); 136*dd1de374Slin wang - Sun Microsystems - Beijing China 137*dd1de374Slin wang - Sun Microsystems - Beijing China if (!on != aniState->ofdmWeakSigDetectOff) { 138*dd1de374Slin wang - Sun Microsystems - Beijing China if (on) 139*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_stats.ast_ani_ofdmon++; 140*dd1de374Slin wang - Sun Microsystems - Beijing China else 141*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_stats.ast_ani_ofdmoff++; 142*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->ofdmWeakSigDetectOff = !on; 143*dd1de374Slin wang - Sun Microsystems - Beijing China } 144*dd1de374Slin wang - Sun Microsystems - Beijing China break; 145*dd1de374Slin wang - Sun Microsystems - Beijing China } 146*dd1de374Slin wang - Sun Microsystems - Beijing China case ATH9K_ANI_CCK_WEAK_SIGNAL_THR: { 147*dd1de374Slin wang - Sun Microsystems - Beijing China const int weakSigThrCck[] = { 8, 6 }; 148*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t high = param ? 1 : 0; 149*dd1de374Slin wang - Sun Microsystems - Beijing China 150*dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT, 151*dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK, 152*dd1de374Slin wang - Sun Microsystems - Beijing China weakSigThrCck[high]); 153*dd1de374Slin wang - Sun Microsystems - Beijing China if (high != aniState->cckWeakSigThreshold) { 154*dd1de374Slin wang - Sun Microsystems - Beijing China if (high) 155*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_stats.ast_ani_cckhigh++; 156*dd1de374Slin wang - Sun Microsystems - Beijing China else 157*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_stats.ast_ani_ccklow++; 158*dd1de374Slin wang - Sun Microsystems - Beijing China /* LINT */ 159*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->cckWeakSigThreshold = (uint8_t)high; 160*dd1de374Slin wang - Sun Microsystems - Beijing China } 161*dd1de374Slin wang - Sun Microsystems - Beijing China break; 162*dd1de374Slin wang - Sun Microsystems - Beijing China } 163*dd1de374Slin wang - Sun Microsystems - Beijing China case ATH9K_ANI_FIRSTEP_LEVEL: { 164*dd1de374Slin wang - Sun Microsystems - Beijing China const int firstep[] = { 0, 4, 8 }; 165*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t level = param; 166*dd1de374Slin wang - Sun Microsystems - Beijing China 167*dd1de374Slin wang - Sun Microsystems - Beijing China if (level >= ARRAY_SIZE(firstep)) { 168*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_ANI, "arn: " 169*dd1de374Slin wang - Sun Microsystems - Beijing China "%s: level out of range (%u > %u)\n", 170*dd1de374Slin wang - Sun Microsystems - Beijing China __func__, level, 171*dd1de374Slin wang - Sun Microsystems - Beijing China (unsigned)ARRAY_SIZE(firstep))); 172*dd1de374Slin wang - Sun Microsystems - Beijing China 173*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 174*dd1de374Slin wang - Sun Microsystems - Beijing China } 175*dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, 176*dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_FIND_SIG_FIRSTEP, firstep[level]); 177*dd1de374Slin wang - Sun Microsystems - Beijing China if (level > aniState->firstepLevel) 178*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_stats.ast_ani_stepup++; 179*dd1de374Slin wang - Sun Microsystems - Beijing China else if (level < aniState->firstepLevel) 180*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_stats.ast_ani_stepdown++; 181*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->firstepLevel = (uint8_t)level; /* LINT */ 182*dd1de374Slin wang - Sun Microsystems - Beijing China break; 183*dd1de374Slin wang - Sun Microsystems - Beijing China } 184*dd1de374Slin wang - Sun Microsystems - Beijing China case ATH9K_ANI_SPUR_IMMUNITY_LEVEL: { 185*dd1de374Slin wang - Sun Microsystems - Beijing China const int cycpwrThr1[] = 186*dd1de374Slin wang - Sun Microsystems - Beijing China { 2, 4, 6, 8, 10, 12, 14, 16 }; 187*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t level = param; 188*dd1de374Slin wang - Sun Microsystems - Beijing China 189*dd1de374Slin wang - Sun Microsystems - Beijing China if (level >= ARRAY_SIZE(cycpwrThr1)) { 190*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_ANI, "arn: " 191*dd1de374Slin wang - Sun Microsystems - Beijing China "%s: level out of range (%u > %u)\n", 192*dd1de374Slin wang - Sun Microsystems - Beijing China __func__, level, 193*dd1de374Slin wang - Sun Microsystems - Beijing China (unsigned)ARRAY_SIZE(cycpwrThr1))); 194*dd1de374Slin wang - Sun Microsystems - Beijing China 195*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 196*dd1de374Slin wang - Sun Microsystems - Beijing China } 197*dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR_PHY_TIMING5, 198*dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_TIMING5_CYCPWR_THR1, cycpwrThr1[level]); 199*dd1de374Slin wang - Sun Microsystems - Beijing China if (level > aniState->spurImmunityLevel) 200*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_stats.ast_ani_spurup++; 201*dd1de374Slin wang - Sun Microsystems - Beijing China else if (level < aniState->spurImmunityLevel) 202*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_stats.ast_ani_spurdown++; 203*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->spurImmunityLevel = (uint8_t)level; /* LINT */ 204*dd1de374Slin wang - Sun Microsystems - Beijing China break; 205*dd1de374Slin wang - Sun Microsystems - Beijing China } 206*dd1de374Slin wang - Sun Microsystems - Beijing China case ATH9K_ANI_PRESENT: 207*dd1de374Slin wang - Sun Microsystems - Beijing China break; 208*dd1de374Slin wang - Sun Microsystems - Beijing China default: 209*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_ANI, "arn: " 210*dd1de374Slin wang - Sun Microsystems - Beijing China "%s: invalid cmd %u\n", __func__, cmd)); 211*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 212*dd1de374Slin wang - Sun Microsystems - Beijing China } 213*dd1de374Slin wang - Sun Microsystems - Beijing China 214*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_ANI, "arn: " 215*dd1de374Slin wang - Sun Microsystems - Beijing China "%s: ANI parameters:\n", __func__)); 216*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_ANI, "arn: " 217*dd1de374Slin wang - Sun Microsystems - Beijing China "noiseImmunityLevel=%d, spurImmunityLevel=%d, " 218*dd1de374Slin wang - Sun Microsystems - Beijing China "ofdmWeakSigDetectOff=%d\n", 219*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->noiseImmunityLevel, aniState->spurImmunityLevel, 220*dd1de374Slin wang - Sun Microsystems - Beijing China !aniState->ofdmWeakSigDetectOff)); 221*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_ANI, "arn: " 222*dd1de374Slin wang - Sun Microsystems - Beijing China "cckWeakSigThreshold=%d, " 223*dd1de374Slin wang - Sun Microsystems - Beijing China "firstepLevel=%d, listenTime=%d\n", 224*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->cckWeakSigThreshold, aniState->firstepLevel, 225*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->listenTime)); 226*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_ANI, "arn: " 227*dd1de374Slin wang - Sun Microsystems - Beijing China "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n", 228*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->cycleCount, aniState->ofdmPhyErrCount, 229*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->cckPhyErrCount)); 230*dd1de374Slin wang - Sun Microsystems - Beijing China 231*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_TRUE); 232*dd1de374Slin wang - Sun Microsystems - Beijing China } 233*dd1de374Slin wang - Sun Microsystems - Beijing China 234*dd1de374Slin wang - Sun Microsystems - Beijing China static void 235*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_update_mibstats(struct ath_hal *ah, struct ath9k_mib_stats *stats) 236*dd1de374Slin wang - Sun Microsystems - Beijing China { 237*dd1de374Slin wang - Sun Microsystems - Beijing China stats->ackrcv_bad += REG_READ(ah, AR_ACK_FAIL); 238*dd1de374Slin wang - Sun Microsystems - Beijing China stats->rts_bad += REG_READ(ah, AR_RTS_FAIL); 239*dd1de374Slin wang - Sun Microsystems - Beijing China stats->fcs_bad += REG_READ(ah, AR_FCS_FAIL); 240*dd1de374Slin wang - Sun Microsystems - Beijing China stats->rts_good += REG_READ(ah, AR_RTS_OK); 241*dd1de374Slin wang - Sun Microsystems - Beijing China stats->beacons += REG_READ(ah, AR_BEACON_CNT); 242*dd1de374Slin wang - Sun Microsystems - Beijing China } 243*dd1de374Slin wang - Sun Microsystems - Beijing China 244*dd1de374Slin wang - Sun Microsystems - Beijing China static void 245*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_ani_restart(struct ath_hal *ah) 246*dd1de374Slin wang - Sun Microsystems - Beijing China { 247*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal_5416 *ahp = AH5416(ah); 248*dd1de374Slin wang - Sun Microsystems - Beijing China struct ar5416AniState *aniState; 249*dd1de374Slin wang - Sun Microsystems - Beijing China 250*dd1de374Slin wang - Sun Microsystems - Beijing China if (!DO_ANI(ah)) 251*dd1de374Slin wang - Sun Microsystems - Beijing China return; 252*dd1de374Slin wang - Sun Microsystems - Beijing China 253*dd1de374Slin wang - Sun Microsystems - Beijing China aniState = ahp->ah_curani; 254*dd1de374Slin wang - Sun Microsystems - Beijing China 255*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->listenTime = 0; 256*dd1de374Slin wang - Sun Microsystems - Beijing China if (ahp->ah_hasHwPhyCounters) { 257*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) { 258*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->ofdmPhyErrBase = 0; 259*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_ANI, "arn: " 260*dd1de374Slin wang - Sun Microsystems - Beijing China "OFDM Trigger is too high for hw counters\n")); 261*dd1de374Slin wang - Sun Microsystems - Beijing China } else { 262*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->ofdmPhyErrBase = 263*dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_COUNTMAX - aniState->ofdmTrigHigh; 264*dd1de374Slin wang - Sun Microsystems - Beijing China } 265*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) { 266*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->cckPhyErrBase = 0; 267*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_ANI, "arn: " 268*dd1de374Slin wang - Sun Microsystems - Beijing China "CCK Trigger is too high for hw counters\n")); 269*dd1de374Slin wang - Sun Microsystems - Beijing China } else { 270*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->cckPhyErrBase = 271*dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_COUNTMAX - aniState->cckTrigHigh; 272*dd1de374Slin wang - Sun Microsystems - Beijing China } 273*dd1de374Slin wang - Sun Microsystems - Beijing China 274*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_ANI, "arn: " 275*dd1de374Slin wang - Sun Microsystems - Beijing China "%s: Writing ofdmbase=%u cckbase=%u\n", 276*dd1de374Slin wang - Sun Microsystems - Beijing China __func__, aniState->ofdmPhyErrBase, 277*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->cckPhyErrBase)); 278*dd1de374Slin wang - Sun Microsystems - Beijing China 279*dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase); 280*dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase); 281*dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); 282*dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); 283*dd1de374Slin wang - Sun Microsystems - Beijing China 284*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats); 285*dd1de374Slin wang - Sun Microsystems - Beijing China } 286*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->ofdmPhyErrCount = 0; 287*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->cckPhyErrCount = 0; 288*dd1de374Slin wang - Sun Microsystems - Beijing China } 289*dd1de374Slin wang - Sun Microsystems - Beijing China 290*dd1de374Slin wang - Sun Microsystems - Beijing China static void 291*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah) 292*dd1de374Slin wang - Sun Microsystems - Beijing China { 293*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal_5416 *ahp = AH5416(ah); 294*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath9k_channel *chan = ah->ah_curchan; 295*dd1de374Slin wang - Sun Microsystems - Beijing China struct ar5416AniState *aniState; 296*dd1de374Slin wang - Sun Microsystems - Beijing China enum wireless_mode mode; 297*dd1de374Slin wang - Sun Microsystems - Beijing China int32_t rssi; 298*dd1de374Slin wang - Sun Microsystems - Beijing China 299*dd1de374Slin wang - Sun Microsystems - Beijing China if (!DO_ANI(ah)) 300*dd1de374Slin wang - Sun Microsystems - Beijing China return; 301*dd1de374Slin wang - Sun Microsystems - Beijing China 302*dd1de374Slin wang - Sun Microsystems - Beijing China aniState = ahp->ah_curani; 303*dd1de374Slin wang - Sun Microsystems - Beijing China 304*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) { 305*dd1de374Slin wang - Sun Microsystems - Beijing China if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 306*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->noiseImmunityLevel + 1)) { 307*dd1de374Slin wang - Sun Microsystems - Beijing China return; 308*dd1de374Slin wang - Sun Microsystems - Beijing China } 309*dd1de374Slin wang - Sun Microsystems - Beijing China } 310*dd1de374Slin wang - Sun Microsystems - Beijing China 311*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->spurImmunityLevel < HAL_SPUR_IMMUNE_MAX) { 312*dd1de374Slin wang - Sun Microsystems - Beijing China if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 313*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->spurImmunityLevel + 1)) { 314*dd1de374Slin wang - Sun Microsystems - Beijing China return; 315*dd1de374Slin wang - Sun Microsystems - Beijing China } 316*dd1de374Slin wang - Sun Microsystems - Beijing China } 317*dd1de374Slin wang - Sun Microsystems - Beijing China 318*dd1de374Slin wang - Sun Microsystems - Beijing China if (ah->ah_opmode == ATH9K_M_HOSTAP) { 319*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) { 320*dd1de374Slin wang - Sun Microsystems - Beijing China (void) ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 321*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->firstepLevel + 1); 322*dd1de374Slin wang - Sun Microsystems - Beijing China } 323*dd1de374Slin wang - Sun Microsystems - Beijing China return; 324*dd1de374Slin wang - Sun Microsystems - Beijing China } 325*dd1de374Slin wang - Sun Microsystems - Beijing China rssi = BEACON_RSSI(ahp); 326*dd1de374Slin wang - Sun Microsystems - Beijing China if (rssi > aniState->rssiThrHigh) { 327*dd1de374Slin wang - Sun Microsystems - Beijing China if (!aniState->ofdmWeakSigDetectOff) { 328*dd1de374Slin wang - Sun Microsystems - Beijing China if (ath9k_hw_ani_control(ah, 329*dd1de374Slin wang - Sun Microsystems - Beijing China ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, 330*dd1de374Slin wang - Sun Microsystems - Beijing China B_FALSE)) { 331*dd1de374Slin wang - Sun Microsystems - Beijing China (void) ath9k_hw_ani_control(ah, 332*dd1de374Slin wang - Sun Microsystems - Beijing China ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0); 333*dd1de374Slin wang - Sun Microsystems - Beijing China return; 334*dd1de374Slin wang - Sun Microsystems - Beijing China } 335*dd1de374Slin wang - Sun Microsystems - Beijing China } 336*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) { 337*dd1de374Slin wang - Sun Microsystems - Beijing China (void) ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 338*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->firstepLevel + 1); 339*dd1de374Slin wang - Sun Microsystems - Beijing China return; 340*dd1de374Slin wang - Sun Microsystems - Beijing China } 341*dd1de374Slin wang - Sun Microsystems - Beijing China } else if (rssi > aniState->rssiThrLow) { 342*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->ofdmWeakSigDetectOff) 343*dd1de374Slin wang - Sun Microsystems - Beijing China (void) ath9k_hw_ani_control(ah, 344*dd1de374Slin wang - Sun Microsystems - Beijing China ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, 345*dd1de374Slin wang - Sun Microsystems - Beijing China B_TRUE); 346*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) 347*dd1de374Slin wang - Sun Microsystems - Beijing China (void) ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 348*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->firstepLevel + 1); 349*dd1de374Slin wang - Sun Microsystems - Beijing China return; 350*dd1de374Slin wang - Sun Microsystems - Beijing China } else { 351*dd1de374Slin wang - Sun Microsystems - Beijing China mode = ath9k_hw_chan2wmode(ah, chan); 352*dd1de374Slin wang - Sun Microsystems - Beijing China if (mode == ATH9K_MODE_11G || mode == ATH9K_MODE_11B) { 353*dd1de374Slin wang - Sun Microsystems - Beijing China if (!aniState->ofdmWeakSigDetectOff) 354*dd1de374Slin wang - Sun Microsystems - Beijing China (void) ath9k_hw_ani_control(ah, 355*dd1de374Slin wang - Sun Microsystems - Beijing China ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, 356*dd1de374Slin wang - Sun Microsystems - Beijing China B_FALSE); 357*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->firstepLevel > 0) 358*dd1de374Slin wang - Sun Microsystems - Beijing China (void) ath9k_hw_ani_control(ah, 359*dd1de374Slin wang - Sun Microsystems - Beijing China ATH9K_ANI_FIRSTEP_LEVEL, 0); 360*dd1de374Slin wang - Sun Microsystems - Beijing China return; 361*dd1de374Slin wang - Sun Microsystems - Beijing China } 362*dd1de374Slin wang - Sun Microsystems - Beijing China } 363*dd1de374Slin wang - Sun Microsystems - Beijing China } 364*dd1de374Slin wang - Sun Microsystems - Beijing China 365*dd1de374Slin wang - Sun Microsystems - Beijing China static void 366*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_ani_cck_err_trigger(struct ath_hal *ah) 367*dd1de374Slin wang - Sun Microsystems - Beijing China { 368*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal_5416 *ahp = AH5416(ah); 369*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath9k_channel *chan = ah->ah_curchan; 370*dd1de374Slin wang - Sun Microsystems - Beijing China struct ar5416AniState *aniState; 371*dd1de374Slin wang - Sun Microsystems - Beijing China enum wireless_mode mode; 372*dd1de374Slin wang - Sun Microsystems - Beijing China int32_t rssi; 373*dd1de374Slin wang - Sun Microsystems - Beijing China 374*dd1de374Slin wang - Sun Microsystems - Beijing China if (!DO_ANI(ah)) 375*dd1de374Slin wang - Sun Microsystems - Beijing China return; 376*dd1de374Slin wang - Sun Microsystems - Beijing China 377*dd1de374Slin wang - Sun Microsystems - Beijing China aniState = ahp->ah_curani; 378*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) { 379*dd1de374Slin wang - Sun Microsystems - Beijing China if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 380*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->noiseImmunityLevel + 1)) { 381*dd1de374Slin wang - Sun Microsystems - Beijing China return; 382*dd1de374Slin wang - Sun Microsystems - Beijing China } 383*dd1de374Slin wang - Sun Microsystems - Beijing China } 384*dd1de374Slin wang - Sun Microsystems - Beijing China if (ah->ah_opmode == ATH9K_M_HOSTAP) { 385*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) { 386*dd1de374Slin wang - Sun Microsystems - Beijing China (void) ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 387*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->firstepLevel + 1); 388*dd1de374Slin wang - Sun Microsystems - Beijing China } 389*dd1de374Slin wang - Sun Microsystems - Beijing China return; 390*dd1de374Slin wang - Sun Microsystems - Beijing China } 391*dd1de374Slin wang - Sun Microsystems - Beijing China rssi = BEACON_RSSI(ahp); 392*dd1de374Slin wang - Sun Microsystems - Beijing China if (rssi > aniState->rssiThrLow) { 393*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) 394*dd1de374Slin wang - Sun Microsystems - Beijing China (void) ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 395*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->firstepLevel + 1); 396*dd1de374Slin wang - Sun Microsystems - Beijing China } else { 397*dd1de374Slin wang - Sun Microsystems - Beijing China mode = ath9k_hw_chan2wmode(ah, chan); 398*dd1de374Slin wang - Sun Microsystems - Beijing China if (mode == ATH9K_MODE_11G || mode == ATH9K_MODE_11B) { 399*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->firstepLevel > 0) 400*dd1de374Slin wang - Sun Microsystems - Beijing China (void) ath9k_hw_ani_control(ah, 401*dd1de374Slin wang - Sun Microsystems - Beijing China ATH9K_ANI_FIRSTEP_LEVEL, 0); 402*dd1de374Slin wang - Sun Microsystems - Beijing China } 403*dd1de374Slin wang - Sun Microsystems - Beijing China } 404*dd1de374Slin wang - Sun Microsystems - Beijing China } 405*dd1de374Slin wang - Sun Microsystems - Beijing China 406*dd1de374Slin wang - Sun Microsystems - Beijing China static void 407*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_ani_lower_immunity(struct ath_hal *ah) 408*dd1de374Slin wang - Sun Microsystems - Beijing China { 409*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal_5416 *ahp = AH5416(ah); 410*dd1de374Slin wang - Sun Microsystems - Beijing China struct ar5416AniState *aniState; 411*dd1de374Slin wang - Sun Microsystems - Beijing China int32_t rssi; 412*dd1de374Slin wang - Sun Microsystems - Beijing China 413*dd1de374Slin wang - Sun Microsystems - Beijing China aniState = ahp->ah_curani; 414*dd1de374Slin wang - Sun Microsystems - Beijing China 415*dd1de374Slin wang - Sun Microsystems - Beijing China if (ah->ah_opmode == ATH9K_M_HOSTAP) { 416*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->firstepLevel > 0) { 417*dd1de374Slin wang - Sun Microsystems - Beijing China if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 418*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->firstepLevel - 1)) 419*dd1de374Slin wang - Sun Microsystems - Beijing China return; 420*dd1de374Slin wang - Sun Microsystems - Beijing China } 421*dd1de374Slin wang - Sun Microsystems - Beijing China } else { 422*dd1de374Slin wang - Sun Microsystems - Beijing China rssi = BEACON_RSSI(ahp); 423*dd1de374Slin wang - Sun Microsystems - Beijing China if (rssi > aniState->rssiThrHigh) { 424*dd1de374Slin wang - Sun Microsystems - Beijing China /* XXX: Handle me */ 425*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_ANI, "arn: ath9k_ani_reset():\n")); 426*dd1de374Slin wang - Sun Microsystems - Beijing China } else if (rssi > aniState->rssiThrLow) { 427*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->ofdmWeakSigDetectOff) { 428*dd1de374Slin wang - Sun Microsystems - Beijing China if (ath9k_hw_ani_control(ah, 429*dd1de374Slin wang - Sun Microsystems - Beijing China ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, 430*dd1de374Slin wang - Sun Microsystems - Beijing China B_TRUE) == B_TRUE) 431*dd1de374Slin wang - Sun Microsystems - Beijing China return; 432*dd1de374Slin wang - Sun Microsystems - Beijing China } 433*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->firstepLevel > 0) { 434*dd1de374Slin wang - Sun Microsystems - Beijing China if (ath9k_hw_ani_control(ah, 435*dd1de374Slin wang - Sun Microsystems - Beijing China ATH9K_ANI_FIRSTEP_LEVEL, 436*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->firstepLevel - 1) == B_TRUE) 437*dd1de374Slin wang - Sun Microsystems - Beijing China return; 438*dd1de374Slin wang - Sun Microsystems - Beijing China } 439*dd1de374Slin wang - Sun Microsystems - Beijing China } else { 440*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->firstepLevel > 0) { 441*dd1de374Slin wang - Sun Microsystems - Beijing China if (ath9k_hw_ani_control(ah, 442*dd1de374Slin wang - Sun Microsystems - Beijing China ATH9K_ANI_FIRSTEP_LEVEL, 443*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->firstepLevel - 1) == B_TRUE) 444*dd1de374Slin wang - Sun Microsystems - Beijing China return; 445*dd1de374Slin wang - Sun Microsystems - Beijing China } 446*dd1de374Slin wang - Sun Microsystems - Beijing China } 447*dd1de374Slin wang - Sun Microsystems - Beijing China } 448*dd1de374Slin wang - Sun Microsystems - Beijing China 449*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->spurImmunityLevel > 0) { 450*dd1de374Slin wang - Sun Microsystems - Beijing China if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 451*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->spurImmunityLevel - 1)) 452*dd1de374Slin wang - Sun Microsystems - Beijing China return; 453*dd1de374Slin wang - Sun Microsystems - Beijing China } 454*dd1de374Slin wang - Sun Microsystems - Beijing China 455*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->noiseImmunityLevel > 0) { 456*dd1de374Slin wang - Sun Microsystems - Beijing China (void) ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 457*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->noiseImmunityLevel - 1); 458*dd1de374Slin wang - Sun Microsystems - Beijing China return; 459*dd1de374Slin wang - Sun Microsystems - Beijing China } 460*dd1de374Slin wang - Sun Microsystems - Beijing China } 461*dd1de374Slin wang - Sun Microsystems - Beijing China 462*dd1de374Slin wang - Sun Microsystems - Beijing China static int32_t 463*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_ani_get_listen_time(struct ath_hal *ah) 464*dd1de374Slin wang - Sun Microsystems - Beijing China { 465*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal_5416 *ahp = AH5416(ah); 466*dd1de374Slin wang - Sun Microsystems - Beijing China struct ar5416AniState *aniState; 467*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t txFrameCount, rxFrameCount, cycleCount; 468*dd1de374Slin wang - Sun Microsystems - Beijing China int32_t listenTime; 469*dd1de374Slin wang - Sun Microsystems - Beijing China 470*dd1de374Slin wang - Sun Microsystems - Beijing China txFrameCount = REG_READ(ah, AR_TFCNT); 471*dd1de374Slin wang - Sun Microsystems - Beijing China rxFrameCount = REG_READ(ah, AR_RFCNT); 472*dd1de374Slin wang - Sun Microsystems - Beijing China cycleCount = REG_READ(ah, AR_CCCNT); 473*dd1de374Slin wang - Sun Microsystems - Beijing China 474*dd1de374Slin wang - Sun Microsystems - Beijing China aniState = ahp->ah_curani; 475*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) { 476*dd1de374Slin wang - Sun Microsystems - Beijing China 477*dd1de374Slin wang - Sun Microsystems - Beijing China listenTime = 0; 478*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_stats.ast_ani_lzero++; 479*dd1de374Slin wang - Sun Microsystems - Beijing China } else { 480*dd1de374Slin wang - Sun Microsystems - Beijing China int32_t ccdelta = cycleCount - aniState->cycleCount; 481*dd1de374Slin wang - Sun Microsystems - Beijing China int32_t rfdelta = rxFrameCount - aniState->rxFrameCount; 482*dd1de374Slin wang - Sun Microsystems - Beijing China int32_t tfdelta = txFrameCount - aniState->txFrameCount; 483*dd1de374Slin wang - Sun Microsystems - Beijing China listenTime = (ccdelta - rfdelta - tfdelta) / 44000; 484*dd1de374Slin wang - Sun Microsystems - Beijing China } 485*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->cycleCount = cycleCount; 486*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->txFrameCount = txFrameCount; 487*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->rxFrameCount = rxFrameCount; 488*dd1de374Slin wang - Sun Microsystems - Beijing China 489*dd1de374Slin wang - Sun Microsystems - Beijing China return (listenTime); 490*dd1de374Slin wang - Sun Microsystems - Beijing China } 491*dd1de374Slin wang - Sun Microsystems - Beijing China 492*dd1de374Slin wang - Sun Microsystems - Beijing China void 493*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_ani_reset(struct ath_hal *ah) 494*dd1de374Slin wang - Sun Microsystems - Beijing China { 495*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal_5416 *ahp = AH5416(ah); 496*dd1de374Slin wang - Sun Microsystems - Beijing China struct ar5416AniState *aniState; 497*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath9k_channel *chan = ah->ah_curchan; 498*dd1de374Slin wang - Sun Microsystems - Beijing China int index; 499*dd1de374Slin wang - Sun Microsystems - Beijing China 500*dd1de374Slin wang - Sun Microsystems - Beijing China /* For Lint Reasons */ 501*dd1de374Slin wang - Sun Microsystems - Beijing China boolean_t ANI_USE_OFDM_WEAK_SIG = ATH9K_ANI_USE_OFDM_WEAK_SIG; 502*dd1de374Slin wang - Sun Microsystems - Beijing China 503*dd1de374Slin wang - Sun Microsystems - Beijing China if (!DO_ANI(ah)) 504*dd1de374Slin wang - Sun Microsystems - Beijing China return; 505*dd1de374Slin wang - Sun Microsystems - Beijing China 506*dd1de374Slin wang - Sun Microsystems - Beijing China index = ath9k_hw_get_ani_channel_idx(ah, chan); 507*dd1de374Slin wang - Sun Microsystems - Beijing China aniState = &ahp->ah_ani[index]; 508*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_curani = aniState; 509*dd1de374Slin wang - Sun Microsystems - Beijing China 510*dd1de374Slin wang - Sun Microsystems - Beijing China if (DO_ANI(ah) && ah->ah_opmode != ATH9K_M_STA && 511*dd1de374Slin wang - Sun Microsystems - Beijing China ah->ah_opmode != ATH9K_M_IBSS) { 512*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_ANI, "arn: ath9k_ani_reset(): " 513*dd1de374Slin wang - Sun Microsystems - Beijing China "Reset ANI state opmode %u\n", ah->ah_opmode)); 514*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_stats.ast_ani_reset++; 515*dd1de374Slin wang - Sun Microsystems - Beijing China 516*dd1de374Slin wang - Sun Microsystems - Beijing China (void) ath9k_hw_ani_control(ah, 517*dd1de374Slin wang - Sun Microsystems - Beijing China ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0); 518*dd1de374Slin wang - Sun Microsystems - Beijing China (void) ath9k_hw_ani_control(ah, 519*dd1de374Slin wang - Sun Microsystems - Beijing China ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0); 520*dd1de374Slin wang - Sun Microsystems - Beijing China (void) ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0); 521*dd1de374Slin wang - Sun Microsystems - Beijing China (void) ath9k_hw_ani_control 522*dd1de374Slin wang - Sun Microsystems - Beijing China (ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, 523*dd1de374Slin wang - Sun Microsystems - Beijing China !ANI_USE_OFDM_WEAK_SIG /* !ATH9K_ANI_USE_OFDM_WEAK_SIG */); 524*dd1de374Slin wang - Sun Microsystems - Beijing China (void) ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR, 525*dd1de374Slin wang - Sun Microsystems - Beijing China ATH9K_ANI_CCK_WEAK_SIG_THR); 526*dd1de374Slin wang - Sun Microsystems - Beijing China 527*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) | 528*dd1de374Slin wang - Sun Microsystems - Beijing China ATH9K_RX_FILTER_PHYERR); 529*dd1de374Slin wang - Sun Microsystems - Beijing China 530*dd1de374Slin wang - Sun Microsystems - Beijing China if (ah->ah_opmode == ATH9K_M_HOSTAP) { 531*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_curani->ofdmTrigHigh = 532*dd1de374Slin wang - Sun Microsystems - Beijing China ah->ah_config.ofdm_trig_high; 533*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_curani->ofdmTrigLow = 534*dd1de374Slin wang - Sun Microsystems - Beijing China ah->ah_config.ofdm_trig_low; 535*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_curani->cckTrigHigh = 536*dd1de374Slin wang - Sun Microsystems - Beijing China ah->ah_config.cck_trig_high; 537*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_curani->cckTrigLow = 538*dd1de374Slin wang - Sun Microsystems - Beijing China ah->ah_config.cck_trig_low; 539*dd1de374Slin wang - Sun Microsystems - Beijing China } 540*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_ani_restart(ah); 541*dd1de374Slin wang - Sun Microsystems - Beijing China return; 542*dd1de374Slin wang - Sun Microsystems - Beijing China } 543*dd1de374Slin wang - Sun Microsystems - Beijing China 544*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->noiseImmunityLevel != 0) 545*dd1de374Slin wang - Sun Microsystems - Beijing China (void) ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 546*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->noiseImmunityLevel); 547*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->spurImmunityLevel != 0) 548*dd1de374Slin wang - Sun Microsystems - Beijing China (void) ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 549*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->spurImmunityLevel); 550*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->ofdmWeakSigDetectOff) 551*dd1de374Slin wang - Sun Microsystems - Beijing China (void) ath9k_hw_ani_control 552*dd1de374Slin wang - Sun Microsystems - Beijing China (ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, 553*dd1de374Slin wang - Sun Microsystems - Beijing China !aniState->ofdmWeakSigDetectOff); 554*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->cckWeakSigThreshold) 555*dd1de374Slin wang - Sun Microsystems - Beijing China (void) ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR, 556*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->cckWeakSigThreshold); 557*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->firstepLevel != 0) 558*dd1de374Slin wang - Sun Microsystems - Beijing China (void) ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 559*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->firstepLevel); 560*dd1de374Slin wang - Sun Microsystems - Beijing China if (ahp->ah_hasHwPhyCounters) { 561*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) & 562*dd1de374Slin wang - Sun Microsystems - Beijing China ~ATH9K_RX_FILTER_PHYERR); 563*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_ani_restart(ah); 564*dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); 565*dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); 566*dd1de374Slin wang - Sun Microsystems - Beijing China 567*dd1de374Slin wang - Sun Microsystems - Beijing China } else { 568*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_ani_restart(ah); 569*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) | 570*dd1de374Slin wang - Sun Microsystems - Beijing China ATH9K_RX_FILTER_PHYERR); 571*dd1de374Slin wang - Sun Microsystems - Beijing China } 572*dd1de374Slin wang - Sun Microsystems - Beijing China } 573*dd1de374Slin wang - Sun Microsystems - Beijing China 574*dd1de374Slin wang - Sun Microsystems - Beijing China /* ARGSUSED */ 575*dd1de374Slin wang - Sun Microsystems - Beijing China void 576*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_ani_monitor(struct ath_hal *ah, const struct ath9k_node_stats *stats, 577*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath9k_channel *chan) 578*dd1de374Slin wang - Sun Microsystems - Beijing China { 579*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal_5416 *ahp = AH5416(ah); 580*dd1de374Slin wang - Sun Microsystems - Beijing China struct ar5416AniState *aniState; 581*dd1de374Slin wang - Sun Microsystems - Beijing China int32_t listenTime; 582*dd1de374Slin wang - Sun Microsystems - Beijing China 583*dd1de374Slin wang - Sun Microsystems - Beijing China aniState = ahp->ah_curani; 584*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_stats.ast_nodestats = *stats; 585*dd1de374Slin wang - Sun Microsystems - Beijing China 586*dd1de374Slin wang - Sun Microsystems - Beijing China listenTime = ath9k_hw_ani_get_listen_time(ah); 587*dd1de374Slin wang - Sun Microsystems - Beijing China if (listenTime < 0) { 588*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_stats.ast_ani_lneg++; 589*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_ani_restart(ah); 590*dd1de374Slin wang - Sun Microsystems - Beijing China return; 591*dd1de374Slin wang - Sun Microsystems - Beijing China } 592*dd1de374Slin wang - Sun Microsystems - Beijing China 593*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->listenTime += listenTime; 594*dd1de374Slin wang - Sun Microsystems - Beijing China 595*dd1de374Slin wang - Sun Microsystems - Beijing China if (ahp->ah_hasHwPhyCounters) { 596*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t phyCnt1, phyCnt2; 597*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t ofdmPhyErrCnt, cckPhyErrCnt; 598*dd1de374Slin wang - Sun Microsystems - Beijing China 599*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats); 600*dd1de374Slin wang - Sun Microsystems - Beijing China 601*dd1de374Slin wang - Sun Microsystems - Beijing China phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); 602*dd1de374Slin wang - Sun Microsystems - Beijing China phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); 603*dd1de374Slin wang - Sun Microsystems - Beijing China 604*dd1de374Slin wang - Sun Microsystems - Beijing China if (phyCnt1 < aniState->ofdmPhyErrBase || 605*dd1de374Slin wang - Sun Microsystems - Beijing China phyCnt2 < aniState->cckPhyErrBase) { 606*dd1de374Slin wang - Sun Microsystems - Beijing China if (phyCnt1 < aniState->ofdmPhyErrBase) { 607*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_ANI, "arn: " 608*dd1de374Slin wang - Sun Microsystems - Beijing China "%s: phyCnt1 0x%x, resetting " 609*dd1de374Slin wang - Sun Microsystems - Beijing China "counter value to 0x%x\n", 610*dd1de374Slin wang - Sun Microsystems - Beijing China __func__, phyCnt1, 611*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->ofdmPhyErrBase)); 612*dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_PHY_ERR_1, 613*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->ofdmPhyErrBase); 614*dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_PHY_ERR_MASK_1, 615*dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_ERR_OFDM_TIMING); 616*dd1de374Slin wang - Sun Microsystems - Beijing China } 617*dd1de374Slin wang - Sun Microsystems - Beijing China if (phyCnt2 < aniState->cckPhyErrBase) { 618*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_ANI, "arn: " 619*dd1de374Slin wang - Sun Microsystems - Beijing China "%s: phyCnt2 0x%x, resetting " 620*dd1de374Slin wang - Sun Microsystems - Beijing China "counter value to 0x%x\n", 621*dd1de374Slin wang - Sun Microsystems - Beijing China __func__, phyCnt2, 622*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->cckPhyErrBase)); 623*dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_PHY_ERR_2, 624*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->cckPhyErrBase); 625*dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_PHY_ERR_MASK_2, 626*dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_ERR_CCK_TIMING); 627*dd1de374Slin wang - Sun Microsystems - Beijing China } 628*dd1de374Slin wang - Sun Microsystems - Beijing China return; 629*dd1de374Slin wang - Sun Microsystems - Beijing China } 630*dd1de374Slin wang - Sun Microsystems - Beijing China 631*dd1de374Slin wang - Sun Microsystems - Beijing China ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase; 632*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_stats.ast_ani_ofdmerrs += 633*dd1de374Slin wang - Sun Microsystems - Beijing China ofdmPhyErrCnt - aniState->ofdmPhyErrCount; 634*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->ofdmPhyErrCount = ofdmPhyErrCnt; 635*dd1de374Slin wang - Sun Microsystems - Beijing China 636*dd1de374Slin wang - Sun Microsystems - Beijing China cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase; 637*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_stats.ast_ani_cckerrs += 638*dd1de374Slin wang - Sun Microsystems - Beijing China cckPhyErrCnt - aniState->cckPhyErrCount; 639*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->cckPhyErrCount = cckPhyErrCnt; 640*dd1de374Slin wang - Sun Microsystems - Beijing China } 641*dd1de374Slin wang - Sun Microsystems - Beijing China 642*dd1de374Slin wang - Sun Microsystems - Beijing China if (!DO_ANI(ah)) 643*dd1de374Slin wang - Sun Microsystems - Beijing China return; 644*dd1de374Slin wang - Sun Microsystems - Beijing China 645*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->listenTime > 5 * ahp->ah_aniPeriod) { 646*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->ofdmPhyErrCount <= aniState->listenTime * 647*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->ofdmTrigLow / 1000 && 648*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->cckPhyErrCount <= aniState->listenTime * 649*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->cckTrigLow / 1000) 650*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_ani_lower_immunity(ah); 651*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_ani_restart(ah); 652*dd1de374Slin wang - Sun Microsystems - Beijing China } else if (aniState->listenTime > ahp->ah_aniPeriod) { 653*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->ofdmPhyErrCount > aniState->listenTime * 654*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->ofdmTrigHigh / 1000) { 655*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_ani_ofdm_err_trigger(ah); 656*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_ani_restart(ah); 657*dd1de374Slin wang - Sun Microsystems - Beijing China } else if (aniState->cckPhyErrCount > 658*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->listenTime * aniState->cckTrigHigh / 1000) { 659*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_ani_cck_err_trigger(ah); 660*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_ani_restart(ah); 661*dd1de374Slin wang - Sun Microsystems - Beijing China } 662*dd1de374Slin wang - Sun Microsystems - Beijing China } 663*dd1de374Slin wang - Sun Microsystems - Beijing China } 664*dd1de374Slin wang - Sun Microsystems - Beijing China 665*dd1de374Slin wang - Sun Microsystems - Beijing China boolean_t 666*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_phycounters(struct ath_hal *ah) 667*dd1de374Slin wang - Sun Microsystems - Beijing China { 668*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal_5416 *ahp = AH5416(ah); 669*dd1de374Slin wang - Sun Microsystems - Beijing China 670*dd1de374Slin wang - Sun Microsystems - Beijing China return (ahp->ah_hasHwPhyCounters ? B_TRUE : B_FALSE); 671*dd1de374Slin wang - Sun Microsystems - Beijing China } 672*dd1de374Slin wang - Sun Microsystems - Beijing China 673*dd1de374Slin wang - Sun Microsystems - Beijing China void 674*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_enable_mib_counters(struct ath_hal *ah) 675*dd1de374Slin wang - Sun Microsystems - Beijing China { 676*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal_5416 *ahp = AH5416(ah); 677*dd1de374Slin wang - Sun Microsystems - Beijing China 678*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_ANI, "arn: ath9k_enable_mib_counters(): " 679*dd1de374Slin wang - Sun Microsystems - Beijing China "Enable MIB counters\n")); 680*dd1de374Slin wang - Sun Microsystems - Beijing China 681*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats); 682*dd1de374Slin wang - Sun Microsystems - Beijing China 683*dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_FILT_OFDM, 0); 684*dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_FILT_CCK, 0); 685*dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_MIBC, 686*dd1de374Slin wang - Sun Microsystems - Beijing China ~(AR_MIBC_COW | AR_MIBC_FMC | AR_MIBC_CMC | AR_MIBC_MCS) & 0x0f); 687*dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); 688*dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); 689*dd1de374Slin wang - Sun Microsystems - Beijing China } 690*dd1de374Slin wang - Sun Microsystems - Beijing China 691*dd1de374Slin wang - Sun Microsystems - Beijing China void 692*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_disable_mib_counters(struct ath_hal *ah) 693*dd1de374Slin wang - Sun Microsystems - Beijing China { 694*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal_5416 *ahp = AH5416(ah); 695*dd1de374Slin wang - Sun Microsystems - Beijing China 696*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_ANI, 697*dd1de374Slin wang - Sun Microsystems - Beijing China "arn: ath9k_hw_disable_mib_counters(): " 698*dd1de374Slin wang - Sun Microsystems - Beijing China "Disable MIB counters\n")); 699*dd1de374Slin wang - Sun Microsystems - Beijing China 700*dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC | AR_MIBC_CMC); 701*dd1de374Slin wang - Sun Microsystems - Beijing China 702*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats); 703*dd1de374Slin wang - Sun Microsystems - Beijing China 704*dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_FILT_OFDM, 0); 705*dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_FILT_CCK, 0); 706*dd1de374Slin wang - Sun Microsystems - Beijing China } 707*dd1de374Slin wang - Sun Microsystems - Beijing China 708*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t 709*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah, uint32_t *rxc_pcnt, 710*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t *rxf_pcnt, uint32_t *txf_pcnt) 711*dd1de374Slin wang - Sun Microsystems - Beijing China { 712*dd1de374Slin wang - Sun Microsystems - Beijing China static uint32_t cycles, rx_clear, rx_frame, tx_frame; 713*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t good = 1; 714*dd1de374Slin wang - Sun Microsystems - Beijing China 715*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t rc = REG_READ(ah, AR_RCCNT); 716*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t rf = REG_READ(ah, AR_RFCNT); 717*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t tf = REG_READ(ah, AR_TFCNT); 718*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t cc = REG_READ(ah, AR_CCCNT); 719*dd1de374Slin wang - Sun Microsystems - Beijing China 720*dd1de374Slin wang - Sun Microsystems - Beijing China if (cycles == 0 || cycles > cc) { 721*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CHANNEL, 722*dd1de374Slin wang - Sun Microsystems - Beijing China "arn: ath9k_hw_GetMibCycleCountsPct(): " 723*dd1de374Slin wang - Sun Microsystems - Beijing China "cycle counter wrap. ExtBusy = 0\n")); 724*dd1de374Slin wang - Sun Microsystems - Beijing China good = 0; 725*dd1de374Slin wang - Sun Microsystems - Beijing China } else { 726*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t cc_d = cc - cycles; 727*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t rc_d = rc - rx_clear; 728*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t rf_d = rf - rx_frame; 729*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t tf_d = tf - tx_frame; 730*dd1de374Slin wang - Sun Microsystems - Beijing China 731*dd1de374Slin wang - Sun Microsystems - Beijing China if (cc_d != 0) { 732*dd1de374Slin wang - Sun Microsystems - Beijing China *rxc_pcnt = rc_d * 100 / cc_d; 733*dd1de374Slin wang - Sun Microsystems - Beijing China *rxf_pcnt = rf_d * 100 / cc_d; 734*dd1de374Slin wang - Sun Microsystems - Beijing China *txf_pcnt = tf_d * 100 / cc_d; 735*dd1de374Slin wang - Sun Microsystems - Beijing China } else { 736*dd1de374Slin wang - Sun Microsystems - Beijing China good = 0; 737*dd1de374Slin wang - Sun Microsystems - Beijing China } 738*dd1de374Slin wang - Sun Microsystems - Beijing China } 739*dd1de374Slin wang - Sun Microsystems - Beijing China 740*dd1de374Slin wang - Sun Microsystems - Beijing China cycles = cc; 741*dd1de374Slin wang - Sun Microsystems - Beijing China rx_frame = rf; 742*dd1de374Slin wang - Sun Microsystems - Beijing China rx_clear = rc; 743*dd1de374Slin wang - Sun Microsystems - Beijing China tx_frame = tf; 744*dd1de374Slin wang - Sun Microsystems - Beijing China 745*dd1de374Slin wang - Sun Microsystems - Beijing China return (good); 746*dd1de374Slin wang - Sun Microsystems - Beijing China } 747*dd1de374Slin wang - Sun Microsystems - Beijing China 748*dd1de374Slin wang - Sun Microsystems - Beijing China /* 749*dd1de374Slin wang - Sun Microsystems - Beijing China * Process a MIB interrupt. We may potentially be invoked because 750*dd1de374Slin wang - Sun Microsystems - Beijing China * any of the MIB counters overflow/trigger so don't assume we're 751*dd1de374Slin wang - Sun Microsystems - Beijing China * here because a PHY error counter triggered. 752*dd1de374Slin wang - Sun Microsystems - Beijing China */ 753*dd1de374Slin wang - Sun Microsystems - Beijing China void 754*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_procmibevent(struct ath_hal *ah, 755*dd1de374Slin wang - Sun Microsystems - Beijing China const struct ath9k_node_stats *stats) 756*dd1de374Slin wang - Sun Microsystems - Beijing China { 757*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal_5416 *ahp = AH5416(ah); 758*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t phyCnt1, phyCnt2; 759*dd1de374Slin wang - Sun Microsystems - Beijing China 760*dd1de374Slin wang - Sun Microsystems - Beijing China /* Reset these counters regardless */ 761*dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_FILT_OFDM, 0); 762*dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_FILT_CCK, 0); 763*dd1de374Slin wang - Sun Microsystems - Beijing China if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING)) 764*dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR); 765*dd1de374Slin wang - Sun Microsystems - Beijing China 766*dd1de374Slin wang - Sun Microsystems - Beijing China /* Clear the mib counters and save them in the stats */ 767*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats); 768*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_stats.ast_nodestats = *stats; 769*dd1de374Slin wang - Sun Microsystems - Beijing China 770*dd1de374Slin wang - Sun Microsystems - Beijing China if (!DO_ANI(ah)) 771*dd1de374Slin wang - Sun Microsystems - Beijing China return; 772*dd1de374Slin wang - Sun Microsystems - Beijing China 773*dd1de374Slin wang - Sun Microsystems - Beijing China /* NB: these are not reset-on-read */ 774*dd1de374Slin wang - Sun Microsystems - Beijing China phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); 775*dd1de374Slin wang - Sun Microsystems - Beijing China phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); 776*dd1de374Slin wang - Sun Microsystems - Beijing China if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) || 777*dd1de374Slin wang - Sun Microsystems - Beijing China ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) { 778*dd1de374Slin wang - Sun Microsystems - Beijing China struct ar5416AniState *aniState = ahp->ah_curani; 779*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t ofdmPhyErrCnt, cckPhyErrCnt; 780*dd1de374Slin wang - Sun Microsystems - Beijing China 781*dd1de374Slin wang - Sun Microsystems - Beijing China /* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */ 782*dd1de374Slin wang - Sun Microsystems - Beijing China ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase; 783*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_stats.ast_ani_ofdmerrs += 784*dd1de374Slin wang - Sun Microsystems - Beijing China ofdmPhyErrCnt - aniState->ofdmPhyErrCount; 785*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->ofdmPhyErrCount = ofdmPhyErrCnt; 786*dd1de374Slin wang - Sun Microsystems - Beijing China 787*dd1de374Slin wang - Sun Microsystems - Beijing China cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase; 788*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_stats.ast_ani_cckerrs += 789*dd1de374Slin wang - Sun Microsystems - Beijing China cckPhyErrCnt - aniState->cckPhyErrCount; 790*dd1de374Slin wang - Sun Microsystems - Beijing China aniState->cckPhyErrCount = cckPhyErrCnt; 791*dd1de374Slin wang - Sun Microsystems - Beijing China 792*dd1de374Slin wang - Sun Microsystems - Beijing China /* 793*dd1de374Slin wang - Sun Microsystems - Beijing China * NB: figure out which counter triggered. If both 794*dd1de374Slin wang - Sun Microsystems - Beijing China * trigger we'll only deal with one as the processing 795*dd1de374Slin wang - Sun Microsystems - Beijing China * clobbers the error counter so the trigger threshold 796*dd1de374Slin wang - Sun Microsystems - Beijing China * check will never be true. 797*dd1de374Slin wang - Sun Microsystems - Beijing China */ 798*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh) 799*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_ani_ofdm_err_trigger(ah); 800*dd1de374Slin wang - Sun Microsystems - Beijing China if (aniState->cckPhyErrCount > aniState->cckTrigHigh) 801*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_ani_cck_err_trigger(ah); 802*dd1de374Slin wang - Sun Microsystems - Beijing China /* NB: always restart to insure the h/w counters are reset */ 803*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_ani_restart(ah); 804*dd1de374Slin wang - Sun Microsystems - Beijing China } 805*dd1de374Slin wang - Sun Microsystems - Beijing China } 806*dd1de374Slin wang - Sun Microsystems - Beijing China 807*dd1de374Slin wang - Sun Microsystems - Beijing China void 808*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_ani_setup(struct ath_hal *ah) 809*dd1de374Slin wang - Sun Microsystems - Beijing China { 810*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal_5416 *ahp = AH5416(ah); 811*dd1de374Slin wang - Sun Microsystems - Beijing China int i; 812*dd1de374Slin wang - Sun Microsystems - Beijing China 813*dd1de374Slin wang - Sun Microsystems - Beijing China const int totalSizeDesired[] = { -55, -55, -55, -55, -62 }; 814*dd1de374Slin wang - Sun Microsystems - Beijing China const int coarseHigh[] = { -14, -14, -14, -14, -12 }; 815*dd1de374Slin wang - Sun Microsystems - Beijing China const int coarseLow[] = { -64, -64, -64, -64, -70 }; 816*dd1de374Slin wang - Sun Microsystems - Beijing China const int firpwr[] = { -78, -78, -78, -78, -80 }; 817*dd1de374Slin wang - Sun Microsystems - Beijing China 818*dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < 5; i++) { 819*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_totalSizeDesired[i] = totalSizeDesired[i]; 820*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_coarseHigh[i] = coarseHigh[i]; 821*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_coarseLow[i] = coarseLow[i]; 822*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_firpwr[i] = firpwr[i]; 823*dd1de374Slin wang - Sun Microsystems - Beijing China } 824*dd1de374Slin wang - Sun Microsystems - Beijing China } 825*dd1de374Slin wang - Sun Microsystems - Beijing China 826*dd1de374Slin wang - Sun Microsystems - Beijing China void 827*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_ani_attach(struct ath_hal *ah) 828*dd1de374Slin wang - Sun Microsystems - Beijing China { 829*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal_5416 *ahp = AH5416(ah); 830*dd1de374Slin wang - Sun Microsystems - Beijing China int i; 831*dd1de374Slin wang - Sun Microsystems - Beijing China 832*dd1de374Slin wang - Sun Microsystems - Beijing China /* For Lint Reasons */ 833*dd1de374Slin wang - Sun Microsystems - Beijing China boolean_t ANI_USE_OFDM_WEAK_SIG = ATH9K_ANI_USE_OFDM_WEAK_SIG; 834*dd1de374Slin wang - Sun Microsystems - Beijing China 835*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_ANI, "arn: ath9k_hw_ani_attach(): " 836*dd1de374Slin wang - Sun Microsystems - Beijing China "Attach ANI\n")); 837*dd1de374Slin wang - Sun Microsystems - Beijing China 838*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_hasHwPhyCounters = 1; 839*dd1de374Slin wang - Sun Microsystems - Beijing China 840*dd1de374Slin wang - Sun Microsystems - Beijing China (void) memset(ahp->ah_ani, 0, sizeof (ahp->ah_ani)); 841*dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < ARRAY_SIZE(ahp->ah_ani); i++) { 842*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH; 843*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW; 844*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH; 845*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW; 846*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH; 847*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW; 848*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_ani[i].ofdmWeakSigDetectOff = 849*dd1de374Slin wang - Sun Microsystems - Beijing China !ANI_USE_OFDM_WEAK_SIG /* !ATH9K_ANI_USE_OFDM_WEAK_SIG */; 850*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_ani[i].cckWeakSigThreshold = 851*dd1de374Slin wang - Sun Microsystems - Beijing China ATH9K_ANI_CCK_WEAK_SIG_THR; 852*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL; 853*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL; 854*dd1de374Slin wang - Sun Microsystems - Beijing China if (ahp->ah_hasHwPhyCounters) { 855*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_ani[i].ofdmPhyErrBase = 856*dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH; 857*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_ani[i].cckPhyErrBase = 858*dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH; 859*dd1de374Slin wang - Sun Microsystems - Beijing China } 860*dd1de374Slin wang - Sun Microsystems - Beijing China } 861*dd1de374Slin wang - Sun Microsystems - Beijing China if (ahp->ah_hasHwPhyCounters) { 862*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_ANI, "arn: ath9k_hw_ani_attach(): " 863*dd1de374Slin wang - Sun Microsystems - Beijing China "Setting OfdmErrBase = 0x%08x\n", 864*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_ani[0].ofdmPhyErrBase)); 865*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_ANI, "arn: ath9k_hw_ani_attach(): " 866*dd1de374Slin wang - Sun Microsystems - Beijing China "Setting cckErrBase = 0x%08x\n", 867*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_ani[0].cckPhyErrBase)); 868*dd1de374Slin wang - Sun Microsystems - Beijing China 869*dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_PHY_ERR_1, ahp->ah_ani[0].ofdmPhyErrBase); 870*dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_PHY_ERR_2, ahp->ah_ani[0].cckPhyErrBase); 871*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_enable_mib_counters(ah); 872*dd1de374Slin wang - Sun Microsystems - Beijing China } 873*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_aniPeriod = ATH9K_ANI_PERIOD; 874*dd1de374Slin wang - Sun Microsystems - Beijing China if (ah->ah_config.enable_ani) 875*dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_procPhyErr |= HAL_PROCESS_ANI; 876*dd1de374Slin wang - Sun Microsystems - Beijing China } 877*dd1de374Slin wang - Sun Microsystems - Beijing China 878*dd1de374Slin wang - Sun Microsystems - Beijing China void 879*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_ani_detach(struct ath_hal *ah) 880*dd1de374Slin wang - Sun Microsystems - Beijing China { 881*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal_5416 *ahp = AH5416(ah); 882*dd1de374Slin wang - Sun Microsystems - Beijing China 883*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_ANI, "arn: ath9k_hw_ani_detach(): " 884*dd1de374Slin wang - Sun Microsystems - Beijing China "Detach ANI\n")); 885*dd1de374Slin wang - Sun Microsystems - Beijing China 886*dd1de374Slin wang - Sun Microsystems - Beijing China if (ahp->ah_hasHwPhyCounters) { 887*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_disable_mib_counters(ah); 888*dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_PHY_ERR_1, 0); 889*dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_PHY_ERR_2, 0); 890*dd1de374Slin wang - Sun Microsystems - Beijing China } 891*dd1de374Slin wang - Sun Microsystems - Beijing China } 892