This change moves the Automatic Noise Immunity code from ath9k into the common atheros module. This will enable ath5k and potentially other Atheros modules to re-use the ANI code.
The patch introduces a new callback to the ath_ops structure for setting the phy error flag in the RX filter since the filter details are slightly different between different parts. Signed-off-by: Bob Copeland <m...@bobcopeland.com> --- drivers/net/wireless/ath/Makefile | 3 +- drivers/net/wireless/ath/{ath9k => }/ani.c | 423 ++++++++++++++-------------- drivers/net/wireless/ath/ani.h | 57 ++++ drivers/net/wireless/ath/ath.h | 89 ++++++- drivers/net/wireless/ath/ath9k/Makefile | 1 - drivers/net/wireless/ath/ath9k/ani.h | 123 -------- drivers/net/wireless/ath/ath9k/common.c | 3 +- drivers/net/wireless/ath/ath9k/hw.c | 25 ++- drivers/net/wireless/ath/ath9k/hw.h | 15 +- drivers/net/wireless/ath/ath9k/mac.c | 6 +- drivers/net/wireless/ath/ath9k/main.c | 7 +- drivers/net/wireless/ath/reg.h | 134 +++++++++ 12 files changed, 525 insertions(+), 361 deletions(-) rename drivers/net/wireless/ath/{ath9k => }/ani.c (63%) create mode 100644 drivers/net/wireless/ath/ani.h delete mode 100644 drivers/net/wireless/ath/ath9k/ani.h diff --git a/drivers/net/wireless/ath/Makefile b/drivers/net/wireless/ath/Makefile index 8113a50..cbd51a3 100644 --- a/drivers/net/wireless/ath/Makefile +++ b/drivers/net/wireless/ath/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_ATH_COMMON) += ath.o ath-objs := main.o \ regd.o \ - hw.o + hw.o \ + ani.o ath-$(CONFIG_ATH_DEBUG) += debug.o diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ani.c similarity index 63% rename from drivers/net/wireless/ath/ath9k/ani.c rename to drivers/net/wireless/ath/ani.c index e5117fe..c2a09fe 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ani.c @@ -15,67 +15,70 @@ */ #include "hw.h" +#include "reg.h" +#include "ani.h" +#include "debug.h" -static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah, - struct ath9k_channel *chan) +static int ath_hw_get_ani_channel_idx(struct ath_common *common, + struct ieee80211_channel *chan) { int i; - for (i = 0; i < ARRAY_SIZE(ah->ani); i++) { - if (ah->ani[i].c && - ah->ani[i].c->channel == chan->channel) + for (i = 0; i < ARRAY_SIZE(common->ani.ani); i++) { + if (common->ani.ani[i].channel && + common->ani.ani[i].channel->hw_value == chan->hw_value) return i; - if (ah->ani[i].c == NULL) { - ah->ani[i].c = chan; + if (common->ani.ani[i].channel == NULL) { + common->ani.ani[i].channel = chan; return i; } } - ath_print(ath9k_hw_common(ah), ATH_DBG_ANI, + ath_print(common, ATH_DBG_ANI, "No more channel states left. Using channel 0\n"); return 0; } -static bool ath9k_hw_ani_control(struct ath_hw *ah, - enum ath9k_ani_cmd cmd, int param) +static bool ath_hw_ani_control(struct ath_common *common, + enum ath_ani_cmd cmd, int param) { - struct ar5416AniState *aniState = ah->curani; - struct ath_common *common = ath9k_hw_common(ah); + void *ah = common->ah; + struct ar5416AniState *aniState = common->ani.curani; - switch (cmd & ah->ani_function) { - case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{ + switch (cmd & common->ani.ani_function) { + case ATH_ANI_NOISE_IMMUNITY_LEVEL:{ u32 level = param; - if (level >= ARRAY_SIZE(ah->totalSizeDesired)) { + if (level >= ARRAY_SIZE(common->ani.totalSizeDesired)) { ath_print(common, ATH_DBG_ANI, "level out of range (%u > %u)\n", level, - (unsigned)ARRAY_SIZE(ah->totalSizeDesired)); + (unsigned)ARRAY_SIZE(common->ani.totalSizeDesired)); return false; } REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_TOT_DES, - ah->totalSizeDesired[level]); + common->ani.totalSizeDesired[level]); REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1, AR_PHY_AGC_CTL1_COARSE_LOW, - ah->coarse_low[level]); + common->ani.coarse_low[level]); REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1, AR_PHY_AGC_CTL1_COARSE_HIGH, - ah->coarse_high[level]); + common->ani.coarse_high[level]); REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_FIRPWR, - ah->firpwr[level]); + common->ani.firpwr[level]); if (level > aniState->noiseImmunityLevel) - ah->stats.ast_ani_niup++; + common->ani.stats.ast_ani_niup++; else if (level < aniState->noiseImmunityLevel) - ah->stats.ast_ani_nidown++; + common->ani.stats.ast_ani_nidown++; aniState->noiseImmunityLevel = level; break; } - case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{ + case ATH_ANI_OFDM_WEAK_SIGNAL_DETECTION:{ const int m1ThreshLow[] = { 127, 50 }; const int m2ThreshLow[] = { 127, 40 }; const int m1Thresh[] = { 127, 0x4d }; @@ -103,6 +106,7 @@ static bool ath9k_hw_ani_control(struct ath_hw *ah, AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, m2CountThrLow[on]); + /* FIXME not ath5k? */ REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLow[on]); @@ -125,14 +129,14 @@ static bool ath9k_hw_ani_control(struct ath_hw *ah, if (!on != aniState->ofdmWeakSigDetectOff) { if (on) - ah->stats.ast_ani_ofdmon++; + common->ani.stats.ast_ani_ofdmon++; else - ah->stats.ast_ani_ofdmoff++; + common->ani.stats.ast_ani_ofdmoff++; aniState->ofdmWeakSigDetectOff = !on; } break; } - case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{ + case ATH_ANI_CCK_WEAK_SIGNAL_THR:{ const int weakSigThrCck[] = { 8, 6 }; u32 high = param ? 1 : 0; @@ -141,14 +145,14 @@ static bool ath9k_hw_ani_control(struct ath_hw *ah, weakSigThrCck[high]); if (high != aniState->cckWeakSigThreshold) { if (high) - ah->stats.ast_ani_cckhigh++; + common->ani.stats.ast_ani_cckhigh++; else - ah->stats.ast_ani_ccklow++; + common->ani.stats.ast_ani_ccklow++; aniState->cckWeakSigThreshold = high; } break; } - case ATH9K_ANI_FIRSTEP_LEVEL:{ + case ATH_ANI_FIRSTEP_LEVEL:{ const int firstep[] = { 0, 4, 8 }; u32 level = param; @@ -163,13 +167,13 @@ static bool ath9k_hw_ani_control(struct ath_hw *ah, AR_PHY_FIND_SIG_FIRSTEP, firstep[level]); if (level > aniState->firstepLevel) - ah->stats.ast_ani_stepup++; + common->ani.stats.ast_ani_stepup++; else if (level < aniState->firstepLevel) - ah->stats.ast_ani_stepdown++; + common->ani.stats.ast_ani_stepdown++; aniState->firstepLevel = level; break; } - case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{ + case ATH_ANI_SPUR_IMMUNITY_LEVEL:{ const int cycpwrThr1[] = { 2, 4, 6, 8, 10, 12, 14, 16 }; u32 level = param; @@ -185,13 +189,13 @@ static bool ath9k_hw_ani_control(struct ath_hw *ah, AR_PHY_TIMING5_CYCPWR_THR1, cycpwrThr1[level]); if (level > aniState->spurImmunityLevel) - ah->stats.ast_ani_spurup++; + common->ani.stats.ast_ani_spurup++; else if (level < aniState->spurImmunityLevel) - ah->stats.ast_ani_spurdown++; + common->ani.stats.ast_ani_spurdown++; aniState->spurImmunityLevel = level; break; } - case ATH9K_ANI_PRESENT: + case ATH_ANI_PRESENT: break; default: ath_print(common, ATH_DBG_ANI, @@ -221,9 +225,11 @@ static bool ath9k_hw_ani_control(struct ath_hw *ah, return true; } -static void ath9k_hw_update_mibstats(struct ath_hw *ah, - struct ath9k_mib_stats *stats) +static void ath_hw_update_mibstats(struct ath_common *common, + struct ath_mib_stats *stats) { + void *ah = common->ah; + stats->ackrcv_bad += REG_READ(ah, AR_ACK_FAIL); stats->rts_bad += REG_READ(ah, AR_RTS_FAIL); stats->fcs_bad += REG_READ(ah, AR_FCS_FAIL); @@ -231,15 +237,15 @@ static void ath9k_hw_update_mibstats(struct ath_hw *ah, stats->beacons += REG_READ(ah, AR_BEACON_CNT); } -static void ath9k_ani_restart(struct ath_hw *ah) +static void ath_ani_restart(struct ath_common *common) { + void *ah = common->ah; struct ar5416AniState *aniState; - struct ath_common *common = ath9k_hw_common(ah); - if (!DO_ANI(ah)) + if (!DO_ANI(common)) return; - aniState = ah->curani; + aniState = common->ani.curani; aniState->listenTime = 0; if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) { @@ -267,33 +273,32 @@ static void ath9k_ani_restart(struct ath_hw *ah) REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); - ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); + ath_hw_update_mibstats(common, &common->mib_stats); aniState->ofdmPhyErrCount = 0; aniState->cckPhyErrCount = 0; } -static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah) +static void ath_hw_ani_ofdm_err_trigger(struct ath_common *common) { - struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; - struct ath_common *common = ath9k_hw_common(ah); + struct ieee80211_conf *conf = &common->hw->conf; struct ar5416AniState *aniState; int32_t rssi; - if (!DO_ANI(ah)) + if (!DO_ANI(common)) return; - aniState = ah->curani; + aniState = common->ani.curani; if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) { - if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, + if (ath_hw_ani_control(common, ATH_ANI_NOISE_IMMUNITY_LEVEL, aniState->noiseImmunityLevel + 1)) { return; } } if (aniState->spurImmunityLevel < HAL_SPUR_IMMUNE_MAX) { - if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, + if (ath_hw_ani_control(common, ATH_ANI_SPUR_IMMUNITY_LEVEL, aniState->spurImmunityLevel + 1)) { return; } @@ -301,125 +306,123 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah) if (common->opmode == NL80211_IFTYPE_AP) { if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) { - ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, + ath_hw_ani_control(common, ATH_ANI_FIRSTEP_LEVEL, aniState->firstepLevel + 1); } return; } - rssi = BEACON_RSSI(ah); + rssi = BEACON_RSSI(common); if (rssi > aniState->rssiThrHigh) { if (!aniState->ofdmWeakSigDetectOff) { - if (ath9k_hw_ani_control(ah, - ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, + if (ath_hw_ani_control(common, + ATH_ANI_OFDM_WEAK_SIGNAL_DETECTION, false)) { - ath9k_hw_ani_control(ah, - ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0); + ath_hw_ani_control(common, + ATH_ANI_SPUR_IMMUNITY_LEVEL, 0); return; } } if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) { - ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, + ath_hw_ani_control(common, ATH_ANI_FIRSTEP_LEVEL, aniState->firstepLevel + 1); return; } } else if (rssi > aniState->rssiThrLow) { if (aniState->ofdmWeakSigDetectOff) - ath9k_hw_ani_control(ah, - ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, + ath_hw_ani_control(common, + ATH_ANI_OFDM_WEAK_SIGNAL_DETECTION, true); if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) - ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, + ath_hw_ani_control(common, ATH_ANI_FIRSTEP_LEVEL, aniState->firstepLevel + 1); return; } else { if ((conf->channel->band == IEEE80211_BAND_2GHZ) && !conf_is_ht(conf)) { if (!aniState->ofdmWeakSigDetectOff) - ath9k_hw_ani_control(ah, - ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, + ath_hw_ani_control(common, + ATH_ANI_OFDM_WEAK_SIGNAL_DETECTION, false); if (aniState->firstepLevel > 0) - ath9k_hw_ani_control(ah, - ATH9K_ANI_FIRSTEP_LEVEL, 0); + ath_hw_ani_control(common, + ATH_ANI_FIRSTEP_LEVEL, 0); return; } } } -static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah) +static void ath_hw_ani_cck_err_trigger(struct ath_common *common) { - struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; - struct ath_common *common = ath9k_hw_common(ah); + struct ieee80211_conf *conf = &common->hw->conf; struct ar5416AniState *aniState; int32_t rssi; - if (!DO_ANI(ah)) + if (!DO_ANI(common)) return; - aniState = ah->curani; + aniState = common->ani.curani; if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) { - if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, + if (ath_hw_ani_control(common, ATH_ANI_NOISE_IMMUNITY_LEVEL, aniState->noiseImmunityLevel + 1)) { return; } } if (common->opmode == NL80211_IFTYPE_AP) { if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) { - ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, + ath_hw_ani_control(common, ATH_ANI_FIRSTEP_LEVEL, aniState->firstepLevel + 1); } return; } - rssi = BEACON_RSSI(ah); + rssi = BEACON_RSSI(common); if (rssi > aniState->rssiThrLow) { if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) - ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, + ath_hw_ani_control(common, ATH_ANI_FIRSTEP_LEVEL, aniState->firstepLevel + 1); } else { if ((conf->channel->band == IEEE80211_BAND_2GHZ) && !conf_is_ht(conf)) { if (aniState->firstepLevel > 0) - ath9k_hw_ani_control(ah, - ATH9K_ANI_FIRSTEP_LEVEL, 0); + ath_hw_ani_control(common, + ATH_ANI_FIRSTEP_LEVEL, 0); } } } -static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah) +static void ath_hw_ani_lower_immunity(struct ath_common *common) { struct ar5416AniState *aniState; int32_t rssi; - struct ath_common *common = ath9k_hw_common(ah); - aniState = ah->curani; + aniState = common->ani.curani; if (common->opmode == NL80211_IFTYPE_AP) { if (aniState->firstepLevel > 0) { - if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, + if (ath_hw_ani_control(common, ATH_ANI_FIRSTEP_LEVEL, aniState->firstepLevel - 1)) return; } } else { - rssi = BEACON_RSSI(ah); + rssi = BEACON_RSSI(common); if (rssi > aniState->rssiThrHigh) { /* XXX: Handle me */ } else if (rssi > aniState->rssiThrLow) { if (aniState->ofdmWeakSigDetectOff) { - if (ath9k_hw_ani_control(ah, - ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, + if (ath_hw_ani_control(common, + ATH_ANI_OFDM_WEAK_SIGNAL_DETECTION, true) == true) return; } if (aniState->firstepLevel > 0) { - if (ath9k_hw_ani_control(ah, - ATH9K_ANI_FIRSTEP_LEVEL, + if (ath_hw_ani_control(common, + ATH_ANI_FIRSTEP_LEVEL, aniState->firstepLevel - 1) == true) return; } } else { if (aniState->firstepLevel > 0) { - if (ath9k_hw_ani_control(ah, - ATH9K_ANI_FIRSTEP_LEVEL, + if (ath_hw_ani_control(common, + ATH_ANI_FIRSTEP_LEVEL, aniState->firstepLevel - 1) == true) return; } @@ -427,20 +430,22 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah) } if (aniState->spurImmunityLevel > 0) { - if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, + if (ath_hw_ani_control(common, ATH_ANI_SPUR_IMMUNITY_LEVEL, aniState->spurImmunityLevel - 1)) return; } if (aniState->noiseImmunityLevel > 0) { - ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, + ath_hw_ani_control(common, ATH_ANI_NOISE_IMMUNITY_LEVEL, aniState->noiseImmunityLevel - 1); return; } } -static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah) +static int32_t ath_hw_ani_get_listen_time(struct ath_common *common) { + void *ah = common->ah; + struct ar5416AniState *aniState; u32 txFrameCount, rxFrameCount, cycleCount; int32_t listenTime; @@ -449,11 +454,11 @@ static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah) rxFrameCount = REG_READ(ah, AR_RFCNT); cycleCount = REG_READ(ah, AR_CCCNT); - aniState = ah->curani; + aniState = common->ani.curani; if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) { listenTime = 0; - ah->stats.ast_ani_lzero++; + common->ani.stats.ast_ani_lzero++; } else { int32_t ccdelta = cycleCount - aniState->cycleCount; int32_t rfdelta = rxFrameCount - aniState->rxFrameCount; @@ -467,110 +472,110 @@ static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah) return listenTime; } -void ath9k_ani_reset(struct ath_hw *ah) +void ath_ani_reset(struct ath_common *common, + struct ieee80211_channel *curchan) { + void *ah = common->ah; + struct ar5416AniState *aniState; - struct ath9k_channel *chan = ah->curchan; - struct ath_common *common = ath9k_hw_common(ah); int index; - if (!DO_ANI(ah)) + if (!DO_ANI(common)) return; - index = ath9k_hw_get_ani_channel_idx(ah, chan); - aniState = &ah->ani[index]; - ah->curani = aniState; + index = ath_hw_get_ani_channel_idx(common, curchan); + aniState = &common->ani.ani[index]; + common->ani.curani = aniState; - if (DO_ANI(ah) && common->opmode != NL80211_IFTYPE_STATION + if (DO_ANI(common) && common->opmode != NL80211_IFTYPE_STATION && common->opmode != NL80211_IFTYPE_ADHOC) { ath_print(common, ATH_DBG_ANI, "Reset ANI state opmode %u\n", common->opmode); - ah->stats.ast_ani_reset++; + common->ani.stats.ast_ani_reset++; if (common->opmode == NL80211_IFTYPE_AP) { /* - * ath9k_hw_ani_control() will only process items set on - * ah->ani_function + * ath_hw_ani_control() will only process items set on + * common->ani.ani_function */ - if (IS_CHAN_2GHZ(chan)) - ah->ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL | - ATH9K_ANI_FIRSTEP_LEVEL); + if (curchan->band == IEEE80211_BAND_2GHZ) + common->ani.ani_function = (ATH_ANI_SPUR_IMMUNITY_LEVEL | + ATH_ANI_FIRSTEP_LEVEL); else - ah->ani_function = 0; + common->ani.ani_function = 0; } - ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0); - ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0); - ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0); - ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, - !ATH9K_ANI_USE_OFDM_WEAK_SIG); - ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR, - ATH9K_ANI_CCK_WEAK_SIG_THR); + ath_hw_ani_control(common, ATH_ANI_NOISE_IMMUNITY_LEVEL, 0); + ath_hw_ani_control(common, ATH_ANI_SPUR_IMMUNITY_LEVEL, 0); + ath_hw_ani_control(common, ATH_ANI_FIRSTEP_LEVEL, 0); + ath_hw_ani_control(common, ATH_ANI_OFDM_WEAK_SIGNAL_DETECTION, + !ATH_ANI_USE_OFDM_WEAK_SIG); + ath_hw_ani_control(common, ATH_ANI_CCK_WEAK_SIGNAL_THR, + ATH_ANI_CCK_WEAK_SIG_THR); - ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) | - ATH9K_RX_FILTER_PHYERR); + common->ops->setrxfilter_phy_err(common->ah, true); if (common->opmode == NL80211_IFTYPE_AP) { - ah->curani->ofdmTrigHigh = - ah->config.ofdm_trig_high; - ah->curani->ofdmTrigLow = - ah->config.ofdm_trig_low; - ah->curani->cckTrigHigh = - ah->config.cck_trig_high; - ah->curani->cckTrigLow = - ah->config.cck_trig_low; + common->ani.curani->ofdmTrigHigh = + ATH_ANI_OFDM_TRIG_HIGH; + common->ani.curani->ofdmTrigLow = + ATH_ANI_OFDM_TRIG_LOW; + common->ani.curani->cckTrigHigh = + ATH_ANI_CCK_TRIG_HIGH; + common->ani.curani->cckTrigLow = + ATH_ANI_OFDM_TRIG_LOW; } - ath9k_ani_restart(ah); + ath_ani_restart(common); return; } if (aniState->noiseImmunityLevel != 0) - ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, + ath_hw_ani_control(common, ATH_ANI_NOISE_IMMUNITY_LEVEL, aniState->noiseImmunityLevel); if (aniState->spurImmunityLevel != 0) - ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, + ath_hw_ani_control(common, ATH_ANI_SPUR_IMMUNITY_LEVEL, aniState->spurImmunityLevel); if (aniState->ofdmWeakSigDetectOff) - ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, + ath_hw_ani_control(common, ATH_ANI_OFDM_WEAK_SIGNAL_DETECTION, !aniState->ofdmWeakSigDetectOff); if (aniState->cckWeakSigThreshold) - ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR, + ath_hw_ani_control(common, ATH_ANI_CCK_WEAK_SIGNAL_THR, aniState->cckWeakSigThreshold); if (aniState->firstepLevel != 0) - ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, + ath_hw_ani_control(common, ATH_ANI_FIRSTEP_LEVEL, aniState->firstepLevel); - ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) & - ~ATH9K_RX_FILTER_PHYERR); - ath9k_ani_restart(ah); + common->ops->setrxfilter_phy_err(common->ah, false); + ath_ani_restart(common); REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); } +EXPORT_SYMBOL(ath_ani_reset); -void ath9k_hw_ani_monitor(struct ath_hw *ah, - struct ath9k_channel *chan) +void ath_hw_ani_monitor(struct ath_common *common) { + void *ah = common->ah; + struct ar5416AniState *aniState; - struct ath_common *common = ath9k_hw_common(ah); int32_t listenTime; u32 phyCnt1, phyCnt2; u32 ofdmPhyErrCnt, cckPhyErrCnt; - if (!DO_ANI(ah)) + if (!DO_ANI(common)) return; - aniState = ah->curani; + aniState = common->ani.curani; - listenTime = ath9k_hw_ani_get_listen_time(ah); + listenTime = ath_hw_ani_get_listen_time(common); if (listenTime < 0) { - ah->stats.ast_ani_lneg++; - ath9k_ani_restart(ah); + common->ani.stats.ast_ani_lneg++; + ath_ani_restart(common); return; } aniState->listenTime += listenTime; - ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); + ath_hw_update_mibstats(common, &common->mib_stats); phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); @@ -603,44 +608,44 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, } ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase; - ah->stats.ast_ani_ofdmerrs += + common->ani.stats.ast_ani_ofdmerrs += ofdmPhyErrCnt - aniState->ofdmPhyErrCount; aniState->ofdmPhyErrCount = ofdmPhyErrCnt; cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase; - ah->stats.ast_ani_cckerrs += + common->ani.stats.ast_ani_cckerrs += cckPhyErrCnt - aniState->cckPhyErrCount; aniState->cckPhyErrCount = cckPhyErrCnt; - if (aniState->listenTime > 5 * ah->aniperiod) { + if (aniState->listenTime > 5 * common->ani.aniperiod) { if (aniState->ofdmPhyErrCount <= aniState->listenTime * aniState->ofdmTrigLow / 1000 && aniState->cckPhyErrCount <= aniState->listenTime * aniState->cckTrigLow / 1000) - ath9k_hw_ani_lower_immunity(ah); - ath9k_ani_restart(ah); - } else if (aniState->listenTime > ah->aniperiod) { + ath_hw_ani_lower_immunity(common); + ath_ani_restart(common); + } else if (aniState->listenTime > common->ani.aniperiod) { if (aniState->ofdmPhyErrCount > aniState->listenTime * aniState->ofdmTrigHigh / 1000) { - ath9k_hw_ani_ofdm_err_trigger(ah); - ath9k_ani_restart(ah); + ath_hw_ani_ofdm_err_trigger(common); + ath_ani_restart(common); } else if (aniState->cckPhyErrCount > aniState->listenTime * aniState->cckTrigHigh / 1000) { - ath9k_hw_ani_cck_err_trigger(ah); - ath9k_ani_restart(ah); + ath_hw_ani_cck_err_trigger(common); + ath_ani_restart(common); } } } -EXPORT_SYMBOL(ath9k_hw_ani_monitor); +EXPORT_SYMBOL(ath_hw_ani_monitor); -void ath9k_enable_mib_counters(struct ath_hw *ah) +void ath_enable_mib_counters(struct ath_common *common) { - struct ath_common *common = ath9k_hw_common(ah); + void *ah = common->ah; ath_print(common, ATH_DBG_ANI, "Enable MIB counters\n"); - ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); + ath_hw_update_mibstats(common, &common->mib_stats); REG_WRITE(ah, AR_FILT_OFDM, 0); REG_WRITE(ah, AR_FILT_CCK, 0); @@ -650,27 +655,29 @@ void ath9k_enable_mib_counters(struct ath_hw *ah) REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); } +EXPORT_SYMBOL(ath_enable_mib_counters); /* Freeze the MIB counters, get the stats and then clear them */ -void ath9k_hw_disable_mib_counters(struct ath_hw *ah) +void ath_hw_disable_mib_counters(struct ath_common *common) { - struct ath_common *common = ath9k_hw_common(ah); + void *ah = common->ah; ath_print(common, ATH_DBG_ANI, "Disable MIB counters\n"); REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC); - ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); + ath_hw_update_mibstats(common, &common->mib_stats); REG_WRITE(ah, AR_MIBC, AR_MIBC_CMC); REG_WRITE(ah, AR_FILT_OFDM, 0); REG_WRITE(ah, AR_FILT_CCK, 0); } +EXPORT_SYMBOL(ath_hw_disable_mib_counters); -u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, +u32 ath_hw_GetMibCycleCountsPct(struct ath_common *common, u32 *rxc_pcnt, u32 *rxf_pcnt, u32 *txf_pcnt) { - struct ath_common *common = ath9k_hw_common(ah); + void *ah = common->ah; static u32 cycles, rx_clear, rx_frame, tx_frame; u32 good = 1; @@ -711,8 +718,10 @@ u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, * any of the MIB counters overflow/trigger so don't assume we're * here because a PHY error counter triggered. */ -void ath9k_hw_procmibevent(struct ath_hw *ah) +void ath_hw_procmibevent(struct ath_common *common) { + void *ah = common->ah; + u32 phyCnt1, phyCnt2; /* Reset these counters regardless */ @@ -722,9 +731,9 @@ void ath9k_hw_procmibevent(struct ath_hw *ah) REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR); /* Clear the mib counters and save them in the stats */ - ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); + ath_hw_update_mibstats(common, &common->mib_stats); - if (!DO_ANI(ah)) + if (!DO_ANI(common)) return; /* NB: these are not reset-on-read */ @@ -732,17 +741,17 @@ void ath9k_hw_procmibevent(struct ath_hw *ah) phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) || ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) { - struct ar5416AniState *aniState = ah->curani; + struct ar5416AniState *aniState = common->ani.curani; u32 ofdmPhyErrCnt, cckPhyErrCnt; /* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */ ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase; - ah->stats.ast_ani_ofdmerrs += + common->ani.stats.ast_ani_ofdmerrs += ofdmPhyErrCnt - aniState->ofdmPhyErrCount; aniState->ofdmPhyErrCount = ofdmPhyErrCnt; cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase; - ah->stats.ast_ani_cckerrs += + common->ani.stats.ast_ani_cckerrs += cckPhyErrCnt - aniState->cckPhyErrCount; aniState->cckPhyErrCount = cckPhyErrCnt; @@ -753,16 +762,16 @@ void ath9k_hw_procmibevent(struct ath_hw *ah) * check will never be true. */ if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh) - ath9k_hw_ani_ofdm_err_trigger(ah); + ath_hw_ani_ofdm_err_trigger(common); if (aniState->cckPhyErrCount > aniState->cckTrigHigh) - ath9k_hw_ani_cck_err_trigger(ah); + ath_hw_ani_cck_err_trigger(common); /* NB: always restart to insure the h/w counters are reset */ - ath9k_ani_restart(ah); + ath_ani_restart(common); } } -EXPORT_SYMBOL(ath9k_hw_procmibevent); +EXPORT_SYMBOL(ath_hw_procmibevent); -void ath9k_hw_ani_setup(struct ath_hw *ah) +void ath_hw_ani_setup(struct ath_common *common) { int i; @@ -772,60 +781,64 @@ void ath9k_hw_ani_setup(struct ath_hw *ah) const int firpwr[] = { -78, -78, -78, -78, -80 }; for (i = 0; i < 5; i++) { - ah->totalSizeDesired[i] = totalSizeDesired[i]; - ah->coarse_high[i] = coarseHigh[i]; - ah->coarse_low[i] = coarseLow[i]; - ah->firpwr[i] = firpwr[i]; + common->ani.totalSizeDesired[i] = totalSizeDesired[i]; + common->ani.coarse_high[i] = coarseHigh[i]; + common->ani.coarse_low[i] = coarseLow[i]; + common->ani.firpwr[i] = firpwr[i]; } } +EXPORT_SYMBOL(ath_hw_ani_setup); -void ath9k_hw_ani_init(struct ath_hw *ah) +void ath_hw_ani_init(struct ath_common *common) { - struct ath_common *common = ath9k_hw_common(ah); + void *ah = common->ah; int i; ath_print(common, ATH_DBG_ANI, "Initialize ANI\n"); - memset(ah->ani, 0, sizeof(ah->ani)); - for (i = 0; i < ARRAY_SIZE(ah->ani); i++) { - ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH; - ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW; - ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH; - ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW; - ah->ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH; - ah->ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW; - ah->ani[i].ofdmWeakSigDetectOff = - !ATH9K_ANI_USE_OFDM_WEAK_SIG; - ah->ani[i].cckWeakSigThreshold = - ATH9K_ANI_CCK_WEAK_SIG_THR; - ah->ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL; - ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL; - ah->ani[i].ofdmPhyErrBase = - AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH; - ah->ani[i].cckPhyErrBase = - AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH; + memset(common->ani.ani, 0, sizeof(common->ani.ani)); + for (i = 0; i < ARRAY_SIZE(common->ani.ani); i++) { + common->ani.ani[i].ofdmTrigHigh = ATH_ANI_OFDM_TRIG_HIGH; + common->ani.ani[i].ofdmTrigLow = ATH_ANI_OFDM_TRIG_LOW; + common->ani.ani[i].cckTrigHigh = ATH_ANI_CCK_TRIG_HIGH; + common->ani.ani[i].cckTrigLow = ATH_ANI_CCK_TRIG_LOW; + common->ani.ani[i].rssiThrHigh = ATH_ANI_RSSI_THR_HIGH; + common->ani.ani[i].rssiThrLow = ATH_ANI_RSSI_THR_LOW; + common->ani.ani[i].ofdmWeakSigDetectOff = + !ATH_ANI_USE_OFDM_WEAK_SIG; + common->ani.ani[i].cckWeakSigThreshold = + ATH_ANI_CCK_WEAK_SIG_THR; + common->ani.ani[i].spurImmunityLevel = ATH_ANI_SPUR_IMMUNE_LVL; + common->ani.ani[i].firstepLevel = ATH_ANI_FIRSTEP_LVL; + common->ani.ani[i].ofdmPhyErrBase = + AR_PHY_COUNTMAX - ATH_ANI_OFDM_TRIG_HIGH; + common->ani.ani[i].cckPhyErrBase = + AR_PHY_COUNTMAX - ATH_ANI_CCK_TRIG_HIGH; } ath_print(common, ATH_DBG_ANI, "Setting OfdmErrBase = 0x%08x\n", - ah->ani[0].ofdmPhyErrBase); + common->ani.ani[0].ofdmPhyErrBase); ath_print(common, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n", - ah->ani[0].cckPhyErrBase); + common->ani.ani[0].cckPhyErrBase); - REG_WRITE(ah, AR_PHY_ERR_1, ah->ani[0].ofdmPhyErrBase); - REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase); - ath9k_enable_mib_counters(ah); + REG_WRITE(ah, AR_PHY_ERR_1, common->ani.ani[0].ofdmPhyErrBase); + REG_WRITE(ah, AR_PHY_ERR_2, common->ani.ani[0].cckPhyErrBase); + ath_enable_mib_counters(common); - ah->aniperiod = ATH9K_ANI_PERIOD; - if (ah->config.enable_ani) - ah->proc_phyerr |= HAL_PROCESS_ANI; + common->ani.aniperiod = ATH_ANI_PERIOD; + common->ani.proc_phyerr |= HAL_PROCESS_ANI; } +EXPORT_SYMBOL(ath_hw_ani_init); -void ath9k_hw_ani_disable(struct ath_hw *ah) +void ath_hw_ani_disable(struct ath_common *common) { - ath_print(ath9k_hw_common(ah), ATH_DBG_ANI, "Disabling ANI\n"); + void *ah = common->ah; + + ath_print(common, ATH_DBG_ANI, "Disabling ANI\n"); - ath9k_hw_disable_mib_counters(ah); + ath_hw_disable_mib_counters(common); REG_WRITE(ah, AR_PHY_ERR_1, 0); REG_WRITE(ah, AR_PHY_ERR_2, 0); } +EXPORT_SYMBOL(ath_hw_ani_disable); diff --git a/drivers/net/wireless/ath/ani.h b/drivers/net/wireless/ath/ani.h new file mode 100644 index 0000000..b9c5d0b --- /dev/null +++ b/drivers/net/wireless/ath/ani.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2008-2009 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef ANI_H +#define ANI_H + +#include "ath.h" + +#define HAL_PROCESS_ANI 0x00000001 + +#define DO_ANI(common) (((common)->ani.proc_phyerr & HAL_PROCESS_ANI)) + +#define BEACON_RSSI(common) (common->ani.stats.avgbrssi) + +#define ATH_ANI_OFDM_TRIG_HIGH 500 +#define ATH_ANI_OFDM_TRIG_LOW 200 +#define ATH_ANI_CCK_TRIG_HIGH 200 +#define ATH_ANI_CCK_TRIG_LOW 100 +#define ATH_ANI_NOISE_IMMUNE_LVL 4 +#define ATH_ANI_USE_OFDM_WEAK_SIG true +#define ATH_ANI_CCK_WEAK_SIG_THR false +#define ATH_ANI_SPUR_IMMUNE_LVL 7 +#define ATH_ANI_FIRSTEP_LVL 0 +#define ATH_ANI_RSSI_THR_HIGH 40 +#define ATH_ANI_RSSI_THR_LOW 7 +#define ATH_ANI_PERIOD 100 + +#define HAL_NOISE_IMMUNE_MAX 4 +#define HAL_SPUR_IMMUNE_MAX 7 +#define HAL_FIRST_STEP_MAX 2 + +#define mib_stats ani.stats.ast_mibstats + +void ath_ani_reset(struct ath_common *common, + struct ieee80211_channel *curchan); +void ath_hw_ani_monitor(struct ath_common *common); +void ath_enable_mib_counters(struct ath_common *common); +void ath_hw_disable_mib_counters(struct ath_common *common); +void ath_hw_procmibevent(struct ath_common *common); +void ath_hw_ani_setup(struct ath_common *common); +void ath_hw_ani_init(struct ath_common *common); +void ath_hw_ani_disable(struct ath_common *common); + +#endif /* ANI_H */ diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index dc09380..99a2a73 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -33,14 +33,92 @@ static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; +struct ath_mib_stats { + u32 ackrcv_bad; + u32 rts_bad; + u32 rts_good; + u32 fcs_bad; + u32 beacons; +}; + +struct ar5416AniState { + struct ieee80211_channel *channel; + u8 noiseImmunityLevel; + u8 spurImmunityLevel; + u8 firstepLevel; + u8 ofdmWeakSigDetectOff; + u8 cckWeakSigThreshold; + u32 listenTime; + u32 ofdmTrigHigh; + u32 ofdmTrigLow; + int32_t cckTrigHigh; + int32_t cckTrigLow; + int32_t rssiThrLow; + int32_t rssiThrHigh; + u32 noiseFloor; + u32 txFrameCount; + u32 rxFrameCount; + u32 cycleCount; + u32 ofdmPhyErrCount; + u32 cckPhyErrCount; + u32 ofdmPhyErrBase; + u32 cckPhyErrBase; + int16_t pktRssi[2]; + int16_t ofdmErrRssi[2]; + int16_t cckErrRssi[2]; +}; + +struct ar5416Stats { + u32 ast_ani_niup; + u32 ast_ani_nidown; + u32 ast_ani_spurup; + u32 ast_ani_spurdown; + u32 ast_ani_ofdmon; + u32 ast_ani_ofdmoff; + u32 ast_ani_cckhigh; + u32 ast_ani_ccklow; + u32 ast_ani_stepup; + u32 ast_ani_stepdown; + u32 ast_ani_ofdmerrs; + u32 ast_ani_cckerrs; + u32 ast_ani_reset; + u32 ast_ani_lzero; + u32 ast_ani_lneg; + u32 avgbrssi; + struct ath_mib_stats ast_mibstats; +}; + +enum ath_ani_cmd { + ATH_ANI_PRESENT = 0x1, + ATH_ANI_NOISE_IMMUNITY_LEVEL = 0x2, + ATH_ANI_OFDM_WEAK_SIGNAL_DETECTION = 0x4, + ATH_ANI_CCK_WEAK_SIGNAL_THR = 0x8, + ATH_ANI_FIRSTEP_LEVEL = 0x10, + ATH_ANI_SPUR_IMMUNITY_LEVEL = 0x20, + ATH_ANI_MODE = 0x40, + ATH_ANI_PHYERR_RESET = 0x80, + ATH_ANI_ALL = 0xff +}; + struct ath_ani { bool caldone; int16_t noise_floor; - unsigned int longcal_timer; - unsigned int shortcal_timer; - unsigned int resetcal_timer; - unsigned int checkani_timer; + unsigned long longcal_timer; + unsigned long shortcal_timer; + unsigned long resetcal_timer; + unsigned long checkani_timer; struct timer_list timer; + + struct ar5416Stats stats; + u32 proc_phyerr; + u32 aniperiod; + struct ar5416AniState *curani; + struct ar5416AniState ani[255]; + int totalSizeDesired[5]; + int coarse_high[5]; + int coarse_low[5]; + int firpwr[5]; + enum ath_ani_cmd ani_function; }; enum ath_device_state { @@ -67,7 +145,8 @@ struct ath_regulatory { struct ath_ops { unsigned int (*read)(void *, u32 reg_offset); - void (*write)(void *, u32 val, u32 reg_offset); + void (*write)(void *, u32 val, u32 reg_offset); + void (*setrxfilter_phy_err)(void *, bool enable); }; struct ath_common; diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index 4985b2b..f702cb2 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile @@ -17,7 +17,6 @@ ath9k_hw-y:= hw.o \ eeprom_4k.o \ eeprom_9287.o \ calib.o \ - ani.o \ phy.o \ btcoex.o \ mac.o \ diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h deleted file mode 100644 index 4e1ab94..0000000 --- a/drivers/net/wireless/ath/ath9k/ani.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2008-2009 Atheros Communications Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef ANI_H -#define ANI_H - -#define HAL_PROCESS_ANI 0x00000001 - -#define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI)) - -#define BEACON_RSSI(ahp) (ahp->stats.avgbrssi) - -#define ATH9K_ANI_OFDM_TRIG_HIGH 500 -#define ATH9K_ANI_OFDM_TRIG_LOW 200 -#define ATH9K_ANI_CCK_TRIG_HIGH 200 -#define ATH9K_ANI_CCK_TRIG_LOW 100 -#define ATH9K_ANI_NOISE_IMMUNE_LVL 4 -#define ATH9K_ANI_USE_OFDM_WEAK_SIG true -#define ATH9K_ANI_CCK_WEAK_SIG_THR false -#define ATH9K_ANI_SPUR_IMMUNE_LVL 7 -#define ATH9K_ANI_FIRSTEP_LVL 0 -#define ATH9K_ANI_RSSI_THR_HIGH 40 -#define ATH9K_ANI_RSSI_THR_LOW 7 -#define ATH9K_ANI_PERIOD 100 - -#define HAL_NOISE_IMMUNE_MAX 4 -#define HAL_SPUR_IMMUNE_MAX 7 -#define HAL_FIRST_STEP_MAX 2 - -enum ath9k_ani_cmd { - ATH9K_ANI_PRESENT = 0x1, - ATH9K_ANI_NOISE_IMMUNITY_LEVEL = 0x2, - ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION = 0x4, - ATH9K_ANI_CCK_WEAK_SIGNAL_THR = 0x8, - ATH9K_ANI_FIRSTEP_LEVEL = 0x10, - ATH9K_ANI_SPUR_IMMUNITY_LEVEL = 0x20, - ATH9K_ANI_MODE = 0x40, - ATH9K_ANI_PHYERR_RESET = 0x80, - ATH9K_ANI_ALL = 0xff -}; - -struct ath9k_mib_stats { - u32 ackrcv_bad; - u32 rts_bad; - u32 rts_good; - u32 fcs_bad; - u32 beacons; -}; - -struct ar5416AniState { - struct ath9k_channel *c; - u8 noiseImmunityLevel; - u8 spurImmunityLevel; - u8 firstepLevel; - u8 ofdmWeakSigDetectOff; - u8 cckWeakSigThreshold; - u32 listenTime; - u32 ofdmTrigHigh; - u32 ofdmTrigLow; - int32_t cckTrigHigh; - int32_t cckTrigLow; - int32_t rssiThrLow; - int32_t rssiThrHigh; - u32 noiseFloor; - u32 txFrameCount; - u32 rxFrameCount; - u32 cycleCount; - u32 ofdmPhyErrCount; - u32 cckPhyErrCount; - u32 ofdmPhyErrBase; - u32 cckPhyErrBase; - int16_t pktRssi[2]; - int16_t ofdmErrRssi[2]; - int16_t cckErrRssi[2]; -}; - -struct ar5416Stats { - u32 ast_ani_niup; - u32 ast_ani_nidown; - u32 ast_ani_spurup; - u32 ast_ani_spurdown; - u32 ast_ani_ofdmon; - u32 ast_ani_ofdmoff; - u32 ast_ani_cckhigh; - u32 ast_ani_ccklow; - u32 ast_ani_stepup; - u32 ast_ani_stepdown; - u32 ast_ani_ofdmerrs; - u32 ast_ani_cckerrs; - u32 ast_ani_reset; - u32 ast_ani_lzero; - u32 ast_ani_lneg; - u32 avgbrssi; - struct ath9k_mib_stats ast_mibstats; -}; -#define ah_mibStats stats.ast_mibstats - -void ath9k_ani_reset(struct ath_hw *ah); -void ath9k_hw_ani_monitor(struct ath_hw *ah, - struct ath9k_channel *chan); -void ath9k_enable_mib_counters(struct ath_hw *ah); -void ath9k_hw_disable_mib_counters(struct ath_hw *ah); -u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt, - u32 *rxf_pcnt, u32 *txf_pcnt); -void ath9k_hw_procmibevent(struct ath_hw *ah); -void ath9k_hw_ani_setup(struct ath_hw *ah); -void ath9k_hw_ani_init(struct ath_hw *ah); -void ath9k_hw_ani_disable(struct ath_hw *ah); - -#endif /* ANI_H */ diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index 9253fee..842c60e 100644 --- a/drivers/net/wireless/ath/ath9k/common.c +++ b/drivers/net/wireless/ath/ath9k/common.c @@ -147,7 +147,6 @@ static void ath9k_process_rssi(struct ath_common *common, struct sk_buff *skb, struct ath_rx_status *rx_stats) { - struct ath_hw *ah = common->ah; struct ieee80211_sta *sta; struct ieee80211_hdr *hdr; struct ath_node *an; @@ -183,7 +182,7 @@ static void ath9k_process_rssi(struct ath_common *common, /* Update Beacon RSSI, this is used by ANI. */ if (ieee80211_is_beacon(fc)) - ah->stats.avgbrssi = rx_stats->rs_rssi; + common->ani.stats.avgbrssi = rx_stats->rs_rssi; } /* diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 88e1929..89e6391 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -546,8 +546,8 @@ static int ath9k_hw_post_init(struct ath_hw *ah) } if (!AR_SREV_9100(ah)) { - ath9k_hw_ani_setup(ah); - ath9k_hw_ani_init(ah); + ath_hw_ani_setup(ath9k_hw_common(ah)); + ath_hw_ani_init(ath9k_hw_common(ah)); } return 0; @@ -920,9 +920,9 @@ int ath9k_hw_init(struct ath_hw *ah) ath9k_hw_init_cal_settings(ah); - ah->ani_function = ATH9K_ANI_ALL; + common->ani.ani_function = ATH_ANI_ALL; if (AR_SREV_9280_10_OR_LATER(ah)) { - ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL; + common->ani.ani_function &= ~ATH_ANI_NOISE_IMMUNITY_LEVEL; ah->ath9k_hw_rf_set_freq = &ath9k_hw_ar9280_set_channel; ah->ath9k_hw_spur_mitigate_freq = &ath9k_hw_9280_spur_mitigate; } else { @@ -1250,7 +1250,7 @@ void ath9k_hw_detach(struct ath_hw *ah) goto free_hw; if (!AR_SREV_9100(ah)) - ath9k_hw_ani_disable(ah); + ath_hw_ani_disable(common); ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP); @@ -3536,6 +3536,21 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits) } EXPORT_SYMBOL(ath9k_hw_setrxfilter); +void ath9k_hw_setrxfilter_phy_err(void *hw, bool enable) +{ + struct ath_hw *ah = hw; + + u32 filt = ath9k_hw_getrxfilter(ah); + + if (enable) + filt |= ATH9K_RX_FILTER_PHYERR; + else + filt &= ~ATH9K_RX_FILTER_PHYERR; + + ath9k_hw_setrxfilter(ah, filt); +} +EXPORT_SYMBOL(ath9k_hw_setrxfilter_phy_err); + bool ath9k_hw_phy_disable(struct ath_hw *ah) { if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM)) diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 3670699..21ea286 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -22,7 +22,6 @@ #include <linux/io.h> #include "mac.h" -#include "ani.h" #include "eeprom.h" #include "calib.h" #include "reg.h" @@ -31,6 +30,7 @@ #include "../regd.h" #include "../debug.h" +#include "../ani.h" #define ATHEROS_VENDOR_ID 0x168c @@ -472,7 +472,6 @@ struct ath_hw { struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS]; struct ath9k_pacal_info pacal_info; - struct ar5416Stats stats; struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES]; int16_t curchan_rad_index; @@ -556,17 +555,6 @@ struct ath_hw { u32 ctstimeout; u32 globaltxtimeout; - /* ANI */ - u32 proc_phyerr; - u32 aniperiod; - struct ar5416AniState *curani; - struct ar5416AniState ani[255]; - int totalSizeDesired[5]; - int coarse_high[5]; - int coarse_low[5]; - int firpwr[5]; - enum ath9k_ani_cmd ani_function; - /* Bluetooth coexistance */ struct ath_btcoex_hw btcoex_hw; @@ -654,6 +642,7 @@ void ath9k_hw_get_channel_centers(struct ath_hw *ah, struct chan_centers *centers); u32 ath9k_hw_getrxfilter(struct ath_hw *ah); void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits); +void ath9k_hw_setrxfilter_phy_err(void *hw, bool enable); bool ath9k_hw_phy_disable(struct ath_hw *ah); bool ath9k_hw_disable(struct ath_hw *ah); void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit); diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index efc420c..2198a04 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -1004,9 +1004,9 @@ EXPORT_SYMBOL(ath9k_hw_rxena); void ath9k_hw_startpcureceive(struct ath_hw *ah) { - ath9k_enable_mib_counters(ah); + ath_enable_mib_counters(ath9k_hw_common(ah)); - ath9k_ani_reset(ah); + ath_ani_reset(ath9k_hw_common(ah), ah->curchan->chan); REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); } @@ -1016,7 +1016,7 @@ void ath9k_hw_stoppcurecv(struct ath_hw *ah) { REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS); - ath9k_hw_disable_mib_counters(ah); + ath_hw_disable_mib_counters(ath9k_hw_common(ah)); } EXPORT_SYMBOL(ath9k_hw_stoppcurecv); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index c8aeef0..e77e8d4 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -404,7 +404,7 @@ static void ath_ani_calibrate(unsigned long data) if (longcal || shortcal || aniflag) { /* Call ANI routine if necessary */ if (aniflag) - ath9k_hw_ani_monitor(ah, ah->curchan); + ath_hw_ani_monitor(ath9k_hw_common(ah)); /* Perform calibration if necessary */ if (longcal || shortcal) { @@ -627,7 +627,7 @@ irqreturn_t ath_isr(int irq, void *dev) * it will clear whatever condition caused * the interrupt. */ - ath9k_hw_procmibevent(ah); + ath_hw_procmibevent(ath9k_hw_common(ah)); ath9k_hw_set_interrupts(ah, sc->imask); } @@ -989,7 +989,7 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, ath_beacon_config(sc, vif); /* Reset rssi stats */ - sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; + common->ani.stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; ath_start_ani(common); } else { @@ -1578,6 +1578,7 @@ static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset) static const struct ath_ops ath9k_common_ops = { .read = ath9k_ioread32, .write = ath9k_iowrite32, + .setrxfilter_phy_err = ath9k_hw_setrxfilter_phy_err, }; /* diff --git a/drivers/net/wireless/ath/reg.h b/drivers/net/wireless/ath/reg.h index dfe1fbe..e20461a 100644 --- a/drivers/net/wireless/ath/reg.h +++ b/drivers/net/wireless/ath/reg.h @@ -17,6 +17,18 @@ #ifndef ATH_REGISTERS_H #define ATH_REGISTERS_H +#define AR_MIBC 0x0040 +#define AR_MIBC_COW 0x00000001 +#define AR_MIBC_FMC 0x00000002 +#define AR_MIBC_CMC 0x00000004 +#define AR_MIBC_MCS 0x00000008 + +#define AR_RTS_OK 0x8088 +#define AR_RTS_FAIL 0x808c +#define AR_ACK_FAIL 0x8090 +#define AR_FCS_FAIL 0x8094 +#define AR_BEACON_CNT 0x8098 + /* * BSSID mask registers. See ath_hw_set_bssid_mask() * for detailed documentation about these registers. @@ -24,4 +36,126 @@ #define AR_BSSMSKL 0x80e0 #define AR_BSSMSKU 0x80e4 +/* + * ANI registers + */ +#define AR_TFCNT 0x80ec +#define AR_RFCNT 0x80f0 +#define AR_RCCNT 0x80f4 +#define AR_CCCNT 0x80f8 + +#define AR_PHY_ERR 0x810c +#define AR_PHY_ERR_DCHIRP 0x00000008 +#define AR_PHY_ERR_RADAR 0x00000020 +#define AR_PHY_ERR_OFDM_TIMING 0x00020000 +#define AR_PHY_ERR_CCK_TIMING 0x02000000 + +#define AR_FILT_OFDM 0x8124 +#define AR_FILT_OFDM_COUNT 0x00FFFFFF + +#define AR_FILT_CCK 0x8128 +#define AR_FILT_CCK_COUNT 0x00FFFFFF + +#define AR_PHY_ERR_1 0x812c +#define AR_PHY_ERR_1_COUNT 0x00FFFFFF +#define AR_PHY_ERR_MASK_1 0x8130 + +#define AR_PHY_ERR_2 0x8134 +#define AR_PHY_ERR_2_COUNT 0x00FFFFFF +#define AR_PHY_ERR_MASK_2 0x8138 + +#define AR_PHY_COUNTMAX (3 << 22) +#define AR_MIBCNT_INTRMASK (3 << 22) + +#define AR_SLP_MIB_CTRL 0x8258 +#define AR_SLP_MIB_CLEAR 0x00000001 +#define AR_SLP_MIB_PENDING 0x00000002 + +/* + * Desired ADC/PGA size register + */ +#define AR_PHY_DESIRED_SZ 0x9850 +#define AR_PHY_DESIRED_SZ_ADC 0x000000FF /* ADC desired sze */ +#define AR_PHY_DESIRED_SZ_ADC_S 0 +#define AR_PHY_DESIRED_SZ_PGA 0x0000FF00 /* PGA desired size */ +#define AR_PHY_DESIRED_SZ_PGA_S 8 +#define AR_PHY_DESIRED_SZ_TOT_DES 0x0FF00000 /* Total desired size */ +#define AR_PHY_DESIRED_SZ_TOT_DES_S 20 + +/* + * PHY signal register + */ +#define AR_PHY_FIND_SIG 0x9858 +#define AR_PHY_FIND_SIG_FIRSTEP 0x0003F000 +#define AR_PHY_FIND_SIG_FIRSTEP_S 12 +#define AR_PHY_FIND_SIG_FIRPWR 0x03FC0000 +#define AR_PHY_FIND_SIG_FIRPWR_S 18 + +/* + * PHY coarse agility control register + */ +#define AR_PHY_AGC_CTL1 0x985C +#define AR_PHY_AGC_CTL1_COARSE_LOW 0x00007F80 /* AGC coarse low */ +#define AR_PHY_AGC_CTL1_COARSE_LOW_S 7 +#define AR_PHY_AGC_CTL1_COARSE_HIGH 0x003F8000 /* AGC coarse high */ +#define AR_PHY_AGC_CTL1_COARSE_HIGH_S 15 + +/* + * PHY agility control register + */ +#define AR_PHY_AGC_CONTROL 0x9860 +#define AR_PHY_AGC_CONTROL_CAL 0x00000001 +#define AR_PHY_AGC_CONTROL_NF 0x00000002 +#define AR_PHY_AGC_CONTROL_ENABLE_NF 0x00008000 +#define AR_PHY_AGC_CONTROL_FLTR_CAL 0x00010000 +#define AR_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000 + +/* + * PHY Weak ofdm signal detection threshold registers + */ +/* High thresholds */ +#define AR_PHY_SFCORR 0x9868 +#define AR_PHY_SFCORR_M2COUNT_THR 0x0000001F +#define AR_PHY_SFCORR_M2COUNT_THR_S 0 +#define AR_PHY_SFCORR_M1_THRESH 0x00FE0000 +#define AR_PHY_SFCORR_M1_THRESH_S 17 +#define AR_PHY_SFCORR_M2_THRESH 0x7F000000 +#define AR_PHY_SFCORR_M2_THRESH_S 24 + +/* Low thresholds */ +#define AR_PHY_SFCORR_LOW 0x986C +#define AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW 0x00000001 +#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW 0x00003F00 +#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S 8 +#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW 0x001FC000 +#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW_S 14 +#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW 0x0FE00000 +#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW_S 21 + +#define AR_PHY_SFCORR_EXT 0x99c0 +#define AR_PHY_SFCORR_EXT_M1_THRESH 0x0000007F +#define AR_PHY_SFCORR_EXT_M1_THRESH_S 0 +#define AR_PHY_SFCORR_EXT_M2_THRESH 0x00003F80 +#define AR_PHY_SFCORR_EXT_M2_THRESH_S 7 +#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW 0x001FC000 +#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14 +#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW 0x0FE00000 +#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21 +#define AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S 28 + +/* + * PHY timing register 5 + * OFDM Self-correlator Cyclic RSSI threshold register + */ +#define AR_PHY_TIMING5 0x9924 +#define AR_PHY_TIMING5_CYCPWR_THR1 0x000000FE +#define AR_PHY_TIMING5_CYCPWR_THR1_S 1 + +/* + * PHY CCK Cross-correlator Barker RSSI threshold register + */ +#define AR_PHY_CCK_DETECT 0xA208 +#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK 0x0000003F +#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S 0 + #endif /* ATH_REGISTERS_H */ -- 1.6.3.3 _______________________________________________ ath5k-devel mailing list ath5k-devel@lists.ath5k.org https://lists.ath5k.org/mailman/listinfo/ath5k-devel