mac80211: fix a crash in the netlink backport
[oweals/openwrt.git] / package / mac80211 / patches / 522-ath_common_counters.patch
1 --- a/drivers/net/wireless/ath/ath.h
2 +++ b/drivers/net/wireless/ath/ath.h
3 @@ -19,6 +19,7 @@
4  
5  #include <linux/skbuff.h>
6  #include <linux/if_ether.h>
7 +#include <linux/spinlock.h>
8  #include <net/mac80211.h>
9  
10  /*
11 @@ -42,6 +43,13 @@ struct ath_ani {
12         struct timer_list timer;
13  };
14  
15 +struct ath_cycle_counters {
16 +       u32 cycles;
17 +       u32 rx_busy;
18 +       u32 rx_frame;
19 +       u32 tx_frame;
20 +};
21 +
22  enum ath_device_state {
23         ATH_HW_UNAVAILABLE,
24         ATH_HW_INITIALIZED,
25 @@ -147,6 +155,10 @@ struct ath_common {
26  
27         unsigned int clockrate;
28  
29 +       spinlock_t cc_lock;
30 +       struct ath_cycle_counters cc_ani;
31 +       struct ath_cycle_counters cc_survey;
32 +
33         struct ath_regulatory regulatory;
34         const struct ath_ops *ops;
35         const struct ath_bus_ops *bus_ops;
36 @@ -163,5 +175,7 @@ int ath_key_config(struct ath_common *co
37                           struct ieee80211_sta *sta,
38                           struct ieee80211_key_conf *key);
39  bool ath_hw_keyreset(struct ath_common *common, u16 entry);
40 +void ath_hw_cycle_counters_update(struct ath_common *common);
41 +int32_t ath_hw_get_listen_time(struct ath_common *common);
42  
43  #endif /* ATH_H */
44 --- a/drivers/net/wireless/ath/ath9k/ani.c
45 +++ b/drivers/net/wireless/ath/ath9k/ani.c
46 @@ -465,18 +465,6 @@ static void ath9k_hw_ani_lower_immunity(
47                 ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1);
48  }
49  
50 -static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah)
51 -{
52 -       struct ath_common *common = ath9k_hw_common(ah);
53 -       int32_t listen_time;
54 -
55 -       ath9k_hw_update_cycle_counters(ah);
56 -       listen_time = ah->listen_time / (common->clockrate * 1000);
57 -       ah->listen_time = 0;
58 -
59 -       return listen_time;
60 -}
61 -
62  static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
63  {
64         struct ar5416AniState *aniState;
65 @@ -655,7 +643,9 @@ static void ath9k_hw_ani_read_counters(s
66         u32 phyCnt1, phyCnt2;
67         int32_t listenTime;
68  
69 -       listenTime = ath9k_hw_ani_get_listen_time(ah);
70 +       ath_hw_cycle_counters_update(common);
71 +       listenTime = ath_hw_get_listen_time(common);
72 +
73         if (listenTime < 0) {
74                 ah->stats.ast_ani_lneg++;
75                 ath9k_ani_restart(ah);
76 @@ -796,54 +786,6 @@ void ath9k_hw_disable_mib_counters(struc
77  }
78  EXPORT_SYMBOL(ath9k_hw_disable_mib_counters);
79  
80 -void ath9k_hw_update_cycle_counters(struct ath_hw *ah)
81 -{
82 -       struct ath_cycle_counters cc;
83 -       bool clear;
84 -
85 -       memcpy(&cc, &ah->cc, sizeof(cc));
86 -
87 -       /* freeze counters */
88 -       REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
89 -
90 -       ah->cc.cycles = REG_READ(ah, AR_CCCNT);
91 -       if (ah->cc.cycles < cc.cycles) {
92 -               clear = true;
93 -               goto skip;
94 -       }
95 -
96 -       ah->cc.rx_clear = REG_READ(ah, AR_RCCNT);
97 -       ah->cc.rx_frame = REG_READ(ah, AR_RFCNT);
98 -       ah->cc.tx_frame = REG_READ(ah, AR_TFCNT);
99 -
100 -       /* prevent wraparound */
101 -       if (ah->cc.cycles & BIT(31))
102 -               clear = true;
103 -
104 -#define CC_DELTA(_field, _reg) ah->cc_delta._field += ah->cc._field - cc._field
105 -       CC_DELTA(cycles, AR_CCCNT);
106 -       CC_DELTA(rx_frame, AR_RFCNT);
107 -       CC_DELTA(rx_clear, AR_RCCNT);
108 -       CC_DELTA(tx_frame, AR_TFCNT);
109 -#undef CC_DELTA
110 -
111 -       ah->listen_time += (ah->cc.cycles - cc.cycles) -
112 -                ((ah->cc.rx_frame - cc.rx_frame) +
113 -                 (ah->cc.tx_frame - cc.tx_frame));
114 -
115 -skip:
116 -       if (clear) {
117 -               REG_WRITE(ah, AR_CCCNT, 0);
118 -               REG_WRITE(ah, AR_RFCNT, 0);
119 -               REG_WRITE(ah, AR_RCCNT, 0);
120 -               REG_WRITE(ah, AR_TFCNT, 0);
121 -               memset(&ah->cc, 0, sizeof(ah->cc));
122 -       }
123 -
124 -       /* unfreeze counters */
125 -       REG_WRITE(ah, AR_MIBC, 0);
126 -}
127 -
128  /*
129   * Process a MIB interrupt.  We may potentially be invoked because
130   * any of the MIB counters overflow/trigger so don't assume we're
131 --- a/drivers/net/wireless/ath/ath9k/ani.h
132 +++ b/drivers/net/wireless/ath/ath9k/ani.h
133 @@ -93,13 +93,6 @@ struct ath9k_mib_stats {
134         u32 beacons;
135  };
136  
137 -struct ath_cycle_counters {
138 -       u32 cycles;
139 -       u32 rx_frame;
140 -       u32 rx_clear;
141 -       u32 tx_frame;
142 -};
143 -
144  /* INI default values for ANI registers */
145  struct ath9k_ani_default {
146         u16 m1ThreshLow;
147 @@ -164,7 +157,6 @@ struct ar5416Stats {
148  
149  void ath9k_enable_mib_counters(struct ath_hw *ah);
150  void ath9k_hw_disable_mib_counters(struct ath_hw *ah);
151 -void ath9k_hw_update_cycle_counters(struct ath_hw *ah);
152  void ath9k_hw_ani_setup(struct ath_hw *ah);
153  void ath9k_hw_ani_init(struct ath_hw *ah);
154  int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
155 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
156 +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
157 @@ -1254,13 +1254,12 @@ void ar9003_hw_bb_watchdog_dbg_info(stru
158                   "** BB mode: BB_gen_controls=0x%08x **\n",
159                   REG_READ(ah, AR_PHY_GEN_CTRL));
160  
161 -       ath9k_hw_update_cycle_counters(ah);
162 -#define PCT(_field) (ah->cc_delta._field * 100 / ah->cc_delta.cycles)
163 -       if (ah->cc_delta.cycles)
164 +#define PCT(_field) (common->cc_survey._field * 100 / common->cc_survey.cycles)
165 +       if (common->cc_survey.cycles)
166                 ath_print(common, ATH_DBG_RESET,
167                           "** BB busy times: rx_clear=%d%%, "
168                           "rx_frame=%d%%, tx_frame=%d%% **\n",
169 -                         PCT(rx_clear), PCT(rx_frame), PCT(tx_frame));
170 +                         PCT(rx_busy), PCT(rx_frame), PCT(tx_frame));
171  
172         ath_print(common, ATH_DBG_RESET,
173                   "==== BB update: done ====\n\n");
174 --- a/drivers/net/wireless/ath/ath9k/hw.h
175 +++ b/drivers/net/wireless/ath/ath9k/hw.h
176 @@ -740,8 +740,6 @@ struct ath_hw {
177         int coarse_low[5];
178         int firpwr[5];
179         enum ath9k_ani_cmd ani_function;
180 -       struct ath_cycle_counters cc, cc_delta;
181 -       int32_t listen_time;
182  
183         /* Bluetooth coexistance */
184         struct ath_btcoex_hw btcoex_hw;
185 --- a/drivers/net/wireless/ath/ath9k/main.c
186 +++ b/drivers/net/wireless/ath/ath9k/main.c
187 @@ -400,6 +400,7 @@ void ath_ani_calibrate(unsigned long dat
188         bool aniflag = false;
189         unsigned int timestamp = jiffies_to_msecs(jiffies);
190         u32 cal_interval, short_cal_interval, long_cal_interval;
191 +       unsigned long flags;
192  
193         if (ah->caldata && ah->caldata->nfcal_interference)
194                 long_cal_interval = ATH_LONG_CALINTERVAL_INT;
195 @@ -450,8 +451,11 @@ void ath_ani_calibrate(unsigned long dat
196         /* Skip all processing if there's nothing to do. */
197         if (longcal || shortcal || aniflag) {
198                 /* Call ANI routine if necessary */
199 -               if (aniflag)
200 +               if (aniflag) {
201 +                       spin_lock_irqsave(&common->cc_lock, flags);
202                         ath9k_hw_ani_monitor(ah, ah->curchan);
203 +                       spin_unlock_irqrestore(&common->cc_lock, flags);
204 +               }
205  
206                 /* Perform calibration if necessary */
207                 if (longcal || shortcal) {
208 @@ -636,6 +640,7 @@ irqreturn_t ath_isr(int irq, void *dev)
209  
210         struct ath_softc *sc = dev;
211         struct ath_hw *ah = sc->sc_ah;
212 +       struct ath_common *common = ath9k_hw_common(ah);
213         enum ath9k_int status;
214         bool sched = false;
215  
216 @@ -685,7 +690,12 @@ irqreturn_t ath_isr(int irq, void *dev)
217  
218         if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
219             (status & ATH9K_INT_BB_WATCHDOG)) {
220 +
221 +               spin_lock(&common->cc_lock);
222 +               ath_hw_cycle_counters_update(common);
223                 ar9003_hw_bb_watchdog_dbg_info(ah);
224 +               spin_unlock(&common->cc_lock);
225 +
226                 goto chip_reset;
227         }
228  
229 --- a/drivers/net/wireless/ath/ath9k/reg.h
230 +++ b/drivers/net/wireless/ath/ath9k/reg.h
231 @@ -107,12 +107,6 @@
232  #define AR_RXCFG_DMASZ_256B  6
233  #define AR_RXCFG_DMASZ_512B  7
234  
235 -#define AR_MIBC              0x0040
236 -#define AR_MIBC_COW          0x00000001
237 -#define AR_MIBC_FMC          0x00000002
238 -#define AR_MIBC_CMC          0x00000004
239 -#define AR_MIBC_MCS          0x00000008
240 -
241  #define AR_TOPS              0x0044
242  #define AR_TOPS_MASK         0x0000FFFF
243  
244 @@ -1524,11 +1518,6 @@ enum {
245  #define AR_TPC_CHIRP           0x003f0000
246  #define AR_TPC_CHIRP_S         0x16
247  
248 -#define AR_TFCNT           0x80ec
249 -#define AR_RFCNT           0x80f0
250 -#define AR_RCCNT           0x80f4
251 -#define AR_CCCNT           0x80f8
252 -
253  #define AR_QUIET1          0x80fc
254  #define AR_QUIET1_NEXT_QUIET_S         0
255  #define AR_QUIET1_NEXT_QUIET_M         0x0000ffff
256 --- a/drivers/net/wireless/ath/hw.c
257 +++ b/drivers/net/wireless/ath/hw.c
258 @@ -124,3 +124,62 @@ void ath_hw_setbssidmask(struct ath_comm
259         REG_WRITE(ah, get_unaligned_le16(common->bssidmask + 4), AR_BSSMSKU);
260  }
261  EXPORT_SYMBOL(ath_hw_setbssidmask);
262 +
263 +
264 +/**
265 + * ath_hw_cycle_counters_update - common function to update cycle counters
266 + *
267 + * @common: the ath_common struct for the device.
268 + *
269 + * This function is used to update all cycle counters in one place.
270 + * It has to be called while holding common->cc_lock!
271 + */
272 +void ath_hw_cycle_counters_update(struct ath_common *common)
273 +{
274 +       u32 cycles, busy, rx, tx;
275 +       void *ah = common->ah;
276 +
277 +       /* freeze */
278 +       REG_WRITE(ah, AR_MIBC_FMC, AR_MIBC);
279 +
280 +       /* read */
281 +       cycles = REG_READ(ah, AR_CCCNT);
282 +       busy = REG_READ(ah, AR_RCCNT);
283 +       rx = REG_READ(ah, AR_RFCNT);
284 +       tx = REG_READ(ah, AR_TFCNT);
285 +
286 +       /* clear */
287 +       REG_WRITE(ah, 0, AR_CCCNT);
288 +       REG_WRITE(ah, 0, AR_RFCNT);
289 +       REG_WRITE(ah, 0, AR_RCCNT);
290 +       REG_WRITE(ah, 0, AR_TFCNT);
291 +
292 +       /* unfreeze */
293 +       REG_WRITE(ah, 0, AR_MIBC);
294 +
295 +       /* update all cycle counters here */
296 +       common->cc_ani.cycles += cycles;
297 +       common->cc_ani.rx_busy += busy;
298 +       common->cc_ani.rx_frame += rx;
299 +       common->cc_ani.tx_frame += tx;
300 +
301 +       common->cc_survey.cycles += cycles;
302 +       common->cc_survey.rx_busy += busy;
303 +       common->cc_survey.rx_frame += rx;
304 +       common->cc_survey.tx_frame += tx;
305 +}
306 +EXPORT_SYMBOL(ath_hw_cycle_counters_update);
307 +
308 +int32_t ath_hw_get_listen_time(struct ath_common *common)
309 +{
310 +       struct ath_cycle_counters *cc = &common->cc_ani;
311 +       int32_t listen_time;
312 +
313 +       listen_time = (cc->cycles - cc->rx_frame - cc->tx_frame) /
314 +                     (common->clockrate * 1000);
315 +
316 +       memset(cc, 0, sizeof(*cc));
317 +
318 +       return listen_time;
319 +}
320 +EXPORT_SYMBOL(ath_hw_get_listen_time);
321 --- a/drivers/net/wireless/ath/reg.h
322 +++ b/drivers/net/wireless/ath/reg.h
323 @@ -17,6 +17,12 @@
324  #ifndef ATH_REGISTERS_H
325  #define ATH_REGISTERS_H
326  
327 +#define AR_MIBC                        0x0040
328 +#define AR_MIBC_COW            0x00000001
329 +#define AR_MIBC_FMC            0x00000002
330 +#define AR_MIBC_CMC            0x00000004
331 +#define AR_MIBC_MCS            0x00000008
332 +
333  /*
334   * BSSID mask registers. See ath_hw_set_bssid_mask()
335   * for detailed documentation about these registers.
336 @@ -24,6 +30,11 @@
337  #define AR_BSSMSKL             0x80e0
338  #define AR_BSSMSKU             0x80e4
339  
340 +#define AR_TFCNT               0x80ec
341 +#define AR_RFCNT               0x80f0
342 +#define AR_RCCNT               0x80f4
343 +#define AR_CCCNT               0x80f8
344 +
345  #define AR_KEYTABLE_0           0x8800
346  #define AR_KEYTABLE(_n)         (AR_KEYTABLE_0 + ((_n)*32))
347  #define AR_KEY_CACHE_SIZE       128