ath9k: add a few de-bloating and optimization patches
[openwrt/svn-archive/archive.git] / package / mac80211 / patches / 300-ath9k_pending_work.patch
1 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
2 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
3 @@ -362,7 +362,7 @@ struct ath_vif {
4 * number of BSSIDs) if a given beacon does not go out even after waiting this
5 * number of beacon intervals, the game's up.
6 */
7 -#define BSTUCK_THRESH (9 * ATH_BCBUF)
8 +#define BSTUCK_THRESH 9
9 #define ATH_BCBUF 4
10 #define ATH_DEFAULT_BINTVAL 100 /* TU */
11 #define ATH_DEFAULT_BMISS_LIMIT 10
12 @@ -386,7 +386,7 @@ struct ath_beacon {
13 u32 beaconq;
14 u32 bmisscnt;
15 u32 ast_be_xmit;
16 - u64 bc_tstamp;
17 + u32 bc_tstamp;
18 struct ieee80211_vif *bslot[ATH_BCBUF];
19 int slottime;
20 int slotupdate;
21 --- a/drivers/net/wireless/ath/ath9k/beacon.c
22 +++ b/drivers/net/wireless/ath/ath9k/beacon.c
23 @@ -57,8 +57,8 @@ int ath_beaconq_config(struct ath_softc
24
25 /*
26 * Associates the beacon frame buffer with a transmit descriptor. Will set
27 - * up all required antenna switch parameters, rate codes, and channel flags.
28 - * Beacons are always sent out at the lowest rate, and are not retried.
29 + * up rate codes, and channel flags. Beacons are always sent out at the
30 + * lowest rate, and are not retried.
31 */
32 static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
33 struct ath_buf *bf, int rateidx)
34 @@ -68,7 +68,7 @@ static void ath_beacon_setup(struct ath_
35 struct ath_common *common = ath9k_hw_common(ah);
36 struct ath_desc *ds;
37 struct ath9k_11n_rate_series series[4];
38 - int flags, antenna, ctsrate = 0, ctsduration = 0;
39 + int flags, ctsrate = 0, ctsduration = 0;
40 struct ieee80211_supported_band *sband;
41 u8 rate = 0;
42
43 @@ -76,12 +76,6 @@ static void ath_beacon_setup(struct ath_
44 flags = ATH9K_TXDESC_NOACK;
45
46 ds->ds_link = 0;
47 - /*
48 - * Switch antenna every beacon.
49 - * Should only switch every beacon period, not for every SWBA
50 - * XXX assumes two antennae
51 - */
52 - antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1);
53
54 sband = &sc->sbands[common->hw->conf.channel->band];
55 rate = sband->bitrates[rateidx].hw_value;
56 @@ -278,7 +272,7 @@ int ath_beacon_alloc(struct ath_softc *s
57 return -ENOMEM;
58
59 tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
60 - sc->beacon.bc_tstamp = le64_to_cpu(tstamp);
61 + sc->beacon.bc_tstamp = (u32) le64_to_cpu(tstamp);
62 /* Calculate a TSF adjustment factor required for staggered beacons. */
63 if (avp->av_bslot > 0) {
64 u64 tsfadjust;
65 @@ -294,8 +288,8 @@ int ath_beacon_alloc(struct ath_softc *s
66 * adjustment. Other slots are adjusted to get the timestamp
67 * close to the TBTT for the BSS.
68 */
69 - tsfadjust = intval * avp->av_bslot / ATH_BCBUF;
70 - avp->tsf_adjust = cpu_to_le64(TU_TO_USEC(tsfadjust));
71 + tsfadjust = TU_TO_USEC(intval * avp->av_bslot) / ATH_BCBUF;
72 + avp->tsf_adjust = cpu_to_le64(tsfadjust);
73
74 ath_dbg(common, ATH_DBG_BEACON,
75 "stagger beacons, bslot %d intval %u tsfadjust %llu\n",
76 @@ -369,12 +363,13 @@ void ath_beacon_tasklet(unsigned long da
77 if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) {
78 sc->beacon.bmisscnt++;
79
80 - if (sc->beacon.bmisscnt < BSTUCK_THRESH) {
81 + if (sc->beacon.bmisscnt < BSTUCK_THRESH * sc->nbcnvifs) {
82 ath_dbg(common, ATH_DBG_BSTUCK,
83 "missed %u consecutive beacons\n",
84 sc->beacon.bmisscnt);
85 ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq);
86 - ath9k_hw_bstuck_nfcal(ah);
87 + if (sc->beacon.bmisscnt > 4)
88 + ath9k_hw_bstuck_nfcal(ah);
89 } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
90 ath_dbg(common, ATH_DBG_BSTUCK,
91 "beacon is officially stuck\n");
92 @@ -385,13 +380,6 @@ void ath_beacon_tasklet(unsigned long da
93 return;
94 }
95
96 - if (sc->beacon.bmisscnt != 0) {
97 - ath_dbg(common, ATH_DBG_BSTUCK,
98 - "resume beacon xmit after %u misses\n",
99 - sc->beacon.bmisscnt);
100 - sc->beacon.bmisscnt = 0;
101 - }
102 -
103 /*
104 * Generate beacon frames. we are sending frames
105 * staggered so calculate the slot for this frame based
106 @@ -401,8 +389,9 @@ void ath_beacon_tasklet(unsigned long da
107 intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL;
108
109 tsf = ath9k_hw_gettsf64(ah);
110 - tsftu = TSF_TO_TU(tsf>>32, tsf);
111 - slot = ((tsftu % intval) * ATH_BCBUF) / intval;
112 + tsf += TU_TO_USEC(ah->config.sw_beacon_response_time);
113 + tsftu = TSF_TO_TU((tsf * ATH_BCBUF) >>32, tsf * ATH_BCBUF);
114 + slot = (tsftu % (intval * ATH_BCBUF)) / intval;
115 /*
116 * Reverse the slot order to get slot 0 on the TBTT offset that does
117 * not require TSF adjustment and other slots adding
118 @@ -415,7 +404,7 @@ void ath_beacon_tasklet(unsigned long da
119
120 ath_dbg(common, ATH_DBG_BEACON,
121 "slot %d [tsf %llu tsftu %u intval %u] vif %p\n",
122 - slot, tsf, tsftu, intval, vif);
123 + slot, tsf, tsftu / ATH_BCBUF, intval, vif);
124
125 bfaddr = 0;
126 if (vif) {
127 @@ -424,6 +413,13 @@ void ath_beacon_tasklet(unsigned long da
128 bfaddr = bf->bf_daddr;
129 bc = 1;
130 }
131 +
132 + if (sc->beacon.bmisscnt != 0) {
133 + ath_dbg(common, ATH_DBG_BSTUCK,
134 + "resume beacon xmit after %u misses\n",
135 + sc->beacon.bmisscnt);
136 + sc->beacon.bmisscnt = 0;
137 + }
138 }
139
140 /*
141 @@ -463,13 +459,17 @@ static void ath9k_beacon_init(struct ath
142 u32 next_beacon,
143 u32 beacon_period)
144 {
145 - if (beacon_period & ATH9K_BEACON_RESET_TSF)
146 + if (sc->sc_flags & SC_OP_TSF_RESET) {
147 ath9k_ps_wakeup(sc);
148 + ath9k_hw_reset_tsf(sc->sc_ah);
149 + }
150
151 ath9k_hw_beaconinit(sc->sc_ah, next_beacon, beacon_period);
152
153 - if (beacon_period & ATH9K_BEACON_RESET_TSF)
154 + if (sc->sc_flags & SC_OP_TSF_RESET) {
155 ath9k_ps_restore(sc);
156 + sc->sc_flags &= ~SC_OP_TSF_RESET;
157 + }
158 }
159
160 /*
161 @@ -484,18 +484,14 @@ static void ath_beacon_config_ap(struct
162 u32 nexttbtt, intval;
163
164 /* NB: the beacon interval is kept internally in TU's */
165 - intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
166 + intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD);
167 intval /= ATH_BCBUF; /* for staggered beacons */
168 nexttbtt = intval;
169
170 - if (sc->sc_flags & SC_OP_TSF_RESET)
171 - intval |= ATH9K_BEACON_RESET_TSF;
172 -
173 /*
174 * In AP mode we enable the beacon timers and SWBA interrupts to
175 * prepare beacon frames.
176 */
177 - intval |= ATH9K_BEACON_ENA;
178 ah->imask |= ATH9K_INT_SWBA;
179 ath_beaconq_config(sc);
180
181 @@ -505,11 +501,6 @@ static void ath_beacon_config_ap(struct
182 ath9k_beacon_init(sc, nexttbtt, intval);
183 sc->beacon.bmisscnt = 0;
184 ath9k_hw_set_interrupts(ah, ah->imask);
185 -
186 - /* Clear the reset TSF flag, so that subsequent beacon updation
187 - will not reset the HW TSF. */
188 -
189 - sc->sc_flags &= ~SC_OP_TSF_RESET;
190 }
191
192 /*
193 @@ -643,25 +634,20 @@ static void ath_beacon_config_adhoc(stru
194 {
195 struct ath_hw *ah = sc->sc_ah;
196 struct ath_common *common = ath9k_hw_common(ah);
197 - u64 tsf;
198 - u32 tsftu, intval, nexttbtt;
199 -
200 - intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
201 + u32 tsf, delta, intval, nexttbtt;
202
203 + tsf = ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE);
204 + intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD);
205
206 - /* Pull nexttbtt forward to reflect the current TSF */
207 -
208 - nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp);
209 - if (nexttbtt == 0)
210 - nexttbtt = intval;
211 - else if (intval)
212 - nexttbtt = roundup(nexttbtt, intval);
213 -
214 - tsf = ath9k_hw_gettsf64(ah);
215 - tsftu = TSF_TO_TU((u32)(tsf>>32), (u32)tsf) + FUDGE;
216 - do {
217 - nexttbtt += intval;
218 - } while (nexttbtt < tsftu);
219 + if (!sc->beacon.bc_tstamp)
220 + nexttbtt = tsf + intval;
221 + else {
222 + if (tsf > sc->beacon.bc_tstamp)
223 + delta = (tsf - sc->beacon.bc_tstamp);
224 + else
225 + delta = (tsf + 1 + (~0U - sc->beacon.bc_tstamp));
226 + nexttbtt = tsf + roundup(delta, intval);
227 + }
228
229 ath_dbg(common, ATH_DBG_BEACON,
230 "IBSS nexttbtt %u intval %u (%u)\n",
231 @@ -672,7 +658,6 @@ static void ath_beacon_config_adhoc(stru
232 * if we need to manually prepare beacon frames. Otherwise we use a
233 * self-linked tx descriptor and let the hardware deal with things.
234 */
235 - intval |= ATH9K_BEACON_ENA;
236 ah->imask |= ATH9K_INT_SWBA;
237
238 ath_beaconq_config(sc);
239 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
240 +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
241 @@ -155,7 +155,7 @@ static void ath9k_htc_beacon_config_ap(s
242 nexttbtt = intval;
243
244 if (priv->op_flags & OP_TSF_RESET) {
245 - intval |= ATH9K_BEACON_RESET_TSF;
246 + ath9k_hw_reset_tsf(priv->ah);
247 priv->op_flags &= ~OP_TSF_RESET;
248 } else {
249 /*
250 @@ -168,8 +168,6 @@ static void ath9k_htc_beacon_config_ap(s
251 } while (nexttbtt < tsftu);
252 }
253
254 - intval |= ATH9K_BEACON_ENA;
255 -
256 if (priv->op_flags & OP_ENABLE_BEACON)
257 imask |= ATH9K_INT_SWBA;
258
259 @@ -178,7 +176,7 @@ static void ath9k_htc_beacon_config_ap(s
260 bss_conf->beacon_interval, nexttbtt, imask);
261
262 WMI_CMD(WMI_DISABLE_INTR_CMDID);
263 - ath9k_hw_beaconinit(priv->ah, nexttbtt, intval);
264 + ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval));
265 priv->bmiss_cnt = 0;
266 htc_imask = cpu_to_be32(imask);
267 WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask);
268 @@ -207,7 +205,6 @@ static void ath9k_htc_beacon_config_adho
269 nexttbtt += intval;
270 } while (nexttbtt < tsftu);
271
272 - intval |= ATH9K_BEACON_ENA;
273 if (priv->op_flags & OP_ENABLE_BEACON)
274 imask |= ATH9K_INT_SWBA;
275
276 @@ -216,7 +213,7 @@ static void ath9k_htc_beacon_config_adho
277 bss_conf->beacon_interval, nexttbtt, imask);
278
279 WMI_CMD(WMI_DISABLE_INTR_CMDID);
280 - ath9k_hw_beaconinit(priv->ah, nexttbtt, intval);
281 + ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval));
282 priv->bmiss_cnt = 0;
283 htc_imask = cpu_to_be32(imask);
284 WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask);
285 --- a/drivers/net/wireless/ath/ath9k/hw.c
286 +++ b/drivers/net/wireless/ath/ath9k/hw.c
287 @@ -1697,21 +1697,15 @@ void ath9k_hw_beaconinit(struct ath_hw *
288 case NL80211_IFTYPE_MESH_POINT:
289 REG_SET_BIT(ah, AR_TXCFG,
290 AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
291 - REG_WRITE(ah, AR_NEXT_NDP_TIMER,
292 - TU_TO_USEC(next_beacon +
293 - (ah->atim_window ? ah->
294 - atim_window : 1)));
295 + REG_WRITE(ah, AR_NEXT_NDP_TIMER, next_beacon +
296 + TU_TO_USEC(ah->atim_window ? ah->atim_window : 1));
297 flags |= AR_NDP_TIMER_EN;
298 case NL80211_IFTYPE_AP:
299 - REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
300 - REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT,
301 - TU_TO_USEC(next_beacon -
302 - ah->config.
303 - dma_beacon_response_time));
304 - REG_WRITE(ah, AR_NEXT_SWBA,
305 - TU_TO_USEC(next_beacon -
306 - ah->config.
307 - sw_beacon_response_time));
308 + REG_WRITE(ah, AR_NEXT_TBTT_TIMER, next_beacon);
309 + REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, next_beacon -
310 + TU_TO_USEC(ah->config.dma_beacon_response_time));
311 + REG_WRITE(ah, AR_NEXT_SWBA, next_beacon -
312 + TU_TO_USEC(ah->config.sw_beacon_response_time));
313 flags |=
314 AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
315 break;
316 @@ -1723,18 +1717,13 @@ void ath9k_hw_beaconinit(struct ath_hw *
317 break;
318 }
319
320 - REG_WRITE(ah, AR_BEACON_PERIOD, TU_TO_USEC(beacon_period));
321 - REG_WRITE(ah, AR_DMA_BEACON_PERIOD, TU_TO_USEC(beacon_period));
322 - REG_WRITE(ah, AR_SWBA_PERIOD, TU_TO_USEC(beacon_period));
323 - REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period));
324 + REG_WRITE(ah, AR_BEACON_PERIOD, beacon_period);
325 + REG_WRITE(ah, AR_DMA_BEACON_PERIOD, beacon_period);
326 + REG_WRITE(ah, AR_SWBA_PERIOD, beacon_period);
327 + REG_WRITE(ah, AR_NDP_PERIOD, beacon_period);
328
329 REGWRITE_BUFFER_FLUSH(ah);
330
331 - beacon_period &= ~ATH9K_BEACON_ENA;
332 - if (beacon_period & ATH9K_BEACON_RESET_TSF) {
333 - ath9k_hw_reset_tsf(ah);
334 - }
335 -
336 REG_SET_BIT(ah, AR_TIMER_MODE, flags);
337 }
338 EXPORT_SYMBOL(ath9k_hw_beaconinit);
339 @@ -2395,10 +2384,11 @@ static u32 rightmost_index(struct ath_ge
340 return timer_table->gen_timer_index[b];
341 }
342
343 -static u32 ath9k_hw_gettsf32(struct ath_hw *ah)
344 +u32 ath9k_hw_gettsf32(struct ath_hw *ah)
345 {
346 return REG_READ(ah, AR_TSF_L32);
347 }
348 +EXPORT_SYMBOL(ath9k_hw_gettsf32);
349
350 struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
351 void (*trigger)(void *),
352 --- a/drivers/net/wireless/ath/ath9k/hw.h
353 +++ b/drivers/net/wireless/ath/ath9k/hw.h
354 @@ -416,8 +416,6 @@ struct ath9k_beacon_state {
355 u32 bs_nextdtim;
356 u32 bs_intval;
357 #define ATH9K_BEACON_PERIOD 0x0000ffff
358 -#define ATH9K_BEACON_ENA 0x00800000
359 -#define ATH9K_BEACON_RESET_TSF 0x01000000
360 #define ATH9K_TSFOOR_THRESHOLD 0x00004240 /* 16k us */
361 u32 bs_dtimperiod;
362 u16 bs_cfpperiod;
363 @@ -930,6 +928,7 @@ void ath9k_hw_setopmode(struct ath_hw *a
364 void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1);
365 void ath9k_hw_setbssidmask(struct ath_hw *ah);
366 void ath9k_hw_write_associd(struct ath_hw *ah);
367 +u32 ath9k_hw_gettsf32(struct ath_hw *ah);
368 u64 ath9k_hw_gettsf64(struct ath_hw *ah);
369 void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64);
370 void ath9k_hw_reset_tsf(struct ath_hw *ah);
371 --- a/drivers/net/wireless/ath/ath9k/main.c
372 +++ b/drivers/net/wireless/ath/ath9k/main.c
373 @@ -2160,6 +2160,8 @@ static void ath9k_flush(struct ieee80211
374 if (!ath_drain_all_txq(sc, false))
375 ath_reset(sc, false);
376
377 + ieee80211_wake_queues(hw);
378 +
379 out:
380 ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0);
381 mutex_unlock(&sc->mutex);