aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2010-04-15 17:38:39 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-04-16 15:43:25 -0400
commitc16fcb49b3849b4dceec9e4bbeb013b0713c7b38 (patch)
treed0bf7517ade9dd8c203746d4ffec0d36f86b37f2
parentcffb5e49a147cfc6491f561f9b330e1001276185 (diff)
ath9k_hw: Split off ANI control to the PHY ops
Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c186
-rw-r--r--drivers/net/wireless/ath/ath9k/ar5008_phy.c184
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/hw-ops.h6
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h2
5 files changed, 201 insertions, 185 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 031802c8c125..5a2d867a4e92 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -15,7 +15,7 @@
15 */ 15 */
16 16
17#include "hw.h" 17#include "hw.h"
18#include "ar9002_phy.h" 18#include "hw-ops.h"
19 19
20static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah, 20static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
21 struct ath9k_channel *chan) 21 struct ath9k_channel *chan)
@@ -38,190 +38,6 @@ static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
38 return 0; 38 return 0;
39} 39}
40 40
41static bool ath9k_hw_ani_control(struct ath_hw *ah,
42 enum ath9k_ani_cmd cmd, int param)
43{
44 struct ar5416AniState *aniState = ah->curani;
45 struct ath_common *common = ath9k_hw_common(ah);
46
47 switch (cmd & ah->ani_function) {
48 case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
49 u32 level = param;
50
51 if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
52 ath_print(common, ATH_DBG_ANI,
53 "level out of range (%u > %u)\n",
54 level,
55 (unsigned)ARRAY_SIZE(ah->totalSizeDesired));
56 return false;
57 }
58
59 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
60 AR_PHY_DESIRED_SZ_TOT_DES,
61 ah->totalSizeDesired[level]);
62 REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
63 AR_PHY_AGC_CTL1_COARSE_LOW,
64 ah->coarse_low[level]);
65 REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
66 AR_PHY_AGC_CTL1_COARSE_HIGH,
67 ah->coarse_high[level]);
68 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
69 AR_PHY_FIND_SIG_FIRPWR,
70 ah->firpwr[level]);
71
72 if (level > aniState->noiseImmunityLevel)
73 ah->stats.ast_ani_niup++;
74 else if (level < aniState->noiseImmunityLevel)
75 ah->stats.ast_ani_nidown++;
76 aniState->noiseImmunityLevel = level;
77 break;
78 }
79 case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
80 const int m1ThreshLow[] = { 127, 50 };
81 const int m2ThreshLow[] = { 127, 40 };
82 const int m1Thresh[] = { 127, 0x4d };
83 const int m2Thresh[] = { 127, 0x40 };
84 const int m2CountThr[] = { 31, 16 };
85 const int m2CountThrLow[] = { 63, 48 };
86 u32 on = param ? 1 : 0;
87
88 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
89 AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
90 m1ThreshLow[on]);
91 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
92 AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
93 m2ThreshLow[on]);
94 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
95 AR_PHY_SFCORR_M1_THRESH,
96 m1Thresh[on]);
97 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
98 AR_PHY_SFCORR_M2_THRESH,
99 m2Thresh[on]);
100 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
101 AR_PHY_SFCORR_M2COUNT_THR,
102 m2CountThr[on]);
103 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
104 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
105 m2CountThrLow[on]);
106
107 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
108 AR_PHY_SFCORR_EXT_M1_THRESH_LOW,
109 m1ThreshLow[on]);
110 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
111 AR_PHY_SFCORR_EXT_M2_THRESH_LOW,
112 m2ThreshLow[on]);
113 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
114 AR_PHY_SFCORR_EXT_M1_THRESH,
115 m1Thresh[on]);
116 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
117 AR_PHY_SFCORR_EXT_M2_THRESH,
118 m2Thresh[on]);
119
120 if (on)
121 REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
122 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
123 else
124 REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
125 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
126
127 if (!on != aniState->ofdmWeakSigDetectOff) {
128 if (on)
129 ah->stats.ast_ani_ofdmon++;
130 else
131 ah->stats.ast_ani_ofdmoff++;
132 aniState->ofdmWeakSigDetectOff = !on;
133 }
134 break;
135 }
136 case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
137 const int weakSigThrCck[] = { 8, 6 };
138 u32 high = param ? 1 : 0;
139
140 REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
141 AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK,
142 weakSigThrCck[high]);
143 if (high != aniState->cckWeakSigThreshold) {
144 if (high)
145 ah->stats.ast_ani_cckhigh++;
146 else
147 ah->stats.ast_ani_ccklow++;
148 aniState->cckWeakSigThreshold = high;
149 }
150 break;
151 }
152 case ATH9K_ANI_FIRSTEP_LEVEL:{
153 const int firstep[] = { 0, 4, 8 };
154 u32 level = param;
155
156 if (level >= ARRAY_SIZE(firstep)) {
157 ath_print(common, ATH_DBG_ANI,
158 "level out of range (%u > %u)\n",
159 level,
160 (unsigned) ARRAY_SIZE(firstep));
161 return false;
162 }
163 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
164 AR_PHY_FIND_SIG_FIRSTEP,
165 firstep[level]);
166 if (level > aniState->firstepLevel)
167 ah->stats.ast_ani_stepup++;
168 else if (level < aniState->firstepLevel)
169 ah->stats.ast_ani_stepdown++;
170 aniState->firstepLevel = level;
171 break;
172 }
173 case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
174 const int cycpwrThr1[] =
175 { 2, 4, 6, 8, 10, 12, 14, 16 };
176 u32 level = param;
177
178 if (level >= ARRAY_SIZE(cycpwrThr1)) {
179 ath_print(common, ATH_DBG_ANI,
180 "level out of range (%u > %u)\n",
181 level,
182 (unsigned) ARRAY_SIZE(cycpwrThr1));
183 return false;
184 }
185 REG_RMW_FIELD(ah, AR_PHY_TIMING5,
186 AR_PHY_TIMING5_CYCPWR_THR1,
187 cycpwrThr1[level]);
188 if (level > aniState->spurImmunityLevel)
189 ah->stats.ast_ani_spurup++;
190 else if (level < aniState->spurImmunityLevel)
191 ah->stats.ast_ani_spurdown++;
192 aniState->spurImmunityLevel = level;
193 break;
194 }
195 case ATH9K_ANI_PRESENT:
196 break;
197 default:
198 ath_print(common, ATH_DBG_ANI,
199 "invalid cmd %u\n", cmd);
200 return false;
201 }
202
203 ath_print(common, ATH_DBG_ANI, "ANI parameters:\n");
204 ath_print(common, ATH_DBG_ANI,
205 "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
206 "ofdmWeakSigDetectOff=%d\n",
207 aniState->noiseImmunityLevel,
208 aniState->spurImmunityLevel,
209 !aniState->ofdmWeakSigDetectOff);
210 ath_print(common, ATH_DBG_ANI,
211 "cckWeakSigThreshold=%d, "
212 "firstepLevel=%d, listenTime=%d\n",
213 aniState->cckWeakSigThreshold,
214 aniState->firstepLevel,
215 aniState->listenTime);
216 ath_print(common, ATH_DBG_ANI,
217 "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
218 aniState->cycleCount,
219 aniState->ofdmPhyErrCount,
220 aniState->cckPhyErrCount);
221
222 return true;
223}
224
225static void ath9k_hw_update_mibstats(struct ath_hw *ah, 41static void ath9k_hw_update_mibstats(struct ath_hw *ah,
226 struct ath9k_mib_stats *stats) 42 struct ath9k_mib_stats *stats)
227{ 43{
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 9685f4c6fc99..dddca59ea46d 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -1015,6 +1015,189 @@ static u32 ar5008_hw_compute_pll_control(struct ath_hw *ah,
1015 return pll; 1015 return pll;
1016} 1016}
1017 1017
1018static bool ar5008_hw_ani_control(struct ath_hw *ah,
1019 enum ath9k_ani_cmd cmd, int param)
1020{
1021 struct ar5416AniState *aniState = ah->curani;
1022 struct ath_common *common = ath9k_hw_common(ah);
1023
1024 switch (cmd & ah->ani_function) {
1025 case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
1026 u32 level = param;
1027
1028 if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
1029 ath_print(common, ATH_DBG_ANI,
1030 "level out of range (%u > %u)\n",
1031 level,
1032 (unsigned)ARRAY_SIZE(ah->totalSizeDesired));
1033 return false;
1034 }
1035
1036 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
1037 AR_PHY_DESIRED_SZ_TOT_DES,
1038 ah->totalSizeDesired[level]);
1039 REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
1040 AR_PHY_AGC_CTL1_COARSE_LOW,
1041 ah->coarse_low[level]);
1042 REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
1043 AR_PHY_AGC_CTL1_COARSE_HIGH,
1044 ah->coarse_high[level]);
1045 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
1046 AR_PHY_FIND_SIG_FIRPWR,
1047 ah->firpwr[level]);
1048
1049 if (level > aniState->noiseImmunityLevel)
1050 ah->stats.ast_ani_niup++;
1051 else if (level < aniState->noiseImmunityLevel)
1052 ah->stats.ast_ani_nidown++;
1053 aniState->noiseImmunityLevel = level;
1054 break;
1055 }
1056 case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
1057 const int m1ThreshLow[] = { 127, 50 };
1058 const int m2ThreshLow[] = { 127, 40 };
1059 const int m1Thresh[] = { 127, 0x4d };
1060 const int m2Thresh[] = { 127, 0x40 };
1061 const int m2CountThr[] = { 31, 16 };
1062 const int m2CountThrLow[] = { 63, 48 };
1063 u32 on = param ? 1 : 0;
1064
1065 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
1066 AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
1067 m1ThreshLow[on]);
1068 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
1069 AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
1070 m2ThreshLow[on]);
1071 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
1072 AR_PHY_SFCORR_M1_THRESH,
1073 m1Thresh[on]);
1074 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
1075 AR_PHY_SFCORR_M2_THRESH,
1076 m2Thresh[on]);
1077 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
1078 AR_PHY_SFCORR_M2COUNT_THR,
1079 m2CountThr[on]);
1080 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
1081 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
1082 m2CountThrLow[on]);
1083
1084 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
1085 AR_PHY_SFCORR_EXT_M1_THRESH_LOW,
1086 m1ThreshLow[on]);
1087 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
1088 AR_PHY_SFCORR_EXT_M2_THRESH_LOW,
1089 m2ThreshLow[on]);
1090 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
1091 AR_PHY_SFCORR_EXT_M1_THRESH,
1092 m1Thresh[on]);
1093 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
1094 AR_PHY_SFCORR_EXT_M2_THRESH,
1095 m2Thresh[on]);
1096
1097 if (on)
1098 REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
1099 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
1100 else
1101 REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
1102 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
1103
1104 if (!on != aniState->ofdmWeakSigDetectOff) {
1105 if (on)
1106 ah->stats.ast_ani_ofdmon++;
1107 else
1108 ah->stats.ast_ani_ofdmoff++;
1109 aniState->ofdmWeakSigDetectOff = !on;
1110 }
1111 break;
1112 }
1113 case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
1114 const int weakSigThrCck[] = { 8, 6 };
1115 u32 high = param ? 1 : 0;
1116
1117 REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
1118 AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK,
1119 weakSigThrCck[high]);
1120 if (high != aniState->cckWeakSigThreshold) {
1121 if (high)
1122 ah->stats.ast_ani_cckhigh++;
1123 else
1124 ah->stats.ast_ani_ccklow++;
1125 aniState->cckWeakSigThreshold = high;
1126 }
1127 break;
1128 }
1129 case ATH9K_ANI_FIRSTEP_LEVEL:{
1130 const int firstep[] = { 0, 4, 8 };
1131 u32 level = param;
1132
1133 if (level >= ARRAY_SIZE(firstep)) {
1134 ath_print(common, ATH_DBG_ANI,
1135 "level out of range (%u > %u)\n",
1136 level,
1137 (unsigned) ARRAY_SIZE(firstep));
1138 return false;
1139 }
1140 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
1141 AR_PHY_FIND_SIG_FIRSTEP,
1142 firstep[level]);
1143 if (level > aniState->firstepLevel)
1144 ah->stats.ast_ani_stepup++;
1145 else if (level < aniState->firstepLevel)
1146 ah->stats.ast_ani_stepdown++;
1147 aniState->firstepLevel = level;
1148 break;
1149 }
1150 case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
1151 const int cycpwrThr1[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
1152 u32 level = param;
1153
1154 if (level >= ARRAY_SIZE(cycpwrThr1)) {
1155 ath_print(common, ATH_DBG_ANI,
1156 "level out of range (%u > %u)\n",
1157 level,
1158 (unsigned) ARRAY_SIZE(cycpwrThr1));
1159 return false;
1160 }
1161 REG_RMW_FIELD(ah, AR_PHY_TIMING5,
1162 AR_PHY_TIMING5_CYCPWR_THR1,
1163 cycpwrThr1[level]);
1164 if (level > aniState->spurImmunityLevel)
1165 ah->stats.ast_ani_spurup++;
1166 else if (level < aniState->spurImmunityLevel)
1167 ah->stats.ast_ani_spurdown++;
1168 aniState->spurImmunityLevel = level;
1169 break;
1170 }
1171 case ATH9K_ANI_PRESENT:
1172 break;
1173 default:
1174 ath_print(common, ATH_DBG_ANI,
1175 "invalid cmd %u\n", cmd);
1176 return false;
1177 }
1178
1179 ath_print(common, ATH_DBG_ANI, "ANI parameters:\n");
1180 ath_print(common, ATH_DBG_ANI,
1181 "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
1182 "ofdmWeakSigDetectOff=%d\n",
1183 aniState->noiseImmunityLevel,
1184 aniState->spurImmunityLevel,
1185 !aniState->ofdmWeakSigDetectOff);
1186 ath_print(common, ATH_DBG_ANI,
1187 "cckWeakSigThreshold=%d, "
1188 "firstepLevel=%d, listenTime=%d\n",
1189 aniState->cckWeakSigThreshold,
1190 aniState->firstepLevel,
1191 aniState->listenTime);
1192 ath_print(common, ATH_DBG_ANI,
1193 "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
1194 aniState->cycleCount,
1195 aniState->ofdmPhyErrCount,
1196 aniState->cckPhyErrCount);
1197
1198 return true;
1199}
1200
1018void ar5008_hw_attach_phy_ops(struct ath_hw *ah) 1201void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
1019{ 1202{
1020 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); 1203 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
@@ -1036,6 +1219,7 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
1036 priv_ops->enable_rfkill = ar5008_hw_enable_rfkill; 1219 priv_ops->enable_rfkill = ar5008_hw_enable_rfkill;
1037 priv_ops->restore_chainmask = ar5008_restore_chainmask; 1220 priv_ops->restore_chainmask = ar5008_restore_chainmask;
1038 priv_ops->set_diversity = ar5008_set_diversity; 1221 priv_ops->set_diversity = ar5008_set_diversity;
1222 priv_ops->ani_control = ar5008_hw_ani_control;
1039 1223
1040 if (AR_SREV_9100(ah)) 1224 if (AR_SREV_9100(ah))
1041 priv_ops->compute_pll_control = ar9100_hw_compute_pll_control; 1225 priv_ops->compute_pll_control = ar9100_hw_compute_pll_control;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index acbf122a150d..356e03db9cf1 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -420,6 +420,13 @@ static void ar9003_hw_set_diversity(struct ath_hw *ah, bool value)
420 /* TODO */ 420 /* TODO */
421} 421}
422 422
423static bool ar9003_hw_ani_control(struct ath_hw *ah,
424 enum ath9k_ani_cmd cmd, int param)
425{
426 /* TODO */
427 return false;
428}
429
423void ar9003_hw_attach_phy_ops(struct ath_hw *ah) 430void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
424{ 431{
425 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); 432 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
@@ -437,4 +444,5 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
437 priv_ops->rfbus_done = ar9003_hw_rfbus_done; 444 priv_ops->rfbus_done = ar9003_hw_rfbus_done;
438 priv_ops->enable_rfkill = ar9003_hw_enable_rfkill; 445 priv_ops->enable_rfkill = ar9003_hw_enable_rfkill;
439 priv_ops->set_diversity = ar9003_hw_set_diversity; 446 priv_ops->set_diversity = ar9003_hw_set_diversity;
447 priv_ops->ani_control = ar9003_hw_ani_control;
440} 448}
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index 19259fbad507..08a51a267681 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -146,4 +146,10 @@ static inline void ath9k_hw_set_diversity(struct ath_hw *ah, bool value)
146 return ath9k_hw_private_ops(ah)->set_diversity(ah, value); 146 return ath9k_hw_private_ops(ah)->set_diversity(ah, value);
147} 147}
148 148
149static inline bool ath9k_hw_ani_control(struct ath_hw *ah,
150 enum ath9k_ani_cmd cmd, int param)
151{
152 return ath9k_hw_private_ops(ah)->ani_control(ah, cmd, param);
153}
154
149#endif /* ATH9K_HW_OPS_H */ 155#endif /* ATH9K_HW_OPS_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index c3928be63b3a..b0cfc77a66fc 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -508,6 +508,8 @@ struct ath_hw_private_ops {
508 void (*set_diversity)(struct ath_hw *ah, bool value); 508 void (*set_diversity)(struct ath_hw *ah, bool value);
509 u32 (*compute_pll_control)(struct ath_hw *ah, 509 u32 (*compute_pll_control)(struct ath_hw *ah,
510 struct ath9k_channel *chan); 510 struct ath9k_channel *chan);
511 bool (*ani_control)(struct ath_hw *ah, enum ath9k_ani_cmd cmd,
512 int param);
511}; 513};
512 514
513/** 515/**