ath9k: add a few fixes and cleanups
[openwrt/svn-archive/archive.git] / package / mac80211 / patches / 540-ath9k_cycle_counters_cleanup.patch
1 --- a/drivers/net/wireless/ath/ath9k/hw.h
2 +++ b/drivers/net/wireless/ath/ath9k/hw.h
3 @@ -765,6 +765,8 @@ struct ath_hw {
4 int coarse_low[5];
5 int firpwr[5];
6 enum ath9k_ani_cmd ani_function;
7 + struct ath_cycle_counters cc, cc_delta;
8 + int32_t listen_time;
9
10 /* Bluetooth coexistance */
11 struct ath_btcoex_hw btcoex_hw;
12 --- a/drivers/net/wireless/ath/ath9k/ani.c
13 +++ b/drivers/net/wireless/ath/ath9k/ani.c
14 @@ -549,47 +549,15 @@ static u8 ath9k_hw_chan_2_clockrate_mhz(
15
16 static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah)
17 {
18 - struct ar5416AniState *aniState;
19 - struct ath_common *common = ath9k_hw_common(ah);
20 - u32 txFrameCount, rxFrameCount, cycleCount;
21 - int32_t listenTime;
22 -
23 - txFrameCount = REG_READ(ah, AR_TFCNT);
24 - rxFrameCount = REG_READ(ah, AR_RFCNT);
25 - cycleCount = REG_READ(ah, AR_CCCNT);
26 -
27 - aniState = ah->curani;
28 - if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) {
29 - listenTime = 0;
30 - ah->stats.ast_ani_lzero++;
31 - ath_print(common, ATH_DBG_ANI,
32 - "1st call: aniState->cycleCount=%d\n",
33 - aniState->cycleCount);
34 - } else {
35 - int32_t ccdelta = cycleCount - aniState->cycleCount;
36 - int32_t rfdelta = rxFrameCount - aniState->rxFrameCount;
37 - int32_t tfdelta = txFrameCount - aniState->txFrameCount;
38 - int32_t clock_rate;
39 -
40 - /*
41 - * convert HW counter values to ms using mode
42 - * specifix clock rate
43 - */
44 - clock_rate = ath9k_hw_chan_2_clockrate_mhz(ah) * 1000;;
45 + int32_t listen_time;
46 + int32_t clock_rate;
47
48 - listenTime = (ccdelta - rfdelta - tfdelta) / clock_rate;
49 + ath9k_hw_update_cycle_counters(ah);
50 + clock_rate = ath9k_hw_chan_2_clockrate_mhz(ah) * 1000;
51 + listen_time = ah->listen_time / clock_rate;
52 + ah->listen_time = 0;
53
54 - ath_print(common, ATH_DBG_ANI,
55 - "cyclecount=%d, rfcount=%d, "
56 - "tfcount=%d, listenTime=%d CLOCK_RATE=%d\n",
57 - ccdelta, rfdelta, tfdelta, listenTime, clock_rate);
58 - }
59 -
60 - aniState->cycleCount = cycleCount;
61 - aniState->txFrameCount = txFrameCount;
62 - aniState->rxFrameCount = rxFrameCount;
63 -
64 - return listenTime;
65 + return listen_time;
66 }
67
68 static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
69 @@ -1041,45 +1009,52 @@ void ath9k_hw_disable_mib_counters(struc
70 }
71 EXPORT_SYMBOL(ath9k_hw_disable_mib_counters);
72
73 -u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah,
74 - u32 *rxc_pcnt,
75 - u32 *rxf_pcnt,
76 - u32 *txf_pcnt)
77 +void ath9k_hw_update_cycle_counters(struct ath_hw *ah)
78 {
79 - struct ath_common *common = ath9k_hw_common(ah);
80 - static u32 cycles, rx_clear, rx_frame, tx_frame;
81 - u32 good = 1;
82 + struct ath_cycle_counters cc;
83 + bool clear;
84
85 - u32 rc = REG_READ(ah, AR_RCCNT);
86 - u32 rf = REG_READ(ah, AR_RFCNT);
87 - u32 tf = REG_READ(ah, AR_TFCNT);
88 - u32 cc = REG_READ(ah, AR_CCCNT);
89 + memcpy(&cc, &ah->cc, sizeof(cc));
90
91 - if (cycles == 0 || cycles > cc) {
92 - ath_print(common, ATH_DBG_ANI,
93 - "cycle counter wrap. ExtBusy = 0\n");
94 - good = 0;
95 - } else {
96 - u32 cc_d = cc - cycles;
97 - u32 rc_d = rc - rx_clear;
98 - u32 rf_d = rf - rx_frame;
99 - u32 tf_d = tf - tx_frame;
100 -
101 - if (cc_d != 0) {
102 - *rxc_pcnt = rc_d * 100 / cc_d;
103 - *rxf_pcnt = rf_d * 100 / cc_d;
104 - *txf_pcnt = tf_d * 100 / cc_d;
105 - } else {
106 - good = 0;
107 - }
108 - }
109 + /* freeze counters */
110 + REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
111
112 - cycles = cc;
113 - rx_frame = rf;
114 - rx_clear = rc;
115 - tx_frame = tf;
116 + ah->cc.cycles = REG_READ(ah, AR_CCCNT);
117 + if (ah->cc.cycles < cc.cycles) {
118 + clear = true;
119 + goto skip;
120 + }
121 +
122 + ah->cc.rx_clear = REG_READ(ah, AR_RCCNT);
123 + ah->cc.rx_frame = REG_READ(ah, AR_RFCNT);
124 + ah->cc.tx_frame = REG_READ(ah, AR_TFCNT);
125 +
126 + /* prevent wraparound */
127 + if (ah->cc.cycles & BIT(31))
128 + clear = true;
129 +
130 +#define CC_DELTA(_field, _reg) ah->cc_delta._field += ah->cc._field - cc._field
131 + CC_DELTA(cycles, AR_CCCNT);
132 + CC_DELTA(rx_frame, AR_RFCNT);
133 + CC_DELTA(rx_clear, AR_RCCNT);
134 + CC_DELTA(tx_frame, AR_TFCNT);
135 +#undef CC_DELTA
136 +
137 + ah->listen_time += (ah->cc.cycles - cc.cycles) -
138 + ((ah->cc.rx_frame - cc.rx_frame) +
139 + (ah->cc.tx_frame - cc.tx_frame));
140 +
141 +skip:
142 + if (clear) {
143 + REG_WRITE(ah, AR_CCCNT, 0);
144 + REG_WRITE(ah, AR_RFCNT, 0);
145 + REG_WRITE(ah, AR_RCCNT, 0);
146 + REG_WRITE(ah, AR_TFCNT, 0);
147 + memset(&ah->cc, 0, sizeof(ah->cc));
148 + }
149
150 - return good;
151 + /* unfreeze counters */
152 + REG_WRITE(ah, AR_MIBC, 0);
153 }
154
155 /*
156 --- a/drivers/net/wireless/ath/ath9k/ani.h
157 +++ b/drivers/net/wireless/ath/ath9k/ani.h
158 @@ -93,6 +93,13 @@ struct ath9k_mib_stats {
159 u32 beacons;
160 };
161
162 +struct ath_cycle_counters {
163 + u32 cycles;
164 + u32 rx_frame;
165 + u32 rx_clear;
166 + u32 tx_frame;
167 +};
168 +
169 /* INI default values for ANI registers */
170 struct ath9k_ani_default {
171 u16 m1ThreshLow;
172 @@ -130,9 +137,6 @@ struct ar5416AniState {
173 int32_t rssiThrLow;
174 int32_t rssiThrHigh;
175 u32 noiseFloor;
176 - u32 txFrameCount;
177 - u32 rxFrameCount;
178 - u32 cycleCount;
179 u32 ofdmPhyErrCount;
180 u32 cckPhyErrCount;
181 u32 ofdmPhyErrBase;
182 @@ -166,8 +170,7 @@ struct ar5416Stats {
183
184 void ath9k_enable_mib_counters(struct ath_hw *ah);
185 void ath9k_hw_disable_mib_counters(struct ath_hw *ah);
186 -u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt,
187 - u32 *rxf_pcnt, u32 *txf_pcnt);
188 +void ath9k_hw_update_cycle_counters(struct ath_hw *ah);
189 void ath9k_hw_ani_setup(struct ath_hw *ah);
190 void ath9k_hw_ani_init(struct ath_hw *ah);
191 int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
192 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
193 +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
194 @@ -1227,8 +1227,7 @@ static bool ar5008_hw_ani_control_old(st
195 aniState->firstepLevel,
196 aniState->listenTime);
197 ath_print(common, ATH_DBG_ANI,
198 - "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
199 - aniState->cycleCount,
200 + "ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
201 aniState->ofdmPhyErrCount,
202 aniState->cckPhyErrCount);
203
204 @@ -1480,15 +1479,13 @@ static bool ar5008_hw_ani_control_new(st
205
206 ath_print(common, ATH_DBG_ANI,
207 "ANI parameters: SI=%d, ofdmWS=%s FS=%d "
208 - "MRCcck=%s listenTime=%d CC=%d listen=%d "
209 + "MRCcck=%s listenTime=%d "
210 "ofdmErrs=%d cckErrs=%d\n",
211 aniState->spurImmunityLevel,
212 !aniState->ofdmWeakSigDetectOff ? "on" : "off",
213 aniState->firstepLevel,
214 !aniState->mrcCCKOff ? "on" : "off",
215 aniState->listenTime,
216 - aniState->cycleCount,
217 - aniState->listenTime,
218 aniState->ofdmPhyErrCount,
219 aniState->cckPhyErrCount);
220 return true;
221 @@ -1581,8 +1578,6 @@ static void ar5008_hw_ani_cache_ini_regs
222 aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
223 aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG;
224 aniState->mrcCCKOff = true; /* not available on pre AR9003 */
225 -
226 - aniState->cycleCount = 0;
227 }
228
229 static void ar5008_hw_set_nf_limits(struct ath_hw *ah)
230 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
231 +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
232 @@ -1005,15 +1005,13 @@ static bool ar9003_hw_ani_control(struct
233
234 ath_print(common, ATH_DBG_ANI,
235 "ANI parameters: SI=%d, ofdmWS=%s FS=%d "
236 - "MRCcck=%s listenTime=%d CC=%d listen=%d "
237 + "MRCcck=%s listenTime=%d "
238 "ofdmErrs=%d cckErrs=%d\n",
239 aniState->spurImmunityLevel,
240 !aniState->ofdmWeakSigDetectOff ? "on" : "off",
241 aniState->firstepLevel,
242 !aniState->mrcCCKOff ? "on" : "off",
243 aniState->listenTime,
244 - aniState->cycleCount,
245 - aniState->listenTime,
246 aniState->ofdmPhyErrCount,
247 aniState->cckPhyErrCount);
248 return true;
249 @@ -1116,8 +1114,6 @@ static void ar9003_hw_ani_cache_ini_regs
250 aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
251 aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG;
252 aniState->mrcCCKOff = !ATH9K_ANI_ENABLE_MRC_CCK;
253 -
254 - aniState->cycleCount = 0;
255 }
256
257 void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
258 @@ -1232,7 +1228,7 @@ void ar9003_hw_bb_watchdog_read(struct a
259 void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah)
260 {
261 struct ath_common *common = ath9k_hw_common(ah);
262 - u32 rxc_pcnt = 0, rxf_pcnt = 0, txf_pcnt = 0, status;
263 + u32 status;
264
265 if (likely(!(common->debug_mask & ATH_DBG_RESET)))
266 return;
267 @@ -1261,11 +1257,13 @@ void ar9003_hw_bb_watchdog_dbg_info(stru
268 "** BB mode: BB_gen_controls=0x%08x **\n",
269 REG_READ(ah, AR_PHY_GEN_CTRL));
270
271 - if (ath9k_hw_GetMibCycleCountsPct(ah, &rxc_pcnt, &rxf_pcnt, &txf_pcnt))
272 + ath9k_hw_update_cycle_counters(ah);
273 +#define PCT(_field) (ah->cc_delta._field * 100 / ah->cc_delta.cycles)
274 + if (ah->cc_delta.cycles)
275 ath_print(common, ATH_DBG_RESET,
276 "** BB busy times: rx_clear=%d%%, "
277 "rx_frame=%d%%, tx_frame=%d%% **\n",
278 - rxc_pcnt, rxf_pcnt, txf_pcnt);
279 + PCT(rx_clear), PCT(rx_frame), PCT(tx_frame));
280
281 ath_print(common, ATH_DBG_RESET,
282 "==== BB update: done ====\n\n");