aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/ar9003_phy.c
diff options
context:
space:
mode:
authorLuis R. Rodriguez <lrodriguez@atheros.com>2010-06-12 00:33:45 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-06-14 15:39:29 -0400
commite36b27aff1b10c81c53990b28da4ab6ab0ed0761 (patch)
treefa2642ea274398ccaac4b9e03efecc766030409b /drivers/net/wireless/ath/ath9k/ar9003_phy.c
parent40346b66799b7d382e61bbb68a6b6bbdd20f320e (diff)
ath9k: add new ANI implementation for AR9003
This adds support for ANI for AR9003. The implementation for ANI for AR9003 is slightly different than the one used for the older chipset families. It can technically be used for the older families as well but this is not yet fully tested so we only enable the new ANI for the AR5008, AR9001 and AR9002 families with a module parameter, force_new_ani. The old ANI implementation is left intact. Details of the new ANI implemention: * ANI adjustment logic is now table driven so that each ANI level setting is parameterized. This makes adjustments much more deterministic than the old procedure based logic and allows adjustments to be made incrementally to several parameters per level. * ANI register settings are now relative to INI values; so ANI param zero level == INI value. Appropriate floor and ceiling values are obeyed when adjustments are combined with INI values. * ANI processing is done once per second rather that every 100ms. The poll interval is now a set upon hardware initialization and can be picked up by the core driver. * OFDM error and CCK error processing are made in a round robin fashion rather than allowing all OFDM adjustments to be made before CCK adjustments. * ANI adjusts MRC CCK off in the presence of high CCK errors * When adjusting spur immunity (SI) and OFDM weak signal detection, ANI now sets register values for the extension channel too * When adjusting FIR step (ST), ANI now sets register for FIR step low too * FIR step adjustments now allow for an extra level of immunity for extremely noisy environments * The old Noise immunity setting (NI), which changes coarse low, size desired, etc have been removed. Changing these settings could affect up RIFS RX as well. * CCK weak signal adjustment is no longer used * ANI no longer enables phy error interrupts; in all cases phy hw counting registers are used instead * The phy error count (overflow) interrupts are also no longer used for ANI adjustments. All ANI adjustments are made via the polling routine and no adjustments are possible in the ISR context anymore * A history settings buffer is now correctly used for each channel; channel settings are initialized with the defaults but later changes are restored when returning back to that channel * When scanning, ANI is disabled settings are returned to (INI) defaults. * OFDM phy error thresholds are now 400 & 1000 (errors/second units) for low/high water marks, providing increased stability/hysteresis when changing levels. * Similarly CCK phy error thresholds are now 300 & 600 (errors/second) Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/ar9003_phy.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c385
1 files changed, 286 insertions, 99 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index c714579b5483..bababbe1edea 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -17,6 +17,28 @@
17#include "hw.h" 17#include "hw.h"
18#include "ar9003_phy.h" 18#include "ar9003_phy.h"
19 19
20static const int firstep_table[] =
21/* level: 0 1 2 3 4 5 6 7 8 */
22 { -4, -2, 0, 2, 4, 6, 8, 10, 12 }; /* lvl 0-8, default 2 */
23
24static const int cycpwrThr1_table[] =
25/* level: 0 1 2 3 4 5 6 7 8 */
26 { -6, -4, -2, 0, 2, 4, 6, 8 }; /* lvl 0-7, default 3 */
27
28/*
29 * register values to turn OFDM weak signal detection OFF
30 */
31static const int m1ThreshLow_off = 127;
32static const int m2ThreshLow_off = 127;
33static const int m1Thresh_off = 127;
34static const int m2Thresh_off = 127;
35static const int m2CountThr_off = 31;
36static const int m2CountThrLow_off = 63;
37static const int m1ThreshLowExt_off = 127;
38static const int m2ThreshLowExt_off = 127;
39static const int m1ThreshExt_off = 127;
40static const int m2ThreshExt_off = 127;
41
20/** 42/**
21 * ar9003_hw_set_channel - set channel on single-chip device 43 * ar9003_hw_set_channel - set channel on single-chip device
22 * @ah: atheros hardware structure 44 * @ah: atheros hardware structure
@@ -94,7 +116,7 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
94} 116}
95 117
96/** 118/**
97 * ar9003_hw_spur_mitigate - convert baseband spur frequency 119 * ar9003_hw_spur_mitigate_mrc_cck - convert baseband spur frequency
98 * @ah: atheros hardware structure 120 * @ah: atheros hardware structure
99 * @chan: 121 * @chan:
100 * 122 *
@@ -732,71 +754,68 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
732{ 754{
733 struct ar5416AniState *aniState = ah->curani; 755 struct ar5416AniState *aniState = ah->curani;
734 struct ath_common *common = ath9k_hw_common(ah); 756 struct ath_common *common = ath9k_hw_common(ah);
757 struct ath9k_channel *chan = ah->curchan;
758 s32 value, value2;
735 759
736 switch (cmd & ah->ani_function) { 760 switch (cmd & ah->ani_function) {
737 case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
738 u32 level = param;
739
740 if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
741 ath_print(common, ATH_DBG_ANI,
742 "level out of range (%u > %u)\n",
743 level,
744 (unsigned)ARRAY_SIZE(ah->totalSizeDesired));
745 return false;
746 }
747
748 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
749 AR_PHY_DESIRED_SZ_TOT_DES,
750 ah->totalSizeDesired[level]);
751 REG_RMW_FIELD(ah, AR_PHY_AGC,
752 AR_PHY_AGC_COARSE_LOW,
753 ah->coarse_low[level]);
754 REG_RMW_FIELD(ah, AR_PHY_AGC,
755 AR_PHY_AGC_COARSE_HIGH,
756 ah->coarse_high[level]);
757 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
758 AR_PHY_FIND_SIG_FIRPWR, ah->firpwr[level]);
759
760 if (level > aniState->noiseImmunityLevel)
761 ah->stats.ast_ani_niup++;
762 else if (level < aniState->noiseImmunityLevel)
763 ah->stats.ast_ani_nidown++;
764 aniState->noiseImmunityLevel = level;
765 break;
766 }
767 case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{ 761 case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
768 const int m1ThreshLow[] = { 127, 50 }; 762 /*
769 const int m2ThreshLow[] = { 127, 40 }; 763 * on == 1 means ofdm weak signal detection is ON
770 const int m1Thresh[] = { 127, 0x4d }; 764 * on == 1 is the default, for less noise immunity
771 const int m2Thresh[] = { 127, 0x40 }; 765 *
772 const int m2CountThr[] = { 31, 16 }; 766 * on == 0 means ofdm weak signal detection is OFF
773 const int m2CountThrLow[] = { 63, 48 }; 767 * on == 0 means more noise imm
768 */
774 u32 on = param ? 1 : 0; 769 u32 on = param ? 1 : 0;
770 /*
771 * make register setting for default
772 * (weak sig detect ON) come from INI file
773 */
774 int m1ThreshLow = on ?
775 aniState->iniDef.m1ThreshLow : m1ThreshLow_off;
776 int m2ThreshLow = on ?
777 aniState->iniDef.m2ThreshLow : m2ThreshLow_off;
778 int m1Thresh = on ?
779 aniState->iniDef.m1Thresh : m1Thresh_off;
780 int m2Thresh = on ?
781 aniState->iniDef.m2Thresh : m2Thresh_off;
782 int m2CountThr = on ?
783 aniState->iniDef.m2CountThr : m2CountThr_off;
784 int m2CountThrLow = on ?
785 aniState->iniDef.m2CountThrLow : m2CountThrLow_off;
786 int m1ThreshLowExt = on ?
787 aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off;
788 int m2ThreshLowExt = on ?
789 aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off;
790 int m1ThreshExt = on ?
791 aniState->iniDef.m1ThreshExt : m1ThreshExt_off;
792 int m2ThreshExt = on ?
793 aniState->iniDef.m2ThreshExt : m2ThreshExt_off;
775 794
776 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, 795 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
777 AR_PHY_SFCORR_LOW_M1_THRESH_LOW, 796 AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
778 m1ThreshLow[on]); 797 m1ThreshLow);
779 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, 798 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
780 AR_PHY_SFCORR_LOW_M2_THRESH_LOW, 799 AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
781 m2ThreshLow[on]); 800 m2ThreshLow);
782 REG_RMW_FIELD(ah, AR_PHY_SFCORR, 801 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
783 AR_PHY_SFCORR_M1_THRESH, m1Thresh[on]); 802 AR_PHY_SFCORR_M1_THRESH, m1Thresh);
784 REG_RMW_FIELD(ah, AR_PHY_SFCORR, 803 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
785 AR_PHY_SFCORR_M2_THRESH, m2Thresh[on]); 804 AR_PHY_SFCORR_M2_THRESH, m2Thresh);
786 REG_RMW_FIELD(ah, AR_PHY_SFCORR, 805 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
787 AR_PHY_SFCORR_M2COUNT_THR, m2CountThr[on]); 806 AR_PHY_SFCORR_M2COUNT_THR, m2CountThr);
788 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, 807 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
789 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, 808 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
790 m2CountThrLow[on]); 809 m2CountThrLow);
791 810
792 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 811 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
793 AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLow[on]); 812 AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLowExt);
794 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 813 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
795 AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLow[on]); 814 AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLowExt);
796 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 815 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
797 AR_PHY_SFCORR_EXT_M1_THRESH, m1Thresh[on]); 816 AR_PHY_SFCORR_EXT_M1_THRESH, m1ThreshExt);
798 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 817 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
799 AR_PHY_SFCORR_EXT_M2_THRESH, m2Thresh[on]); 818 AR_PHY_SFCORR_EXT_M2_THRESH, m2ThreshExt);
800 819
801 if (on) 820 if (on)
802 REG_SET_BIT(ah, AR_PHY_SFCORR_LOW, 821 REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
@@ -806,6 +825,12 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
806 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); 825 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
807 826
808 if (!on != aniState->ofdmWeakSigDetectOff) { 827 if (!on != aniState->ofdmWeakSigDetectOff) {
828 ath_print(common, ATH_DBG_ANI,
829 "** ch %d: ofdm weak signal: %s=>%s\n",
830 chan->channel,
831 !aniState->ofdmWeakSigDetectOff ?
832 "on" : "off",
833 on ? "on" : "off");
809 if (on) 834 if (on)
810 ah->stats.ast_ani_ofdmon++; 835 ah->stats.ast_ani_ofdmon++;
811 else 836 else
@@ -814,64 +839,167 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
814 } 839 }
815 break; 840 break;
816 } 841 }
817 case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
818 const int weakSigThrCck[] = { 8, 6 };
819 u32 high = param ? 1 : 0;
820
821 REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
822 AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK,
823 weakSigThrCck[high]);
824 if (high != aniState->cckWeakSigThreshold) {
825 if (high)
826 ah->stats.ast_ani_cckhigh++;
827 else
828 ah->stats.ast_ani_ccklow++;
829 aniState->cckWeakSigThreshold = high;
830 }
831 break;
832 }
833 case ATH9K_ANI_FIRSTEP_LEVEL:{ 842 case ATH9K_ANI_FIRSTEP_LEVEL:{
834 const int firstep[] = { 0, 4, 8 };
835 u32 level = param; 843 u32 level = param;
836 844
837 if (level >= ARRAY_SIZE(firstep)) { 845 if (level >= ARRAY_SIZE(firstep_table)) {
838 ath_print(common, ATH_DBG_ANI, 846 ath_print(common, ATH_DBG_ANI,
839 "level out of range (%u > %u)\n", 847 "ATH9K_ANI_FIRSTEP_LEVEL: level "
848 "out of range (%u > %u)\n",
840 level, 849 level,
841 (unsigned) ARRAY_SIZE(firstep)); 850 (unsigned) ARRAY_SIZE(firstep_table));
842 return false; 851 return false;
843 } 852 }
853
854 /*
855 * make register setting relative to default
856 * from INI file & cap value
857 */
858 value = firstep_table[level] -
859 firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] +
860 aniState->iniDef.firstep;
861 if (value < ATH9K_SIG_FIRSTEP_SETTING_MIN)
862 value = ATH9K_SIG_FIRSTEP_SETTING_MIN;
863 if (value > ATH9K_SIG_FIRSTEP_SETTING_MAX)
864 value = ATH9K_SIG_FIRSTEP_SETTING_MAX;
844 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, 865 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
845 AR_PHY_FIND_SIG_FIRSTEP, 866 AR_PHY_FIND_SIG_FIRSTEP,
846 firstep[level]); 867 value);
847 if (level > aniState->firstepLevel) 868 /*
848 ah->stats.ast_ani_stepup++; 869 * we need to set first step low register too
849 else if (level < aniState->firstepLevel) 870 * make register setting relative to default
850 ah->stats.ast_ani_stepdown++; 871 * from INI file & cap value
851 aniState->firstepLevel = level; 872 */
873 value2 = firstep_table[level] -
874 firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] +
875 aniState->iniDef.firstepLow;
876 if (value2 < ATH9K_SIG_FIRSTEP_SETTING_MIN)
877 value2 = ATH9K_SIG_FIRSTEP_SETTING_MIN;
878 if (value2 > ATH9K_SIG_FIRSTEP_SETTING_MAX)
879 value2 = ATH9K_SIG_FIRSTEP_SETTING_MAX;
880
881 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW,
882 AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW, value2);
883
884 if (level != aniState->firstepLevel) {
885 ath_print(common, ATH_DBG_ANI,
886 "** ch %d: level %d=>%d[def:%d] "
887 "firstep[level]=%d ini=%d\n",
888 chan->channel,
889 aniState->firstepLevel,
890 level,
891 ATH9K_ANI_FIRSTEP_LVL_NEW,
892 value,
893 aniState->iniDef.firstep);
894 ath_print(common, ATH_DBG_ANI,
895 "** ch %d: level %d=>%d[def:%d] "
896 "firstep_low[level]=%d ini=%d\n",
897 chan->channel,
898 aniState->firstepLevel,
899 level,
900 ATH9K_ANI_FIRSTEP_LVL_NEW,
901 value2,
902 aniState->iniDef.firstepLow);
903 if (level > aniState->firstepLevel)
904 ah->stats.ast_ani_stepup++;
905 else if (level < aniState->firstepLevel)
906 ah->stats.ast_ani_stepdown++;
907 aniState->firstepLevel = level;
908 }
852 break; 909 break;
853 } 910 }
854 case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{ 911 case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
855 const int cycpwrThr1[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
856 u32 level = param; 912 u32 level = param;
857 913
858 if (level >= ARRAY_SIZE(cycpwrThr1)) { 914 if (level >= ARRAY_SIZE(cycpwrThr1_table)) {
859 ath_print(common, ATH_DBG_ANI, 915 ath_print(common, ATH_DBG_ANI,
860 "level out of range (%u > %u)\n", 916 "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level "
917 "out of range (%u > %u)\n",
861 level, 918 level,
862 (unsigned) ARRAY_SIZE(cycpwrThr1)); 919 (unsigned) ARRAY_SIZE(cycpwrThr1_table));
863 return false; 920 return false;
864 } 921 }
922 /*
923 * make register setting relative to default
924 * from INI file & cap value
925 */
926 value = cycpwrThr1_table[level] -
927 cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] +
928 aniState->iniDef.cycpwrThr1;
929 if (value < ATH9K_SIG_SPUR_IMM_SETTING_MIN)
930 value = ATH9K_SIG_SPUR_IMM_SETTING_MIN;
931 if (value > ATH9K_SIG_SPUR_IMM_SETTING_MAX)
932 value = ATH9K_SIG_SPUR_IMM_SETTING_MAX;
865 REG_RMW_FIELD(ah, AR_PHY_TIMING5, 933 REG_RMW_FIELD(ah, AR_PHY_TIMING5,
866 AR_PHY_TIMING5_CYCPWR_THR1, 934 AR_PHY_TIMING5_CYCPWR_THR1,
867 cycpwrThr1[level]); 935 value);
868 if (level > aniState->spurImmunityLevel) 936
869 ah->stats.ast_ani_spurup++; 937 /*
870 else if (level < aniState->spurImmunityLevel) 938 * set AR_PHY_EXT_CCA for extension channel
871 ah->stats.ast_ani_spurdown++; 939 * make register setting relative to default
872 aniState->spurImmunityLevel = level; 940 * from INI file & cap value
941 */
942 value2 = cycpwrThr1_table[level] -
943 cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] +
944 aniState->iniDef.cycpwrThr1Ext;
945 if (value2 < ATH9K_SIG_SPUR_IMM_SETTING_MIN)
946 value2 = ATH9K_SIG_SPUR_IMM_SETTING_MIN;
947 if (value2 > ATH9K_SIG_SPUR_IMM_SETTING_MAX)
948 value2 = ATH9K_SIG_SPUR_IMM_SETTING_MAX;
949 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
950 AR_PHY_EXT_CYCPWR_THR1, value2);
951
952 if (level != aniState->spurImmunityLevel) {
953 ath_print(common, ATH_DBG_ANI,
954 "** ch %d: level %d=>%d[def:%d] "
955 "cycpwrThr1[level]=%d ini=%d\n",
956 chan->channel,
957 aniState->spurImmunityLevel,
958 level,
959 ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
960 value,
961 aniState->iniDef.cycpwrThr1);
962 ath_print(common, ATH_DBG_ANI,
963 "** ch %d: level %d=>%d[def:%d] "
964 "cycpwrThr1Ext[level]=%d ini=%d\n",
965 chan->channel,
966 aniState->spurImmunityLevel,
967 level,
968 ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
969 value2,
970 aniState->iniDef.cycpwrThr1Ext);
971 if (level > aniState->spurImmunityLevel)
972 ah->stats.ast_ani_spurup++;
973 else if (level < aniState->spurImmunityLevel)
974 ah->stats.ast_ani_spurdown++;
975 aniState->spurImmunityLevel = level;
976 }
873 break; 977 break;
874 } 978 }
979 case ATH9K_ANI_MRC_CCK:{
980 /*
981 * is_on == 1 means MRC CCK ON (default, less noise imm)
982 * is_on == 0 means MRC CCK is OFF (more noise imm)
983 */
984 bool is_on = param ? 1 : 0;
985 REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL,
986 AR_PHY_MRC_CCK_ENABLE, is_on);
987 REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL,
988 AR_PHY_MRC_CCK_MUX_REG, is_on);
989 if (!is_on != aniState->mrcCCKOff) {
990 ath_print(common, ATH_DBG_ANI,
991 "** ch %d: MRC CCK: %s=>%s\n",
992 chan->channel,
993 !aniState->mrcCCKOff ? "on" : "off",
994 is_on ? "on" : "off");
995 if (is_on)
996 ah->stats.ast_ani_ccklow++;
997 else
998 ah->stats.ast_ani_cckhigh++;
999 aniState->mrcCCKOff = !is_on;
1000 }
1001 break;
1002 }
875 case ATH9K_ANI_PRESENT: 1003 case ATH9K_ANI_PRESENT:
876 break; 1004 break;
877 default: 1005 default:
@@ -880,25 +1008,19 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
880 return false; 1008 return false;
881 } 1009 }
882 1010
883 ath_print(common, ATH_DBG_ANI, "ANI parameters:\n");
884 ath_print(common, ATH_DBG_ANI, 1011 ath_print(common, ATH_DBG_ANI,
885 "noiseImmunityLevel=%d, spurImmunityLevel=%d, " 1012 "ANI parameters: SI=%d, ofdmWS=%s FS=%d "
886 "ofdmWeakSigDetectOff=%d\n", 1013 "MRCcck=%s listenTime=%d CC=%d listen=%d "
887 aniState->noiseImmunityLevel, 1014 "ofdmErrs=%d cckErrs=%d\n",
888 aniState->spurImmunityLevel, 1015 aniState->spurImmunityLevel,
889 !aniState->ofdmWeakSigDetectOff); 1016 !aniState->ofdmWeakSigDetectOff ? "on" : "off",
890 ath_print(common, ATH_DBG_ANI,
891 "cckWeakSigThreshold=%d, "
892 "firstepLevel=%d, listenTime=%d\n",
893 aniState->cckWeakSigThreshold,
894 aniState->firstepLevel, 1017 aniState->firstepLevel,
895 aniState->listenTime); 1018 !aniState->mrcCCKOff ? "on" : "off",
896 ath_print(common, ATH_DBG_ANI, 1019 aniState->listenTime,
897 "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n", 1020 aniState->cycleCount,
898 aniState->cycleCount, 1021 aniState->listenTime,
899 aniState->ofdmPhyErrCount, 1022 aniState->ofdmPhyErrCount,
900 aniState->cckPhyErrCount); 1023 aniState->cckPhyErrCount);
901
902 return true; 1024 return true;
903} 1025}
904 1026
@@ -1111,6 +1233,70 @@ static void ar9003_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
1111 } 1233 }
1112} 1234}
1113 1235
1236/*
1237 * Initialize the ANI register values with default (ini) values.
1238 * This routine is called during a (full) hardware reset after
1239 * all the registers are initialised from the INI.
1240 */
1241static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
1242{
1243 struct ar5416AniState *aniState;
1244 struct ath_common *common = ath9k_hw_common(ah);
1245 struct ath9k_channel *chan = ah->curchan;
1246 struct ath9k_ani_default *iniDef;
1247 int index;
1248 u32 val;
1249
1250 index = ath9k_hw_get_ani_channel_idx(ah, chan);
1251 aniState = &ah->ani[index];
1252 ah->curani = aniState;
1253 iniDef = &aniState->iniDef;
1254
1255 ath_print(common, ATH_DBG_ANI,
1256 "ver %d.%d opmode %u chan %d Mhz/0x%x\n",
1257 ah->hw_version.macVersion,
1258 ah->hw_version.macRev,
1259 ah->opmode,
1260 chan->channel,
1261 chan->channelFlags);
1262
1263 val = REG_READ(ah, AR_PHY_SFCORR);
1264 iniDef->m1Thresh = MS(val, AR_PHY_SFCORR_M1_THRESH);
1265 iniDef->m2Thresh = MS(val, AR_PHY_SFCORR_M2_THRESH);
1266 iniDef->m2CountThr = MS(val, AR_PHY_SFCORR_M2COUNT_THR);
1267
1268 val = REG_READ(ah, AR_PHY_SFCORR_LOW);
1269 iniDef->m1ThreshLow = MS(val, AR_PHY_SFCORR_LOW_M1_THRESH_LOW);
1270 iniDef->m2ThreshLow = MS(val, AR_PHY_SFCORR_LOW_M2_THRESH_LOW);
1271 iniDef->m2CountThrLow = MS(val, AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW);
1272
1273 val = REG_READ(ah, AR_PHY_SFCORR_EXT);
1274 iniDef->m1ThreshExt = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH);
1275 iniDef->m2ThreshExt = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH);
1276 iniDef->m1ThreshLowExt = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH_LOW);
1277 iniDef->m2ThreshLowExt = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH_LOW);
1278 iniDef->firstep = REG_READ_FIELD(ah,
1279 AR_PHY_FIND_SIG,
1280 AR_PHY_FIND_SIG_FIRSTEP);
1281 iniDef->firstepLow = REG_READ_FIELD(ah,
1282 AR_PHY_FIND_SIG_LOW,
1283 AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW);
1284 iniDef->cycpwrThr1 = REG_READ_FIELD(ah,
1285 AR_PHY_TIMING5,
1286 AR_PHY_TIMING5_CYCPWR_THR1);
1287 iniDef->cycpwrThr1Ext = REG_READ_FIELD(ah,
1288 AR_PHY_EXT_CCA,
1289 AR_PHY_EXT_CYCPWR_THR1);
1290
1291 /* these levels just got reset to defaults by the INI */
1292 aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL_NEW;
1293 aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
1294 aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG;
1295 aniState->mrcCCKOff = !ATH9K_ANI_ENABLE_MRC_CCK;
1296
1297 aniState->cycleCount = 0;
1298}
1299
1114void ar9003_hw_attach_phy_ops(struct ath_hw *ah) 1300void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
1115{ 1301{
1116 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); 1302 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
@@ -1131,6 +1317,7 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
1131 priv_ops->ani_control = ar9003_hw_ani_control; 1317 priv_ops->ani_control = ar9003_hw_ani_control;
1132 priv_ops->do_getnf = ar9003_hw_do_getnf; 1318 priv_ops->do_getnf = ar9003_hw_do_getnf;
1133 priv_ops->loadnf = ar9003_hw_loadnf; 1319 priv_ops->loadnf = ar9003_hw_loadnf;
1320 priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs;
1134} 1321}
1135 1322
1136void ar9003_hw_bb_watchdog_config(struct ath_hw *ah) 1323void ar9003_hw_bb_watchdog_config(struct ath_hw *ah)