ath9k: add a few fixes and cleanups
[oweals/openwrt.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");