2 * Copyright (c) 2008-2009 Atheros Communications Inc.
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.
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.
22 * This function will modify certain transmit queue properties depending on
23 * the operating mode of the station (AP or AdHoc). Parameters are AIFS
24 * settings and channel width min/max
26 int ath_beaconq_config(struct ath_softc
*sc
)
28 struct ath_hw
*ah
= sc
->sc_ah
;
29 struct ath_common
*common
= ath9k_hw_common(ah
);
30 struct ath9k_tx_queue_info qi
, qi_be
;
33 ath9k_hw_get_txq_props(ah
, sc
->beacon
.beaconq
, &qi
);
34 if (sc
->sc_ah
->opmode
== NL80211_IFTYPE_AP
) {
35 /* Always burst out beacon and CAB traffic. */
40 /* Adhoc mode; important thing is to use 2x cwmin. */
41 qnum
= sc
->tx
.hwq_map
[WME_AC_BE
];
42 ath9k_hw_get_txq_props(ah
, qnum
, &qi_be
);
43 qi
.tqi_aifs
= qi_be
.tqi_aifs
;
44 qi
.tqi_cwmin
= 4*qi_be
.tqi_cwmin
;
45 qi
.tqi_cwmax
= qi_be
.tqi_cwmax
;
48 if (!ath9k_hw_set_txq_props(ah
, sc
->beacon
.beaconq
, &qi
)) {
49 ath_print(common
, ATH_DBG_FATAL
,
50 "Unable to update h/w beacon queue parameters\n");
53 ath9k_hw_resettxqueue(ah
, sc
->beacon
.beaconq
);
59 * Associates the beacon frame buffer with a transmit descriptor. Will set
60 * up all required antenna switch parameters, rate codes, and channel flags.
61 * Beacons are always sent out at the lowest rate, and are not retried.
63 static void ath_beacon_setup(struct ath_softc
*sc
, struct ath_vif
*avp
,
64 struct ath_buf
*bf
, int rateidx
)
66 struct sk_buff
*skb
= bf
->bf_mpdu
;
67 struct ath_hw
*ah
= sc
->sc_ah
;
68 struct ath_common
*common
= ath9k_hw_common(ah
);
70 struct ath9k_11n_rate_series series
[4];
71 int flags
, antenna
, ctsrate
= 0, ctsduration
= 0;
72 struct ieee80211_supported_band
*sband
;
76 flags
= ATH9K_TXDESC_NOACK
;
79 antenna
= ((sc
->beacon
.ast_be_xmit
/ sc
->nbcnvifs
) & 1 ? 2 : 1);
81 sband
= &sc
->sbands
[common
->hw
->conf
.channel
->band
];
82 rate
= sband
->bitrates
[rateidx
].hw_value
;
83 if (sc
->sc_flags
& SC_OP_PREAMBLE_SHORT
)
84 rate
|= sband
->bitrates
[rateidx
].hw_value_short
;
86 ath9k_hw_set11n_txdesc(ah
, ds
, skb
->len
+ FCS_LEN
,
87 ATH9K_PKT_TYPE_BEACON
,
89 ATH9K_TXKEYIX_INVALID
,
93 /* NB: beacon's BufLen must be a multiple of 4 bytes */
94 ath9k_hw_filltxdesc(ah
, ds
, roundup(skb
->len
, 4),
95 true, true, ds
, bf
->bf_buf_addr
,
98 memset(series
, 0, sizeof(struct ath9k_11n_rate_series
) * 4);
100 series
[0].Rate
= rate
;
101 series
[0].ChSel
= common
->tx_chainmask
;
102 series
[0].RateFlags
= (ctsrate
) ? ATH9K_RATESERIES_RTS_CTS
: 0;
103 ath9k_hw_set11n_ratescenario(ah
, ds
, ds
, 0, ctsrate
, ctsduration
,
107 static struct ath_buf
*ath_beacon_generate(struct ieee80211_hw
*hw
,
108 struct ieee80211_vif
*vif
)
110 struct ath_wiphy
*aphy
= hw
->priv
;
111 struct ath_softc
*sc
= aphy
->sc
;
112 struct ath_common
*common
= ath9k_hw_common(sc
->sc_ah
);
116 struct ath_txq
*cabq
;
117 struct ieee80211_tx_info
*info
;
120 if (aphy
->state
!= ATH_WIPHY_ACTIVE
)
123 avp
= (void *)vif
->drv_priv
;
124 cabq
= sc
->beacon
.cabq
;
126 if (avp
->av_bcbuf
== NULL
)
129 /* Release the old beacon first */
134 dma_unmap_single(sc
->dev
, bf
->bf_dmacontext
,
135 skb
->len
, DMA_TO_DEVICE
);
136 dev_kfree_skb_any(skb
);
139 /* Get a new beacon from mac80211 */
141 skb
= ieee80211_beacon_get(hw
, vif
);
145 ((struct ieee80211_mgmt
*)skb
->data
)->u
.beacon
.timestamp
=
148 info
= IEEE80211_SKB_CB(skb
);
149 if (info
->flags
& IEEE80211_TX_CTL_ASSIGN_SEQ
) {
151 * TODO: make sure the seq# gets assigned properly (vs. other
154 struct ieee80211_hdr
*hdr
= (struct ieee80211_hdr
*)skb
->data
;
155 sc
->tx
.seq_no
+= 0x10;
156 hdr
->seq_ctrl
&= cpu_to_le16(IEEE80211_SCTL_FRAG
);
157 hdr
->seq_ctrl
|= cpu_to_le16(sc
->tx
.seq_no
);
160 bf
->bf_buf_addr
= bf
->bf_dmacontext
=
161 dma_map_single(sc
->dev
, skb
->data
,
162 skb
->len
, DMA_TO_DEVICE
);
163 if (unlikely(dma_mapping_error(sc
->dev
, bf
->bf_buf_addr
))) {
164 dev_kfree_skb_any(skb
);
166 ath_print(common
, ATH_DBG_FATAL
,
167 "dma_mapping_error on beaconing\n");
171 skb
= ieee80211_get_buffered_bc(hw
, vif
);
174 * if the CABQ traffic from previous DTIM is pending and the current
175 * beacon is also a DTIM.
176 * 1) if there is only one vif let the cab traffic continue.
177 * 2) if there are more than one vif and we are using staggered
178 * beacons, then drain the cabq by dropping all the frames in
179 * the cabq so that the current vifs cab traffic can be scheduled.
181 spin_lock_bh(&cabq
->axq_lock
);
182 cabq_depth
= cabq
->axq_depth
;
183 spin_unlock_bh(&cabq
->axq_lock
);
185 if (skb
&& cabq_depth
) {
187 ath_print(common
, ATH_DBG_BEACON
,
188 "Flushing previous cabq traffic\n");
189 ath_draintxq(sc
, cabq
, false);
193 ath_beacon_setup(sc
, avp
, bf
, info
->control
.rates
[0].idx
);
196 ath_tx_cabq(hw
, skb
);
197 skb
= ieee80211_get_buffered_bc(hw
, vif
);
203 int ath_beacon_alloc(struct ath_wiphy
*aphy
, struct ieee80211_vif
*vif
)
205 struct ath_softc
*sc
= aphy
->sc
;
206 struct ath_common
*common
= ath9k_hw_common(sc
->sc_ah
);
212 avp
= (void *)vif
->drv_priv
;
214 /* Allocate a beacon descriptor if we haven't done so. */
215 if (!avp
->av_bcbuf
) {
216 /* Allocate beacon state for hostap/ibss. We know
217 * a buffer is available. */
218 avp
->av_bcbuf
= list_first_entry(&sc
->beacon
.bbuf
,
219 struct ath_buf
, list
);
220 list_del(&avp
->av_bcbuf
->list
);
222 if (sc
->sc_ah
->opmode
== NL80211_IFTYPE_AP
||
223 sc
->sc_ah
->opmode
== NL80211_IFTYPE_ADHOC
||
224 sc
->sc_ah
->opmode
== NL80211_IFTYPE_MESH_POINT
) {
227 * Assign the vif to a beacon xmit slot. As
228 * above, this cannot fail to find one.
231 for (slot
= 0; slot
< ATH_BCBUF
; slot
++)
232 if (sc
->beacon
.bslot
[slot
] == NULL
) {
233 avp
->av_bslot
= slot
;
235 /* NB: keep looking for a double slot */
236 if (slot
== 0 || !sc
->beacon
.bslot
[slot
-1])
239 BUG_ON(sc
->beacon
.bslot
[avp
->av_bslot
] != NULL
);
240 sc
->beacon
.bslot
[avp
->av_bslot
] = vif
;
241 sc
->beacon
.bslot_aphy
[avp
->av_bslot
] = aphy
;
246 /* release the previous beacon frame, if it already exists. */
248 if (bf
->bf_mpdu
!= NULL
) {
250 dma_unmap_single(sc
->dev
, bf
->bf_dmacontext
,
251 skb
->len
, DMA_TO_DEVICE
);
252 dev_kfree_skb_any(skb
);
256 /* NB: the beacon data buffer must be 32-bit aligned. */
257 skb
= ieee80211_beacon_get(sc
->hw
, vif
);
259 ath_print(common
, ATH_DBG_BEACON
, "cannot get skb\n");
263 tstamp
= ((struct ieee80211_mgmt
*)skb
->data
)->u
.beacon
.timestamp
;
264 sc
->beacon
.bc_tstamp
= le64_to_cpu(tstamp
);
265 /* Calculate a TSF adjustment factor required for staggered beacons. */
266 if (avp
->av_bslot
> 0) {
270 intval
= sc
->beacon_interval
? : ATH_DEFAULT_BINTVAL
;
273 * Calculate the TSF offset for this beacon slot, i.e., the
274 * number of usecs that need to be added to the timestamp field
275 * in Beacon and Probe Response frames. Beacon slot 0 is
276 * processed at the correct offset, so it does not require TSF
277 * adjustment. Other slots are adjusted to get the timestamp
278 * close to the TBTT for the BSS.
280 tsfadjust
= intval
* avp
->av_bslot
/ ATH_BCBUF
;
281 avp
->tsf_adjust
= cpu_to_le64(TU_TO_USEC(tsfadjust
));
283 ath_print(common
, ATH_DBG_BEACON
,
284 "stagger beacons, bslot %d intval "
285 "%u tsfadjust %llu\n",
286 avp
->av_bslot
, intval
, (unsigned long long)tsfadjust
);
288 ((struct ieee80211_mgmt
*)skb
->data
)->u
.beacon
.timestamp
=
291 avp
->tsf_adjust
= cpu_to_le64(0);
294 bf
->bf_buf_addr
= bf
->bf_dmacontext
=
295 dma_map_single(sc
->dev
, skb
->data
,
296 skb
->len
, DMA_TO_DEVICE
);
297 if (unlikely(dma_mapping_error(sc
->dev
, bf
->bf_buf_addr
))) {
298 dev_kfree_skb_any(skb
);
300 ath_print(common
, ATH_DBG_FATAL
,
301 "dma_mapping_error on beacon alloc\n");
308 void ath_beacon_return(struct ath_softc
*sc
, struct ath_vif
*avp
)
310 if (avp
->av_bcbuf
!= NULL
) {
313 if (avp
->av_bslot
!= -1) {
314 sc
->beacon
.bslot
[avp
->av_bslot
] = NULL
;
315 sc
->beacon
.bslot_aphy
[avp
->av_bslot
] = NULL
;
320 if (bf
->bf_mpdu
!= NULL
) {
321 struct sk_buff
*skb
= bf
->bf_mpdu
;
322 dma_unmap_single(sc
->dev
, bf
->bf_dmacontext
,
323 skb
->len
, DMA_TO_DEVICE
);
324 dev_kfree_skb_any(skb
);
327 list_add_tail(&bf
->list
, &sc
->beacon
.bbuf
);
329 avp
->av_bcbuf
= NULL
;
333 void ath_beacon_tasklet(unsigned long data
)
335 struct ath_softc
*sc
= (struct ath_softc
*)data
;
336 struct ath_hw
*ah
= sc
->sc_ah
;
337 struct ath_common
*common
= ath9k_hw_common(ah
);
338 struct ath_buf
*bf
= NULL
;
339 struct ieee80211_vif
*vif
;
340 struct ath_wiphy
*aphy
;
342 u32 bfaddr
, bc
= 0, tsftu
;
347 * Check if the previous beacon has gone out. If
348 * not don't try to post another, skip this period
349 * and wait for the next. Missed beacons indicate
350 * a problem and should not occur. If we miss too
351 * many consecutive beacons reset the device.
353 if (ath9k_hw_numtxpending(ah
, sc
->beacon
.beaconq
) != 0) {
354 sc
->beacon
.bmisscnt
++;
356 if (sc
->beacon
.bmisscnt
< BSTUCK_THRESH
) {
357 ath_print(common
, ATH_DBG_BEACON
,
358 "missed %u consecutive beacons\n",
359 sc
->beacon
.bmisscnt
);
360 } else if (sc
->beacon
.bmisscnt
>= BSTUCK_THRESH
) {
361 ath_print(common
, ATH_DBG_BEACON
,
362 "beacon is officially stuck\n");
363 sc
->sc_flags
|= SC_OP_TSF_RESET
;
370 if (sc
->beacon
.bmisscnt
!= 0) {
371 ath_print(common
, ATH_DBG_BEACON
,
372 "resume beacon xmit after %u misses\n",
373 sc
->beacon
.bmisscnt
);
374 sc
->beacon
.bmisscnt
= 0;
378 * Generate beacon frames. we are sending frames
379 * staggered so calculate the slot for this frame based
380 * on the tsf to safeguard against missing an swba.
383 intval
= sc
->beacon_interval
? : ATH_DEFAULT_BINTVAL
;
385 tsf
= ath9k_hw_gettsf64(ah
);
386 tsftu
= TSF_TO_TU(tsf
>>32, tsf
);
387 slot
= ((tsftu
% intval
) * ATH_BCBUF
) / intval
;
389 * Reverse the slot order to get slot 0 on the TBTT offset that does
390 * not require TSF adjustment and other slots adding
391 * slot/ATH_BCBUF * beacon_int to timestamp. For example, with
392 * ATH_BCBUF = 4, we process beacon slots as follows: 3 2 1 0 3 2 1 ..
393 * and slot 0 is at correct offset to TBTT.
395 slot
= ATH_BCBUF
- slot
- 1;
396 vif
= sc
->beacon
.bslot
[slot
];
397 aphy
= sc
->beacon
.bslot_aphy
[slot
];
399 ath_print(common
, ATH_DBG_BEACON
,
400 "slot %d [tsf %llu tsftu %u intval %u] vif %p\n",
401 slot
, tsf
, tsftu
, intval
, vif
);
405 bf
= ath_beacon_generate(aphy
->hw
, vif
);
407 bfaddr
= bf
->bf_daddr
;
413 * Handle slot time change when a non-ERP station joins/leaves
414 * an 11g network. The 802.11 layer notifies us via callback,
415 * we mark updateslot, then wait one beacon before effecting
416 * the change. This gives associated stations at least one
417 * beacon interval to note the state change.
419 * NB: The slot time change state machine is clocked according
420 * to whether we are bursting or staggering beacons. We
421 * recognize the request to update and record the current
422 * slot then don't transition until that slot is reached
423 * again. If we miss a beacon for that slot then we'll be
424 * slow to transition but we'll be sure at least one beacon
425 * interval has passed. When bursting slot is always left
426 * set to ATH_BCBUF so this check is a noop.
428 if (sc
->beacon
.updateslot
== UPDATE
) {
429 sc
->beacon
.updateslot
= COMMIT
; /* commit next beacon */
430 sc
->beacon
.slotupdate
= slot
;
431 } else if (sc
->beacon
.updateslot
== COMMIT
&& sc
->beacon
.slotupdate
== slot
) {
432 ah
->slottime
= sc
->beacon
.slottime
;
433 ath9k_hw_init_global_settings(ah
);
434 sc
->beacon
.updateslot
= OK
;
438 * Stop any current dma and put the new frame(s) on the queue.
439 * This should never fail since we check above that no frames
440 * are still pending on the queue.
442 if (!ath9k_hw_stoptxdma(ah
, sc
->beacon
.beaconq
)) {
443 ath_print(common
, ATH_DBG_FATAL
,
444 "beacon queue %u did not stop?\n", sc
->beacon
.beaconq
);
447 /* NB: cabq traffic should already be queued and primed */
448 ath9k_hw_puttxbuf(ah
, sc
->beacon
.beaconq
, bfaddr
);
449 ath9k_hw_txstart(ah
, sc
->beacon
.beaconq
);
451 sc
->beacon
.ast_be_xmit
+= bc
;
455 static void ath9k_beacon_init(struct ath_softc
*sc
,
459 if (beacon_period
& ATH9K_BEACON_RESET_TSF
)
462 ath9k_hw_beaconinit(sc
->sc_ah
, next_beacon
, beacon_period
);
464 if (beacon_period
& ATH9K_BEACON_RESET_TSF
)
465 ath9k_ps_restore(sc
);
469 * For multi-bss ap support beacons are either staggered evenly over N slots or
470 * burst together. For the former arrange for the SWBA to be delivered for each
471 * slot. Slots that are not occupied will generate nothing.
473 static void ath_beacon_config_ap(struct ath_softc
*sc
,
474 struct ath_beacon_config
*conf
)
476 struct ath_hw
*ah
= sc
->sc_ah
;
477 u32 nexttbtt
, intval
;
479 /* NB: the beacon interval is kept internally in TU's */
480 intval
= conf
->beacon_interval
& ATH9K_BEACON_PERIOD
;
481 intval
/= ATH_BCBUF
; /* for staggered beacons */
484 if (sc
->sc_flags
& SC_OP_TSF_RESET
)
485 intval
|= ATH9K_BEACON_RESET_TSF
;
488 * In AP mode we enable the beacon timers and SWBA interrupts to
489 * prepare beacon frames.
491 intval
|= ATH9K_BEACON_ENA
;
492 ah
->imask
|= ATH9K_INT_SWBA
;
493 ath_beaconq_config(sc
);
495 /* Set the computed AP beacon timers */
497 ath9k_hw_set_interrupts(ah
, 0);
498 ath9k_beacon_init(sc
, nexttbtt
, intval
);
499 sc
->beacon
.bmisscnt
= 0;
500 ath9k_hw_set_interrupts(ah
, ah
->imask
);
502 /* Clear the reset TSF flag, so that subsequent beacon updation
503 will not reset the HW TSF. */
505 sc
->sc_flags
&= ~SC_OP_TSF_RESET
;
509 * This sets up the beacon timers according to the timestamp of the last
510 * received beacon and the current TSF, configures PCF and DTIM
511 * handling, programs the sleep registers so the hardware will wakeup in
512 * time to receive beacons, and configures the beacon miss handling so
513 * we'll receive a BMISS interrupt when we stop seeing beacons from the AP
514 * we've associated with.
516 static void ath_beacon_config_sta(struct ath_softc
*sc
,
517 struct ath_beacon_config
*conf
)
519 struct ath_hw
*ah
= sc
->sc_ah
;
520 struct ath_common
*common
= ath9k_hw_common(ah
);
521 struct ath9k_beacon_state bs
;
522 int dtimperiod
, dtimcount
, sleepduration
;
523 int cfpperiod
, cfpcount
;
524 u32 nexttbtt
= 0, intval
, tsftu
;
526 int num_beacons
, offset
, dtim_dec_count
, cfp_dec_count
;
528 /* No need to configure beacon if we are not associated */
529 if (!common
->curaid
) {
530 ath_print(common
, ATH_DBG_BEACON
,
531 "STA is not yet associated..skipping beacon config\n");
535 memset(&bs
, 0, sizeof(bs
));
536 intval
= conf
->beacon_interval
& ATH9K_BEACON_PERIOD
;
539 * Setup dtim and cfp parameters according to
540 * last beacon we received (which may be none).
542 dtimperiod
= conf
->dtim_period
;
543 if (dtimperiod
<= 0) /* NB: 0 if not known */
545 dtimcount
= conf
->dtim_count
;
546 if (dtimcount
>= dtimperiod
) /* NB: sanity check */
548 cfpperiod
= 1; /* NB: no PCF support yet */
551 sleepduration
= conf
->listen_interval
* intval
;
552 if (sleepduration
<= 0)
553 sleepduration
= intval
;
556 * Pull nexttbtt forward to reflect the current
557 * TSF and calculate dtim+cfp state for the result.
559 tsf
= ath9k_hw_gettsf64(ah
);
560 tsftu
= TSF_TO_TU(tsf
>>32, tsf
) + FUDGE
;
562 num_beacons
= tsftu
/ intval
+ 1;
563 offset
= tsftu
% intval
;
564 nexttbtt
= tsftu
- offset
;
568 /* DTIM Beacon every dtimperiod Beacon */
569 dtim_dec_count
= num_beacons
% dtimperiod
;
570 /* CFP every cfpperiod DTIM Beacon */
571 cfp_dec_count
= (num_beacons
/ dtimperiod
) % cfpperiod
;
575 dtimcount
-= dtim_dec_count
;
577 dtimcount
+= dtimperiod
;
579 cfpcount
-= cfp_dec_count
;
581 cfpcount
+= cfpperiod
;
583 bs
.bs_intval
= intval
;
584 bs
.bs_nexttbtt
= nexttbtt
;
585 bs
.bs_dtimperiod
= dtimperiod
*intval
;
586 bs
.bs_nextdtim
= bs
.bs_nexttbtt
+ dtimcount
*intval
;
587 bs
.bs_cfpperiod
= cfpperiod
*bs
.bs_dtimperiod
;
588 bs
.bs_cfpnext
= bs
.bs_nextdtim
+ cfpcount
*bs
.bs_dtimperiod
;
589 bs
.bs_cfpmaxduration
= 0;
592 * Calculate the number of consecutive beacons to miss* before taking
593 * a BMISS interrupt. The configuration is specified in TU so we only
594 * need calculate based on the beacon interval. Note that we clamp the
595 * result to at most 15 beacons.
597 if (sleepduration
> intval
) {
598 bs
.bs_bmissthreshold
= conf
->listen_interval
*
599 ATH_DEFAULT_BMISS_LIMIT
/ 2;
601 bs
.bs_bmissthreshold
= DIV_ROUND_UP(conf
->bmiss_timeout
, intval
);
602 if (bs
.bs_bmissthreshold
> 15)
603 bs
.bs_bmissthreshold
= 15;
604 else if (bs
.bs_bmissthreshold
<= 0)
605 bs
.bs_bmissthreshold
= 1;
609 bs
.bs_sleepduration
= roundup(IEEE80211_MS_TO_TU(100), sleepduration
);
610 if (bs
.bs_sleepduration
> bs
.bs_dtimperiod
)
611 bs
.bs_sleepduration
= bs
.bs_dtimperiod
;
613 /* TSF out of range threshold fixed at 1 second */
614 bs
.bs_tsfoor_threshold
= ATH9K_TSFOOR_THRESHOLD
;
616 ath_print(common
, ATH_DBG_BEACON
, "tsf: %llu tsftu: %u\n", tsf
, tsftu
);
617 ath_print(common
, ATH_DBG_BEACON
,
618 "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
619 bs
.bs_bmissthreshold
, bs
.bs_sleepduration
,
620 bs
.bs_cfpperiod
, bs
.bs_cfpmaxduration
, bs
.bs_cfpnext
);
622 /* Set the computed STA beacon timers */
624 ath9k_hw_set_interrupts(ah
, 0);
625 ath9k_hw_set_sta_beacon_timers(ah
, &bs
);
626 ah
->imask
|= ATH9K_INT_BMISS
;
627 ath9k_hw_set_interrupts(ah
, ah
->imask
);
630 static void ath_beacon_config_adhoc(struct ath_softc
*sc
,
631 struct ath_beacon_config
*conf
,
632 struct ieee80211_vif
*vif
)
634 struct ath_hw
*ah
= sc
->sc_ah
;
635 struct ath_common
*common
= ath9k_hw_common(ah
);
637 u32 tsftu
, intval
, nexttbtt
;
639 intval
= conf
->beacon_interval
& ATH9K_BEACON_PERIOD
;
642 /* Pull nexttbtt forward to reflect the current TSF */
644 nexttbtt
= TSF_TO_TU(sc
->beacon
.bc_tstamp
>> 32, sc
->beacon
.bc_tstamp
);
648 nexttbtt
= roundup(nexttbtt
, intval
);
650 tsf
= ath9k_hw_gettsf64(ah
);
651 tsftu
= TSF_TO_TU((u32
)(tsf
>>32), (u32
)tsf
) + FUDGE
;
654 } while (nexttbtt
< tsftu
);
656 ath_print(common
, ATH_DBG_BEACON
,
657 "IBSS nexttbtt %u intval %u (%u)\n",
658 nexttbtt
, intval
, conf
->beacon_interval
);
661 * In IBSS mode enable the beacon timers but only enable SWBA interrupts
662 * if we need to manually prepare beacon frames. Otherwise we use a
663 * self-linked tx descriptor and let the hardware deal with things.
665 intval
|= ATH9K_BEACON_ENA
;
666 ah
->imask
|= ATH9K_INT_SWBA
;
668 ath_beaconq_config(sc
);
670 /* Set the computed ADHOC beacon timers */
672 ath9k_hw_set_interrupts(ah
, 0);
673 ath9k_beacon_init(sc
, nexttbtt
, intval
);
674 sc
->beacon
.bmisscnt
= 0;
675 ath9k_hw_set_interrupts(ah
, ah
->imask
);
678 void ath_beacon_config(struct ath_softc
*sc
, struct ieee80211_vif
*vif
)
680 struct ath_beacon_config
*cur_conf
= &sc
->cur_beacon_conf
;
681 struct ath_common
*common
= ath9k_hw_common(sc
->sc_ah
);
682 enum nl80211_iftype iftype
;
684 /* Setup the beacon configuration parameters */
686 struct ieee80211_bss_conf
*bss_conf
= &vif
->bss_conf
;
690 cur_conf
->beacon_interval
= bss_conf
->beacon_int
;
691 cur_conf
->dtim_period
= bss_conf
->dtim_period
;
692 cur_conf
->listen_interval
= 1;
693 cur_conf
->dtim_count
= 1;
694 cur_conf
->bmiss_timeout
=
695 ATH_DEFAULT_BMISS_LIMIT
* cur_conf
->beacon_interval
;
697 iftype
= sc
->sc_ah
->opmode
;
701 * It looks like mac80211 may end up using beacon interval of zero in
702 * some cases (at least for mesh point). Avoid getting into an
703 * infinite loop by using a bit safer value instead. To be safe,
704 * do sanity check on beacon interval for all operating modes.
706 if (cur_conf
->beacon_interval
== 0)
707 cur_conf
->beacon_interval
= 100;
710 case NL80211_IFTYPE_AP
:
711 ath_beacon_config_ap(sc
, cur_conf
);
713 case NL80211_IFTYPE_ADHOC
:
714 case NL80211_IFTYPE_MESH_POINT
:
715 ath_beacon_config_adhoc(sc
, cur_conf
, vif
);
717 case NL80211_IFTYPE_STATION
:
718 ath_beacon_config_sta(sc
, cur_conf
);
721 ath_print(common
, ATH_DBG_CONFIG
,
722 "Unsupported beaconing mode\n");
726 sc
->sc_flags
|= SC_OP_BEACONS
;