df492bb81277fd4a3a6e7b3fd8690a4b7fb2dc1b
[openwrt/staging/wigyori.git] / package / kernel / mac80211 / patches / 300-pending_work.patch
1 commit 60ccc107c9b9fb732fdee1f76bb2dad44f0e1798
2 Author: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
3 Date: Tue May 27 16:58:02 2014 +0530
4
5 ath9k: Fix deadlock while updating p2p beacon timer
6
7 pm_lock is taken twice while syncing HW TSF of p2p vif.
8 Fix this by taking the lock at caller side.
9
10 Cc: Felix Fietkau <nbd@openwrt.org>
11 Signed-off-by: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
12 Signed-off-by: John W. Linville <linville@tuxdriver.com>
13
14 commit f3831a4e3903dbc1a57d5df56deb6a143fd001bc
15 Author: Stanislaw Gruszka <sgruszka@redhat.com>
16 Date: Thu Jun 5 13:52:27 2014 +0200
17
18 rt2x00: do not initialize BCN_OFFSET registers
19
20 We setup BCN_OFFSET{0,1} registers dynamically, don't have to
21 initialize them.
22
23 Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
24
25 commit e5c58ca7a48d4c82f282749a978052c47fd95998
26 Author: Stanislaw Gruszka <sgruszka@redhat.com>
27 Date: Thu Jun 5 13:52:26 2014 +0200
28
29 rt2x00: change order when stop beaconing
30
31 When no beaconing is needed, first stop beacon queue (disable beaconing
32 globally) to avoid possible sending of not prepared beacon on short
33 period after clearing beacon and before stop of BCN queue.
34
35 Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
36
37 commit 382c1b9e03f52d0cd741ef1d942cad0f649f0744
38 Author: Stanislaw Gruszka <sgruszka@redhat.com>
39 Date: Thu Jun 5 13:52:25 2014 +0200
40
41 rt2x00: change default MAC_BSSID_DW1_BSS_BCN_NUM
42
43 We setup MAC_BSSID_DW1_BSS_BCN_NUM dynamically when numbers of active
44 beacons increase. Change default to 0 to tell hardware that we want to
45 send only one beacon as default.
46
47 Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
48
49 commit 3b400571dd033e46fa7e76c5bb92a3ce8198afa9
50 Author: Stanislaw Gruszka <sgruszka@redhat.com>
51 Date: Thu Jun 5 13:52:24 2014 +0200
52
53 rt2x00: change beaconing setup on RT2800
54
55 As reported by Matthias, on 5572 chip, even if we clear up TXWI
56 of corresponding beacon, hardware still try to send it or do other
57 action that increase power consumption peak up to 1A.
58
59 To avoid the issue, setup beaconing dynamically by configuring offsets
60 of currently active beacons and MAC_BSSID_DW1_BSS_BCN_NUM variable,
61 which limit number of beacons that hardware will try to send.
62
63 Reported-by: Matthias Fend <Matthias.Fend@wolfvision.net>
64 Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
65
66 commit 916e591b2cc41f7e572992175ca56d866d7bc958
67 Author: Stanislaw Gruszka <sgruszka@redhat.com>
68 Date: Thu Jun 5 13:52:23 2014 +0200
69
70 rt2x00: change beaconing locking
71
72 This patch is needed for further changes to keep global variables
73 consistent when changing beaconing on diffrent vif's.
74
75 Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
76
77 commit 930b0dffd1731f3f418f9132faea720a23b7af61
78 Author: Johannes Berg <johannes.berg@intel.com>
79 Date: Tue Jun 3 11:18:47 2014 +0200
80
81 mac80211: fix station/driver powersave race
82
83 It is currently possible to have a race due to the station PS
84 unblock work like this:
85 * station goes to sleep with frames buffered in the driver
86 * driver blocks wakeup
87 * station wakes up again
88 * driver flushes/returns frames, and unblocks, which schedules
89 the unblock work
90 * unblock work starts to run, and checks that the station is
91 awake (i.e. that the WLAN_STA_PS_STA flag isn't set)
92 * we process a received frame with PM=1, setting the flag again
93 * ieee80211_sta_ps_deliver_wakeup() runs, delivering all frames
94 to the driver, and then clearing the WLAN_STA_PS_DRIVER and
95 WLAN_STA_PS_STA flags
96
97 In this scenario, mac80211 will think that the station is awake,
98 while it really is asleep, and any TX'ed frames should be filtered
99 by the device (it will know that the station is sleeping) but then
100 passed to mac80211 again, which will not buffer it either as it
101 thinks the station is awake, and eventually the packets will be
102 dropped.
103
104 Fix this by moving the clearing of the flags to exactly where we
105 learn about the situation. This creates a problem of reordering,
106 so introduce another flag indicating that delivery is being done,
107 this new flag also queues frames and is cleared only while the
108 spinlock is held (which the queuing code also holds) so that any
109 concurrent delivery/TX is handled correctly.
110
111 Reported-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
112 Signed-off-by: Johannes Berg <johannes.berg@intel.com>
113
114 commit 6df35206bc6c1c6aad1d8077df5786b4a7f77873
115 Author: Felix Fietkau <nbd@openwrt.org>
116 Date: Fri May 23 19:58:14 2014 +0200
117
118 mac80211: reduce packet loss notifications under load
119
120 During strong signal fluctuations under high throughput, few consecutive
121 failed A-MPDU transmissions can easily trigger packet loss notification,
122 and thus (in AP mode) client disconnection.
123
124 Reduce the number of false positives by checking the A-MPDU status flag
125 and treating a failed A-MPDU as a single packet.
126
127 Signed-off-by: Felix Fietkau <nbd@openwrt.org>
128
129 commit 7b7843a36fbcc568834404c7430ff895d8502131
130 Author: Felix Fietkau <nbd@openwrt.org>
131 Date: Fri May 23 19:26:32 2014 +0200
132
133 mac80211: fix a memory leak on sta rate selection table
134
135 Cc: stable@vger.kernel.org
136 Reported-by: Christophe Prévotaux <cprevotaux@nltinc.com>
137 Signed-off-by: Felix Fietkau <nbd@openwrt.org>
138
139 commit 96892d6aa0a153423070addf3070bc79578b3897
140 Author: Felix Fietkau <nbd@openwrt.org>
141 Date: Mon May 19 21:20:49 2014 +0200
142
143 ath9k: avoid passing buffers to the hardware during flush
144
145 The commit "ath9k: fix possible hang on flush" changed the receive code
146 to always link rx descriptors of processed frames, even when flushing.
147 In some cases, this leads to flushed rx buffers being passed to the
148 hardware while rx is already stopped.
149
150 Signed-off-by: Felix Fietkau <nbd@openwrt.org>
151
152 --- a/drivers/net/wireless/ath/ath9k/recv.c
153 +++ b/drivers/net/wireless/ath/ath9k/recv.c
154 @@ -34,7 +34,8 @@ static inline bool ath9k_check_auto_slee
155 * buffer (or rx fifo). This can incorrectly acknowledge packets
156 * to a sender if last desc is self-linked.
157 */
158 -static void ath_rx_buf_link(struct ath_softc *sc, struct ath_rxbuf *bf)
159 +static void ath_rx_buf_link(struct ath_softc *sc, struct ath_rxbuf *bf,
160 + bool flush)
161 {
162 struct ath_hw *ah = sc->sc_ah;
163 struct ath_common *common = ath9k_hw_common(ah);
164 @@ -59,18 +60,19 @@ static void ath_rx_buf_link(struct ath_s
165 common->rx_bufsize,
166 0);
167
168 - if (sc->rx.rxlink == NULL)
169 - ath9k_hw_putrxbuf(ah, bf->bf_daddr);
170 - else
171 + if (sc->rx.rxlink)
172 *sc->rx.rxlink = bf->bf_daddr;
173 + else if (!flush)
174 + ath9k_hw_putrxbuf(ah, bf->bf_daddr);
175
176 sc->rx.rxlink = &ds->ds_link;
177 }
178
179 -static void ath_rx_buf_relink(struct ath_softc *sc, struct ath_rxbuf *bf)
180 +static void ath_rx_buf_relink(struct ath_softc *sc, struct ath_rxbuf *bf,
181 + bool flush)
182 {
183 if (sc->rx.buf_hold)
184 - ath_rx_buf_link(sc, sc->rx.buf_hold);
185 + ath_rx_buf_link(sc, sc->rx.buf_hold, flush);
186
187 sc->rx.buf_hold = bf;
188 }
189 @@ -442,7 +444,7 @@ int ath_startrecv(struct ath_softc *sc)
190 sc->rx.buf_hold = NULL;
191 sc->rx.rxlink = NULL;
192 list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list) {
193 - ath_rx_buf_link(sc, bf);
194 + ath_rx_buf_link(sc, bf, false);
195 }
196
197 /* We could have deleted elements so the list may be empty now */
198 @@ -1118,12 +1120,12 @@ requeue_drop_frag:
199 requeue:
200 list_add_tail(&bf->list, &sc->rx.rxbuf);
201
202 - if (edma) {
203 - ath_rx_edma_buf_link(sc, qtype);
204 - } else {
205 - ath_rx_buf_relink(sc, bf);
206 + if (!edma) {
207 + ath_rx_buf_relink(sc, bf, flush);
208 if (!flush)
209 ath9k_hw_rxena(ah);
210 + } else if (!flush) {
211 + ath_rx_edma_buf_link(sc, qtype);
212 }
213
214 if (!budget--)
215 --- a/net/mac80211/sta_info.c
216 +++ b/net/mac80211/sta_info.c
217 @@ -100,7 +100,8 @@ static void __cleanup_single_sta(struct
218 struct ps_data *ps;
219
220 if (test_sta_flag(sta, WLAN_STA_PS_STA) ||
221 - test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
222 + test_sta_flag(sta, WLAN_STA_PS_DRIVER) ||
223 + test_sta_flag(sta, WLAN_STA_PS_DELIVER)) {
224 if (sta->sdata->vif.type == NL80211_IFTYPE_AP ||
225 sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
226 ps = &sdata->bss->ps;
227 @@ -111,6 +112,7 @@ static void __cleanup_single_sta(struct
228
229 clear_sta_flag(sta, WLAN_STA_PS_STA);
230 clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
231 + clear_sta_flag(sta, WLAN_STA_PS_DELIVER);
232
233 atomic_dec(&ps->num_sta_ps);
234 sta_info_recalc_tim(sta);
235 @@ -125,7 +127,7 @@ static void __cleanup_single_sta(struct
236 if (ieee80211_vif_is_mesh(&sdata->vif))
237 mesh_sta_cleanup(sta);
238
239 - cancel_work_sync(&sta->drv_unblock_wk);
240 + cancel_work_sync(&sta->drv_deliver_wk);
241
242 /*
243 * Destroy aggregation state here. It would be nice to wait for the
244 @@ -227,6 +229,7 @@ struct sta_info *sta_info_get_by_idx(str
245 */
246 void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
247 {
248 + struct ieee80211_sta_rates *rates;
249 int i;
250
251 if (sta->rate_ctrl)
252 @@ -238,6 +241,10 @@ void sta_info_free(struct ieee80211_loca
253 kfree(sta->tx_lat);
254 }
255
256 + rates = rcu_dereference_protected(sta->sta.rates, true);
257 + if (rates)
258 + kfree(rates);
259 +
260 sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr);
261
262 kfree(sta);
263 @@ -252,33 +259,23 @@ static void sta_info_hash_add(struct iee
264 rcu_assign_pointer(local->sta_hash[STA_HASH(sta->sta.addr)], sta);
265 }
266
267 -static void sta_unblock(struct work_struct *wk)
268 +static void sta_deliver_ps_frames(struct work_struct *wk)
269 {
270 struct sta_info *sta;
271
272 - sta = container_of(wk, struct sta_info, drv_unblock_wk);
273 + sta = container_of(wk, struct sta_info, drv_deliver_wk);
274
275 if (sta->dead)
276 return;
277
278 - if (!test_sta_flag(sta, WLAN_STA_PS_STA)) {
279 - local_bh_disable();
280 + local_bh_disable();
281 + if (!test_sta_flag(sta, WLAN_STA_PS_STA))
282 ieee80211_sta_ps_deliver_wakeup(sta);
283 - local_bh_enable();
284 - } else if (test_and_clear_sta_flag(sta, WLAN_STA_PSPOLL)) {
285 - clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
286 -
287 - local_bh_disable();
288 + else if (test_and_clear_sta_flag(sta, WLAN_STA_PSPOLL))
289 ieee80211_sta_ps_deliver_poll_response(sta);
290 - local_bh_enable();
291 - } else if (test_and_clear_sta_flag(sta, WLAN_STA_UAPSD)) {
292 - clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
293 -
294 - local_bh_disable();
295 + else if (test_and_clear_sta_flag(sta, WLAN_STA_UAPSD))
296 ieee80211_sta_ps_deliver_uapsd(sta);
297 - local_bh_enable();
298 - } else
299 - clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
300 + local_bh_enable();
301 }
302
303 static int sta_prepare_rate_control(struct ieee80211_local *local,
304 @@ -340,7 +337,7 @@ struct sta_info *sta_info_alloc(struct i
305
306 spin_lock_init(&sta->lock);
307 spin_lock_init(&sta->ps_lock);
308 - INIT_WORK(&sta->drv_unblock_wk, sta_unblock);
309 + INIT_WORK(&sta->drv_deliver_wk, sta_deliver_ps_frames);
310 INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work);
311 mutex_init(&sta->ampdu_mlme.mtx);
312 #ifdef CPTCFG_MAC80211_MESH
313 @@ -1140,8 +1137,15 @@ void ieee80211_sta_ps_deliver_wakeup(str
314 }
315
316 ieee80211_add_pending_skbs(local, &pending);
317 - clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
318 - clear_sta_flag(sta, WLAN_STA_PS_STA);
319 +
320 + /* now we're no longer in the deliver code */
321 + clear_sta_flag(sta, WLAN_STA_PS_DELIVER);
322 +
323 + /* The station might have polled and then woken up before we responded,
324 + * so clear these flags now to avoid them sticking around.
325 + */
326 + clear_sta_flag(sta, WLAN_STA_PSPOLL);
327 + clear_sta_flag(sta, WLAN_STA_UAPSD);
328 spin_unlock(&sta->ps_lock);
329
330 atomic_dec(&ps->num_sta_ps);
331 @@ -1542,10 +1546,26 @@ void ieee80211_sta_block_awake(struct ie
332
333 trace_api_sta_block_awake(sta->local, pubsta, block);
334
335 - if (block)
336 + if (block) {
337 set_sta_flag(sta, WLAN_STA_PS_DRIVER);
338 - else if (test_sta_flag(sta, WLAN_STA_PS_DRIVER))
339 - ieee80211_queue_work(hw, &sta->drv_unblock_wk);
340 + return;
341 + }
342 +
343 + if (!test_sta_flag(sta, WLAN_STA_PS_DRIVER))
344 + return;
345 +
346 + if (!test_sta_flag(sta, WLAN_STA_PS_STA)) {
347 + set_sta_flag(sta, WLAN_STA_PS_DELIVER);
348 + clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
349 + ieee80211_queue_work(hw, &sta->drv_deliver_wk);
350 + } else if (test_sta_flag(sta, WLAN_STA_PSPOLL) ||
351 + test_sta_flag(sta, WLAN_STA_UAPSD)) {
352 + /* must be asleep in this case */
353 + clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
354 + ieee80211_queue_work(hw, &sta->drv_deliver_wk);
355 + } else {
356 + clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
357 + }
358 }
359 EXPORT_SYMBOL(ieee80211_sta_block_awake);
360
361 --- a/net/mac80211/status.c
362 +++ b/net/mac80211/status.c
363 @@ -541,6 +541,23 @@ static void ieee80211_tx_latency_end_msr
364 */
365 #define STA_LOST_PKT_THRESHOLD 50
366
367 +static void ieee80211_lost_packet(struct sta_info *sta, struct sk_buff *skb)
368 +{
369 + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
370 +
371 + /* This packet was aggregated but doesn't carry status info */
372 + if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
373 + !(info->flags & IEEE80211_TX_STAT_AMPDU))
374 + return;
375 +
376 + if (++sta->lost_packets < STA_LOST_PKT_THRESHOLD)
377 + return;
378 +
379 + cfg80211_cqm_pktloss_notify(sta->sdata->dev, sta->sta.addr,
380 + sta->lost_packets, GFP_ATOMIC);
381 + sta->lost_packets = 0;
382 +}
383 +
384 void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
385 {
386 struct sk_buff *skb2;
387 @@ -680,12 +697,8 @@ void ieee80211_tx_status(struct ieee8021
388 if (info->flags & IEEE80211_TX_STAT_ACK) {
389 if (sta->lost_packets)
390 sta->lost_packets = 0;
391 - } else if (++sta->lost_packets >= STA_LOST_PKT_THRESHOLD) {
392 - cfg80211_cqm_pktloss_notify(sta->sdata->dev,
393 - sta->sta.addr,
394 - sta->lost_packets,
395 - GFP_ATOMIC);
396 - sta->lost_packets = 0;
397 + } else {
398 + ieee80211_lost_packet(sta, skb);
399 }
400 }
401
402 --- a/net/mac80211/rx.c
403 +++ b/net/mac80211/rx.c
404 @@ -1107,6 +1107,8 @@ static void sta_ps_end(struct sta_info *
405 return;
406 }
407
408 + set_sta_flag(sta, WLAN_STA_PS_DELIVER);
409 + clear_sta_flag(sta, WLAN_STA_PS_STA);
410 ieee80211_sta_ps_deliver_wakeup(sta);
411 }
412
413 --- a/net/mac80211/sta_info.h
414 +++ b/net/mac80211/sta_info.h
415 @@ -82,6 +82,7 @@ enum ieee80211_sta_info_flags {
416 WLAN_STA_TOFFSET_KNOWN,
417 WLAN_STA_MPSP_OWNER,
418 WLAN_STA_MPSP_RECIPIENT,
419 + WLAN_STA_PS_DELIVER,
420 };
421
422 #define ADDBA_RESP_INTERVAL HZ
423 @@ -265,7 +266,7 @@ struct ieee80211_tx_latency_stat {
424 * @last_rx_rate_vht_nss: rx status nss of last data packet
425 * @lock: used for locking all fields that require locking, see comments
426 * in the header file.
427 - * @drv_unblock_wk: used for driver PS unblocking
428 + * @drv_deliver_wk: used for delivering frames after driver PS unblocking
429 * @listen_interval: listen interval of this station, when we're acting as AP
430 * @_flags: STA flags, see &enum ieee80211_sta_info_flags, do not use directly
431 * @ps_lock: used for powersave (when mac80211 is the AP) related locking
432 @@ -345,7 +346,7 @@ struct sta_info {
433 void *rate_ctrl_priv;
434 spinlock_t lock;
435
436 - struct work_struct drv_unblock_wk;
437 + struct work_struct drv_deliver_wk;
438
439 u16 listen_interval;
440
441 --- a/net/mac80211/tx.c
442 +++ b/net/mac80211/tx.c
443 @@ -469,7 +469,8 @@ ieee80211_tx_h_unicast_ps_buf(struct iee
444 return TX_CONTINUE;
445
446 if (unlikely((test_sta_flag(sta, WLAN_STA_PS_STA) ||
447 - test_sta_flag(sta, WLAN_STA_PS_DRIVER)) &&
448 + test_sta_flag(sta, WLAN_STA_PS_DRIVER) ||
449 + test_sta_flag(sta, WLAN_STA_PS_DELIVER)) &&
450 !(info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER))) {
451 int ac = skb_get_queue_mapping(tx->skb);
452
453 @@ -486,7 +487,8 @@ ieee80211_tx_h_unicast_ps_buf(struct iee
454 * ahead and Tx the packet.
455 */
456 if (!test_sta_flag(sta, WLAN_STA_PS_STA) &&
457 - !test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
458 + !test_sta_flag(sta, WLAN_STA_PS_DRIVER) &&
459 + !test_sta_flag(sta, WLAN_STA_PS_DELIVER)) {
460 spin_unlock(&sta->ps_lock);
461 return TX_CONTINUE;
462 }
463 --- a/drivers/net/wireless/rt2x00/rt2800lib.c
464 +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
465 @@ -947,6 +947,40 @@ static inline u8 rt2800_get_beacon_offse
466 return BEACON_BASE_TO_OFFSET(rt2800_hw_beacon_base(rt2x00dev, index));
467 }
468
469 +static void rt2800_update_beacons_setup(struct rt2x00_dev *rt2x00dev)
470 +{
471 + struct data_queue *queue = rt2x00dev->bcn;
472 + struct queue_entry *entry;
473 + int i, bcn_num = 0;
474 + u64 off, reg = 0;
475 + u32 bssid_dw1;
476 +
477 + /*
478 + * Setup offsets of all active beacons in BCN_OFFSET{0,1} registers.
479 + */
480 + for (i = 0; i < queue->limit; i++) {
481 + entry = &queue->entries[i];
482 + if (!test_bit(ENTRY_BCN_ENABLED, &entry->flags))
483 + continue;
484 + off = rt2800_get_beacon_offset(rt2x00dev, entry->entry_idx);
485 + reg |= off << (8 * bcn_num);
486 + bcn_num++;
487 + }
488 +
489 + WARN_ON_ONCE(bcn_num != rt2x00dev->intf_beaconing);
490 +
491 + rt2800_register_write(rt2x00dev, BCN_OFFSET0, (u32) reg);
492 + rt2800_register_write(rt2x00dev, BCN_OFFSET1, (u32) (reg >> 32));
493 +
494 + /*
495 + * H/W sends up to MAC_BSSID_DW1_BSS_BCN_NUM + 1 consecutive beacons.
496 + */
497 + rt2800_register_read(rt2x00dev, MAC_BSSID_DW1, &bssid_dw1);
498 + rt2x00_set_field32(&bssid_dw1, MAC_BSSID_DW1_BSS_BCN_NUM,
499 + bcn_num > 0 ? bcn_num - 1 : 0);
500 + rt2800_register_write(rt2x00dev, MAC_BSSID_DW1, bssid_dw1);
501 +}
502 +
503 void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
504 {
505 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
506 @@ -1003,6 +1037,12 @@ void rt2800_write_beacon(struct queue_en
507
508 rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
509 entry->skb->len + padding_len);
510 + __set_bit(ENTRY_BCN_ENABLED, &entry->flags);
511 +
512 + /*
513 + * Change global beacons settings.
514 + */
515 + rt2800_update_beacons_setup(rt2x00dev);
516
517 /*
518 * Restore beaconing state.
519 @@ -1053,8 +1093,13 @@ void rt2800_clear_beacon(struct queue_en
520 * Clear beacon.
521 */
522 rt2800_clear_beacon_register(rt2x00dev, entry->entry_idx);
523 + __clear_bit(ENTRY_BCN_ENABLED, &entry->flags);
524
525 /*
526 + * Change global beacons settings.
527 + */
528 + rt2800_update_beacons_setup(rt2x00dev);
529 + /*
530 * Restore beaconing state.
531 */
532 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, orig_reg);
533 @@ -1556,7 +1601,7 @@ void rt2800_config_intf(struct rt2x00_de
534 if (!is_zero_ether_addr((const u8 *)conf->bssid)) {
535 reg = le32_to_cpu(conf->bssid[1]);
536 rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_ID_MASK, 3);
537 - rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_BCN_NUM, 7);
538 + rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_BCN_NUM, 0);
539 conf->bssid[1] = cpu_to_le32(reg);
540 }
541
542 @@ -4517,28 +4562,6 @@ static int rt2800_init_registers(struct
543 if (ret)
544 return ret;
545
546 - rt2800_register_read(rt2x00dev, BCN_OFFSET0, &reg);
547 - rt2x00_set_field32(&reg, BCN_OFFSET0_BCN0,
548 - rt2800_get_beacon_offset(rt2x00dev, 0));
549 - rt2x00_set_field32(&reg, BCN_OFFSET0_BCN1,
550 - rt2800_get_beacon_offset(rt2x00dev, 1));
551 - rt2x00_set_field32(&reg, BCN_OFFSET0_BCN2,
552 - rt2800_get_beacon_offset(rt2x00dev, 2));
553 - rt2x00_set_field32(&reg, BCN_OFFSET0_BCN3,
554 - rt2800_get_beacon_offset(rt2x00dev, 3));
555 - rt2800_register_write(rt2x00dev, BCN_OFFSET0, reg);
556 -
557 - rt2800_register_read(rt2x00dev, BCN_OFFSET1, &reg);
558 - rt2x00_set_field32(&reg, BCN_OFFSET1_BCN4,
559 - rt2800_get_beacon_offset(rt2x00dev, 4));
560 - rt2x00_set_field32(&reg, BCN_OFFSET1_BCN5,
561 - rt2800_get_beacon_offset(rt2x00dev, 5));
562 - rt2x00_set_field32(&reg, BCN_OFFSET1_BCN6,
563 - rt2800_get_beacon_offset(rt2x00dev, 6));
564 - rt2x00_set_field32(&reg, BCN_OFFSET1_BCN7,
565 - rt2800_get_beacon_offset(rt2x00dev, 7));
566 - rt2800_register_write(rt2x00dev, BCN_OFFSET1, reg);
567 -
568 rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, 0x0000013f);
569 rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
570
571 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c
572 +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
573 @@ -141,8 +141,11 @@ static void rt2x00lib_intf_scheduled_ite
574 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
575 return;
576
577 - if (test_and_clear_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags))
578 + if (test_and_clear_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags)) {
579 + mutex_lock(&intf->beacon_skb_mutex);
580 rt2x00queue_update_beacon(rt2x00dev, vif);
581 + mutex_unlock(&intf->beacon_skb_mutex);
582 + }
583 }
584
585 static void rt2x00lib_intf_scheduled(struct work_struct *work)
586 @@ -216,7 +219,7 @@ static void rt2x00lib_beaconupdate_iter(
587 * never be called for USB devices.
588 */
589 WARN_ON(rt2x00_is_usb(rt2x00dev));
590 - rt2x00queue_update_beacon_locked(rt2x00dev, vif);
591 + rt2x00queue_update_beacon(rt2x00dev, vif);
592 }
593
594 void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
595 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c
596 +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
597 @@ -624,25 +624,24 @@ void rt2x00mac_bss_info_changed(struct i
598 * Start/stop beaconing.
599 */
600 if (changes & BSS_CHANGED_BEACON_ENABLED) {
601 + mutex_lock(&intf->beacon_skb_mutex);
602 if (!bss_conf->enable_beacon && intf->enable_beacon) {
603 rt2x00dev->intf_beaconing--;
604 intf->enable_beacon = false;
605 - /*
606 - * Clear beacon in the H/W for this vif. This is needed
607 - * to disable beaconing on this particular interface
608 - * and keep it running on other interfaces.
609 - */
610 - rt2x00queue_clear_beacon(rt2x00dev, vif);
611
612 if (rt2x00dev->intf_beaconing == 0) {
613 /*
614 * Last beaconing interface disabled
615 * -> stop beacon queue.
616 */
617 - mutex_lock(&intf->beacon_skb_mutex);
618 rt2x00queue_stop_queue(rt2x00dev->bcn);
619 - mutex_unlock(&intf->beacon_skb_mutex);
620 }
621 + /*
622 + * Clear beacon in the H/W for this vif. This is needed
623 + * to disable beaconing on this particular interface
624 + * and keep it running on other interfaces.
625 + */
626 + rt2x00queue_clear_beacon(rt2x00dev, vif);
627 } else if (bss_conf->enable_beacon && !intf->enable_beacon) {
628 rt2x00dev->intf_beaconing++;
629 intf->enable_beacon = true;
630 @@ -658,11 +657,10 @@ void rt2x00mac_bss_info_changed(struct i
631 * First beaconing interface enabled
632 * -> start beacon queue.
633 */
634 - mutex_lock(&intf->beacon_skb_mutex);
635 rt2x00queue_start_queue(rt2x00dev->bcn);
636 - mutex_unlock(&intf->beacon_skb_mutex);
637 }
638 }
639 + mutex_unlock(&intf->beacon_skb_mutex);
640 }
641
642 /*
643 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c
644 +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
645 @@ -754,8 +754,6 @@ int rt2x00queue_clear_beacon(struct rt2x
646 if (unlikely(!intf->beacon))
647 return -ENOBUFS;
648
649 - mutex_lock(&intf->beacon_skb_mutex);
650 -
651 /*
652 * Clean up the beacon skb.
653 */
654 @@ -768,13 +766,11 @@ int rt2x00queue_clear_beacon(struct rt2x
655 if (rt2x00dev->ops->lib->clear_beacon)
656 rt2x00dev->ops->lib->clear_beacon(intf->beacon);
657
658 - mutex_unlock(&intf->beacon_skb_mutex);
659 -
660 return 0;
661 }
662
663 -int rt2x00queue_update_beacon_locked(struct rt2x00_dev *rt2x00dev,
664 - struct ieee80211_vif *vif)
665 +int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
666 + struct ieee80211_vif *vif)
667 {
668 struct rt2x00_intf *intf = vif_to_intf(vif);
669 struct skb_frame_desc *skbdesc;
670 @@ -815,19 +811,6 @@ int rt2x00queue_update_beacon_locked(str
671
672 }
673
674 -int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
675 - struct ieee80211_vif *vif)
676 -{
677 - struct rt2x00_intf *intf = vif_to_intf(vif);
678 - int ret;
679 -
680 - mutex_lock(&intf->beacon_skb_mutex);
681 - ret = rt2x00queue_update_beacon_locked(rt2x00dev, vif);
682 - mutex_unlock(&intf->beacon_skb_mutex);
683 -
684 - return ret;
685 -}
686 -
687 bool rt2x00queue_for_each_entry(struct data_queue *queue,
688 enum queue_index start,
689 enum queue_index end,
690 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h
691 +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
692 @@ -353,6 +353,7 @@ struct txentry_desc {
693 */
694 enum queue_entry_flags {
695 ENTRY_BCN_ASSIGNED,
696 + ENTRY_BCN_ENABLED,
697 ENTRY_OWNER_DEVICE_DATA,
698 ENTRY_DATA_PENDING,
699 ENTRY_DATA_IO_FAILED,
700 --- a/drivers/net/wireless/ath/ath9k/main.c
701 +++ b/drivers/net/wireless/ath/ath9k/main.c
702 @@ -1757,7 +1757,6 @@ out:
703 void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif)
704 {
705 struct ath_vif *avp = (void *)vif->drv_priv;
706 - unsigned long flags;
707 u32 tsf;
708
709 if (!sc->p2p_ps_timer)
710 @@ -1767,14 +1766,9 @@ void ath9k_update_p2p_ps(struct ath_soft
711 return;
712
713 sc->p2p_ps_vif = avp;
714 -
715 - spin_lock_irqsave(&sc->sc_pm_lock, flags);
716 - if (!(sc->ps_flags & PS_BEACON_SYNC)) {
717 - tsf = ath9k_hw_gettsf32(sc->sc_ah);
718 - ieee80211_parse_p2p_noa(&vif->bss_conf.p2p_noa_attr, &avp->noa, tsf);
719 - ath9k_update_p2p_ps_timer(sc, avp);
720 - }
721 - spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
722 + tsf = ath9k_hw_gettsf32(sc->sc_ah);
723 + ieee80211_parse_p2p_noa(&vif->bss_conf.p2p_noa_attr, &avp->noa, tsf);
724 + ath9k_update_p2p_ps_timer(sc, avp);
725 }
726
727 static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
728 @@ -1791,6 +1785,7 @@ static void ath9k_bss_info_changed(struc
729 struct ath_hw *ah = sc->sc_ah;
730 struct ath_common *common = ath9k_hw_common(ah);
731 struct ath_vif *avp = (void *)vif->drv_priv;
732 + unsigned long flags;
733 int slottime;
734
735 ath9k_ps_wakeup(sc);
736 @@ -1853,7 +1848,10 @@ static void ath9k_bss_info_changed(struc
737
738 if (changed & BSS_CHANGED_P2P_PS) {
739 spin_lock_bh(&sc->sc_pcu_lock);
740 - ath9k_update_p2p_ps(sc, vif);
741 + spin_lock_irqsave(&sc->sc_pm_lock, flags);
742 + if (!(sc->ps_flags & PS_BEACON_SYNC))
743 + ath9k_update_p2p_ps(sc, vif);
744 + spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
745 spin_unlock_bh(&sc->sc_pcu_lock);
746 }
747