• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ath9k_reset_beacon_status(struct ath_softc * sc)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 */
ath9k_beaconq_config(struct ath_softc * sc)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 */
ath9k_beacon_setup(struct ath_softc * sc,struct ieee80211_vif * vif,struct ath_buf * bf,int rateidx)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 
ath9k_beacon_generate(struct ieee80211_hw * hw,struct ieee80211_vif * vif)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 
ath9k_beacon_assign_slot(struct ath_softc * sc,struct ieee80211_vif * vif)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 
ath9k_beacon_remove_slot(struct ath_softc * sc,struct ieee80211_vif * vif)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 
ath9k_beacon_choose_slot(struct ath_softc * sc)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 
ath9k_set_tsfadjust(struct ath_softc * sc,struct ieee80211_vif * vif)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 
ath9k_csa_is_finished(struct ath_softc * sc,struct ieee80211_vif * vif)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 
ath9k_csa_update_vif(void * data,u8 * mac,struct ieee80211_vif * vif)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 
ath9k_csa_update(struct ath_softc * sc)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 
ath9k_beacon_tasklet(unsigned long data)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  */
ath9k_beacon_init(struct ath_softc * sc,u32 nexttbtt,u32 intval,bool reset_tsf)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  */
ath9k_beacon_config_ap(struct ath_softc * sc,struct ath_beacon_config * conf)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 
ath9k_beacon_config_sta(struct ath_hw * ah,struct ath_beacon_config * conf)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 
ath9k_beacon_config_adhoc(struct ath_softc * sc,struct ath_beacon_config * conf)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 
ath9k_allow_beacon_config(struct ath_softc * sc,struct ieee80211_vif * vif)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 
ath9k_cache_beacon_config(struct ath_softc * sc,struct ath_chanctx * ctx,struct ieee80211_bss_conf * bss_conf)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 
ath9k_beacon_config(struct ath_softc * sc,struct ieee80211_vif * vif,u32 changed)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 
ath9k_set_beacon(struct ath_softc * sc)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 }
687