mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2024-11-01 18:15:20 +02:00
ba1de008db
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@32448 3c298f89-4303-0410-b956-a3cf2f4a3e73
1605 lines
51 KiB
Diff
1605 lines
51 KiB
Diff
--- a/drivers/net/wireless/ath/ath9k/ani.c
|
|
+++ b/drivers/net/wireless/ath/ath9k/ani.c
|
|
@@ -104,11 +104,6 @@ static const struct ani_cck_level_entry
|
|
#define ATH9K_ANI_CCK_DEF_LEVEL \
|
|
2 /* default level - matches the INI settings */
|
|
|
|
-static bool use_new_ani(struct ath_hw *ah)
|
|
-{
|
|
- return AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani;
|
|
-}
|
|
-
|
|
static void ath9k_hw_update_mibstats(struct ath_hw *ah,
|
|
struct ath9k_mib_stats *stats)
|
|
{
|
|
@@ -122,8 +117,6 @@ static void ath9k_hw_update_mibstats(str
|
|
static void ath9k_ani_restart(struct ath_hw *ah)
|
|
{
|
|
struct ar5416AniState *aniState;
|
|
- struct ath_common *common = ath9k_hw_common(ah);
|
|
- u32 ofdm_base = 0, cck_base = 0;
|
|
|
|
if (!DO_ANI(ah))
|
|
return;
|
|
@@ -131,18 +124,10 @@ static void ath9k_ani_restart(struct ath
|
|
aniState = &ah->curchan->ani;
|
|
aniState->listenTime = 0;
|
|
|
|
- if (!use_new_ani(ah)) {
|
|
- ofdm_base = AR_PHY_COUNTMAX - ah->config.ofdm_trig_high;
|
|
- cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high;
|
|
- }
|
|
-
|
|
- ath_dbg(common, ANI, "Writing ofdmbase=%u cckbase=%u\n",
|
|
- ofdm_base, cck_base);
|
|
-
|
|
ENABLE_REGWRITE_BUFFER(ah);
|
|
|
|
- REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base);
|
|
- REG_WRITE(ah, AR_PHY_ERR_2, cck_base);
|
|
+ REG_WRITE(ah, AR_PHY_ERR_1, 0);
|
|
+ REG_WRITE(ah, AR_PHY_ERR_2, 0);
|
|
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);
|
|
|
|
@@ -154,110 +139,6 @@ static void ath9k_ani_restart(struct ath
|
|
aniState->cckPhyErrCount = 0;
|
|
}
|
|
|
|
-static void ath9k_hw_ani_ofdm_err_trigger_old(struct ath_hw *ah)
|
|
-{
|
|
- struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
|
|
- struct ar5416AniState *aniState;
|
|
- int32_t rssi;
|
|
-
|
|
- aniState = &ah->curchan->ani;
|
|
-
|
|
- if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
|
|
- if (ath9k_hw_ani_control(ah, ATH9K_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,
|
|
- aniState->spurImmunityLevel + 1)) {
|
|
- return;
|
|
- }
|
|
- }
|
|
-
|
|
- if (ah->opmode == NL80211_IFTYPE_AP) {
|
|
- if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
|
|
- ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
|
|
- aniState->firstepLevel + 1);
|
|
- }
|
|
- return;
|
|
- }
|
|
- rssi = BEACON_RSSI(ah);
|
|
- if (rssi > aniState->rssiThrHigh) {
|
|
- if (!aniState->ofdmWeakSigDetectOff) {
|
|
- if (ath9k_hw_ani_control(ah,
|
|
- ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
|
|
- false)) {
|
|
- ath9k_hw_ani_control(ah,
|
|
- ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
|
|
- return;
|
|
- }
|
|
- }
|
|
- if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
|
|
- ath9k_hw_ani_control(ah, ATH9K_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,
|
|
- true);
|
|
- if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
|
|
- ath9k_hw_ani_control(ah, ATH9K_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,
|
|
- false);
|
|
- if (aniState->firstepLevel > 0)
|
|
- ath9k_hw_ani_control(ah,
|
|
- ATH9K_ANI_FIRSTEP_LEVEL, 0);
|
|
- return;
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-static void ath9k_hw_ani_cck_err_trigger_old(struct ath_hw *ah)
|
|
-{
|
|
- struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
|
|
- struct ar5416AniState *aniState;
|
|
- int32_t rssi;
|
|
-
|
|
- aniState = &ah->curchan->ani;
|
|
- if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
|
|
- if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
|
|
- aniState->noiseImmunityLevel + 1)) {
|
|
- return;
|
|
- }
|
|
- }
|
|
- if (ah->opmode == NL80211_IFTYPE_AP) {
|
|
- if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
|
|
- ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
|
|
- aniState->firstepLevel + 1);
|
|
- }
|
|
- return;
|
|
- }
|
|
- rssi = BEACON_RSSI(ah);
|
|
- if (rssi > aniState->rssiThrLow) {
|
|
- if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
|
|
- ath9k_hw_ani_control(ah, ATH9K_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);
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
/* Adjust the OFDM Noise Immunity Level */
|
|
static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel)
|
|
{
|
|
@@ -265,18 +146,15 @@ static void ath9k_hw_set_ofdm_nil(struct
|
|
struct ath_common *common = ath9k_hw_common(ah);
|
|
const struct ani_ofdm_level_entry *entry_ofdm;
|
|
const struct ani_cck_level_entry *entry_cck;
|
|
-
|
|
- aniState->noiseFloor = BEACON_RSSI(ah);
|
|
+ bool weak_sig;
|
|
|
|
ath_dbg(common, ANI, "**** ofdmlevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
|
|
aniState->ofdmNoiseImmunityLevel,
|
|
- immunityLevel, aniState->noiseFloor,
|
|
+ immunityLevel, BEACON_RSSI(ah),
|
|
aniState->rssiThrLow, aniState->rssiThrHigh);
|
|
|
|
if (aniState->update_ani)
|
|
- aniState->ofdmNoiseImmunityLevel =
|
|
- (immunityLevel > ATH9K_ANI_OFDM_DEF_LEVEL) ?
|
|
- immunityLevel : ATH9K_ANI_OFDM_DEF_LEVEL;
|
|
+ aniState->ofdmNoiseImmunityLevel = immunityLevel;
|
|
|
|
entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel];
|
|
entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel];
|
|
@@ -292,12 +170,22 @@ static void ath9k_hw_set_ofdm_nil(struct
|
|
ATH9K_ANI_FIRSTEP_LEVEL,
|
|
entry_ofdm->fir_step_level);
|
|
|
|
- if ((aniState->noiseFloor >= aniState->rssiThrHigh) &&
|
|
- (!aniState->ofdmWeakSigDetectOff !=
|
|
- entry_ofdm->ofdm_weak_signal_on)) {
|
|
+ weak_sig = entry_ofdm->ofdm_weak_signal_on;
|
|
+ if (ah->opmode == NL80211_IFTYPE_STATION &&
|
|
+ BEACON_RSSI(ah) <= aniState->rssiThrHigh)
|
|
+ weak_sig = true;
|
|
+
|
|
+ if (aniState->ofdmWeakSigDetect != weak_sig)
|
|
ath9k_hw_ani_control(ah,
|
|
ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
|
|
entry_ofdm->ofdm_weak_signal_on);
|
|
+
|
|
+ if (aniState->ofdmNoiseImmunityLevel >= ATH9K_ANI_OFDM_DEF_LEVEL) {
|
|
+ ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
|
|
+ ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI;
|
|
+ } else {
|
|
+ ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI;
|
|
+ ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW;
|
|
}
|
|
}
|
|
|
|
@@ -308,11 +196,6 @@ static void ath9k_hw_ani_ofdm_err_trigge
|
|
if (!DO_ANI(ah))
|
|
return;
|
|
|
|
- if (!use_new_ani(ah)) {
|
|
- ath9k_hw_ani_ofdm_err_trigger_old(ah);
|
|
- return;
|
|
- }
|
|
-
|
|
aniState = &ah->curchan->ani;
|
|
|
|
if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL)
|
|
@@ -329,22 +212,18 @@ static void ath9k_hw_set_cck_nil(struct
|
|
const struct ani_ofdm_level_entry *entry_ofdm;
|
|
const struct ani_cck_level_entry *entry_cck;
|
|
|
|
- aniState->noiseFloor = BEACON_RSSI(ah);
|
|
ath_dbg(common, ANI, "**** ccklevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
|
|
aniState->cckNoiseImmunityLevel, immunityLevel,
|
|
- aniState->noiseFloor, aniState->rssiThrLow,
|
|
+ BEACON_RSSI(ah), aniState->rssiThrLow,
|
|
aniState->rssiThrHigh);
|
|
|
|
- if ((ah->opmode == NL80211_IFTYPE_STATION ||
|
|
- ah->opmode == NL80211_IFTYPE_ADHOC) &&
|
|
- aniState->noiseFloor <= aniState->rssiThrLow &&
|
|
+ if (ah->opmode == NL80211_IFTYPE_STATION &&
|
|
+ BEACON_RSSI(ah) <= aniState->rssiThrLow &&
|
|
immunityLevel > ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI)
|
|
immunityLevel = ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI;
|
|
|
|
if (aniState->update_ani)
|
|
- aniState->cckNoiseImmunityLevel =
|
|
- (immunityLevel > ATH9K_ANI_CCK_DEF_LEVEL) ?
|
|
- immunityLevel : ATH9K_ANI_CCK_DEF_LEVEL;
|
|
+ aniState->cckNoiseImmunityLevel = immunityLevel;
|
|
|
|
entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel];
|
|
entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel];
|
|
@@ -372,70 +251,12 @@ static void ath9k_hw_ani_cck_err_trigger
|
|
if (!DO_ANI(ah))
|
|
return;
|
|
|
|
- if (!use_new_ani(ah)) {
|
|
- ath9k_hw_ani_cck_err_trigger_old(ah);
|
|
- return;
|
|
- }
|
|
-
|
|
aniState = &ah->curchan->ani;
|
|
|
|
if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL)
|
|
ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1);
|
|
}
|
|
|
|
-static void ath9k_hw_ani_lower_immunity_old(struct ath_hw *ah)
|
|
-{
|
|
- struct ar5416AniState *aniState;
|
|
- int32_t rssi;
|
|
-
|
|
- aniState = &ah->curchan->ani;
|
|
-
|
|
- if (ah->opmode == NL80211_IFTYPE_AP) {
|
|
- if (aniState->firstepLevel > 0) {
|
|
- if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
|
|
- aniState->firstepLevel - 1))
|
|
- return;
|
|
- }
|
|
- } else {
|
|
- rssi = BEACON_RSSI(ah);
|
|
- 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,
|
|
- true))
|
|
- return;
|
|
- }
|
|
- if (aniState->firstepLevel > 0) {
|
|
- if (ath9k_hw_ani_control(ah,
|
|
- ATH9K_ANI_FIRSTEP_LEVEL,
|
|
- aniState->firstepLevel - 1))
|
|
- return;
|
|
- }
|
|
- } else {
|
|
- if (aniState->firstepLevel > 0) {
|
|
- if (ath9k_hw_ani_control(ah,
|
|
- ATH9K_ANI_FIRSTEP_LEVEL,
|
|
- aniState->firstepLevel - 1))
|
|
- return;
|
|
- }
|
|
- }
|
|
- }
|
|
-
|
|
- if (aniState->spurImmunityLevel > 0) {
|
|
- if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
|
|
- aniState->spurImmunityLevel - 1))
|
|
- return;
|
|
- }
|
|
-
|
|
- if (aniState->noiseImmunityLevel > 0) {
|
|
- ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
|
|
- aniState->noiseImmunityLevel - 1);
|
|
- return;
|
|
- }
|
|
-}
|
|
-
|
|
/*
|
|
* only lower either OFDM or CCK errors per turn
|
|
* we lower the other one next time
|
|
@@ -446,11 +267,6 @@ static void ath9k_hw_ani_lower_immunity(
|
|
|
|
aniState = &ah->curchan->ani;
|
|
|
|
- if (!use_new_ani(ah)) {
|
|
- ath9k_hw_ani_lower_immunity_old(ah);
|
|
- return;
|
|
- }
|
|
-
|
|
/* lower OFDM noise immunity */
|
|
if (aniState->ofdmNoiseImmunityLevel > 0 &&
|
|
(aniState->ofdmsTurn || aniState->cckNoiseImmunityLevel == 0)) {
|
|
@@ -463,72 +279,6 @@ static void ath9k_hw_ani_lower_immunity(
|
|
ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1);
|
|
}
|
|
|
|
-static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
|
|
-{
|
|
- struct ar5416AniState *aniState;
|
|
- struct ath9k_channel *chan = ah->curchan;
|
|
- struct ath_common *common = ath9k_hw_common(ah);
|
|
-
|
|
- if (!DO_ANI(ah))
|
|
- return;
|
|
-
|
|
- aniState = &ah->curchan->ani;
|
|
-
|
|
- if (ah->opmode != NL80211_IFTYPE_STATION
|
|
- && ah->opmode != NL80211_IFTYPE_ADHOC) {
|
|
- ath_dbg(common, ANI, "Reset ANI state opmode %u\n", ah->opmode);
|
|
- ah->stats.ast_ani_reset++;
|
|
-
|
|
- if (ah->opmode == NL80211_IFTYPE_AP) {
|
|
- /*
|
|
- * ath9k_hw_ani_control() will only process items set on
|
|
- * ah->ani_function
|
|
- */
|
|
- if (IS_CHAN_2GHZ(chan))
|
|
- ah->ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL |
|
|
- ATH9K_ANI_FIRSTEP_LEVEL);
|
|
- else
|
|
- ah->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);
|
|
-
|
|
- ath9k_ani_restart(ah);
|
|
- return;
|
|
- }
|
|
-
|
|
- if (aniState->noiseImmunityLevel != 0)
|
|
- ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
|
|
- aniState->noiseImmunityLevel);
|
|
- if (aniState->spurImmunityLevel != 0)
|
|
- ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
|
|
- aniState->spurImmunityLevel);
|
|
- if (aniState->ofdmWeakSigDetectOff)
|
|
- ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
|
|
- !aniState->ofdmWeakSigDetectOff);
|
|
- if (aniState->cckWeakSigThreshold)
|
|
- ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
|
|
- aniState->cckWeakSigThreshold);
|
|
- if (aniState->firstepLevel != 0)
|
|
- ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
|
|
- aniState->firstepLevel);
|
|
-
|
|
- ath9k_ani_restart(ah);
|
|
-
|
|
- ENABLE_REGWRITE_BUFFER(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);
|
|
-
|
|
- REGWRITE_BUFFER_FLUSH(ah);
|
|
-}
|
|
-
|
|
/*
|
|
* Restore the ANI parameters in the HAL and reset the statistics.
|
|
* This routine should be called for every hardware reset and for
|
|
@@ -539,13 +289,11 @@ void ath9k_ani_reset(struct ath_hw *ah,
|
|
struct ar5416AniState *aniState = &ah->curchan->ani;
|
|
struct ath9k_channel *chan = ah->curchan;
|
|
struct ath_common *common = ath9k_hw_common(ah);
|
|
+ int ofdm_nil, cck_nil;
|
|
|
|
if (!DO_ANI(ah))
|
|
return;
|
|
|
|
- if (!use_new_ani(ah))
|
|
- return ath9k_ani_reset_old(ah, is_scanning);
|
|
-
|
|
BUG_ON(aniState == NULL);
|
|
ah->stats.ast_ani_reset++;
|
|
|
|
@@ -563,6 +311,11 @@ void ath9k_ani_reset(struct ath_hw *ah,
|
|
/* always allow mode (on/off) to be controlled */
|
|
ah->ani_function |= ATH9K_ANI_MODE;
|
|
|
|
+ ofdm_nil = max_t(int, ATH9K_ANI_OFDM_DEF_LEVEL,
|
|
+ aniState->ofdmNoiseImmunityLevel);
|
|
+ cck_nil = max_t(int, ATH9K_ANI_CCK_DEF_LEVEL,
|
|
+ aniState->cckNoiseImmunityLevel);
|
|
+
|
|
if (is_scanning ||
|
|
(ah->opmode != NL80211_IFTYPE_STATION &&
|
|
ah->opmode != NL80211_IFTYPE_ADHOC)) {
|
|
@@ -586,8 +339,8 @@ void ath9k_ani_reset(struct ath_hw *ah,
|
|
aniState->cckNoiseImmunityLevel);
|
|
|
|
aniState->update_ani = false;
|
|
- ath9k_hw_set_ofdm_nil(ah, ATH9K_ANI_OFDM_DEF_LEVEL);
|
|
- ath9k_hw_set_cck_nil(ah, ATH9K_ANI_CCK_DEF_LEVEL);
|
|
+ ofdm_nil = ATH9K_ANI_OFDM_DEF_LEVEL;
|
|
+ cck_nil = ATH9K_ANI_CCK_DEF_LEVEL;
|
|
}
|
|
} else {
|
|
/*
|
|
@@ -603,11 +356,9 @@ void ath9k_ani_reset(struct ath_hw *ah,
|
|
aniState->cckNoiseImmunityLevel);
|
|
|
|
aniState->update_ani = true;
|
|
- ath9k_hw_set_ofdm_nil(ah,
|
|
- aniState->ofdmNoiseImmunityLevel);
|
|
- ath9k_hw_set_cck_nil(ah,
|
|
- aniState->cckNoiseImmunityLevel);
|
|
}
|
|
+ ath9k_hw_set_ofdm_nil(ah, ofdm_nil);
|
|
+ ath9k_hw_set_cck_nil(ah, cck_nil);
|
|
|
|
/*
|
|
* enable phy counters if hw supports or if not, enable phy
|
|
@@ -627,9 +378,6 @@ static bool ath9k_hw_ani_read_counters(s
|
|
{
|
|
struct ath_common *common = ath9k_hw_common(ah);
|
|
struct ar5416AniState *aniState = &ah->curchan->ani;
|
|
- u32 ofdm_base = 0;
|
|
- u32 cck_base = 0;
|
|
- u32 ofdmPhyErrCnt, cckPhyErrCnt;
|
|
u32 phyCnt1, phyCnt2;
|
|
int32_t listenTime;
|
|
|
|
@@ -642,11 +390,6 @@ static bool ath9k_hw_ani_read_counters(s
|
|
return false;
|
|
}
|
|
|
|
- if (!use_new_ani(ah)) {
|
|
- ofdm_base = AR_PHY_COUNTMAX - ah->config.ofdm_trig_high;
|
|
- cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high;
|
|
- }
|
|
-
|
|
aniState->listenTime += listenTime;
|
|
|
|
ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
|
|
@@ -654,35 +397,12 @@ static bool ath9k_hw_ani_read_counters(s
|
|
phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
|
|
phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
|
|
|
|
- if (!use_new_ani(ah) && (phyCnt1 < ofdm_base || phyCnt2 < cck_base)) {
|
|
- if (phyCnt1 < ofdm_base) {
|
|
- ath_dbg(common, ANI,
|
|
- "phyCnt1 0x%x, resetting counter value to 0x%x\n",
|
|
- phyCnt1, ofdm_base);
|
|
- REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base);
|
|
- REG_WRITE(ah, AR_PHY_ERR_MASK_1,
|
|
- AR_PHY_ERR_OFDM_TIMING);
|
|
- }
|
|
- if (phyCnt2 < cck_base) {
|
|
- ath_dbg(common, ANI,
|
|
- "phyCnt2 0x%x, resetting counter value to 0x%x\n",
|
|
- phyCnt2, cck_base);
|
|
- REG_WRITE(ah, AR_PHY_ERR_2, cck_base);
|
|
- REG_WRITE(ah, AR_PHY_ERR_MASK_2,
|
|
- AR_PHY_ERR_CCK_TIMING);
|
|
- }
|
|
- return false;
|
|
- }
|
|
+ ah->stats.ast_ani_ofdmerrs += phyCnt1 - aniState->ofdmPhyErrCount;
|
|
+ aniState->ofdmPhyErrCount = phyCnt1;
|
|
+
|
|
+ ah->stats.ast_ani_cckerrs += phyCnt2 - aniState->cckPhyErrCount;
|
|
+ aniState->cckPhyErrCount = phyCnt2;
|
|
|
|
- ofdmPhyErrCnt = phyCnt1 - ofdm_base;
|
|
- ah->stats.ast_ani_ofdmerrs +=
|
|
- ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
|
|
- aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
|
|
-
|
|
- cckPhyErrCnt = phyCnt2 - cck_base;
|
|
- ah->stats.ast_ani_cckerrs +=
|
|
- cckPhyErrCnt - aniState->cckPhyErrCount;
|
|
- aniState->cckPhyErrCount = cckPhyErrCnt;
|
|
return true;
|
|
}
|
|
|
|
@@ -716,21 +436,10 @@ void ath9k_hw_ani_monitor(struct ath_hw
|
|
|
|
if (aniState->listenTime > ah->aniperiod) {
|
|
if (cckPhyErrRate < ah->config.cck_trig_low &&
|
|
- ((ofdmPhyErrRate < ah->config.ofdm_trig_low &&
|
|
- aniState->ofdmNoiseImmunityLevel <
|
|
- ATH9K_ANI_OFDM_DEF_LEVEL) ||
|
|
- (ofdmPhyErrRate < ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI &&
|
|
- aniState->ofdmNoiseImmunityLevel >=
|
|
- ATH9K_ANI_OFDM_DEF_LEVEL))) {
|
|
+ ofdmPhyErrRate < ah->config.ofdm_trig_low) {
|
|
ath9k_hw_ani_lower_immunity(ah);
|
|
aniState->ofdmsTurn = !aniState->ofdmsTurn;
|
|
- } else if ((ofdmPhyErrRate > ah->config.ofdm_trig_high &&
|
|
- aniState->ofdmNoiseImmunityLevel >=
|
|
- ATH9K_ANI_OFDM_DEF_LEVEL) ||
|
|
- (ofdmPhyErrRate >
|
|
- ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI &&
|
|
- aniState->ofdmNoiseImmunityLevel <
|
|
- ATH9K_ANI_OFDM_DEF_LEVEL)) {
|
|
+ } else if (ofdmPhyErrRate > ah->config.ofdm_trig_high) {
|
|
ath9k_hw_ani_ofdm_err_trigger(ah);
|
|
aniState->ofdmsTurn = false;
|
|
} else if (cckPhyErrRate > ah->config.cck_trig_high) {
|
|
@@ -778,49 +487,6 @@ void ath9k_hw_disable_mib_counters(struc
|
|
}
|
|
EXPORT_SYMBOL(ath9k_hw_disable_mib_counters);
|
|
|
|
-/*
|
|
- * Process a MIB interrupt. We may potentially be invoked because
|
|
- * any of the MIB counters overflow/trigger so don't assume we're
|
|
- * here because a PHY error counter triggered.
|
|
- */
|
|
-void ath9k_hw_proc_mib_event(struct ath_hw *ah)
|
|
-{
|
|
- u32 phyCnt1, phyCnt2;
|
|
-
|
|
- /* Reset these counters regardless */
|
|
- REG_WRITE(ah, AR_FILT_OFDM, 0);
|
|
- REG_WRITE(ah, AR_FILT_CCK, 0);
|
|
- if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING))
|
|
- 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);
|
|
-
|
|
- if (!DO_ANI(ah)) {
|
|
- /*
|
|
- * We must always clear the interrupt cause by
|
|
- * resetting the phy error regs.
|
|
- */
|
|
- REG_WRITE(ah, AR_PHY_ERR_1, 0);
|
|
- REG_WRITE(ah, AR_PHY_ERR_2, 0);
|
|
- return;
|
|
- }
|
|
-
|
|
- /* NB: these are not reset-on-read */
|
|
- phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
|
|
- phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
|
|
- if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
|
|
- ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) {
|
|
-
|
|
- if (!use_new_ani(ah))
|
|
- ath9k_hw_ani_read_counters(ah);
|
|
-
|
|
- /* NB: always restart to insure the h/w counters are reset */
|
|
- ath9k_ani_restart(ah);
|
|
- }
|
|
-}
|
|
-EXPORT_SYMBOL(ath9k_hw_proc_mib_event);
|
|
-
|
|
void ath9k_hw_ani_setup(struct ath_hw *ah)
|
|
{
|
|
int i;
|
|
@@ -845,50 +511,31 @@ void ath9k_hw_ani_init(struct ath_hw *ah
|
|
|
|
ath_dbg(common, ANI, "Initialize ANI\n");
|
|
|
|
- if (use_new_ani(ah)) {
|
|
- ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_NEW;
|
|
- ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_NEW;
|
|
+ ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
|
|
+ ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW;
|
|
|
|
- ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_NEW;
|
|
- ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_NEW;
|
|
- } else {
|
|
- ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_OLD;
|
|
- ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_OLD;
|
|
-
|
|
- ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_OLD;
|
|
- ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_OLD;
|
|
- }
|
|
+ ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH;
|
|
+ ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW;
|
|
|
|
for (i = 0; i < ARRAY_SIZE(ah->channels); i++) {
|
|
struct ath9k_channel *chan = &ah->channels[i];
|
|
struct ar5416AniState *ani = &chan->ani;
|
|
|
|
- if (use_new_ani(ah)) {
|
|
- ani->spurImmunityLevel =
|
|
- ATH9K_ANI_SPUR_IMMUNE_LVL_NEW;
|
|
+ ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
|
|
|
|
- ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
|
|
+ ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
|
|
|
|
- if (AR_SREV_9300_20_OR_LATER(ah))
|
|
- ani->mrcCCKOff =
|
|
- !ATH9K_ANI_ENABLE_MRC_CCK;
|
|
- else
|
|
- ani->mrcCCKOff = true;
|
|
-
|
|
- ani->ofdmsTurn = true;
|
|
- } else {
|
|
- ani->spurImmunityLevel =
|
|
- ATH9K_ANI_SPUR_IMMUNE_LVL_OLD;
|
|
- ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_OLD;
|
|
+ if (AR_SREV_9300_20_OR_LATER(ah))
|
|
+ ani->mrcCCKOff =
|
|
+ !ATH9K_ANI_ENABLE_MRC_CCK;
|
|
+ else
|
|
+ ani->mrcCCKOff = true;
|
|
|
|
- ani->cckWeakSigThreshold =
|
|
- ATH9K_ANI_CCK_WEAK_SIG_THR;
|
|
- }
|
|
+ ani->ofdmsTurn = true;
|
|
|
|
ani->rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
|
|
ani->rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
|
|
- ani->ofdmWeakSigDetectOff =
|
|
- !ATH9K_ANI_USE_OFDM_WEAK_SIG;
|
|
+ ani->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG;
|
|
ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
|
|
ani->ofdmNoiseImmunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL;
|
|
ani->update_ani = false;
|
|
@@ -898,13 +545,8 @@ void ath9k_hw_ani_init(struct ath_hw *ah
|
|
* since we expect some ongoing maintenance on the tables, let's sanity
|
|
* check here default level should not modify INI setting.
|
|
*/
|
|
- if (use_new_ani(ah)) {
|
|
- ah->aniperiod = ATH9K_ANI_PERIOD_NEW;
|
|
- ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_NEW;
|
|
- } else {
|
|
- ah->aniperiod = ATH9K_ANI_PERIOD_OLD;
|
|
- ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_OLD;
|
|
- }
|
|
+ ah->aniperiod = ATH9K_ANI_PERIOD;
|
|
+ ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL;
|
|
|
|
if (ah->config.enable_ani)
|
|
ah->proc_phyerr |= HAL_PROCESS_ANI;
|
|
--- a/drivers/net/wireless/ath/ath9k/ani.h
|
|
+++ b/drivers/net/wireless/ath/ath9k/ani.h
|
|
@@ -24,42 +24,34 @@
|
|
#define BEACON_RSSI(ahp) (ahp->stats.avgbrssi)
|
|
|
|
/* units are errors per second */
|
|
-#define ATH9K_ANI_OFDM_TRIG_HIGH_OLD 500
|
|
-#define ATH9K_ANI_OFDM_TRIG_HIGH_NEW 3500
|
|
+#define ATH9K_ANI_OFDM_TRIG_HIGH 3500
|
|
#define ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI 1000
|
|
|
|
/* units are errors per second */
|
|
-#define ATH9K_ANI_OFDM_TRIG_LOW_OLD 200
|
|
-#define ATH9K_ANI_OFDM_TRIG_LOW_NEW 400
|
|
+#define ATH9K_ANI_OFDM_TRIG_LOW 400
|
|
#define ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI 900
|
|
|
|
/* units are errors per second */
|
|
-#define ATH9K_ANI_CCK_TRIG_HIGH_OLD 200
|
|
-#define ATH9K_ANI_CCK_TRIG_HIGH_NEW 600
|
|
+#define ATH9K_ANI_CCK_TRIG_HIGH 600
|
|
|
|
/* units are errors per second */
|
|
-#define ATH9K_ANI_CCK_TRIG_LOW_OLD 100
|
|
-#define ATH9K_ANI_CCK_TRIG_LOW_NEW 300
|
|
+#define ATH9K_ANI_CCK_TRIG_LOW 300
|
|
|
|
#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_OLD 7
|
|
-#define ATH9K_ANI_SPUR_IMMUNE_LVL_NEW 3
|
|
+#define ATH9K_ANI_SPUR_IMMUNE_LVL 3
|
|
|
|
-#define ATH9K_ANI_FIRSTEP_LVL_OLD 0
|
|
-#define ATH9K_ANI_FIRSTEP_LVL_NEW 2
|
|
+#define ATH9K_ANI_FIRSTEP_LVL 2
|
|
|
|
#define ATH9K_ANI_RSSI_THR_HIGH 40
|
|
#define ATH9K_ANI_RSSI_THR_LOW 7
|
|
|
|
-#define ATH9K_ANI_PERIOD_OLD 100
|
|
-#define ATH9K_ANI_PERIOD_NEW 300
|
|
+#define ATH9K_ANI_PERIOD 300
|
|
|
|
/* in ms */
|
|
-#define ATH9K_ANI_POLLINTERVAL_OLD 100
|
|
-#define ATH9K_ANI_POLLINTERVAL_NEW 1000
|
|
+#define ATH9K_ANI_POLLINTERVAL 1000
|
|
|
|
#define HAL_NOISE_IMMUNE_MAX 4
|
|
#define HAL_SPUR_IMMUNE_MAX 7
|
|
@@ -122,13 +114,12 @@ struct ar5416AniState {
|
|
u8 mrcCCKOff;
|
|
u8 spurImmunityLevel;
|
|
u8 firstepLevel;
|
|
- u8 ofdmWeakSigDetectOff;
|
|
+ u8 ofdmWeakSigDetect;
|
|
u8 cckWeakSigThreshold;
|
|
bool update_ani;
|
|
u32 listenTime;
|
|
int32_t rssiThrLow;
|
|
int32_t rssiThrHigh;
|
|
- u32 noiseFloor;
|
|
u32 ofdmPhyErrCount;
|
|
u32 cckPhyErrCount;
|
|
int16_t pktRssi[2];
|
|
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
|
|
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
|
|
@@ -995,141 +995,6 @@ static u32 ar5008_hw_compute_pll_control
|
|
return pll;
|
|
}
|
|
|
|
-static bool ar5008_hw_ani_control_old(struct ath_hw *ah,
|
|
- enum ath9k_ani_cmd cmd,
|
|
- int param)
|
|
-{
|
|
- struct ar5416AniState *aniState = &ah->curchan->ani;
|
|
- struct ath_common *common = ath9k_hw_common(ah);
|
|
-
|
|
- switch (cmd & ah->ani_function) {
|
|
- case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
|
|
- u32 level = param;
|
|
-
|
|
- if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
|
|
- ath_dbg(common, ANI, "level out of range (%u > %zu)\n",
|
|
- level, ARRAY_SIZE(ah->totalSizeDesired));
|
|
- return false;
|
|
- }
|
|
-
|
|
- REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
|
|
- AR_PHY_DESIRED_SZ_TOT_DES,
|
|
- ah->totalSizeDesired[level]);
|
|
- REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
|
|
- AR_PHY_AGC_CTL1_COARSE_LOW,
|
|
- ah->coarse_low[level]);
|
|
- REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
|
|
- AR_PHY_AGC_CTL1_COARSE_HIGH,
|
|
- ah->coarse_high[level]);
|
|
- REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
|
|
- AR_PHY_FIND_SIG_FIRPWR,
|
|
- ah->firpwr[level]);
|
|
-
|
|
- if (level > aniState->noiseImmunityLevel)
|
|
- ah->stats.ast_ani_niup++;
|
|
- else if (level < aniState->noiseImmunityLevel)
|
|
- ah->stats.ast_ani_nidown++;
|
|
- aniState->noiseImmunityLevel = level;
|
|
- break;
|
|
- }
|
|
- case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
|
|
- u32 on = param ? 1 : 0;
|
|
-
|
|
- if (on)
|
|
- REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
|
|
- AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
|
|
- else
|
|
- REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
|
|
- AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
|
|
-
|
|
- if (!on != aniState->ofdmWeakSigDetectOff) {
|
|
- if (on)
|
|
- ah->stats.ast_ani_ofdmon++;
|
|
- else
|
|
- ah->stats.ast_ani_ofdmoff++;
|
|
- aniState->ofdmWeakSigDetectOff = !on;
|
|
- }
|
|
- break;
|
|
- }
|
|
- case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
|
|
- static const int weakSigThrCck[] = { 8, 6 };
|
|
- u32 high = param ? 1 : 0;
|
|
-
|
|
- REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
|
|
- AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK,
|
|
- weakSigThrCck[high]);
|
|
- if (high != aniState->cckWeakSigThreshold) {
|
|
- if (high)
|
|
- ah->stats.ast_ani_cckhigh++;
|
|
- else
|
|
- ah->stats.ast_ani_ccklow++;
|
|
- aniState->cckWeakSigThreshold = high;
|
|
- }
|
|
- break;
|
|
- }
|
|
- case ATH9K_ANI_FIRSTEP_LEVEL:{
|
|
- static const int firstep[] = { 0, 4, 8 };
|
|
- u32 level = param;
|
|
-
|
|
- if (level >= ARRAY_SIZE(firstep)) {
|
|
- ath_dbg(common, ANI, "level out of range (%u > %zu)\n",
|
|
- level, ARRAY_SIZE(firstep));
|
|
- return false;
|
|
- }
|
|
- REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
|
|
- AR_PHY_FIND_SIG_FIRSTEP,
|
|
- firstep[level]);
|
|
- if (level > aniState->firstepLevel)
|
|
- ah->stats.ast_ani_stepup++;
|
|
- else if (level < aniState->firstepLevel)
|
|
- ah->stats.ast_ani_stepdown++;
|
|
- aniState->firstepLevel = level;
|
|
- break;
|
|
- }
|
|
- case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
|
|
- static const int cycpwrThr1[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
|
|
- u32 level = param;
|
|
-
|
|
- if (level >= ARRAY_SIZE(cycpwrThr1)) {
|
|
- ath_dbg(common, ANI, "level out of range (%u > %zu)\n",
|
|
- level, ARRAY_SIZE(cycpwrThr1));
|
|
- return false;
|
|
- }
|
|
- REG_RMW_FIELD(ah, AR_PHY_TIMING5,
|
|
- AR_PHY_TIMING5_CYCPWR_THR1,
|
|
- cycpwrThr1[level]);
|
|
- if (level > aniState->spurImmunityLevel)
|
|
- ah->stats.ast_ani_spurup++;
|
|
- else if (level < aniState->spurImmunityLevel)
|
|
- ah->stats.ast_ani_spurdown++;
|
|
- aniState->spurImmunityLevel = level;
|
|
- break;
|
|
- }
|
|
- case ATH9K_ANI_PRESENT:
|
|
- break;
|
|
- default:
|
|
- ath_dbg(common, ANI, "invalid cmd %u\n", cmd);
|
|
- return false;
|
|
- }
|
|
-
|
|
- ath_dbg(common, ANI, "ANI parameters:\n");
|
|
- ath_dbg(common, ANI,
|
|
- "noiseImmunityLevel=%d, spurImmunityLevel=%d, ofdmWeakSigDetectOff=%d\n",
|
|
- aniState->noiseImmunityLevel,
|
|
- aniState->spurImmunityLevel,
|
|
- !aniState->ofdmWeakSigDetectOff);
|
|
- ath_dbg(common, ANI,
|
|
- "cckWeakSigThreshold=%d, firstepLevel=%d, listenTime=%d\n",
|
|
- aniState->cckWeakSigThreshold,
|
|
- aniState->firstepLevel,
|
|
- aniState->listenTime);
|
|
- ath_dbg(common, ANI, "ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
|
|
- aniState->ofdmPhyErrCount,
|
|
- aniState->cckPhyErrCount);
|
|
-
|
|
- return true;
|
|
-}
|
|
-
|
|
static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
|
|
enum ath9k_ani_cmd cmd,
|
|
int param)
|
|
@@ -1206,18 +1071,18 @@ static bool ar5008_hw_ani_control_new(st
|
|
REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
|
|
AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
|
|
|
|
- if (!on != aniState->ofdmWeakSigDetectOff) {
|
|
+ if (on != aniState->ofdmWeakSigDetect) {
|
|
ath_dbg(common, ANI,
|
|
"** ch %d: ofdm weak signal: %s=>%s\n",
|
|
chan->channel,
|
|
- !aniState->ofdmWeakSigDetectOff ?
|
|
+ aniState->ofdmWeakSigDetect ?
|
|
"on" : "off",
|
|
on ? "on" : "off");
|
|
if (on)
|
|
ah->stats.ast_ani_ofdmon++;
|
|
else
|
|
ah->stats.ast_ani_ofdmoff++;
|
|
- aniState->ofdmWeakSigDetectOff = !on;
|
|
+ aniState->ofdmWeakSigDetect = on;
|
|
}
|
|
break;
|
|
}
|
|
@@ -1236,7 +1101,7 @@ static bool ar5008_hw_ani_control_new(st
|
|
* from INI file & cap value
|
|
*/
|
|
value = firstep_table[level] -
|
|
- firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] +
|
|
+ firstep_table[ATH9K_ANI_FIRSTEP_LVL] +
|
|
aniState->iniDef.firstep;
|
|
if (value < ATH9K_SIG_FIRSTEP_SETTING_MIN)
|
|
value = ATH9K_SIG_FIRSTEP_SETTING_MIN;
|
|
@@ -1251,7 +1116,7 @@ static bool ar5008_hw_ani_control_new(st
|
|
* from INI file & cap value
|
|
*/
|
|
value2 = firstep_table[level] -
|
|
- firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] +
|
|
+ firstep_table[ATH9K_ANI_FIRSTEP_LVL] +
|
|
aniState->iniDef.firstepLow;
|
|
if (value2 < ATH9K_SIG_FIRSTEP_SETTING_MIN)
|
|
value2 = ATH9K_SIG_FIRSTEP_SETTING_MIN;
|
|
@@ -1267,7 +1132,7 @@ static bool ar5008_hw_ani_control_new(st
|
|
chan->channel,
|
|
aniState->firstepLevel,
|
|
level,
|
|
- ATH9K_ANI_FIRSTEP_LVL_NEW,
|
|
+ ATH9K_ANI_FIRSTEP_LVL,
|
|
value,
|
|
aniState->iniDef.firstep);
|
|
ath_dbg(common, ANI,
|
|
@@ -1275,7 +1140,7 @@ static bool ar5008_hw_ani_control_new(st
|
|
chan->channel,
|
|
aniState->firstepLevel,
|
|
level,
|
|
- ATH9K_ANI_FIRSTEP_LVL_NEW,
|
|
+ ATH9K_ANI_FIRSTEP_LVL,
|
|
value2,
|
|
aniState->iniDef.firstepLow);
|
|
if (level > aniState->firstepLevel)
|
|
@@ -1300,7 +1165,7 @@ static bool ar5008_hw_ani_control_new(st
|
|
* from INI file & cap value
|
|
*/
|
|
value = cycpwrThr1_table[level] -
|
|
- cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] +
|
|
+ cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL] +
|
|
aniState->iniDef.cycpwrThr1;
|
|
if (value < ATH9K_SIG_SPUR_IMM_SETTING_MIN)
|
|
value = ATH9K_SIG_SPUR_IMM_SETTING_MIN;
|
|
@@ -1316,7 +1181,7 @@ static bool ar5008_hw_ani_control_new(st
|
|
* from INI file & cap value
|
|
*/
|
|
value2 = cycpwrThr1_table[level] -
|
|
- cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] +
|
|
+ cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL] +
|
|
aniState->iniDef.cycpwrThr1Ext;
|
|
if (value2 < ATH9K_SIG_SPUR_IMM_SETTING_MIN)
|
|
value2 = ATH9K_SIG_SPUR_IMM_SETTING_MIN;
|
|
@@ -1331,7 +1196,7 @@ static bool ar5008_hw_ani_control_new(st
|
|
chan->channel,
|
|
aniState->spurImmunityLevel,
|
|
level,
|
|
- ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
|
|
+ ATH9K_ANI_SPUR_IMMUNE_LVL,
|
|
value,
|
|
aniState->iniDef.cycpwrThr1);
|
|
ath_dbg(common, ANI,
|
|
@@ -1339,7 +1204,7 @@ static bool ar5008_hw_ani_control_new(st
|
|
chan->channel,
|
|
aniState->spurImmunityLevel,
|
|
level,
|
|
- ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
|
|
+ ATH9K_ANI_SPUR_IMMUNE_LVL,
|
|
value2,
|
|
aniState->iniDef.cycpwrThr1Ext);
|
|
if (level > aniState->spurImmunityLevel)
|
|
@@ -1367,7 +1232,7 @@ static bool ar5008_hw_ani_control_new(st
|
|
ath_dbg(common, ANI,
|
|
"ANI parameters: SI=%d, ofdmWS=%s FS=%d MRCcck=%s listenTime=%d ofdmErrs=%d cckErrs=%d\n",
|
|
aniState->spurImmunityLevel,
|
|
- !aniState->ofdmWeakSigDetectOff ? "on" : "off",
|
|
+ aniState->ofdmWeakSigDetect ? "on" : "off",
|
|
aniState->firstepLevel,
|
|
!aniState->mrcCCKOff ? "on" : "off",
|
|
aniState->listenTime,
|
|
@@ -1454,9 +1319,9 @@ static void ar5008_hw_ani_cache_ini_regs
|
|
AR_PHY_EXT_TIMING5_CYCPWR_THR1);
|
|
|
|
/* these levels just got reset to defaults by the INI */
|
|
- aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL_NEW;
|
|
- aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
|
|
- aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG;
|
|
+ aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
|
|
+ aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
|
|
+ aniState->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG;
|
|
aniState->mrcCCKOff = true; /* not available on pre AR9003 */
|
|
}
|
|
|
|
@@ -1545,11 +1410,8 @@ void ar5008_hw_attach_phy_ops(struct ath
|
|
priv_ops->do_getnf = ar5008_hw_do_getnf;
|
|
priv_ops->set_radar_params = ar5008_hw_set_radar_params;
|
|
|
|
- if (modparam_force_new_ani) {
|
|
- priv_ops->ani_control = ar5008_hw_ani_control_new;
|
|
- priv_ops->ani_cache_ini_regs = ar5008_hw_ani_cache_ini_regs;
|
|
- } else
|
|
- priv_ops->ani_control = ar5008_hw_ani_control_old;
|
|
+ priv_ops->ani_control = ar5008_hw_ani_control_new;
|
|
+ priv_ops->ani_cache_ini_regs = ar5008_hw_ani_cache_ini_regs;
|
|
|
|
if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah))
|
|
priv_ops->compute_pll_control = ar9160_hw_compute_pll_control;
|
|
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
|
|
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
|
|
@@ -21,10 +21,6 @@
|
|
#include "ar9002_initvals.h"
|
|
#include "ar9002_phy.h"
|
|
|
|
-int modparam_force_new_ani;
|
|
-module_param_named(force_new_ani, modparam_force_new_ani, int, 0444);
|
|
-MODULE_PARM_DESC(force_new_ani, "Force new ANI for AR5008, AR9001, AR9002");
|
|
-
|
|
/* General hardware code for the A5008/AR9001/AR9002 hadware families */
|
|
|
|
static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
|
|
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
|
|
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
|
|
@@ -825,18 +825,18 @@ static bool ar9003_hw_ani_control(struct
|
|
REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
|
|
AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
|
|
|
|
- if (!on != aniState->ofdmWeakSigDetectOff) {
|
|
+ if (on != aniState->ofdmWeakSigDetect) {
|
|
ath_dbg(common, ANI,
|
|
"** ch %d: ofdm weak signal: %s=>%s\n",
|
|
chan->channel,
|
|
- !aniState->ofdmWeakSigDetectOff ?
|
|
+ aniState->ofdmWeakSigDetect ?
|
|
"on" : "off",
|
|
on ? "on" : "off");
|
|
if (on)
|
|
ah->stats.ast_ani_ofdmon++;
|
|
else
|
|
ah->stats.ast_ani_ofdmoff++;
|
|
- aniState->ofdmWeakSigDetectOff = !on;
|
|
+ aniState->ofdmWeakSigDetect = on;
|
|
}
|
|
break;
|
|
}
|
|
@@ -855,7 +855,7 @@ static bool ar9003_hw_ani_control(struct
|
|
* from INI file & cap value
|
|
*/
|
|
value = firstep_table[level] -
|
|
- firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] +
|
|
+ firstep_table[ATH9K_ANI_FIRSTEP_LVL] +
|
|
aniState->iniDef.firstep;
|
|
if (value < ATH9K_SIG_FIRSTEP_SETTING_MIN)
|
|
value = ATH9K_SIG_FIRSTEP_SETTING_MIN;
|
|
@@ -870,7 +870,7 @@ static bool ar9003_hw_ani_control(struct
|
|
* from INI file & cap value
|
|
*/
|
|
value2 = firstep_table[level] -
|
|
- firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] +
|
|
+ firstep_table[ATH9K_ANI_FIRSTEP_LVL] +
|
|
aniState->iniDef.firstepLow;
|
|
if (value2 < ATH9K_SIG_FIRSTEP_SETTING_MIN)
|
|
value2 = ATH9K_SIG_FIRSTEP_SETTING_MIN;
|
|
@@ -886,7 +886,7 @@ static bool ar9003_hw_ani_control(struct
|
|
chan->channel,
|
|
aniState->firstepLevel,
|
|
level,
|
|
- ATH9K_ANI_FIRSTEP_LVL_NEW,
|
|
+ ATH9K_ANI_FIRSTEP_LVL,
|
|
value,
|
|
aniState->iniDef.firstep);
|
|
ath_dbg(common, ANI,
|
|
@@ -894,7 +894,7 @@ static bool ar9003_hw_ani_control(struct
|
|
chan->channel,
|
|
aniState->firstepLevel,
|
|
level,
|
|
- ATH9K_ANI_FIRSTEP_LVL_NEW,
|
|
+ ATH9K_ANI_FIRSTEP_LVL,
|
|
value2,
|
|
aniState->iniDef.firstepLow);
|
|
if (level > aniState->firstepLevel)
|
|
@@ -919,7 +919,7 @@ static bool ar9003_hw_ani_control(struct
|
|
* from INI file & cap value
|
|
*/
|
|
value = cycpwrThr1_table[level] -
|
|
- cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] +
|
|
+ cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL] +
|
|
aniState->iniDef.cycpwrThr1;
|
|
if (value < ATH9K_SIG_SPUR_IMM_SETTING_MIN)
|
|
value = ATH9K_SIG_SPUR_IMM_SETTING_MIN;
|
|
@@ -935,7 +935,7 @@ static bool ar9003_hw_ani_control(struct
|
|
* from INI file & cap value
|
|
*/
|
|
value2 = cycpwrThr1_table[level] -
|
|
- cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] +
|
|
+ cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL] +
|
|
aniState->iniDef.cycpwrThr1Ext;
|
|
if (value2 < ATH9K_SIG_SPUR_IMM_SETTING_MIN)
|
|
value2 = ATH9K_SIG_SPUR_IMM_SETTING_MIN;
|
|
@@ -950,7 +950,7 @@ static bool ar9003_hw_ani_control(struct
|
|
chan->channel,
|
|
aniState->spurImmunityLevel,
|
|
level,
|
|
- ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
|
|
+ ATH9K_ANI_SPUR_IMMUNE_LVL,
|
|
value,
|
|
aniState->iniDef.cycpwrThr1);
|
|
ath_dbg(common, ANI,
|
|
@@ -958,7 +958,7 @@ static bool ar9003_hw_ani_control(struct
|
|
chan->channel,
|
|
aniState->spurImmunityLevel,
|
|
level,
|
|
- ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
|
|
+ ATH9K_ANI_SPUR_IMMUNE_LVL,
|
|
value2,
|
|
aniState->iniDef.cycpwrThr1Ext);
|
|
if (level > aniState->spurImmunityLevel)
|
|
@@ -1002,7 +1002,7 @@ static bool ar9003_hw_ani_control(struct
|
|
ath_dbg(common, ANI,
|
|
"ANI parameters: SI=%d, ofdmWS=%s FS=%d MRCcck=%s listenTime=%d ofdmErrs=%d cckErrs=%d\n",
|
|
aniState->spurImmunityLevel,
|
|
- !aniState->ofdmWeakSigDetectOff ? "on" : "off",
|
|
+ aniState->ofdmWeakSigDetect ? "on" : "off",
|
|
aniState->firstepLevel,
|
|
!aniState->mrcCCKOff ? "on" : "off",
|
|
aniState->listenTime,
|
|
@@ -1111,9 +1111,9 @@ static void ar9003_hw_ani_cache_ini_regs
|
|
AR_PHY_EXT_CYCPWR_THR1);
|
|
|
|
/* these levels just got reset to defaults by the INI */
|
|
- aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL_NEW;
|
|
- aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
|
|
- aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG;
|
|
+ aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
|
|
+ aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
|
|
+ aniState->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG;
|
|
aniState->mrcCCKOff = !ATH9K_ANI_ENABLE_MRC_CCK;
|
|
}
|
|
|
|
--- a/drivers/net/wireless/ath/ath9k/debug.c
|
|
+++ b/drivers/net/wireless/ath/ath9k/debug.c
|
|
@@ -348,8 +348,6 @@ void ath_debug_stat_interrupt(struct ath
|
|
sc->debug.stats.istats.txok++;
|
|
if (status & ATH9K_INT_TXURN)
|
|
sc->debug.stats.istats.txurn++;
|
|
- if (status & ATH9K_INT_MIB)
|
|
- sc->debug.stats.istats.mib++;
|
|
if (status & ATH9K_INT_RXPHY)
|
|
sc->debug.stats.istats.rxphyerr++;
|
|
if (status & ATH9K_INT_RXKCM)
|
|
--- a/drivers/net/wireless/ath/ath9k/hw.h
|
|
+++ b/drivers/net/wireless/ath/ath9k/hw.h
|
|
@@ -1019,16 +1019,8 @@ void ar9002_hw_attach_ops(struct ath_hw
|
|
void ar9003_hw_attach_ops(struct ath_hw *ah);
|
|
|
|
void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan);
|
|
-/*
|
|
- * ANI work can be shared between all families but a next
|
|
- * generation implementation of ANI will be used only for AR9003 only
|
|
- * for now as the other families still need to be tested with the same
|
|
- * next generation ANI. Feel free to start testing it though for the
|
|
- * older families (AR5008, AR9001, AR9002) by using modparam_force_new_ani.
|
|
- */
|
|
-extern int modparam_force_new_ani;
|
|
+
|
|
void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning);
|
|
-void ath9k_hw_proc_mib_event(struct ath_hw *ah);
|
|
void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan);
|
|
|
|
#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
|
|
--- a/drivers/net/wireless/ath/ath9k/main.c
|
|
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
|
@@ -516,24 +516,6 @@ irqreturn_t ath_isr(int irq, void *dev)
|
|
ath9k_hw_set_interrupts(ah);
|
|
}
|
|
|
|
- if (status & ATH9K_INT_MIB) {
|
|
- /*
|
|
- * Disable interrupts until we service the MIB
|
|
- * interrupt; otherwise it will continue to
|
|
- * fire.
|
|
- */
|
|
- ath9k_hw_disable_interrupts(ah);
|
|
- /*
|
|
- * Let the hal handle the event. We assume
|
|
- * it will clear whatever condition caused
|
|
- * the interrupt.
|
|
- */
|
|
- spin_lock(&common->cc_lock);
|
|
- ath9k_hw_proc_mib_event(ah);
|
|
- spin_unlock(&common->cc_lock);
|
|
- ath9k_hw_enable_interrupts(ah);
|
|
- }
|
|
-
|
|
if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
|
|
if (status & ATH9K_INT_TIM_TIMER) {
|
|
if (ATH_DBG_WARN_ON_ONCE(sc->ps_idle))
|
|
@@ -959,14 +941,10 @@ static void ath9k_calculate_summary_stat
|
|
/*
|
|
* Enable MIB interrupts when there are hardware phy counters.
|
|
*/
|
|
- if ((iter_data.nstations + iter_data.nadhocs + iter_data.nmeshes) > 0) {
|
|
- if (ah->config.enable_ani)
|
|
- ah->imask |= ATH9K_INT_MIB;
|
|
+ if ((iter_data.nstations + iter_data.nadhocs + iter_data.nmeshes) > 0)
|
|
ah->imask |= ATH9K_INT_TSFOOR;
|
|
- } else {
|
|
- ah->imask &= ~ATH9K_INT_MIB;
|
|
+ else
|
|
ah->imask &= ~ATH9K_INT_TSFOOR;
|
|
- }
|
|
|
|
ath9k_hw_set_interrupts(ah);
|
|
|
|
--- a/net/mac80211/agg-rx.c
|
|
+++ b/net/mac80211/agg-rx.c
|
|
@@ -201,6 +201,8 @@ static void ieee80211_send_addba_resp(st
|
|
memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
|
|
else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
|
|
memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);
|
|
+ else if (sdata->vif.type == NL80211_IFTYPE_WDS)
|
|
+ memcpy(mgmt->bssid, da, ETH_ALEN);
|
|
|
|
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
|
|
IEEE80211_STYPE_ACTION);
|
|
--- a/net/mac80211/agg-tx.c
|
|
+++ b/net/mac80211/agg-tx.c
|
|
@@ -81,7 +81,8 @@ static void ieee80211_send_addba_request
|
|
memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
|
|
if (sdata->vif.type == NL80211_IFTYPE_AP ||
|
|
sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
|
|
- sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
|
|
+ sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
|
|
+ sdata->vif.type == NL80211_IFTYPE_WDS)
|
|
memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
|
|
else if (sdata->vif.type == NL80211_IFTYPE_STATION)
|
|
memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
|
|
@@ -456,6 +457,7 @@ int ieee80211_start_tx_ba_session(struct
|
|
sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
|
|
sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
|
|
sdata->vif.type != NL80211_IFTYPE_AP &&
|
|
+ sdata->vif.type != NL80211_IFTYPE_WDS &&
|
|
sdata->vif.type != NL80211_IFTYPE_ADHOC)
|
|
return -EINVAL;
|
|
|
|
--- a/net/mac80211/debugfs_sta.c
|
|
+++ b/net/mac80211/debugfs_sta.c
|
|
@@ -63,11 +63,11 @@ static ssize_t sta_flags_read(struct fil
|
|
test_sta_flag(sta, WLAN_STA_##flg) ? #flg "\n" : ""
|
|
|
|
int res = scnprintf(buf, sizeof(buf),
|
|
- "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
|
|
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
|
|
TEST(AUTH), TEST(ASSOC), TEST(PS_STA),
|
|
TEST(PS_DRIVER), TEST(AUTHORIZED),
|
|
TEST(SHORT_PREAMBLE),
|
|
- TEST(WME), TEST(WDS), TEST(CLEAR_PS_FILT),
|
|
+ TEST(WME), TEST(CLEAR_PS_FILT),
|
|
TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL),
|
|
TEST(UAPSD), TEST(SP), TEST(TDLS_PEER),
|
|
TEST(TDLS_PEER_AUTH), TEST(4ADDR_EVENT),
|
|
--- a/net/mac80211/iface.c
|
|
+++ b/net/mac80211/iface.c
|
|
@@ -284,7 +284,6 @@ static int ieee80211_do_open(struct net_
|
|
{
|
|
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
|
struct ieee80211_local *local = sdata->local;
|
|
- struct sta_info *sta;
|
|
u32 changed = 0;
|
|
int res;
|
|
u32 hw_reconf_flags = 0;
|
|
@@ -430,28 +429,6 @@ static int ieee80211_do_open(struct net_
|
|
|
|
set_bit(SDATA_STATE_RUNNING, &sdata->state);
|
|
|
|
- if (sdata->vif.type == NL80211_IFTYPE_WDS) {
|
|
- /* Create STA entry for the WDS peer */
|
|
- sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
|
|
- GFP_KERNEL);
|
|
- if (!sta) {
|
|
- res = -ENOMEM;
|
|
- goto err_del_interface;
|
|
- }
|
|
-
|
|
- sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
|
|
- sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
|
|
- sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
|
|
-
|
|
- res = sta_info_insert(sta);
|
|
- if (res) {
|
|
- /* STA has been freed */
|
|
- goto err_del_interface;
|
|
- }
|
|
-
|
|
- rate_control_rate_init(sta);
|
|
- }
|
|
-
|
|
/*
|
|
* set_multicast_list will be invoked by the networking core
|
|
* which will check whether any increments here were done in
|
|
@@ -639,6 +616,8 @@ static void ieee80211_do_stop(struct iee
|
|
ieee80211_configure_filter(local);
|
|
break;
|
|
default:
|
|
+ flush_work(&local->hw_roc_start);
|
|
+ flush_work(&local->hw_roc_done);
|
|
flush_work(&sdata->work);
|
|
/*
|
|
* When we get here, the interface is marked down.
|
|
@@ -845,6 +824,72 @@ static void ieee80211_if_setup(struct ne
|
|
dev->destructor = free_netdev;
|
|
}
|
|
|
|
+static void ieee80211_wds_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
|
|
+ struct sk_buff *skb)
|
|
+{
|
|
+ struct ieee80211_local *local = sdata->local;
|
|
+ struct ieee80211_rx_status *rx_status;
|
|
+ struct ieee802_11_elems elems;
|
|
+ struct ieee80211_mgmt *mgmt;
|
|
+ struct sta_info *sta;
|
|
+ size_t baselen;
|
|
+ u32 rates = 0;
|
|
+ u16 stype;
|
|
+ bool new = false;
|
|
+ enum ieee80211_band band = local->hw.conf.channel->band;
|
|
+ struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
|
|
+
|
|
+ rx_status = IEEE80211_SKB_RXCB(skb);
|
|
+ mgmt = (struct ieee80211_mgmt *) skb->data;
|
|
+ stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
|
|
+
|
|
+ if (stype != IEEE80211_STYPE_BEACON)
|
|
+ return;
|
|
+
|
|
+ baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
|
|
+ if (baselen > skb->len)
|
|
+ return;
|
|
+
|
|
+ ieee802_11_parse_elems(mgmt->u.probe_resp.variable,
|
|
+ skb->len - baselen, &elems);
|
|
+
|
|
+ rates = ieee80211_sta_get_rates(local, &elems, band, NULL);
|
|
+
|
|
+ rcu_read_lock();
|
|
+
|
|
+ sta = sta_info_get(sdata, sdata->u.wds.remote_addr);
|
|
+
|
|
+ if (!sta) {
|
|
+ rcu_read_unlock();
|
|
+ sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
|
|
+ GFP_KERNEL);
|
|
+ if (!sta)
|
|
+ return;
|
|
+
|
|
+ new = true;
|
|
+ }
|
|
+
|
|
+ sta->last_rx = jiffies;
|
|
+ sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
|
|
+
|
|
+ if (elems.ht_cap_elem)
|
|
+ ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
|
|
+ elems.ht_cap_elem, &sta->sta.ht_cap);
|
|
+
|
|
+ if (elems.wmm_param)
|
|
+ set_sta_flag(sta, WLAN_STA_WME);
|
|
+
|
|
+ if (new) {
|
|
+ sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
|
|
+ sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
|
|
+ sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
|
|
+ rate_control_rate_init(sta);
|
|
+ sta_info_insert_rcu(sta);
|
|
+ }
|
|
+
|
|
+ rcu_read_unlock();
|
|
+}
|
|
+
|
|
static void ieee80211_iface_work(struct work_struct *work)
|
|
{
|
|
struct ieee80211_sub_if_data *sdata =
|
|
@@ -949,6 +994,9 @@ static void ieee80211_iface_work(struct
|
|
break;
|
|
ieee80211_mesh_rx_queued_mgmt(sdata, skb);
|
|
break;
|
|
+ case NL80211_IFTYPE_WDS:
|
|
+ ieee80211_wds_rx_queued_mgmt(sdata, skb);
|
|
+ break;
|
|
default:
|
|
WARN(1, "frame for unexpected interface type");
|
|
break;
|
|
--- a/net/mac80211/rx.c
|
|
+++ b/net/mac80211/rx.c
|
|
@@ -2281,6 +2281,7 @@ ieee80211_rx_h_action(struct ieee80211_r
|
|
sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
|
|
sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
|
|
sdata->vif.type != NL80211_IFTYPE_AP &&
|
|
+ sdata->vif.type != NL80211_IFTYPE_WDS &&
|
|
sdata->vif.type != NL80211_IFTYPE_ADHOC)
|
|
break;
|
|
|
|
@@ -2495,14 +2496,15 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_
|
|
|
|
if (!ieee80211_vif_is_mesh(&sdata->vif) &&
|
|
sdata->vif.type != NL80211_IFTYPE_ADHOC &&
|
|
- sdata->vif.type != NL80211_IFTYPE_STATION)
|
|
+ sdata->vif.type != NL80211_IFTYPE_STATION &&
|
|
+ sdata->vif.type != NL80211_IFTYPE_WDS)
|
|
return RX_DROP_MONITOR;
|
|
|
|
switch (stype) {
|
|
case cpu_to_le16(IEEE80211_STYPE_AUTH):
|
|
case cpu_to_le16(IEEE80211_STYPE_BEACON):
|
|
case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
|
|
- /* process for all: mesh, mlme, ibss */
|
|
+ /* process for all: mesh, mlme, ibss, wds */
|
|
break;
|
|
case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP):
|
|
case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP):
|
|
@@ -2833,10 +2835,16 @@ static int prepare_for_handlers(struct i
|
|
}
|
|
break;
|
|
case NL80211_IFTYPE_WDS:
|
|
- if (bssid || !ieee80211_is_data(hdr->frame_control))
|
|
- return 0;
|
|
if (!ether_addr_equal(sdata->u.wds.remote_addr, hdr->addr2))
|
|
return 0;
|
|
+
|
|
+ if (ieee80211_is_data(hdr->frame_control) ||
|
|
+ ieee80211_is_action(hdr->frame_control)) {
|
|
+ if (compare_ether_addr(sdata->vif.addr, hdr->addr1))
|
|
+ return 0;
|
|
+ } else if (!ieee80211_is_beacon(hdr->frame_control))
|
|
+ return 0;
|
|
+
|
|
break;
|
|
default:
|
|
/* should never get here */
|
|
--- a/net/mac80211/sta_info.h
|
|
+++ b/net/mac80211/sta_info.h
|
|
@@ -32,7 +32,6 @@
|
|
* @WLAN_STA_SHORT_PREAMBLE: Station is capable of receiving short-preamble
|
|
* frames.
|
|
* @WLAN_STA_WME: Station is a QoS-STA.
|
|
- * @WLAN_STA_WDS: Station is one of our WDS peers.
|
|
* @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the
|
|
* IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next
|
|
* frame to this station is transmitted.
|
|
@@ -64,7 +63,6 @@ enum ieee80211_sta_info_flags {
|
|
WLAN_STA_AUTHORIZED,
|
|
WLAN_STA_SHORT_PREAMBLE,
|
|
WLAN_STA_WME,
|
|
- WLAN_STA_WDS,
|
|
WLAN_STA_CLEAR_PS_FILT,
|
|
WLAN_STA_MFP,
|
|
WLAN_STA_BLOCK_BA,
|
|
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
|
|
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
|
|
@@ -214,6 +214,7 @@ struct ath_frame_info {
|
|
enum ath9k_key_type keytype;
|
|
u8 keyix;
|
|
u8 retries;
|
|
+ u8 rtscts_rate;
|
|
};
|
|
|
|
struct ath_buf_state {
|
|
--- a/drivers/net/wireless/ath/ath9k/xmit.c
|
|
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
|
|
@@ -938,6 +938,7 @@ static void ath_buf_set_rate(struct ath_
|
|
struct ieee80211_tx_rate *rates;
|
|
const struct ieee80211_rate *rate;
|
|
struct ieee80211_hdr *hdr;
|
|
+ struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu);
|
|
int i;
|
|
u8 rix = 0;
|
|
|
|
@@ -948,18 +949,7 @@ static void ath_buf_set_rate(struct ath_
|
|
|
|
/* set dur_update_en for l-sig computation except for PS-Poll frames */
|
|
info->dur_update = !ieee80211_is_pspoll(hdr->frame_control);
|
|
-
|
|
- /*
|
|
- * We check if Short Preamble is needed for the CTS rate by
|
|
- * checking the BSS's global flag.
|
|
- * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used.
|
|
- */
|
|
- rate = ieee80211_get_rts_cts_rate(sc->hw, tx_info);
|
|
- info->rtscts_rate = rate->hw_value;
|
|
-
|
|
- if (tx_info->control.vif &&
|
|
- tx_info->control.vif->bss_conf.use_short_preamble)
|
|
- info->rtscts_rate |= rate->hw_value_short;
|
|
+ info->rtscts_rate = fi->rtscts_rate;
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
bool is_40, is_sgi, is_sp;
|
|
@@ -1001,13 +991,13 @@ static void ath_buf_set_rate(struct ath_
|
|
}
|
|
|
|
/* legacy rates */
|
|
+ rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx];
|
|
if ((tx_info->band == IEEE80211_BAND_2GHZ) &&
|
|
!(rate->flags & IEEE80211_RATE_ERP_G))
|
|
phy = WLAN_RC_PHY_CCK;
|
|
else
|
|
phy = WLAN_RC_PHY_OFDM;
|
|
|
|
- rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx];
|
|
info->rates[i].Rate = rate->hw_value;
|
|
if (rate->hw_value_short) {
|
|
if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
|
|
@@ -1776,10 +1766,22 @@ static void setup_frame_info(struct ieee
|
|
struct ieee80211_sta *sta = tx_info->control.sta;
|
|
struct ieee80211_key_conf *hw_key = tx_info->control.hw_key;
|
|
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
|
+ const struct ieee80211_rate *rate;
|
|
struct ath_frame_info *fi = get_frame_info(skb);
|
|
struct ath_node *an = NULL;
|
|
enum ath9k_key_type keytype;
|
|
+ bool short_preamble = false;
|
|
+
|
|
+ /*
|
|
+ * We check if Short Preamble is needed for the CTS rate by
|
|
+ * checking the BSS's global flag.
|
|
+ * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used.
|
|
+ */
|
|
+ if (tx_info->control.vif &&
|
|
+ tx_info->control.vif->bss_conf.use_short_preamble)
|
|
+ short_preamble = true;
|
|
|
|
+ rate = ieee80211_get_rts_cts_rate(hw, tx_info);
|
|
keytype = ath9k_cmn_get_hw_crypto_keytype(skb);
|
|
|
|
if (sta)
|
|
@@ -1794,6 +1796,9 @@ static void setup_frame_info(struct ieee
|
|
fi->keyix = ATH9K_TXKEYIX_INVALID;
|
|
fi->keytype = keytype;
|
|
fi->framelen = framelen;
|
|
+ fi->rtscts_rate = rate->hw_value;
|
|
+ if (short_preamble)
|
|
+ fi->rtscts_rate |= rate->hw_value_short;
|
|
}
|
|
|
|
u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate)
|
|
--- a/net/wireless/nl80211.c
|
|
+++ b/net/wireless/nl80211.c
|
|
@@ -2246,6 +2246,33 @@ static int nl80211_parse_beacon(struct g
|
|
return 0;
|
|
}
|
|
|
|
+static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
|
|
+ struct cfg80211_ap_settings *params)
|
|
+{
|
|
+ struct wireless_dev *wdev;
|
|
+ bool ret = false;
|
|
+
|
|
+ mutex_lock(&rdev->devlist_mtx);
|
|
+
|
|
+ list_for_each_entry(wdev, &rdev->netdev_list, list) {
|
|
+ if (wdev->iftype != NL80211_IFTYPE_AP &&
|
|
+ wdev->iftype != NL80211_IFTYPE_P2P_GO)
|
|
+ continue;
|
|
+
|
|
+ if (!wdev->preset_chan)
|
|
+ continue;
|
|
+
|
|
+ params->channel = wdev->preset_chan;
|
|
+ params->channel_type = wdev->preset_chantype;
|
|
+ ret = true;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ mutex_unlock(&rdev->devlist_mtx);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
|
|
{
|
|
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
|
@@ -2348,7 +2375,7 @@ static int nl80211_start_ap(struct sk_bu
|
|
} else if (wdev->preset_chan) {
|
|
params.channel = wdev->preset_chan;
|
|
params.channel_type = wdev->preset_chantype;
|
|
- } else
|
|
+ } else if (!nl80211_get_ap_channel(rdev, ¶ms))
|
|
return -EINVAL;
|
|
|
|
if (!cfg80211_can_beacon_sec_chan(&rdev->wiphy, params.channel,
|
|
@@ -2356,8 +2383,11 @@ static int nl80211_start_ap(struct sk_bu
|
|
return -EINVAL;
|
|
|
|
err = rdev->ops->start_ap(&rdev->wiphy, dev, ¶ms);
|
|
- if (!err)
|
|
+ if (!err) {
|
|
+ wdev->preset_chan = params.channel;
|
|
+ wdev->preset_chantype = params.channel_type;
|
|
wdev->beacon_interval = params.beacon_interval;
|
|
+ }
|
|
return err;
|
|
}
|
|
|