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