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