1 commit 60ccc107c9b9fb732fdee1f76bb2dad44f0e1798
2 Author: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
3 Date: Tue May 27 16:58:02 2014 +0530
5 ath9k: Fix deadlock while updating p2p beacon timer
7 pm_lock is taken twice while syncing HW TSF of p2p vif.
8 Fix this by taking the lock at caller side.
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>
14 commit f3831a4e3903dbc1a57d5df56deb6a143fd001bc
15 Author: Stanislaw Gruszka <sgruszka@redhat.com>
16 Date: Thu Jun 5 13:52:27 2014 +0200
18 rt2x00: do not initialize BCN_OFFSET registers
20 We setup BCN_OFFSET{0,1} registers dynamically, don't have to
23 Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
25 commit e5c58ca7a48d4c82f282749a978052c47fd95998
26 Author: Stanislaw Gruszka <sgruszka@redhat.com>
27 Date: Thu Jun 5 13:52:26 2014 +0200
29 rt2x00: change order when stop beaconing
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.
35 Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
37 commit 382c1b9e03f52d0cd741ef1d942cad0f649f0744
38 Author: Stanislaw Gruszka <sgruszka@redhat.com>
39 Date: Thu Jun 5 13:52:25 2014 +0200
41 rt2x00: change default MAC_BSSID_DW1_BSS_BCN_NUM
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.
47 Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
49 commit 3b400571dd033e46fa7e76c5bb92a3ce8198afa9
50 Author: Stanislaw Gruszka <sgruszka@redhat.com>
51 Date: Thu Jun 5 13:52:24 2014 +0200
53 rt2x00: change beaconing setup on RT2800
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.
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.
63 Reported-by: Matthias Fend <Matthias.Fend@wolfvision.net>
64 Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
66 commit 916e591b2cc41f7e572992175ca56d866d7bc958
67 Author: Stanislaw Gruszka <sgruszka@redhat.com>
68 Date: Thu Jun 5 13:52:23 2014 +0200
70 rt2x00: change beaconing locking
72 This patch is needed for further changes to keep global variables
73 consistent when changing beaconing on diffrent vif's.
75 Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
77 commit 930b0dffd1731f3f418f9132faea720a23b7af61
78 Author: Johannes Berg <johannes.berg@intel.com>
79 Date: Tue Jun 3 11:18:47 2014 +0200
81 mac80211: fix station/driver powersave race
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
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
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
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.
111 Reported-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
112 Signed-off-by: Johannes Berg <johannes.berg@intel.com>
114 commit 6df35206bc6c1c6aad1d8077df5786b4a7f77873
115 Author: Felix Fietkau <nbd@openwrt.org>
116 Date: Fri May 23 19:58:14 2014 +0200
118 mac80211: reduce packet loss notifications under load
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.
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.
127 Signed-off-by: Felix Fietkau <nbd@openwrt.org>
129 commit 7b7843a36fbcc568834404c7430ff895d8502131
130 Author: Felix Fietkau <nbd@openwrt.org>
131 Date: Fri May 23 19:26:32 2014 +0200
133 mac80211: fix a memory leak on sta rate selection table
135 Cc: stable@vger.kernel.org
136 Reported-by: Christophe Prévotaux <cprevotaux@nltinc.com>
137 Signed-off-by: Felix Fietkau <nbd@openwrt.org>
139 commit 96892d6aa0a153423070addf3070bc79578b3897
140 Author: Felix Fietkau <nbd@openwrt.org>
141 Date: Mon May 19 21:20:49 2014 +0200
143 ath9k: avoid passing buffers to the hardware during flush
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.
150 Signed-off-by: Felix Fietkau <nbd@openwrt.org>
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.
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,
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
168 - if (sc->rx.rxlink == NULL)
169 - ath9k_hw_putrxbuf(ah, bf->bf_daddr);
172 *sc->rx.rxlink = bf->bf_daddr;
174 + ath9k_hw_putrxbuf(ah, bf->bf_daddr);
176 sc->rx.rxlink = &ds->ds_link;
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,
184 - ath_rx_buf_link(sc, sc->rx.buf_hold);
185 + ath_rx_buf_link(sc, sc->rx.buf_hold, flush);
187 sc->rx.buf_hold = bf;
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);
197 /* We could have deleted elements so the list may be empty now */
198 @@ -1118,12 +1120,12 @@ requeue_drop_frag:
200 list_add_tail(&bf->list, &sc->rx.rxbuf);
203 - ath_rx_edma_buf_link(sc, qtype);
205 - ath_rx_buf_relink(sc, bf);
207 + ath_rx_buf_relink(sc, bf, flush);
210 + } else if (!flush) {
211 + ath_rx_edma_buf_link(sc, qtype);
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
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
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);
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);
239 - cancel_work_sync(&sta->drv_unblock_wk);
240 + cancel_work_sync(&sta->drv_deliver_wk);
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
246 void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
248 + struct ieee80211_sta_rates *rates;
252 @@ -238,6 +241,10 @@ void sta_info_free(struct ieee80211_loca
256 + rates = rcu_dereference_protected(sta->sta.rates, true);
260 sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr);
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);
267 -static void sta_unblock(struct work_struct *wk)
268 +static void sta_deliver_ps_frames(struct work_struct *wk)
270 struct sta_info *sta;
272 - sta = container_of(wk, struct sta_info, drv_unblock_wk);
273 + sta = container_of(wk, struct sta_info, drv_deliver_wk);
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);
284 - } else if (test_and_clear_sta_flag(sta, WLAN_STA_PSPOLL)) {
285 - clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
287 - local_bh_disable();
288 + else if (test_and_clear_sta_flag(sta, WLAN_STA_PSPOLL))
289 ieee80211_sta_ps_deliver_poll_response(sta);
291 - } else if (test_and_clear_sta_flag(sta, WLAN_STA_UAPSD)) {
292 - clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
294 - local_bh_disable();
295 + else if (test_and_clear_sta_flag(sta, WLAN_STA_UAPSD))
296 ieee80211_sta_ps_deliver_uapsd(sta);
299 - clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
303 static int sta_prepare_rate_control(struct ieee80211_local *local,
304 @@ -340,7 +337,7 @@ struct sta_info *sta_info_alloc(struct i
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
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);
320 + /* now we're no longer in the deliver code */
321 + clear_sta_flag(sta, WLAN_STA_PS_DELIVER);
323 + /* The station might have polled and then woken up before we responded,
324 + * so clear these flags now to avoid them sticking around.
326 + clear_sta_flag(sta, WLAN_STA_PSPOLL);
327 + clear_sta_flag(sta, WLAN_STA_UAPSD);
328 spin_unlock(&sta->ps_lock);
330 atomic_dec(&ps->num_sta_ps);
331 @@ -1542,10 +1546,26 @@ void ieee80211_sta_block_awake(struct ie
333 trace_api_sta_block_awake(sta->local, pubsta, 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);
343 + if (!test_sta_flag(sta, WLAN_STA_PS_DRIVER))
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);
356 + clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
359 EXPORT_SYMBOL(ieee80211_sta_block_awake);
361 --- a/net/mac80211/status.c
362 +++ b/net/mac80211/status.c
363 @@ -541,6 +541,23 @@ static void ieee80211_tx_latency_end_msr
365 #define STA_LOST_PKT_THRESHOLD 50
367 +static void ieee80211_lost_packet(struct sta_info *sta, struct sk_buff *skb)
369 + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
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))
376 + if (++sta->lost_packets < STA_LOST_PKT_THRESHOLD)
379 + cfg80211_cqm_pktloss_notify(sta->sdata->dev, sta->sta.addr,
380 + sta->lost_packets, GFP_ATOMIC);
381 + sta->lost_packets = 0;
384 void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
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,
396 - sta->lost_packets = 0;
398 + ieee80211_lost_packet(sta, skb);
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 *
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);
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,
418 WLAN_STA_MPSP_RECIPIENT,
419 + WLAN_STA_PS_DELIVER,
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;
436 - struct work_struct drv_unblock_wk;
437 + struct work_struct drv_deliver_wk;
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
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);
453 @@ -486,7 +487,8 @@ ieee80211_tx_h_unicast_ps_buf(struct iee
454 * ahead and Tx the packet.
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);
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));
469 +static void rt2800_update_beacons_setup(struct rt2x00_dev *rt2x00dev)
471 + struct data_queue *queue = rt2x00dev->bcn;
472 + struct queue_entry *entry;
473 + int i, bcn_num = 0;
478 + * Setup offsets of all active beacons in BCN_OFFSET{0,1} registers.
480 + for (i = 0; i < queue->limit; i++) {
481 + entry = &queue->entries[i];
482 + if (!test_bit(ENTRY_BCN_ENABLED, &entry->flags))
484 + off = rt2800_get_beacon_offset(rt2x00dev, entry->entry_idx);
485 + reg |= off << (8 * bcn_num);
489 + WARN_ON_ONCE(bcn_num != rt2x00dev->intf_beaconing);
491 + rt2800_register_write(rt2x00dev, BCN_OFFSET0, (u32) reg);
492 + rt2800_register_write(rt2x00dev, BCN_OFFSET1, (u32) (reg >> 32));
495 + * H/W sends up to MAC_BSSID_DW1_BSS_BCN_NUM + 1 consecutive beacons.
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);
503 void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
505 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
506 @@ -1003,6 +1037,12 @@ void rt2800_write_beacon(struct queue_en
508 rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
509 entry->skb->len + padding_len);
510 + __set_bit(ENTRY_BCN_ENABLED, &entry->flags);
513 + * Change global beacons settings.
515 + rt2800_update_beacons_setup(rt2x00dev);
518 * Restore beaconing state.
519 @@ -1053,8 +1093,13 @@ void rt2800_clear_beacon(struct queue_en
522 rt2800_clear_beacon_register(rt2x00dev, entry->entry_idx);
523 + __clear_bit(ENTRY_BCN_ENABLED, &entry->flags);
526 + * Change global beacons settings.
528 + rt2800_update_beacons_setup(rt2x00dev);
530 * Restore beaconing state.
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(®, MAC_BSSID_DW1_BSS_ID_MASK, 3);
537 - rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_BCN_NUM, 7);
538 + rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_BCN_NUM, 0);
539 conf->bssid[1] = cpu_to_le32(reg);
542 @@ -4517,28 +4562,6 @@ static int rt2800_init_registers(struct
546 - rt2800_register_read(rt2x00dev, BCN_OFFSET0, ®);
547 - rt2x00_set_field32(®, BCN_OFFSET0_BCN0,
548 - rt2800_get_beacon_offset(rt2x00dev, 0));
549 - rt2x00_set_field32(®, BCN_OFFSET0_BCN1,
550 - rt2800_get_beacon_offset(rt2x00dev, 1));
551 - rt2x00_set_field32(®, BCN_OFFSET0_BCN2,
552 - rt2800_get_beacon_offset(rt2x00dev, 2));
553 - rt2x00_set_field32(®, BCN_OFFSET0_BCN3,
554 - rt2800_get_beacon_offset(rt2x00dev, 3));
555 - rt2800_register_write(rt2x00dev, BCN_OFFSET0, reg);
557 - rt2800_register_read(rt2x00dev, BCN_OFFSET1, ®);
558 - rt2x00_set_field32(®, BCN_OFFSET1_BCN4,
559 - rt2800_get_beacon_offset(rt2x00dev, 4));
560 - rt2x00_set_field32(®, BCN_OFFSET1_BCN5,
561 - rt2800_get_beacon_offset(rt2x00dev, 5));
562 - rt2x00_set_field32(®, BCN_OFFSET1_BCN6,
563 - rt2800_get_beacon_offset(rt2x00dev, 6));
564 - rt2x00_set_field32(®, BCN_OFFSET1_BCN7,
565 - rt2800_get_beacon_offset(rt2x00dev, 7));
566 - rt2800_register_write(rt2x00dev, BCN_OFFSET1, reg);
568 rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, 0x0000013f);
569 rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
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))
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);
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.
589 WARN_ON(rt2x00_is_usb(rt2x00dev));
590 - rt2x00queue_update_beacon_locked(rt2x00dev, vif);
591 + rt2x00queue_update_beacon(rt2x00dev, vif);
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.
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;
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.
610 - rt2x00queue_clear_beacon(rt2x00dev, vif);
612 if (rt2x00dev->intf_beaconing == 0) {
614 * Last beaconing interface disabled
615 * -> stop beacon queue.
617 - mutex_lock(&intf->beacon_skb_mutex);
618 rt2x00queue_stop_queue(rt2x00dev->bcn);
619 - mutex_unlock(&intf->beacon_skb_mutex);
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.
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.
634 - mutex_lock(&intf->beacon_skb_mutex);
635 rt2x00queue_start_queue(rt2x00dev->bcn);
636 - mutex_unlock(&intf->beacon_skb_mutex);
639 + mutex_unlock(&intf->beacon_skb_mutex);
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))
649 - mutex_lock(&intf->beacon_skb_mutex);
652 * Clean up the beacon skb.
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);
658 - mutex_unlock(&intf->beacon_skb_mutex);
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)
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
674 -int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
675 - struct ieee80211_vif *vif)
677 - struct rt2x00_intf *intf = vif_to_intf(vif);
680 - mutex_lock(&intf->beacon_skb_mutex);
681 - ret = rt2x00queue_update_beacon_locked(rt2x00dev, vif);
682 - mutex_unlock(&intf->beacon_skb_mutex);
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 {
694 enum queue_entry_flags {
697 ENTRY_OWNER_DEVICE_DATA,
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)
705 struct ath_vif *avp = (void *)vif->drv_priv;
706 - unsigned long flags;
709 if (!sc->p2p_ps_timer)
710 @@ -1767,14 +1766,9 @@ void ath9k_update_p2p_ps(struct ath_soft
713 sc->p2p_ps_vif = avp;
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);
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);
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;
736 @@ -1853,7 +1848,10 @@ static void ath9k_bss_info_changed(struc
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);