Merge tag 'for-4.1' of git://git.kernel.org/pub/scm/linux/kernel/git/kishon/linux...
[deliverable/linux.git] / drivers / net / wireless / ath / ath9k / beacon.c
1 /*
2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17 #include <linux/dma-mapping.h>
18 #include "ath9k.h"
19
20 #define FUDGE 2
21
22 static void ath9k_reset_beacon_status(struct ath_softc *sc)
23 {
24 sc->beacon.tx_processed = false;
25 sc->beacon.tx_last = false;
26 }
27
28 /*
29 * This function will modify certain transmit queue properties depending on
30 * the operating mode of the station (AP or AdHoc). Parameters are AIFS
31 * settings and channel width min/max
32 */
33 static void ath9k_beaconq_config(struct ath_softc *sc)
34 {
35 struct ath_hw *ah = sc->sc_ah;
36 struct ath_common *common = ath9k_hw_common(ah);
37 struct ath9k_tx_queue_info qi, qi_be;
38 struct ath_txq *txq;
39
40 ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi);
41
42 if (sc->sc_ah->opmode == NL80211_IFTYPE_AP ||
43 sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) {
44 /* Always burst out beacon and CAB traffic. */
45 qi.tqi_aifs = 1;
46 qi.tqi_cwmin = 0;
47 qi.tqi_cwmax = 0;
48 } else {
49 /* Adhoc mode; important thing is to use 2x cwmin. */
50 txq = sc->tx.txq_map[IEEE80211_AC_BE];
51 ath9k_hw_get_txq_props(ah, txq->axq_qnum, &qi_be);
52 qi.tqi_aifs = qi_be.tqi_aifs;
53 if (ah->slottime == ATH9K_SLOT_TIME_20)
54 qi.tqi_cwmin = 2*qi_be.tqi_cwmin;
55 else
56 qi.tqi_cwmin = 4*qi_be.tqi_cwmin;
57 qi.tqi_cwmax = qi_be.tqi_cwmax;
58 }
59
60 if (!ath9k_hw_set_txq_props(ah, sc->beacon.beaconq, &qi)) {
61 ath_err(common, "Unable to update h/w beacon queue parameters\n");
62 } else {
63 ath9k_hw_resettxqueue(ah, sc->beacon.beaconq);
64 }
65 }
66
67 /*
68 * Associates the beacon frame buffer with a transmit descriptor. Will set
69 * up rate codes, and channel flags. Beacons are always sent out at the
70 * lowest rate, and are not retried.
71 */
72 static void ath9k_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif,
73 struct ath_buf *bf, int rateidx)
74 {
75 struct sk_buff *skb = bf->bf_mpdu;
76 struct ath_hw *ah = sc->sc_ah;
77 struct ath_common *common = ath9k_hw_common(ah);
78 struct ath_tx_info info;
79 struct ieee80211_supported_band *sband;
80 u8 chainmask = ah->txchainmask;
81 u8 i, rate = 0;
82
83 sband = &common->sbands[sc->cur_chandef.chan->band];
84 rate = sband->bitrates[rateidx].hw_value;
85 if (vif->bss_conf.use_short_preamble)
86 rate |= sband->bitrates[rateidx].hw_value_short;
87
88 memset(&info, 0, sizeof(info));
89 info.pkt_len = skb->len + FCS_LEN;
90 info.type = ATH9K_PKT_TYPE_BEACON;
91 for (i = 0; i < 4; i++)
92 info.txpower[i] = MAX_RATE_POWER;
93 info.keyix = ATH9K_TXKEYIX_INVALID;
94 info.keytype = ATH9K_KEY_TYPE_CLEAR;
95 info.flags = ATH9K_TXDESC_NOACK | ATH9K_TXDESC_CLRDMASK;
96
97 info.buf_addr[0] = bf->bf_buf_addr;
98 info.buf_len[0] = roundup(skb->len, 4);
99
100 info.is_first = true;
101 info.is_last = true;
102
103 info.qcu = sc->beacon.beaconq;
104
105 info.rates[0].Tries = 1;
106 info.rates[0].Rate = rate;
107 info.rates[0].ChSel = ath_txchainmask_reduction(sc, chainmask, rate);
108
109 ath9k_hw_set_txdesc(ah, bf->bf_desc, &info);
110 }
111
112 static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw,
113 struct ieee80211_vif *vif)
114 {
115 struct ath_softc *sc = hw->priv;
116 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
117 struct ath_buf *bf;
118 struct ath_vif *avp = (void *)vif->drv_priv;
119 struct sk_buff *skb;
120 struct ath_txq *cabq = sc->beacon.cabq;
121 struct ieee80211_tx_info *info;
122 struct ieee80211_mgmt *mgmt_hdr;
123 int cabq_depth;
124
125 if (avp->av_bcbuf == NULL)
126 return NULL;
127
128 bf = avp->av_bcbuf;
129 skb = bf->bf_mpdu;
130 if (skb) {
131 dma_unmap_single(sc->dev, bf->bf_buf_addr,
132 skb->len, DMA_TO_DEVICE);
133 dev_kfree_skb_any(skb);
134 bf->bf_buf_addr = 0;
135 bf->bf_mpdu = NULL;
136 }
137
138 skb = ieee80211_beacon_get(hw, vif);
139 if (skb == NULL)
140 return NULL;
141
142 bf->bf_mpdu = skb;
143
144 mgmt_hdr = (struct ieee80211_mgmt *)skb->data;
145 mgmt_hdr->u.beacon.timestamp = avp->tsf_adjust;
146
147 info = IEEE80211_SKB_CB(skb);
148
149 ath_assign_seq(common, skb);
150
151 if (vif->p2p)
152 ath9k_beacon_add_noa(sc, avp, skb);
153
154 bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
155 skb->len, DMA_TO_DEVICE);
156 if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
157 dev_kfree_skb_any(skb);
158 bf->bf_mpdu = NULL;
159 bf->bf_buf_addr = 0;
160 ath_err(common, "dma_mapping_error on beaconing\n");
161 return NULL;
162 }
163
164 skb = ieee80211_get_buffered_bc(hw, vif);
165
166 /*
167 * if the CABQ traffic from previous DTIM is pending and the current
168 * beacon is also a DTIM.
169 * 1) if there is only one vif let the cab traffic continue.
170 * 2) if there are more than one vif and we are using staggered
171 * beacons, then drain the cabq by dropping all the frames in
172 * the cabq so that the current vifs cab traffic can be scheduled.
173 */
174 spin_lock_bh(&cabq->axq_lock);
175 cabq_depth = cabq->axq_depth;
176 spin_unlock_bh(&cabq->axq_lock);
177
178 if (skb && cabq_depth) {
179 if (sc->cur_chan->nvifs > 1) {
180 ath_dbg(common, BEACON,
181 "Flushing previous cabq traffic\n");
182 ath_draintxq(sc, cabq);
183 }
184 }
185
186 ath9k_beacon_setup(sc, vif, bf, info->control.rates[0].idx);
187
188 if (skb)
189 ath_tx_cabq(hw, vif, skb);
190
191 return bf;
192 }
193
194 void ath9k_beacon_assign_slot(struct ath_softc *sc, struct ieee80211_vif *vif)
195 {
196 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
197 struct ath_vif *avp = (void *)vif->drv_priv;
198 int slot;
199
200 avp->av_bcbuf = list_first_entry(&sc->beacon.bbuf, struct ath_buf, list);
201 list_del(&avp->av_bcbuf->list);
202
203 for (slot = 0; slot < ATH_BCBUF; slot++) {
204 if (sc->beacon.bslot[slot] == NULL) {
205 avp->av_bslot = slot;
206 break;
207 }
208 }
209
210 sc->beacon.bslot[avp->av_bslot] = vif;
211 sc->nbcnvifs++;
212
213 ath_dbg(common, CONFIG, "Added interface at beacon slot: %d\n",
214 avp->av_bslot);
215 }
216
217 void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif)
218 {
219 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
220 struct ath_vif *avp = (void *)vif->drv_priv;
221 struct ath_buf *bf = avp->av_bcbuf;
222 struct ath_beacon_config *cur_conf = &sc->cur_chan->beacon;
223
224 ath_dbg(common, CONFIG, "Removing interface at beacon slot: %d\n",
225 avp->av_bslot);
226
227 tasklet_disable(&sc->bcon_tasklet);
228
229 cur_conf->enable_beacon &= ~BIT(avp->av_bslot);
230
231 if (bf && bf->bf_mpdu) {
232 struct sk_buff *skb = bf->bf_mpdu;
233 dma_unmap_single(sc->dev, bf->bf_buf_addr,
234 skb->len, DMA_TO_DEVICE);
235 dev_kfree_skb_any(skb);
236 bf->bf_mpdu = NULL;
237 bf->bf_buf_addr = 0;
238 }
239
240 avp->av_bcbuf = NULL;
241 sc->beacon.bslot[avp->av_bslot] = NULL;
242 sc->nbcnvifs--;
243 list_add_tail(&bf->list, &sc->beacon.bbuf);
244
245 tasklet_enable(&sc->bcon_tasklet);
246 }
247
248 static int ath9k_beacon_choose_slot(struct ath_softc *sc)
249 {
250 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
251 struct ath_beacon_config *cur_conf = &sc->cur_chan->beacon;
252 u16 intval;
253 u32 tsftu;
254 u64 tsf;
255 int slot;
256
257 if (sc->sc_ah->opmode != NL80211_IFTYPE_AP &&
258 sc->sc_ah->opmode != NL80211_IFTYPE_MESH_POINT) {
259 ath_dbg(common, BEACON, "slot 0, tsf: %llu\n",
260 ath9k_hw_gettsf64(sc->sc_ah));
261 return 0;
262 }
263
264 intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL;
265 tsf = ath9k_hw_gettsf64(sc->sc_ah);
266 tsf += TU_TO_USEC(sc->sc_ah->config.sw_beacon_response_time);
267 tsftu = TSF_TO_TU((tsf * ATH_BCBUF) >>32, tsf * ATH_BCBUF);
268 slot = (tsftu % (intval * ATH_BCBUF)) / intval;
269
270 ath_dbg(common, BEACON, "slot: %d tsf: %llu tsftu: %u\n",
271 slot, tsf, tsftu / ATH_BCBUF);
272
273 return slot;
274 }
275
276 static void ath9k_set_tsfadjust(struct ath_softc *sc, struct ieee80211_vif *vif)
277 {
278 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
279 struct ath_vif *avp = (void *)vif->drv_priv;
280 struct ath_beacon_config *cur_conf = &avp->chanctx->beacon;
281 u32 tsfadjust;
282
283 if (avp->av_bslot == 0)
284 return;
285
286 tsfadjust = cur_conf->beacon_interval * avp->av_bslot;
287 tsfadjust = TU_TO_USEC(tsfadjust) / ATH_BCBUF;
288 avp->tsf_adjust = cpu_to_le64(tsfadjust);
289
290 ath_dbg(common, CONFIG, "tsfadjust is: %llu for bslot: %d\n",
291 (unsigned long long)tsfadjust, avp->av_bslot);
292 }
293
294 bool ath9k_csa_is_finished(struct ath_softc *sc, struct ieee80211_vif *vif)
295 {
296 if (!vif || !vif->csa_active)
297 return false;
298
299 if (!ieee80211_csa_is_complete(vif))
300 return false;
301
302 ieee80211_csa_finish(vif);
303 return true;
304 }
305
306 static void ath9k_csa_update_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
307 {
308 struct ath_softc *sc = data;
309 ath9k_csa_is_finished(sc, vif);
310 }
311
312 void ath9k_csa_update(struct ath_softc *sc)
313 {
314 ieee80211_iterate_active_interfaces_atomic(sc->hw,
315 IEEE80211_IFACE_ITER_NORMAL,
316 ath9k_csa_update_vif, sc);
317 }
318
319 void ath9k_beacon_tasklet(unsigned long data)
320 {
321 struct ath_softc *sc = (struct ath_softc *)data;
322 struct ath_hw *ah = sc->sc_ah;
323 struct ath_common *common = ath9k_hw_common(ah);
324 struct ath_buf *bf = NULL;
325 struct ieee80211_vif *vif;
326 bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA);
327 int slot;
328
329 if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) {
330 ath_dbg(common, RESET,
331 "reset work is pending, skip beaconing now\n");
332 return;
333 }
334
335 /*
336 * Check if the previous beacon has gone out. If
337 * not don't try to post another, skip this period
338 * and wait for the next. Missed beacons indicate
339 * a problem and should not occur. If we miss too
340 * many consecutive beacons reset the device.
341 */
342 if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) {
343 sc->beacon.bmisscnt++;
344
345 ath9k_hw_check_nav(ah);
346
347 /*
348 * If the previous beacon has not been transmitted
349 * and a MAC/BB hang has been identified, return
350 * here because a chip reset would have been
351 * initiated.
352 */
353 if (!ath_hw_check(sc))
354 return;
355
356 if (sc->beacon.bmisscnt < BSTUCK_THRESH * sc->nbcnvifs) {
357 ath_dbg(common, BSTUCK,
358 "missed %u consecutive beacons\n",
359 sc->beacon.bmisscnt);
360 ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq);
361 if (sc->beacon.bmisscnt > 3)
362 ath9k_hw_bstuck_nfcal(ah);
363 } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
364 ath_dbg(common, BSTUCK, "beacon is officially stuck\n");
365 sc->beacon.bmisscnt = 0;
366 ath9k_queue_reset(sc, RESET_TYPE_BEACON_STUCK);
367 }
368
369 return;
370 }
371
372 slot = ath9k_beacon_choose_slot(sc);
373 vif = sc->beacon.bslot[slot];
374
375 /* EDMA devices check that in the tx completion function. */
376 if (!edma) {
377 if (ath9k_is_chanctx_enabled()) {
378 ath_chanctx_beacon_sent_ev(sc,
379 ATH_CHANCTX_EVENT_BEACON_SENT);
380 }
381
382 if (ath9k_csa_is_finished(sc, vif))
383 return;
384 }
385
386 if (!vif || !vif->bss_conf.enable_beacon)
387 return;
388
389 if (ath9k_is_chanctx_enabled()) {
390 ath_chanctx_event(sc, vif, ATH_CHANCTX_EVENT_BEACON_PREPARE);
391 }
392
393 bf = ath9k_beacon_generate(sc->hw, vif);
394
395 if (sc->beacon.bmisscnt != 0) {
396 ath_dbg(common, BSTUCK, "resume beacon xmit after %u misses\n",
397 sc->beacon.bmisscnt);
398 sc->beacon.bmisscnt = 0;
399 }
400
401 /*
402 * Handle slot time change when a non-ERP station joins/leaves
403 * an 11g network. The 802.11 layer notifies us via callback,
404 * we mark updateslot, then wait one beacon before effecting
405 * the change. This gives associated stations at least one
406 * beacon interval to note the state change.
407 *
408 * NB: The slot time change state machine is clocked according
409 * to whether we are bursting or staggering beacons. We
410 * recognize the request to update and record the current
411 * slot then don't transition until that slot is reached
412 * again. If we miss a beacon for that slot then we'll be
413 * slow to transition but we'll be sure at least one beacon
414 * interval has passed. When bursting slot is always left
415 * set to ATH_BCBUF so this check is a noop.
416 */
417 if (sc->beacon.updateslot == UPDATE) {
418 sc->beacon.updateslot = COMMIT;
419 sc->beacon.slotupdate = slot;
420 } else if (sc->beacon.updateslot == COMMIT &&
421 sc->beacon.slotupdate == slot) {
422 ah->slottime = sc->beacon.slottime;
423 ath9k_hw_init_global_settings(ah);
424 sc->beacon.updateslot = OK;
425 }
426
427 if (bf) {
428 ath9k_reset_beacon_status(sc);
429
430 ath_dbg(common, BEACON,
431 "Transmitting beacon for slot: %d\n", slot);
432
433 /* NB: cabq traffic should already be queued and primed */
434 ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr);
435
436 if (!edma)
437 ath9k_hw_txstart(ah, sc->beacon.beaconq);
438 }
439 }
440
441 /*
442 * Both nexttbtt and intval have to be in usecs.
443 */
444 static void ath9k_beacon_init(struct ath_softc *sc, u32 nexttbtt,
445 u32 intval, bool reset_tsf)
446 {
447 struct ath_hw *ah = sc->sc_ah;
448
449 ath9k_hw_disable_interrupts(ah);
450 if (reset_tsf)
451 ath9k_hw_reset_tsf(ah);
452 ath9k_beaconq_config(sc);
453 ath9k_hw_beaconinit(ah, nexttbtt, intval);
454 sc->beacon.bmisscnt = 0;
455 ath9k_hw_set_interrupts(ah);
456 ath9k_hw_enable_interrupts(ah);
457 }
458
459 /*
460 * For multi-bss ap support beacons are either staggered evenly over N slots or
461 * burst together. For the former arrange for the SWBA to be delivered for each
462 * slot. Slots that are not occupied will generate nothing.
463 */
464 static void ath9k_beacon_config_ap(struct ath_softc *sc,
465 struct ath_beacon_config *conf)
466 {
467 struct ath_hw *ah = sc->sc_ah;
468
469 ath9k_cmn_beacon_config_ap(ah, conf, ATH_BCBUF);
470 ath9k_beacon_init(sc, conf->nexttbtt, conf->intval, false);
471 }
472
473 static void ath9k_beacon_config_sta(struct ath_hw *ah,
474 struct ath_beacon_config *conf)
475 {
476 struct ath9k_beacon_state bs;
477
478 if (ath9k_cmn_beacon_config_sta(ah, conf, &bs) == -EPERM)
479 return;
480
481 ath9k_hw_disable_interrupts(ah);
482 ath9k_hw_set_sta_beacon_timers(ah, &bs);
483 ah->imask |= ATH9K_INT_BMISS;
484
485 ath9k_hw_set_interrupts(ah);
486 ath9k_hw_enable_interrupts(ah);
487 }
488
489 static void ath9k_beacon_config_adhoc(struct ath_softc *sc,
490 struct ath_beacon_config *conf)
491 {
492 struct ath_hw *ah = sc->sc_ah;
493 struct ath_common *common = ath9k_hw_common(ah);
494
495 ath9k_reset_beacon_status(sc);
496
497 ath9k_cmn_beacon_config_adhoc(ah, conf);
498
499 ath9k_beacon_init(sc, conf->nexttbtt, conf->intval, conf->ibss_creator);
500
501 /*
502 * Set the global 'beacon has been configured' flag for the
503 * joiner case in IBSS mode.
504 */
505 if (!conf->ibss_creator && conf->enable_beacon)
506 set_bit(ATH_OP_BEACONS, &common->op_flags);
507 }
508
509 static bool ath9k_allow_beacon_config(struct ath_softc *sc,
510 struct ieee80211_vif *vif)
511 {
512 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
513 struct ath_vif *avp = (void *)vif->drv_priv;
514
515 if (ath9k_is_chanctx_enabled()) {
516 /*
517 * If the VIF is not present in the current channel context,
518 * then we can't do the usual opmode checks. Allow the
519 * beacon config for the VIF to be updated in this case and
520 * return immediately.
521 */
522 if (sc->cur_chan != avp->chanctx)
523 return true;
524 }
525
526 if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
527 if (vif->type != NL80211_IFTYPE_AP) {
528 ath_dbg(common, CONFIG,
529 "An AP interface is already present !\n");
530 return false;
531 }
532 }
533
534 if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) {
535 if ((vif->type == NL80211_IFTYPE_STATION) &&
536 test_bit(ATH_OP_BEACONS, &common->op_flags) &&
537 vif != sc->cur_chan->primary_sta) {
538 ath_dbg(common, CONFIG,
539 "Beacon already configured for a station interface\n");
540 return false;
541 }
542 }
543
544 return true;
545 }
546
547 static void ath9k_cache_beacon_config(struct ath_softc *sc,
548 struct ath_chanctx *ctx,
549 struct ieee80211_bss_conf *bss_conf)
550 {
551 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
552 struct ath_beacon_config *cur_conf = &ctx->beacon;
553
554 ath_dbg(common, BEACON,
555 "Caching beacon data for BSS: %pM\n", bss_conf->bssid);
556
557 cur_conf->beacon_interval = bss_conf->beacon_int;
558 cur_conf->dtim_period = bss_conf->dtim_period;
559 cur_conf->dtim_count = 1;
560 cur_conf->ibss_creator = bss_conf->ibss_creator;
561
562 /*
563 * It looks like mac80211 may end up using beacon interval of zero in
564 * some cases (at least for mesh point). Avoid getting into an
565 * infinite loop by using a bit safer value instead. To be safe,
566 * do sanity check on beacon interval for all operating modes.
567 */
568 if (cur_conf->beacon_interval == 0)
569 cur_conf->beacon_interval = 100;
570
571 cur_conf->bmiss_timeout =
572 ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval;
573
574 /*
575 * We don't parse dtim period from mac80211 during the driver
576 * initialization as it breaks association with hidden-ssid
577 * AP and it causes latency in roaming
578 */
579 if (cur_conf->dtim_period == 0)
580 cur_conf->dtim_period = 1;
581
582 }
583
584 void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif,
585 u32 changed)
586 {
587 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
588 struct ath_hw *ah = sc->sc_ah;
589 struct ath_common *common = ath9k_hw_common(ah);
590 struct ath_vif *avp = (void *)vif->drv_priv;
591 struct ath_chanctx *ctx = avp->chanctx;
592 struct ath_beacon_config *cur_conf;
593 unsigned long flags;
594 bool skip_beacon = false;
595
596 if (!ctx)
597 return;
598
599 cur_conf = &avp->chanctx->beacon;
600 if (vif->type == NL80211_IFTYPE_AP)
601 ath9k_set_tsfadjust(sc, vif);
602
603 if (!ath9k_allow_beacon_config(sc, vif))
604 return;
605
606 if (vif->type == NL80211_IFTYPE_STATION) {
607 ath9k_cache_beacon_config(sc, ctx, bss_conf);
608 if (ctx != sc->cur_chan)
609 return;
610
611 ath9k_set_beacon(sc);
612 set_bit(ATH_OP_BEACONS, &common->op_flags);
613 return;
614 }
615
616 /*
617 * Take care of multiple interfaces when
618 * enabling/disabling SWBA.
619 */
620 if (changed & BSS_CHANGED_BEACON_ENABLED) {
621 bool enabled = cur_conf->enable_beacon;
622
623 if (!bss_conf->enable_beacon) {
624 cur_conf->enable_beacon &= ~BIT(avp->av_bslot);
625 } else {
626 cur_conf->enable_beacon |= BIT(avp->av_bslot);
627 if (!enabled)
628 ath9k_cache_beacon_config(sc, ctx, bss_conf);
629 }
630 }
631
632 if (ctx != sc->cur_chan)
633 return;
634
635 /*
636 * Configure the HW beacon registers only when we have a valid
637 * beacon interval.
638 */
639 if (cur_conf->beacon_interval) {
640 /*
641 * If we are joining an existing IBSS network, start beaconing
642 * only after a TSF-sync has taken place. Ensure that this
643 * happens by setting the appropriate flags.
644 */
645 if ((changed & BSS_CHANGED_IBSS) && !bss_conf->ibss_creator &&
646 bss_conf->enable_beacon) {
647 spin_lock_irqsave(&sc->sc_pm_lock, flags);
648 sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
649 spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
650 skip_beacon = true;
651 } else {
652 ath9k_set_beacon(sc);
653 }
654
655 /*
656 * Do not set the ATH_OP_BEACONS flag for IBSS joiner mode
657 * here, it is done in ath9k_beacon_config_adhoc().
658 */
659 if (cur_conf->enable_beacon && !skip_beacon)
660 set_bit(ATH_OP_BEACONS, &common->op_flags);
661 else
662 clear_bit(ATH_OP_BEACONS, &common->op_flags);
663 }
664 }
665
666 void ath9k_set_beacon(struct ath_softc *sc)
667 {
668 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
669 struct ath_beacon_config *cur_conf = &sc->cur_chan->beacon;
670
671 switch (sc->sc_ah->opmode) {
672 case NL80211_IFTYPE_AP:
673 case NL80211_IFTYPE_MESH_POINT:
674 ath9k_beacon_config_ap(sc, cur_conf);
675 break;
676 case NL80211_IFTYPE_ADHOC:
677 ath9k_beacon_config_adhoc(sc, cur_conf);
678 break;
679 case NL80211_IFTYPE_STATION:
680 ath9k_beacon_config_sta(sc->sc_ah, cur_conf);
681 break;
682 default:
683 ath_dbg(common, CONFIG, "Unsupported beaconing mode\n");
684 return;
685 }
686 }
This page took 0.046996 seconds and 5 git commands to generate.