760f5b80f79e4bc0c31d6f24b70b3f7c4ced1d28
[safe/jmp/linux-2.6] / drivers / net / wireless / ath9k / beacon.c
1 /*
2  * Copyright (c) 2008 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 "ath9k.h"
18
19 #define FUDGE 2
20
21 /*
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
25 */
26 static int ath_beaconq_config(struct ath_softc *sc)
27 {
28         struct ath_hw *ah = sc->sc_ah;
29         struct ath9k_tx_queue_info qi;
30
31         ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi);
32         if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
33                 /* Always burst out beacon and CAB traffic. */
34                 qi.tqi_aifs = 1;
35                 qi.tqi_cwmin = 0;
36                 qi.tqi_cwmax = 0;
37         } else {
38                 /* Adhoc mode; important thing is to use 2x cwmin. */
39                 qi.tqi_aifs = sc->beacon.beacon_qi.tqi_aifs;
40                 qi.tqi_cwmin = 2*sc->beacon.beacon_qi.tqi_cwmin;
41                 qi.tqi_cwmax = sc->beacon.beacon_qi.tqi_cwmax;
42         }
43
44         if (!ath9k_hw_set_txq_props(ah, sc->beacon.beaconq, &qi)) {
45                 DPRINTF(sc, ATH_DBG_FATAL,
46                         "unable to update h/w beacon queue parameters\n");
47                 return 0;
48         } else {
49                 ath9k_hw_resettxqueue(ah, sc->beacon.beaconq);
50                 return 1;
51         }
52 }
53
54 /*
55  *  Associates the beacon frame buffer with a transmit descriptor.  Will set
56  *  up all required antenna switch parameters, rate codes, and channel flags.
57  *  Beacons are always sent out at the lowest rate, and are not retried.
58 */
59 static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
60                              struct ath_buf *bf)
61 {
62         struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
63         struct ath_hw *ah = sc->sc_ah;
64         struct ath_desc *ds;
65         struct ath9k_11n_rate_series series[4];
66         struct ath_rate_table *rt;
67         int flags, antenna, ctsrate = 0, ctsduration = 0;
68         u8 rate;
69
70         ds = bf->bf_desc;
71         flags = ATH9K_TXDESC_NOACK;
72
73         if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC &&
74             (ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
75                 ds->ds_link = bf->bf_daddr; /* self-linked */
76                 flags |= ATH9K_TXDESC_VEOL;
77                 /* Let hardware handle antenna switching. */
78                 antenna = 0;
79         } else {
80                 ds->ds_link = 0;
81                 /*
82                  * Switch antenna every beacon.
83                  * Should only switch every beacon period, not for every SWBA
84                  * XXX assumes two antennae
85                  */
86                 antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1);
87         }
88
89         ds->ds_data = bf->bf_buf_addr;
90
91         rt = sc->cur_rate_table;
92         rate = rt->info[0].ratecode;
93         if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
94                 rate |= rt->info[0].short_preamble;
95
96         ath9k_hw_set11n_txdesc(ah, ds, skb->len + FCS_LEN,
97                                ATH9K_PKT_TYPE_BEACON,
98                                MAX_RATE_POWER,
99                                ATH9K_TXKEYIX_INVALID,
100                                ATH9K_KEY_TYPE_CLEAR,
101                                flags);
102
103         /* NB: beacon's BufLen must be a multiple of 4 bytes */
104         ath9k_hw_filltxdesc(ah, ds, roundup(skb->len, 4),
105                             true, true, ds);
106
107         memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
108         series[0].Tries = 1;
109         series[0].Rate = rate;
110         series[0].ChSel = sc->tx_chainmask;
111         series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0;
112         ath9k_hw_set11n_ratescenario(ah, ds, ds, 0, ctsrate, ctsduration,
113                                      series, 4, 0);
114 }
115
116 static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
117                                            struct ieee80211_vif *vif)
118 {
119         struct ath_wiphy *aphy = hw->priv;
120         struct ath_softc *sc = aphy->sc;
121         struct ath_buf *bf;
122         struct ath_vif *avp;
123         struct sk_buff *skb;
124         struct ath_txq *cabq;
125         struct ieee80211_tx_info *info;
126         int cabq_depth;
127
128         avp = (void *)vif->drv_priv;
129         cabq = sc->beacon.cabq;
130
131         if (avp->av_bcbuf == NULL) {
132                 DPRINTF(sc, ATH_DBG_BEACON, "avp=%p av_bcbuf=%p\n",
133                         avp, avp->av_bcbuf);
134                 return NULL;
135         }
136
137         /* Release the old beacon first */
138
139         bf = avp->av_bcbuf;
140         skb = (struct sk_buff *)bf->bf_mpdu;
141         if (skb) {
142                 dma_unmap_single(sc->dev, bf->bf_dmacontext,
143                                  skb->len, DMA_TO_DEVICE);
144                 dev_kfree_skb_any(skb);
145         }
146
147         /* Get a new beacon from mac80211 */
148
149         skb = ieee80211_beacon_get(hw, vif);
150         bf->bf_mpdu = skb;
151         if (skb == NULL)
152                 return NULL;
153
154         info = IEEE80211_SKB_CB(skb);
155         if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
156                 /*
157                  * TODO: make sure the seq# gets assigned properly (vs. other
158                  * TX frames)
159                  */
160                 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
161                 sc->tx.seq_no += 0x10;
162                 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
163                 hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
164         }
165
166         bf->bf_buf_addr = bf->bf_dmacontext =
167                 dma_map_single(sc->dev, skb->data,
168                                skb->len, DMA_TO_DEVICE);
169         if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
170                 dev_kfree_skb_any(skb);
171                 bf->bf_mpdu = NULL;
172                 DPRINTF(sc, ATH_DBG_FATAL, "dma_mapping_error on beaconing\n");
173                 return NULL;
174         }
175
176         skb = ieee80211_get_buffered_bc(hw, vif);
177
178         /*
179          * if the CABQ traffic from previous DTIM is pending and the current
180          *  beacon is also a DTIM.
181          *  1) if there is only one vif let the cab traffic continue.
182          *  2) if there are more than one vif and we are using staggered
183          *     beacons, then drain the cabq by dropping all the frames in
184          *     the cabq so that the current vifs cab traffic can be scheduled.
185          */
186         spin_lock_bh(&cabq->axq_lock);
187         cabq_depth = cabq->axq_depth;
188         spin_unlock_bh(&cabq->axq_lock);
189
190         if (skb && cabq_depth) {
191                 if (sc->nvifs > 1) {
192                         DPRINTF(sc, ATH_DBG_BEACON,
193                                 "Flushing previous cabq traffic\n");
194                         ath_draintxq(sc, cabq, false);
195                 }
196         }
197
198         ath_beacon_setup(sc, avp, bf);
199
200         while (skb) {
201                 ath_tx_cabq(hw, skb);
202                 skb = ieee80211_get_buffered_bc(hw, vif);
203         }
204
205         return bf;
206 }
207
208 /*
209  * Startup beacon transmission for adhoc mode when they are sent entirely
210  * by the hardware using the self-linked descriptor + veol trick.
211 */
212 static void ath_beacon_start_adhoc(struct ath_softc *sc,
213                                    struct ieee80211_vif *vif)
214 {
215         struct ath_hw *ah = sc->sc_ah;
216         struct ath_buf *bf;
217         struct ath_vif *avp;
218         struct sk_buff *skb;
219
220         avp = (void *)vif->drv_priv;
221
222         if (avp->av_bcbuf == NULL)
223                 return;
224
225         bf = avp->av_bcbuf;
226         skb = (struct sk_buff *) bf->bf_mpdu;
227
228         ath_beacon_setup(sc, avp, bf);
229
230         /* NB: caller is known to have already stopped tx dma */
231         ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr);
232         ath9k_hw_txstart(ah, sc->beacon.beaconq);
233         DPRINTF(sc, ATH_DBG_BEACON, "TXDP%u = %llx (%p)\n",
234                 sc->beacon.beaconq, ito64(bf->bf_daddr), bf->bf_desc);
235 }
236
237 int ath_beaconq_setup(struct ath_hw *ah)
238 {
239         struct ath9k_tx_queue_info qi;
240
241         memset(&qi, 0, sizeof(qi));
242         qi.tqi_aifs = 1;
243         qi.tqi_cwmin = 0;
244         qi.tqi_cwmax = 0;
245         /* NB: don't enable any interrupts */
246         return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi);
247 }
248
249 int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
250 {
251         struct ath_softc *sc = aphy->sc;
252         struct ath_vif *avp;
253         struct ieee80211_hdr *hdr;
254         struct ath_buf *bf;
255         struct sk_buff *skb;
256         __le64 tstamp;
257
258         avp = (void *)vif->drv_priv;
259
260         /* Allocate a beacon descriptor if we haven't done so. */
261         if (!avp->av_bcbuf) {
262                 /* Allocate beacon state for hostap/ibss.  We know
263                  * a buffer is available. */
264                 avp->av_bcbuf = list_first_entry(&sc->beacon.bbuf,
265                                                  struct ath_buf, list);
266                 list_del(&avp->av_bcbuf->list);
267
268                 if (sc->sc_ah->opmode == NL80211_IFTYPE_AP ||
269                     !(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
270                         int slot;
271                         /*
272                          * Assign the vif to a beacon xmit slot. As
273                          * above, this cannot fail to find one.
274                          */
275                         avp->av_bslot = 0;
276                         for (slot = 0; slot < ATH_BCBUF; slot++)
277                                 if (sc->beacon.bslot[slot] == NULL) {
278                                         /*
279                                          * XXX hack, space out slots to better
280                                          * deal with misses
281                                          */
282                                         if (slot+1 < ATH_BCBUF &&
283                                             sc->beacon.bslot[slot+1] == NULL) {
284                                                 avp->av_bslot = slot+1;
285                                                 break;
286                                         }
287                                         avp->av_bslot = slot;
288                                         /* NB: keep looking for a double slot */
289                                 }
290                         BUG_ON(sc->beacon.bslot[avp->av_bslot] != NULL);
291                         sc->beacon.bslot[avp->av_bslot] = vif;
292                         sc->beacon.bslot_aphy[avp->av_bslot] = aphy;
293                         sc->nbcnvifs++;
294                 }
295         }
296
297         /* release the previous beacon frame, if it already exists. */
298         bf = avp->av_bcbuf;
299         if (bf->bf_mpdu != NULL) {
300                 skb = (struct sk_buff *)bf->bf_mpdu;
301                 dma_unmap_single(sc->dev, bf->bf_dmacontext,
302                                  skb->len, DMA_TO_DEVICE);
303                 dev_kfree_skb_any(skb);
304                 bf->bf_mpdu = NULL;
305         }
306
307         /* NB: the beacon data buffer must be 32-bit aligned. */
308         skb = ieee80211_beacon_get(sc->hw, vif);
309         if (skb == NULL) {
310                 DPRINTF(sc, ATH_DBG_BEACON, "cannot get skb\n");
311                 return -ENOMEM;
312         }
313
314         tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
315         sc->beacon.bc_tstamp = le64_to_cpu(tstamp);
316
317         /*
318          * Calculate a TSF adjustment factor required for
319          * staggered beacons.  Note that we assume the format
320          * of the beacon frame leaves the tstamp field immediately
321          * following the header.
322          */
323         if (avp->av_bslot > 0) {
324                 u64 tsfadjust;
325                 __le64 val;
326                 int intval;
327
328                 intval = sc->hw->conf.beacon_int ?
329                         sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
330
331                 /*
332                  * The beacon interval is in TU's; the TSF in usecs.
333                  * We figure out how many TU's to add to align the
334                  * timestamp then convert to TSF units and handle
335                  * byte swapping before writing it in the frame.
336                  * The hardware will then add this each time a beacon
337                  * frame is sent.  Note that we align vif's 1..N
338                  * and leave vif 0 untouched.  This means vap 0
339                  * has a timestamp in one beacon interval while the
340                  * others get a timestamp aligned to the next interval.
341                  */
342                 tsfadjust = (intval * (ATH_BCBUF - avp->av_bslot)) / ATH_BCBUF;
343                 val = cpu_to_le64(tsfadjust << 10);     /* TU->TSF */
344
345                 DPRINTF(sc, ATH_DBG_BEACON,
346                         "stagger beacons, bslot %d intval %u tsfadjust %llu\n",
347                         avp->av_bslot, intval, (unsigned long long)tsfadjust);
348
349                 hdr = (struct ieee80211_hdr *)skb->data;
350                 memcpy(&hdr[1], &val, sizeof(val));
351         }
352
353         bf->bf_mpdu = skb;
354         bf->bf_buf_addr = bf->bf_dmacontext =
355                 dma_map_single(sc->dev, skb->data,
356                                skb->len, DMA_TO_DEVICE);
357         if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
358                 dev_kfree_skb_any(skb);
359                 bf->bf_mpdu = NULL;
360                 DPRINTF(sc, ATH_DBG_FATAL,
361                         "dma_mapping_error on beacon alloc\n");
362                 return -ENOMEM;
363         }
364
365         return 0;
366 }
367
368 void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp)
369 {
370         if (avp->av_bcbuf != NULL) {
371                 struct ath_buf *bf;
372
373                 if (avp->av_bslot != -1) {
374                         sc->beacon.bslot[avp->av_bslot] = NULL;
375                         sc->beacon.bslot_aphy[avp->av_bslot] = NULL;
376                         sc->nbcnvifs--;
377                 }
378
379                 bf = avp->av_bcbuf;
380                 if (bf->bf_mpdu != NULL) {
381                         struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
382                         dma_unmap_single(sc->dev, bf->bf_dmacontext,
383                                          skb->len, DMA_TO_DEVICE);
384                         dev_kfree_skb_any(skb);
385                         bf->bf_mpdu = NULL;
386                 }
387                 list_add_tail(&bf->list, &sc->beacon.bbuf);
388
389                 avp->av_bcbuf = NULL;
390         }
391 }
392
393 void ath_beacon_tasklet(unsigned long data)
394 {
395         struct ath_softc *sc = (struct ath_softc *)data;
396         struct ath_hw *ah = sc->sc_ah;
397         struct ath_buf *bf = NULL;
398         struct ieee80211_vif *vif;
399         struct ath_wiphy *aphy;
400         int slot;
401         u32 bfaddr, bc = 0, tsftu;
402         u64 tsf;
403         u16 intval;
404
405         /*
406          * Check if the previous beacon has gone out.  If
407          * not don't try to post another, skip this period
408          * and wait for the next.  Missed beacons indicate
409          * a problem and should not occur.  If we miss too
410          * many consecutive beacons reset the device.
411          */
412         if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) {
413                 sc->beacon.bmisscnt++;
414
415                 if (sc->beacon.bmisscnt < BSTUCK_THRESH) {
416                         DPRINTF(sc, ATH_DBG_BEACON,
417                                 "missed %u consecutive beacons\n",
418                                 sc->beacon.bmisscnt);
419                 } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
420                         DPRINTF(sc, ATH_DBG_BEACON,
421                                 "beacon is officially stuck\n");
422                         ath_reset(sc, false);
423                 }
424
425                 return;
426         }
427
428         if (sc->beacon.bmisscnt != 0) {
429                 DPRINTF(sc, ATH_DBG_BEACON,
430                         "resume beacon xmit after %u misses\n",
431                         sc->beacon.bmisscnt);
432                 sc->beacon.bmisscnt = 0;
433         }
434
435         /*
436          * Generate beacon frames. we are sending frames
437          * staggered so calculate the slot for this frame based
438          * on the tsf to safeguard against missing an swba.
439          */
440
441         intval = sc->hw->conf.beacon_int ?
442                 sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
443
444         tsf = ath9k_hw_gettsf64(ah);
445         tsftu = TSF_TO_TU(tsf>>32, tsf);
446         slot = ((tsftu % intval) * ATH_BCBUF) / intval;
447         vif = sc->beacon.bslot[(slot + 1) % ATH_BCBUF];
448         aphy = sc->beacon.bslot_aphy[(slot + 1) % ATH_BCBUF];
449
450         DPRINTF(sc, ATH_DBG_BEACON,
451                 "slot %d [tsf %llu tsftu %u intval %u] vif %p\n",
452                 slot, tsf, tsftu, intval, vif);
453
454         bfaddr = 0;
455         if (vif) {
456                 bf = ath_beacon_generate(aphy->hw, vif);
457                 if (bf != NULL) {
458                         bfaddr = bf->bf_daddr;
459                         bc = 1;
460                 }
461         }
462
463         /*
464          * Handle slot time change when a non-ERP station joins/leaves
465          * an 11g network.  The 802.11 layer notifies us via callback,
466          * we mark updateslot, then wait one beacon before effecting
467          * the change.  This gives associated stations at least one
468          * beacon interval to note the state change.
469          *
470          * NB: The slot time change state machine is clocked according
471          *     to whether we are bursting or staggering beacons.  We
472          *     recognize the request to update and record the current
473          *     slot then don't transition until that slot is reached
474          *     again.  If we miss a beacon for that slot then we'll be
475          *     slow to transition but we'll be sure at least one beacon
476          *     interval has passed.  When bursting slot is always left
477          *     set to ATH_BCBUF so this check is a noop.
478          */
479         if (sc->beacon.updateslot == UPDATE) {
480                 sc->beacon.updateslot = COMMIT; /* commit next beacon */
481                 sc->beacon.slotupdate = slot;
482         } else if (sc->beacon.updateslot == COMMIT && sc->beacon.slotupdate == slot) {
483                 ath9k_hw_setslottime(sc->sc_ah, sc->beacon.slottime);
484                 sc->beacon.updateslot = OK;
485         }
486         if (bfaddr != 0) {
487                 /*
488                  * Stop any current dma and put the new frame(s) on the queue.
489                  * This should never fail since we check above that no frames
490                  * are still pending on the queue.
491                  */
492                 if (!ath9k_hw_stoptxdma(ah, sc->beacon.beaconq)) {
493                         DPRINTF(sc, ATH_DBG_FATAL,
494                                 "beacon queue %u did not stop?\n", sc->beacon.beaconq);
495                 }
496
497                 /* NB: cabq traffic should already be queued and primed */
498                 ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bfaddr);
499                 ath9k_hw_txstart(ah, sc->beacon.beaconq);
500
501                 sc->beacon.ast_be_xmit += bc;     /* XXX per-vif? */
502         }
503 }
504
505 /*
506  * For multi-bss ap support beacons are either staggered evenly over N slots or
507  * burst together.  For the former arrange for the SWBA to be delivered for each
508  * slot. Slots that are not occupied will generate nothing.
509  */
510 static void ath_beacon_config_ap(struct ath_softc *sc,
511                                  struct ath_beacon_config *conf,
512                                  struct ath_vif *avp)
513 {
514         u32 nexttbtt, intval;
515
516         /* Configure the timers only when the TSF has to be reset */
517
518         if (!(sc->sc_flags & SC_OP_TSF_RESET))
519                 return;
520
521         /* NB: the beacon interval is kept internally in TU's */
522         intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
523         intval /= ATH_BCBUF;    /* for staggered beacons */
524         nexttbtt = intval;
525         intval |= ATH9K_BEACON_RESET_TSF;
526
527         /*
528          * In AP mode we enable the beacon timers and SWBA interrupts to
529          * prepare beacon frames.
530          */
531         intval |= ATH9K_BEACON_ENA;
532         sc->imask |= ATH9K_INT_SWBA;
533         ath_beaconq_config(sc);
534
535         /* Set the computed AP beacon timers */
536
537         ath9k_hw_set_interrupts(sc->sc_ah, 0);
538         ath9k_hw_beaconinit(sc->sc_ah, nexttbtt, intval);
539         sc->beacon.bmisscnt = 0;
540         ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
541
542         /* Clear the reset TSF flag, so that subsequent beacon updation
543            will not reset the HW TSF. */
544
545         sc->sc_flags &= ~SC_OP_TSF_RESET;
546 }
547
548 /*
549  * This sets up the beacon timers according to the timestamp of the last
550  * received beacon and the current TSF, configures PCF and DTIM
551  * handling, programs the sleep registers so the hardware will wakeup in
552  * time to receive beacons, and configures the beacon miss handling so
553  * we'll receive a BMISS interrupt when we stop seeing beacons from the AP
554  * we've associated with.
555  */
556 static void ath_beacon_config_sta(struct ath_softc *sc,
557                                   struct ath_beacon_config *conf,
558                                   struct ath_vif *avp)
559 {
560         struct ath9k_beacon_state bs;
561         int dtimperiod, dtimcount, sleepduration;
562         int cfpperiod, cfpcount;
563         u32 nexttbtt = 0, intval, tsftu;
564         u64 tsf;
565
566         memset(&bs, 0, sizeof(bs));
567         intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
568
569         /*
570          * Setup dtim and cfp parameters according to
571          * last beacon we received (which may be none).
572          */
573         dtimperiod = conf->dtim_period;
574         if (dtimperiod <= 0)            /* NB: 0 if not known */
575                 dtimperiod = 1;
576         dtimcount = conf->dtim_count;
577         if (dtimcount >= dtimperiod)    /* NB: sanity check */
578                 dtimcount = 0;
579         cfpperiod = 1;                  /* NB: no PCF support yet */
580         cfpcount = 0;
581
582         sleepduration = conf->listen_interval * intval;
583         if (sleepduration <= 0)
584                 sleepduration = intval;
585
586         /*
587          * Pull nexttbtt forward to reflect the current
588          * TSF and calculate dtim+cfp state for the result.
589          */
590         tsf = ath9k_hw_gettsf64(sc->sc_ah);
591         tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
592         do {
593                 nexttbtt += intval;
594                 if (--dtimcount < 0) {
595                         dtimcount = dtimperiod - 1;
596                         if (--cfpcount < 0)
597                                 cfpcount = cfpperiod - 1;
598                 }
599         } while (nexttbtt < tsftu);
600
601         bs.bs_intval = intval;
602         bs.bs_nexttbtt = nexttbtt;
603         bs.bs_dtimperiod = dtimperiod*intval;
604         bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount*intval;
605         bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod;
606         bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod;
607         bs.bs_cfpmaxduration = 0;
608
609         /*
610          * Calculate the number of consecutive beacons to miss* before taking
611          * a BMISS interrupt. The configuration is specified in TU so we only
612          * need calculate based on the beacon interval.  Note that we clamp the
613          * result to at most 15 beacons.
614          */
615         if (sleepduration > intval) {
616                 bs.bs_bmissthreshold = conf->listen_interval *
617                         ATH_DEFAULT_BMISS_LIMIT / 2;
618         } else {
619                 bs.bs_bmissthreshold = DIV_ROUND_UP(conf->bmiss_timeout, intval);
620                 if (bs.bs_bmissthreshold > 15)
621                         bs.bs_bmissthreshold = 15;
622                 else if (bs.bs_bmissthreshold <= 0)
623                         bs.bs_bmissthreshold = 1;
624         }
625
626         /*
627          * Calculate sleep duration. The configuration is given in ms.
628          * We ensure a multiple of the beacon period is used. Also, if the sleep
629          * duration is greater than the DTIM period then it makes senses
630          * to make it a multiple of that.
631          *
632          * XXX fixed at 100ms
633          */
634
635         bs.bs_sleepduration = roundup(IEEE80211_MS_TO_TU(100), sleepduration);
636         if (bs.bs_sleepduration > bs.bs_dtimperiod)
637                 bs.bs_sleepduration = bs.bs_dtimperiod;
638
639         /* TSF out of range threshold fixed at 1 second */
640         bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD;
641
642         DPRINTF(sc, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu);
643         DPRINTF(sc, ATH_DBG_BEACON,
644                 "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
645                 bs.bs_bmissthreshold, bs.bs_sleepduration,
646                 bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
647
648         /* Set the computed STA beacon timers */
649
650         ath9k_hw_set_interrupts(sc->sc_ah, 0);
651         ath9k_hw_set_sta_beacon_timers(sc->sc_ah, &bs);
652         sc->imask |= ATH9K_INT_BMISS;
653         ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
654 }
655
656 static void ath_beacon_config_adhoc(struct ath_softc *sc,
657                                     struct ath_beacon_config *conf,
658                                     struct ath_vif *avp,
659                                     struct ieee80211_vif *vif)
660 {
661         u64 tsf;
662         u32 tsftu, intval, nexttbtt;
663
664         intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
665
666         /* Pull nexttbtt forward to reflect the current TSF */
667
668         nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp);
669         if (nexttbtt == 0)
670                 nexttbtt = intval;
671         else if (intval)
672                 nexttbtt = roundup(nexttbtt, intval);
673
674         tsf = ath9k_hw_gettsf64(sc->sc_ah);
675         tsftu = TSF_TO_TU((u32)(tsf>>32), (u32)tsf) + FUDGE;
676         do {
677                 nexttbtt += intval;
678         } while (nexttbtt < tsftu);
679
680         DPRINTF(sc, ATH_DBG_BEACON,
681                 "IBSS nexttbtt %u intval %u (%u)\n",
682                 nexttbtt, intval, conf->beacon_interval);
683
684         /*
685          * In IBSS mode enable the beacon timers but only enable SWBA interrupts
686          * if we need to manually prepare beacon frames.  Otherwise we use a
687          * self-linked tx descriptor and let the hardware deal with things.
688          */
689         intval |= ATH9K_BEACON_ENA;
690         if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL))
691                 sc->imask |= ATH9K_INT_SWBA;
692
693         ath_beaconq_config(sc);
694
695         /* Set the computed ADHOC beacon timers */
696
697         ath9k_hw_set_interrupts(sc->sc_ah, 0);
698         ath9k_hw_beaconinit(sc->sc_ah, nexttbtt, intval);
699         sc->beacon.bmisscnt = 0;
700         ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
701
702         if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)
703                 ath_beacon_start_adhoc(sc, vif);
704 }
705
706 void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
707 {
708         struct ath_beacon_config conf;
709
710         /* Setup the beacon configuration parameters */
711
712         memset(&conf, 0, sizeof(struct ath_beacon_config));
713         conf.beacon_interval = sc->hw->conf.beacon_int ?
714                 sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
715         conf.listen_interval = 1;
716         conf.dtim_period = conf.beacon_interval;
717         conf.dtim_count = 1;
718         conf.bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf.beacon_interval;
719
720         if (vif) {
721                 struct ath_vif *avp = (struct ath_vif *)vif->drv_priv;
722
723                 switch(avp->av_opmode) {
724                 case NL80211_IFTYPE_AP:
725                         ath_beacon_config_ap(sc, &conf, avp);
726                         break;
727                 case NL80211_IFTYPE_ADHOC:
728                         ath_beacon_config_adhoc(sc, &conf, avp, vif);
729                         break;
730                 case NL80211_IFTYPE_STATION:
731                         ath_beacon_config_sta(sc, &conf, avp);
732                         break;
733                 default:
734                         DPRINTF(sc, ATH_DBG_CONFIG,
735                                 "Unsupported beaconing mode\n");
736                         return;
737                 }
738
739                 sc->sc_flags |= SC_OP_BEACONS;
740         }
741 }