aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRajkumar Manoharan <rmanohar@qca.qualcomm.com>2012-03-14 20:04:26 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-04-09 16:05:52 -0400
commit54da20d83f0e7fe87b75aec44bc2b1448d119320 (patch)
treeaee471dfdc06698c83ce38b563e4926a5838bb0c
parent7dd30d447b7f4a129586cce8e57d0163dde876b0 (diff)
ath9k_hw: improve ANI processing and rx desensitizing parameters
This patch improves ANI operations by switching among the immunity levels based on PHY errors and beacon rssi which will adjust receiver desensitizing parameters. The changes are * Configure the Weak Signal Detection based on current immunity value. * At highest OFDM immunity level poor performance was observed with strong interference. By tuning the FIR step and spur immunity levels and not changing any weak signal detection thresholds at any level helped to improve the performance. * ANI took long time to recover back to lower immunity levels on heavy data load. As the listen time got reset to zero before reaching to the 5x of aniperiod, the immunity level is not lowering back even without any interference. This patch fix that. Cc: Paul Stewart <pstew@google.com> Cc: Susinder Gulasekaran <susinder@qca.qualcomm.com> Signed-off-by: Suresh Chandrasekaran <csuresh@qca.qualcomm.com> Signed-off-by: Rajkumar Manoharan <rmanohar@qca.qualcomm.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c49
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.h6
-rw-r--r--drivers/net/wireless/ath/ath9k/ar5008_phy.c38
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c49
4 files changed, 27 insertions, 115 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 7e0ea4e9833..47a9fb4a116 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -46,8 +46,8 @@ static const struct ani_ofdm_level_entry ofdm_level_table[] = {
46 { 5, 4, 1 }, /* lvl 5 */ 46 { 5, 4, 1 }, /* lvl 5 */
47 { 6, 5, 1 }, /* lvl 6 */ 47 { 6, 5, 1 }, /* lvl 6 */
48 { 7, 6, 1 }, /* lvl 7 */ 48 { 7, 6, 1 }, /* lvl 7 */
49 { 7, 7, 1 }, /* lvl 8 */ 49 { 7, 6, 0 }, /* lvl 8 */
50 { 7, 8, 0 } /* lvl 9 */ 50 { 7, 7, 0 } /* lvl 9 */
51}; 51};
52#define ATH9K_ANI_OFDM_NUM_LEVEL \ 52#define ATH9K_ANI_OFDM_NUM_LEVEL \
53 ARRAY_SIZE(ofdm_level_table) 53 ARRAY_SIZE(ofdm_level_table)
@@ -91,8 +91,8 @@ static const struct ani_cck_level_entry cck_level_table[] = {
91 { 4, 0 }, /* lvl 4 */ 91 { 4, 0 }, /* lvl 4 */
92 { 5, 0 }, /* lvl 5 */ 92 { 5, 0 }, /* lvl 5 */
93 { 6, 0 }, /* lvl 6 */ 93 { 6, 0 }, /* lvl 6 */
94 { 7, 0 }, /* lvl 7 (only for high rssi) */ 94 { 6, 0 }, /* lvl 7 (only for high rssi) */
95 { 8, 0 } /* lvl 8 (only for high rssi) */ 95 { 7, 0 } /* lvl 8 (only for high rssi) */
96}; 96};
97 97
98#define ATH9K_ANI_CCK_NUM_LEVEL \ 98#define ATH9K_ANI_CCK_NUM_LEVEL \
@@ -290,16 +290,9 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel)
290 ATH9K_ANI_FIRSTEP_LEVEL, 290 ATH9K_ANI_FIRSTEP_LEVEL,
291 entry_ofdm->fir_step_level); 291 entry_ofdm->fir_step_level);
292 292
293 if ((ah->opmode != NL80211_IFTYPE_STATION && 293 if ((aniState->noiseFloor >= aniState->rssiThrHigh) &&
294 ah->opmode != NL80211_IFTYPE_ADHOC) || 294 (!aniState->ofdmWeakSigDetectOff !=
295 aniState->noiseFloor <= aniState->rssiThrHigh) { 295 entry_ofdm->ofdm_weak_signal_on)) {
296 if (aniState->ofdmWeakSigDetectOff)
297 /* force on ofdm weak sig detect */
298 ath9k_hw_ani_control(ah,
299 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
300 true);
301 else if (aniState->ofdmWeakSigDetectOff ==
302 entry_ofdm->ofdm_weak_signal_on)
303 ath9k_hw_ani_control(ah, 296 ath9k_hw_ani_control(ah,
304 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, 297 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
305 entry_ofdm->ofdm_weak_signal_on); 298 entry_ofdm->ofdm_weak_signal_on);
@@ -717,26 +710,30 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan)
717 ofdmPhyErrRate, aniState->cckNoiseImmunityLevel, 710 ofdmPhyErrRate, aniState->cckNoiseImmunityLevel,
718 cckPhyErrRate, aniState->ofdmsTurn); 711 cckPhyErrRate, aniState->ofdmsTurn);
719 712
720 if (aniState->listenTime > 5 * ah->aniperiod) { 713 if (aniState->listenTime > ah->aniperiod) {
721 if (ofdmPhyErrRate <= ah->config.ofdm_trig_low && 714 if (cckPhyErrRate < ah->config.cck_trig_low &&
722 cckPhyErrRate <= ah->config.cck_trig_low) { 715 ((ofdmPhyErrRate < ah->config.ofdm_trig_low &&
716 aniState->ofdmNoiseImmunityLevel <
717 ATH9K_ANI_OFDM_DEF_LEVEL) ||
718 (ofdmPhyErrRate < ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI &&
719 aniState->ofdmNoiseImmunityLevel >=
720 ATH9K_ANI_OFDM_DEF_LEVEL))) {
723 ath9k_hw_ani_lower_immunity(ah); 721 ath9k_hw_ani_lower_immunity(ah);
724 aniState->ofdmsTurn = !aniState->ofdmsTurn; 722 aniState->ofdmsTurn = !aniState->ofdmsTurn;
725 } 723 } else if ((ofdmPhyErrRate > ah->config.ofdm_trig_high &&
726 ath9k_ani_restart(ah); 724 aniState->ofdmNoiseImmunityLevel >=
727 } else if (aniState->listenTime > ah->aniperiod) { 725 ATH9K_ANI_OFDM_DEF_LEVEL) ||
728 /* check to see if need to raise immunity */ 726 (ofdmPhyErrRate >
729 if (ofdmPhyErrRate > ah->config.ofdm_trig_high && 727 ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI &&
730 (cckPhyErrRate <= ah->config.cck_trig_high || 728 aniState->ofdmNoiseImmunityLevel <
731 aniState->ofdmsTurn)) { 729 ATH9K_ANI_OFDM_DEF_LEVEL)) {
732 ath9k_hw_ani_ofdm_err_trigger(ah); 730 ath9k_hw_ani_ofdm_err_trigger(ah);
733 ath9k_ani_restart(ah);
734 aniState->ofdmsTurn = false; 731 aniState->ofdmsTurn = false;
735 } else if (cckPhyErrRate > ah->config.cck_trig_high) { 732 } else if (cckPhyErrRate > ah->config.cck_trig_high) {
736 ath9k_hw_ani_cck_err_trigger(ah); 733 ath9k_hw_ani_cck_err_trigger(ah);
737 ath9k_ani_restart(ah);
738 aniState->ofdmsTurn = true; 734 aniState->ofdmsTurn = true;
739 } 735 }
736 ath9k_ani_restart(ah);
740 } 737 }
741} 738}
742EXPORT_SYMBOL(ath9k_hw_ani_monitor); 739EXPORT_SYMBOL(ath9k_hw_ani_monitor);
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
index 83029d6c7b2..72e2b874e17 100644
--- a/drivers/net/wireless/ath/ath9k/ani.h
+++ b/drivers/net/wireless/ath/ath9k/ani.h
@@ -25,11 +25,13 @@
25 25
26/* units are errors per second */ 26/* units are errors per second */
27#define ATH9K_ANI_OFDM_TRIG_HIGH_OLD 500 27#define ATH9K_ANI_OFDM_TRIG_HIGH_OLD 500
28#define ATH9K_ANI_OFDM_TRIG_HIGH_NEW 1000 28#define ATH9K_ANI_OFDM_TRIG_HIGH_NEW 3500
29#define ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI 1000
29 30
30/* units are errors per second */ 31/* units are errors per second */
31#define ATH9K_ANI_OFDM_TRIG_LOW_OLD 200 32#define ATH9K_ANI_OFDM_TRIG_LOW_OLD 200
32#define ATH9K_ANI_OFDM_TRIG_LOW_NEW 400 33#define ATH9K_ANI_OFDM_TRIG_LOW_NEW 400
34#define ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI 900
33 35
34/* units are errors per second */ 36/* units are errors per second */
35#define ATH9K_ANI_CCK_TRIG_HIGH_OLD 200 37#define ATH9K_ANI_CCK_TRIG_HIGH_OLD 200
@@ -53,7 +55,7 @@
53#define ATH9K_ANI_RSSI_THR_LOW 7 55#define ATH9K_ANI_RSSI_THR_LOW 7
54 56
55#define ATH9K_ANI_PERIOD_OLD 100 57#define ATH9K_ANI_PERIOD_OLD 100
56#define ATH9K_ANI_PERIOD_NEW 1000 58#define ATH9K_ANI_PERIOD_NEW 300
57 59
58/* in ms */ 60/* in ms */
59#define ATH9K_ANI_POLLINTERVAL_OLD 100 61#define ATH9K_ANI_POLLINTERVAL_OLD 100
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index d7d8e919914..52ff5caf2d0 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -1047,46 +1047,8 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah,
1047 break; 1047 break;
1048 } 1048 }
1049 case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{ 1049 case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
1050 static const int m1ThreshLow[] = { 127, 50 };
1051 static const int m2ThreshLow[] = { 127, 40 };
1052 static const int m1Thresh[] = { 127, 0x4d };
1053 static const int m2Thresh[] = { 127, 0x40 };
1054 static const int m2CountThr[] = { 31, 16 };
1055 static const int m2CountThrLow[] = { 63, 48 };
1056 u32 on = param ? 1 : 0; 1050 u32 on = param ? 1 : 0;
1057 1051
1058 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
1059 AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
1060 m1ThreshLow[on]);
1061 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
1062 AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
1063 m2ThreshLow[on]);
1064 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
1065 AR_PHY_SFCORR_M1_THRESH,
1066 m1Thresh[on]);
1067 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
1068 AR_PHY_SFCORR_M2_THRESH,
1069 m2Thresh[on]);
1070 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
1071 AR_PHY_SFCORR_M2COUNT_THR,
1072 m2CountThr[on]);
1073 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
1074 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
1075 m2CountThrLow[on]);
1076
1077 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
1078 AR_PHY_SFCORR_EXT_M1_THRESH_LOW,
1079 m1ThreshLow[on]);
1080 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
1081 AR_PHY_SFCORR_EXT_M2_THRESH_LOW,
1082 m2ThreshLow[on]);
1083 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
1084 AR_PHY_SFCORR_EXT_M1_THRESH,
1085 m1Thresh[on]);
1086 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
1087 AR_PHY_SFCORR_EXT_M2_THRESH,
1088 m2Thresh[on]);
1089
1090 if (on) 1052 if (on)
1091 REG_SET_BIT(ah, AR_PHY_SFCORR_LOW, 1053 REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
1092 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); 1054 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index bc992b237ae..79070bf04ea 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -823,55 +823,6 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
823 * on == 0 means more noise imm 823 * on == 0 means more noise imm
824 */ 824 */
825 u32 on = param ? 1 : 0; 825 u32 on = param ? 1 : 0;
826 /*
827 * make register setting for default
828 * (weak sig detect ON) come from INI file
829 */
830 int m1ThreshLow = on ?
831 aniState->iniDef.m1ThreshLow : m1ThreshLow_off;
832 int m2ThreshLow = on ?
833 aniState->iniDef.m2ThreshLow : m2ThreshLow_off;
834 int m1Thresh = on ?
835 aniState->iniDef.m1Thresh : m1Thresh_off;
836 int m2Thresh = on ?
837 aniState->iniDef.m2Thresh : m2Thresh_off;
838 int m2CountThr = on ?
839 aniState->iniDef.m2CountThr : m2CountThr_off;
840 int m2CountThrLow = on ?
841 aniState->iniDef.m2CountThrLow : m2CountThrLow_off;
842 int m1ThreshLowExt = on ?
843 aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off;
844 int m2ThreshLowExt = on ?
845 aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off;
846 int m1ThreshExt = on ?
847 aniState->iniDef.m1ThreshExt : m1ThreshExt_off;
848 int m2ThreshExt = on ?
849 aniState->iniDef.m2ThreshExt : m2ThreshExt_off;
850
851 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
852 AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
853 m1ThreshLow);
854 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
855 AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
856 m2ThreshLow);
857 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
858 AR_PHY_SFCORR_M1_THRESH, m1Thresh);
859 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
860 AR_PHY_SFCORR_M2_THRESH, m2Thresh);
861 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
862 AR_PHY_SFCORR_M2COUNT_THR, m2CountThr);
863 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
864 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
865 m2CountThrLow);
866
867 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
868 AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLowExt);
869 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
870 AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLowExt);
871 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
872 AR_PHY_SFCORR_EXT_M1_THRESH, m1ThreshExt);
873 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
874 AR_PHY_SFCORR_EXT_M2_THRESH, m2ThreshExt);
875 826
876 if (on) 827 if (on)
877 REG_SET_BIT(ah, AR_PHY_SFCORR_LOW, 828 REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,