ath9k: Configure Power control register appropriately for h/w with 4k eeprom
[safe/jmp/linux-2.6] / drivers / net / wireless / ath9k / beacon.c
index ee11856..18bda36 100644 (file)
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
- /* Implementation of beacon processing. */
-
-#include <asm/unaligned.h>
-#include "core.h"
+#include "ath9k.h"
 
 /*
- *  Configure parameters for the beacon queue
- *
  *  This function will modify certain transmit queue properties depending on
  *  the operating mode of the station (AP or AdHoc).  Parameters are AIFS
  *  settings and channel width min/max
 */
-
 static int ath_beaconq_config(struct ath_softc *sc)
 {
-       struct ath_hal *ah = sc->sc_ah;
+       struct ath_hw *ah = sc->sc_ah;
        struct ath9k_tx_queue_info qi;
 
-       ath9k_hw_get_txq_props(ah, sc->sc_bhalq, &qi);
-       if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) {
+       ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi);
+       if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
                /* Always burst out beacon and CAB traffic. */
                qi.tqi_aifs = 1;
                qi.tqi_cwmin = 0;
                qi.tqi_cwmax = 0;
        } else {
                /* Adhoc mode; important thing is to use 2x cwmin. */
-               qi.tqi_aifs = sc->sc_beacon_qi.tqi_aifs;
-               qi.tqi_cwmin = 2*sc->sc_beacon_qi.tqi_cwmin;
-               qi.tqi_cwmax = sc->sc_beacon_qi.tqi_cwmax;
+               qi.tqi_aifs = sc->beacon.beacon_qi.tqi_aifs;
+               qi.tqi_cwmin = 2*sc->beacon.beacon_qi.tqi_cwmin;
+               qi.tqi_cwmax = sc->beacon.beacon_qi.tqi_cwmax;
        }
 
-       if (!ath9k_hw_set_txq_props(ah, sc->sc_bhalq, &qi)) {
+       if (!ath9k_hw_set_txq_props(ah, sc->beacon.beaconq, &qi)) {
                DPRINTF(sc, ATH_DBG_FATAL,
-                       "%s: unable to update h/w beacon queue parameters\n",
-                       __func__);
+                       "unable to update h/w beacon queue parameters\n");
                return 0;
        } else {
-               ath9k_hw_resettxqueue(ah, sc->sc_bhalq); /* push to h/w */
+               ath9k_hw_resettxqueue(ah, sc->beacon.beaconq); /* push to h/w */
                return 1;
        }
 }
 
+static void ath_bstuck_process(struct ath_softc *sc)
+{
+       DPRINTF(sc, ATH_DBG_BEACON,
+               "stuck beacon; resetting (bmiss count %u)\n",
+               sc->beacon.bmisscnt);
+       ath_reset(sc, false);
+}
+
 /*
- *  Setup the beacon frame for transmit.
- *
  *  Associates the beacon frame buffer with a transmit descriptor.  Will set
  *  up all required antenna switch parameters, rate codes, and channel flags.
  *  Beacons are always sent out at the lowest rate, and are not retried.
 */
-
 static void ath_beacon_setup(struct ath_softc *sc,
-       struct ath_vap *avp, struct ath_buf *bf)
+                            struct ath_vif *avp, struct ath_buf *bf)
 {
        struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
-       struct ath_hal *ah = sc->sc_ah;
+       struct ath_hw *ah = sc->sc_ah;
        struct ath_desc *ds;
+       struct ath9k_11n_rate_series series[4];
+       struct ath_rate_table *rt;
        int flags, antenna;
-       const struct ath9k_rate_table *rt;
        u8 rix, rate;
        int ctsrate = 0;
        int ctsduration = 0;
-       struct ath9k_11n_rate_series  series[4];
 
-       DPRINTF(sc, ATH_DBG_BEACON, "%s: m %p len %u\n",
-               __func__, skb, skb->len);
+       DPRINTF(sc, ATH_DBG_BEACON, "m %p len %u\n", skb, skb->len);
 
        /* setup descriptors */
        ds = bf->bf_desc;
 
        flags = ATH9K_TXDESC_NOACK;
 
-       if (sc->sc_ah->ah_opmode == ATH9K_M_IBSS &&
-           (ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
+       if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC &&
+           (ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
                ds->ds_link = bf->bf_daddr; /* self-linked */
                flags |= ATH9K_TXDESC_VEOL;
                /* Let hardware handle antenna switching. */
@@ -99,7 +96,7 @@ static void ath_beacon_setup(struct ath_softc *sc,
                 * SWBA's
                 * XXX assumes two antenna
                 */
-               antenna = ((sc->ast_be_xmit / sc->sc_nbcnvaps) & 1 ? 2 : 1);
+               antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1);
        }
 
        ds->ds_data = bf->bf_buf_addr;
@@ -109,178 +106,123 @@ static void ath_beacon_setup(struct ath_softc *sc,
         * XXX everything at min xmit rate
         */
        rix = 0;
-       rt = sc->sc_currates;
-       rate = rt->info[rix].rateCode;
+       rt = sc->cur_rate_table;
+       rate = rt->info[rix].ratecode;
        if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
-               rate |= rt->info[rix].shortPreamble;
+               rate |= rt->info[rix].short_preamble;
 
        ath9k_hw_set11n_txdesc(ah, ds,
-                              skb->len + FCS_LEN, /* frame length */
-                              ATH9K_PKT_TYPE_BEACON, /* Atheros packet type */
-                              avp->av_btxctl.txpower, /* txpower XXX */
-                              ATH9K_TXKEYIX_INVALID, /* no encryption */
-                              ATH9K_KEY_TYPE_CLEAR, /* no encryption */
-                              flags /* no ack, veol for beacons */
+                              skb->len + FCS_LEN,     /* frame length */
+                              ATH9K_PKT_TYPE_BEACON,  /* Atheros packet type */
+                              MAX_RATE_POWER,         /* FIXME */
+                              ATH9K_TXKEYIX_INVALID,  /* no encryption */
+                              ATH9K_KEY_TYPE_CLEAR,   /* no encryption */
+                              flags                   /* no ack,
+                                                         veol for beacons */
                );
 
        /* NB: beacon's BufLen must be a multiple of 4 bytes */
        ath9k_hw_filltxdesc(ah, ds,
                            roundup(skb->len, 4), /* buffer length */
-                           true, /* first segment */
-                           true, /* last segment */
-                           ds /* first descriptor */
+                           true,                 /* first segment */
+                           true,                 /* last segment */
+                           ds                    /* first descriptor */
                );
 
-       memzero(series, sizeof(struct ath9k_11n_rate_series) * 4);
+       memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
        series[0].Tries = 1;
        series[0].Rate = rate;
-       series[0].ChSel = sc->sc_tx_chainmask;
+       series[0].ChSel = sc->tx_chainmask;
        series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0;
        ath9k_hw_set11n_ratescenario(ah, ds, ds, 0,
                ctsrate, ctsduration, series, 4, 0);
 }
 
-/* Move everything from the vap's mcast queue to the hardware cab queue.
- * Caller must hold mcasq lock and cabq lock
- * XXX MORE_DATA bit?
- */
-static void empty_mcastq_into_cabq(struct ath_hal *ah,
-       struct ath_txq *mcastq, struct ath_txq *cabq)
-{
-       struct ath_buf *bfmcast;
-
-       BUG_ON(list_empty(&mcastq->axq_q));
-
-       bfmcast = list_first_entry(&mcastq->axq_q, struct ath_buf, list);
-
-       /* link the descriptors */
-       if (!cabq->axq_link)
-               ath9k_hw_puttxbuf(ah, cabq->axq_qnum, bfmcast->bf_daddr);
-       else
-               *cabq->axq_link = bfmcast->bf_daddr;
-
-       /* append the private vap mcast list to  the cabq */
-
-       cabq->axq_depth += mcastq->axq_depth;
-       cabq->axq_totalqueued += mcastq->axq_totalqueued;
-       cabq->axq_linkbuf = mcastq->axq_linkbuf;
-       cabq->axq_link = mcastq->axq_link;
-       list_splice_tail_init(&mcastq->axq_q, &cabq->axq_q);
-       mcastq->axq_depth = 0;
-       mcastq->axq_totalqueued = 0;
-       mcastq->axq_linkbuf = NULL;
-       mcastq->axq_link = NULL;
-}
-
-/* TODO: use ieee80211_get_buffered_bc() to fetch power saved mcast frames */
-/* This is only run at DTIM. We move everything from the vap's mcast queue
- * to the hardware cab queue. Caller must hold the mcastq lock. */
-static void trigger_mcastq(struct ath_hal *ah,
-       struct ath_txq *mcastq, struct ath_txq *cabq)
-{
-       spin_lock_bh(&cabq->axq_lock);
-
-       if (!list_empty(&mcastq->axq_q))
-               empty_mcastq_into_cabq(ah, mcastq, cabq);
-
-       /* cabq is gated by beacon so it is safe to start here */
-       if (!list_empty(&cabq->axq_q))
-               ath9k_hw_txstart(ah, cabq->axq_qnum);
-
-       spin_unlock_bh(&cabq->axq_lock);
-}
-
-/*
- *  Generate beacon frame and queue cab data for a vap.
- *
- *  Updates the contents of the beacon frame.  It is assumed that the buffer for
- *  the beacon frame has been allocated in the ATH object, and simply needs to
- *  be filled for this cycle.  Also, any CAB (crap after beacon?) traffic will
- *  be added to the beacon frame at this point.
-*/
+/* Generate beacon frame and queue cab data for a VIF */
 static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
 {
-       struct ath_hal *ah = sc->sc_ah;
        struct ath_buf *bf;
-       struct ath_vap *avp;
+       struct ath_vif *avp;
        struct sk_buff *skb;
-       int cabq_depth;
-       int mcastq_depth;
-       int is_beacon_dtim = 0;
        struct ath_txq *cabq;
-       struct ath_txq *mcastq;
+       struct ieee80211_vif *vif;
        struct ieee80211_tx_info *info;
-       avp = sc->sc_vaps[if_id];
+       int cabq_depth;
 
-       mcastq = &avp->av_mcastq;
-       cabq = sc->sc_cabq;
+       vif = sc->vifs[if_id];
+       ASSERT(vif);
 
-       ASSERT(avp);
+       avp = (void *)vif->drv_priv;
+       cabq = sc->beacon.cabq;
 
        if (avp->av_bcbuf == NULL) {
-               DPRINTF(sc, ATH_DBG_BEACON, "%s: avp=%p av_bcbuf=%p\n",
-                       __func__, avp, avp->av_bcbuf);
+               DPRINTF(sc, ATH_DBG_BEACON, "avp=%p av_bcbuf=%p\n",
+                       avp, avp->av_bcbuf);
                return NULL;
        }
+
        bf = avp->av_bcbuf;
-       skb = (struct sk_buff *) bf->bf_mpdu;
+       skb = (struct sk_buff *)bf->bf_mpdu;
        if (skb) {
-               pci_unmap_single(sc->pdev, bf->bf_dmacontext,
-                                skb_end_pointer(skb) - skb->head,
-                                PCI_DMA_TODEVICE);
+               dma_unmap_single(sc->dev, bf->bf_dmacontext,
+                                skb->len,
+                                DMA_TO_DEVICE);
+               dev_kfree_skb_any(skb);
        }
 
-       skb = ieee80211_beacon_get(sc->hw, avp->av_if_data);
+       skb = ieee80211_beacon_get(sc->hw, vif);
        bf->bf_mpdu = skb;
        if (skb == NULL)
                return NULL;
+
        info = IEEE80211_SKB_CB(skb);
        if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
                /*
                 * TODO: make sure the seq# gets assigned properly (vs. other
                 * TX frames)
                 */
-               struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-               sc->seq_no += 0x10;
+               struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+               sc->tx.seq_no += 0x10;
                hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
-               hdr->seq_ctrl |= cpu_to_le16(sc->seq_no);
+               hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
        }
+
        bf->bf_buf_addr = bf->bf_dmacontext =
-               pci_map_single(sc->pdev, skb->data,
-                              skb_end_pointer(skb) - skb->head,
-                              PCI_DMA_TODEVICE);
+               dma_map_single(sc->dev, skb->data,
+                              skb->len,
+                              DMA_TO_DEVICE);
+       if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
+               dev_kfree_skb_any(skb);
+               bf->bf_mpdu = NULL;
+               DPRINTF(sc, ATH_DBG_CONFIG,
+                       "dma_mapping_error() on beaconing\n");
+               return NULL;
+       }
 
-       /* TODO: convert to use ieee80211_get_buffered_bc() */
-       /* XXX: spin_lock_bh should not be used here, but sparse bitches
-        * otherwise. We should fix sparse :) */
-       spin_lock_bh(&mcastq->axq_lock);
-       mcastq_depth = avp->av_mcastq.axq_depth;
+       skb = ieee80211_get_buffered_bc(sc->hw, vif);
 
        /*
         * if the CABQ traffic from previous DTIM is pending and the current
         *  beacon is also a DTIM.
-        *  1) if there is only one vap let the cab traffic continue.
-        *  2) if there are more than one vap and we are using staggered
+        *  1) if there is only one vif let the cab traffic continue.
+        *  2) if there are more than one vif and we are using staggered
         *     beacons, then drain the cabq by dropping all the frames in
-        *     the cabq so that the current vaps cab traffic can be scheduled.
+        *     the cabq so that the current vifs cab traffic can be scheduled.
         */
        spin_lock_bh(&cabq->axq_lock);
        cabq_depth = cabq->axq_depth;
        spin_unlock_bh(&cabq->axq_lock);
 
-       if (avp->av_boff.bo_tim)
-               is_beacon_dtim = avp->av_boff.bo_tim[4] & 1;
-
-       if (mcastq_depth && is_beacon_dtim && cabq_depth) {
+       if (skb && cabq_depth) {
                /*
                 * Unlock the cabq lock as ath_tx_draintxq acquires
                 * the lock again which is a common function and that
                 * acquires txq lock inside.
                 */
-               if (sc->sc_nvaps > 1) {
-                       ath_tx_draintxq(sc, cabq, false);
+               if (sc->nvifs > 1) {
+                       ath_draintxq(sc, cabq, false);
                        DPRINTF(sc, ATH_DBG_BEACON,
-                               "%s: flush previous cabq traffic\n", __func__);
+                               "flush previous cabq traffic\n");
                }
        }
 
@@ -291,10 +233,11 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
         * Enable the CAB queue before the beacon queue to
         * insure cab frames are triggered by this beacon.
         */
-       if (is_beacon_dtim)
-               trigger_mcastq(ah, mcastq, cabq);
+       while (skb) {
+               ath_tx_cabq(sc, skb);
+               skb = ieee80211_get_buffered_bc(sc->hw, vif);
+       }
 
-       spin_unlock_bh(&mcastq->axq_lock);
        return bf;
 }
 
@@ -302,20 +245,22 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
  * Startup beacon transmission for adhoc mode when they are sent entirely
  * by the hardware using the self-linked descriptor + veol trick.
 */
-
 static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id)
 {
-       struct ath_hal *ah = sc->sc_ah;
+       struct ieee80211_vif *vif;
+       struct ath_hw *ah = sc->sc_ah;
        struct ath_buf *bf;
-       struct ath_vap *avp;
+       struct ath_vif *avp;
        struct sk_buff *skb;
 
-       avp = sc->sc_vaps[if_id];
-       ASSERT(avp);
+       vif = sc->vifs[if_id];
+       ASSERT(vif);
+
+       avp = (void *)vif->drv_priv;
 
        if (avp->av_bcbuf == NULL) {
-               DPRINTF(sc, ATH_DBG_BEACON, "%s: avp=%p av_bcbuf=%p\n",
-                       __func__, avp, avp != NULL ? avp->av_bcbuf : NULL);
+               DPRINTF(sc, ATH_DBG_BEACON, "avp=%p av_bcbuf=%p\n",
+                       avp, avp != NULL ? avp->av_bcbuf : NULL);
                return;
        }
        bf = avp->av_bcbuf;
@@ -325,26 +270,17 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id)
        ath_beacon_setup(sc, avp, bf);
 
        /* NB: caller is known to have already stopped tx dma */
-       ath9k_hw_puttxbuf(ah, sc->sc_bhalq, bf->bf_daddr);
-       ath9k_hw_txstart(ah, sc->sc_bhalq);
-       DPRINTF(sc, ATH_DBG_BEACON, "%s: TXDP%u = %llx (%p)\n", __func__,
-               sc->sc_bhalq, ito64(bf->bf_daddr), bf->bf_desc);
+       ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr);
+       ath9k_hw_txstart(ah, sc->beacon.beaconq);
+       DPRINTF(sc, ATH_DBG_BEACON, "TXDP%u = %llx (%p)\n",
+               sc->beacon.beaconq, ito64(bf->bf_daddr), bf->bf_desc);
 }
 
-/*
- *  Setup a h/w transmit queue for beacons.
- *
- *  This function allocates an information structure (struct ath9k_txq_info)
- *  on the stack, sets some specific parameters (zero out channel width
- *  min/max, and enable aifs). The info structure does not need to be
- *  persistant.
-*/
-
-int ath_beaconq_setup(struct ath_hal *ah)
+int ath_beaconq_setup(struct ath_hw *ah)
 {
        struct ath9k_tx_queue_info qi;
 
-       memzero(&qi, sizeof(qi));
+       memset(&qi, 0, sizeof(qi));
        qi.tqi_aifs = 1;
        qi.tqi_cwmin = 0;
        qi.tqi_cwmax = 0;
@@ -352,52 +288,44 @@ int ath_beaconq_setup(struct ath_hal *ah)
        return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi);
 }
 
-
-/*
- *  Allocate and setup an initial beacon frame.
- *
- *  Allocate a beacon state variable for a specific VAP instance created on
- *  the ATH interface.  This routine also calculates the beacon "slot" for
- *  staggared beacons in the mBSSID case.
-*/
-
 int ath_beacon_alloc(struct ath_softc *sc, int if_id)
 {
-       struct ath_vap *avp;
-       struct ieee80211_hdr *wh;
+       struct ieee80211_vif *vif;
+       struct ath_vif *avp;
+       struct ieee80211_hdr *hdr;
        struct ath_buf *bf;
        struct sk_buff *skb;
+       __le64 tstamp;
 
-       avp = sc->sc_vaps[if_id];
-       ASSERT(avp);
+       vif = sc->vifs[if_id];
+       ASSERT(vif);
+
+       avp = (void *)vif->drv_priv;
 
        /* Allocate a beacon descriptor if we haven't done so. */
        if (!avp->av_bcbuf) {
-               /*
-                * Allocate beacon state for hostap/ibss.  We know
-                * a buffer is available.
-                */
-
-               avp->av_bcbuf = list_first_entry(&sc->sc_bbuf,
-                               struct ath_buf, list);
+               /* Allocate beacon state for hostap/ibss.  We know
+                * a buffer is available. */
+               avp->av_bcbuf = list_first_entry(&sc->beacon.bbuf,
+                                                struct ath_buf, list);
                list_del(&avp->av_bcbuf->list);
 
-               if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP ||
-                   !(sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
+               if (sc->sc_ah->opmode == NL80211_IFTYPE_AP ||
+                   !(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
                        int slot;
                        /*
-                        * Assign the vap to a beacon xmit slot. As
+                        * Assign the vif to a beacon xmit slot. As
                         * above, this cannot fail to find one.
                         */
                        avp->av_bslot = 0;
                        for (slot = 0; slot < ATH_BCBUF; slot++)
-                               if (sc->sc_bslot[slot] == ATH_IF_ID_ANY) {
+                               if (sc->beacon.bslot[slot] == ATH_IF_ID_ANY) {
                                        /*
                                         * XXX hack, space out slots to better
                                         * deal with misses
                                         */
                                        if (slot+1 < ATH_BCBUF &&
-                                           sc->sc_bslot[slot+1] ==
+                                           sc->beacon.bslot[slot+1] ==
                                                ATH_IF_ID_ANY) {
                                                avp->av_bslot = slot+1;
                                                break;
@@ -405,9 +333,9 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
                                        avp->av_bslot = slot;
                                        /* NB: keep looking for a double slot */
                                }
-                       BUG_ON(sc->sc_bslot[avp->av_bslot] != ATH_IF_ID_ANY);
-                       sc->sc_bslot[avp->av_bslot] = if_id;
-                       sc->sc_nbcnvaps++;
+                       BUG_ON(sc->beacon.bslot[avp->av_bslot] != ATH_IF_ID_ANY);
+                       sc->beacon.bslot[avp->av_bslot] = if_id;
+                       sc->nbcnvifs++;
                }
        }
 
@@ -415,27 +343,27 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
        bf = avp->av_bcbuf;
        if (bf->bf_mpdu != NULL) {
                skb = (struct sk_buff *)bf->bf_mpdu;
-               pci_unmap_single(sc->pdev, bf->bf_dmacontext,
-                                skb_end_pointer(skb) - skb->head,
-                                PCI_DMA_TODEVICE);
+               dma_unmap_single(sc->dev, bf->bf_dmacontext,
+                                skb->len,
+                                DMA_TO_DEVICE);
                dev_kfree_skb_any(skb);
                bf->bf_mpdu = NULL;
        }
 
        /*
-        * NB: the beacon data buffer must be 32-bit aligned;
-        * we assume the wbuf routines will return us something
-        * with this alignment (perhaps should assert).
-        * FIXME: Fill avp->av_boff.bo_tim,avp->av_btxctl.txpower and
+        * NB: the beacon data buffer must be 32-bit aligned.
+        * FIXME: Fill avp->av_btxctl.txpower and
         * avp->av_btxctl.shortPreamble
         */
-       skb = ieee80211_beacon_get(sc->hw, avp->av_if_data);
+       skb = ieee80211_beacon_get(sc->hw, vif);
        if (skb == NULL) {
-               DPRINTF(sc, ATH_DBG_BEACON, "%s: cannot get skb\n",
-                       __func__);
+               DPRINTF(sc, ATH_DBG_BEACON, "cannot get skb\n");
                return -ENOMEM;
        }
 
+       tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
+       sc->beacon.bc_tstamp = le64_to_cpu(tstamp);
+
        /*
         * Calculate a TSF adjustment factor required for
         * staggered beacons.  Note that we assume the format
@@ -456,8 +384,8 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
                 * timestamp then convert to TSF units and handle
                 * byte swapping before writing it in the frame.
                 * The hardware will then add this each time a beacon
-                * frame is sent.  Note that we align vap's 1..N
-                * and leave vap 0 untouched.  This means vap 0
+                * frame is sent.  Note that we align vif's 1..N
+                * and leave vif 0 untouched.  This means vap 0
                 * has a timestamp in one beacon interval while the
                 * others get a timestamp aligned to the next interval.
                 */
@@ -465,94 +393,58 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
                val = cpu_to_le64(tsfadjust << 10);     /* TU->TSF */
 
                DPRINTF(sc, ATH_DBG_BEACON,
-                       "%s: %s beacons, bslot %d intval %u tsfadjust %llu\n",
-                       __func__, "stagger",
+                       "stagger beacons, bslot %d intval %u tsfadjust %llu\n",
                        avp->av_bslot, intval, (unsigned long long)tsfadjust);
 
-               wh = (struct ieee80211_hdr *)skb->data;
-               memcpy(&wh[1], &val, sizeof(val));
+               hdr = (struct ieee80211_hdr *)skb->data;
+               memcpy(&hdr[1], &val, sizeof(val));
        }
 
-       bf->bf_buf_addr = bf->bf_dmacontext =
-               pci_map_single(sc->pdev, skb->data,
-                              skb_end_pointer(skb) - skb->head,
-                              PCI_DMA_TODEVICE);
        bf->bf_mpdu = skb;
+       bf->bf_buf_addr = bf->bf_dmacontext =
+               dma_map_single(sc->dev, skb->data,
+                              skb->len,
+                              DMA_TO_DEVICE);
+       if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
+               dev_kfree_skb_any(skb);
+               bf->bf_mpdu = NULL;
+               DPRINTF(sc, ATH_DBG_CONFIG,
+                       "dma_mapping_error() on beacon alloc\n");
+               return -ENOMEM;
+       }
 
        return 0;
 }
 
-/*
- *  Reclaim beacon resources and return buffer to the pool.
- *
- *  Checks the VAP to put the beacon frame buffer back to the ATH object
- *  queue, and de-allocates any wbuf frames that were sent as CAB traffic.
-*/
-
-void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp)
+void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp)
 {
        if (avp->av_bcbuf != NULL) {
                struct ath_buf *bf;
 
                if (avp->av_bslot != -1) {
-                       sc->sc_bslot[avp->av_bslot] = ATH_IF_ID_ANY;
-                       sc->sc_nbcnvaps--;
+                       sc->beacon.bslot[avp->av_bslot] = ATH_IF_ID_ANY;
+                       sc->nbcnvifs--;
                }
 
                bf = avp->av_bcbuf;
                if (bf->bf_mpdu != NULL) {
                        struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
-                       pci_unmap_single(sc->pdev, bf->bf_dmacontext,
-                                        skb_end_pointer(skb) - skb->head,
-                                        PCI_DMA_TODEVICE);
+                       dma_unmap_single(sc->dev, bf->bf_dmacontext,
+                                        skb->len,
+                                        DMA_TO_DEVICE);
                        dev_kfree_skb_any(skb);
                        bf->bf_mpdu = NULL;
                }
-               list_add_tail(&bf->list, &sc->sc_bbuf);
+               list_add_tail(&bf->list, &sc->beacon.bbuf);
 
                avp->av_bcbuf = NULL;
        }
 }
 
-/*
- *  Reclaim beacon resources and return buffer to the pool.
- *
- *  This function will free any wbuf frames that are still attached to the
- *  beacon buffers in the ATH object.  Note that this does not de-allocate
- *  any wbuf objects that are in the transmit queue and have not yet returned
- *  to the ATH object.
-*/
-
-void ath_beacon_free(struct ath_softc *sc)
-{
-       struct ath_buf *bf;
-
-       list_for_each_entry(bf, &sc->sc_bbuf, list) {
-               if (bf->bf_mpdu != NULL) {
-                       struct sk_buff *skb = (struct sk_buff *) bf->bf_mpdu;
-                       pci_unmap_single(sc->pdev, bf->bf_dmacontext,
-                                        skb_end_pointer(skb) - skb->head,
-                                        PCI_DMA_TODEVICE);
-                       dev_kfree_skb_any(skb);
-                       bf->bf_mpdu = NULL;
-               }
-       }
-}
-
-/*
- * Tasklet for Sending Beacons
- *
- * Transmit one or more beacon frames at SWBA.  Dynamic updates to the frame
- * contents are done as needed and the slot time is also adjusted based on
- * current state.
- *
- * This tasklet is not scheduled, it's called in ISR context.
-*/
-
 void ath9k_beacon_tasklet(unsigned long data)
 {
        struct ath_softc *sc = (struct ath_softc *)data;
-       struct ath_hal *ah = sc->sc_ah;
+       struct ath_hw *ah = sc->sc_ah;
        struct ath_buf *bf = NULL;
        int slot, if_id;
        u32 bfaddr;
@@ -565,9 +457,7 @@ void ath9k_beacon_tasklet(unsigned long data)
 
        if (sc->sc_flags & SC_OP_NO_RESET) {
                show_cycles = ath9k_hw_GetMibCycleCountsPct(ah,
-                                                           &rx_clear,
-                                                           &rx_frame,
-                                                           &tx_frame);
+                                           &rx_clear, &rx_frame, &tx_frame);
        }
 
        /*
@@ -576,73 +466,68 @@ void ath9k_beacon_tasklet(unsigned long data)
         * and wait for the next.  Missed beacons indicate
         * a problem and should not occur.  If we miss too
         * many consecutive beacons reset the device.
+        *
+        * FIXME: Clean up this mess !!
         */
-       if (ath9k_hw_numtxpending(ah, sc->sc_bhalq) != 0) {
-               sc->sc_bmisscount++;
+       if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) {
+               sc->beacon.bmisscnt++;
                /* XXX: doth needs the chanchange IE countdown decremented.
                 *      We should consider adding a mac80211 call to indicate
                 *      a beacon miss so appropriate action could be taken
                 *      (in that layer).
                 */
-               if (sc->sc_bmisscount < BSTUCK_THRESH) {
+               if (sc->beacon.bmisscnt < BSTUCK_THRESH) {
                        if (sc->sc_flags & SC_OP_NO_RESET) {
                                DPRINTF(sc, ATH_DBG_BEACON,
-                                       "%s: missed %u consecutive beacons\n",
-                                       __func__, sc->sc_bmisscount);
+                                       "missed %u consecutive beacons\n",
+                                       sc->beacon.bmisscnt);
                                if (show_cycles) {
                                        /*
-                                        * Display cycle counter stats
-                                        * from HW to aide in debug of
-                                        * stickiness.
+                                        * Display cycle counter stats from HW
+                                        * to aide in debug of stickiness.
                                         */
-                                       DPRINTF(sc,
-                                               ATH_DBG_BEACON,
-                                               "%s: busy times: rx_clear=%d, "
+                                       DPRINTF(sc, ATH_DBG_BEACON,
+                                               "busy times: rx_clear=%d, "
                                                "rx_frame=%d, tx_frame=%d\n",
-                                               __func__, rx_clear, rx_frame,
+                                               rx_clear, rx_frame,
                                                tx_frame);
                                } else {
-                                       DPRINTF(sc,
-                                               ATH_DBG_BEACON,
-                                               "%s: unable to obtain "
-                                               "busy times\n", __func__);
+                                       DPRINTF(sc, ATH_DBG_BEACON,
+                                               "unable to obtain "
+                                               "busy times\n");
                                }
                        } else {
                                DPRINTF(sc, ATH_DBG_BEACON,
-                                       "%s: missed %u consecutive beacons\n",
-                                       __func__, sc->sc_bmisscount);
+                                       "missed %u consecutive beacons\n",
+                                       sc->beacon.bmisscnt);
                        }
-               } else if (sc->sc_bmisscount >= BSTUCK_THRESH) {
+               } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
                        if (sc->sc_flags & SC_OP_NO_RESET) {
-                               if (sc->sc_bmisscount == BSTUCK_THRESH) {
-                                       DPRINTF(sc,
-                                               ATH_DBG_BEACON,
-                                               "%s: beacon is officially "
-                                               "stuck\n", __func__);
-                                       ath9k_hw_dmaRegDump(ah);
+                               if (sc->beacon.bmisscnt == BSTUCK_THRESH) {
+                                       DPRINTF(sc, ATH_DBG_BEACON,
+                                               "beacon is officially "
+                                               "stuck\n");
                                }
                        } else {
                                DPRINTF(sc, ATH_DBG_BEACON,
-                                       "%s: beacon is officially stuck\n",
-                                       __func__);
+                                       "beacon is officially stuck\n");
                                ath_bstuck_process(sc);
                        }
                }
-
                return;
        }
-       if (sc->sc_bmisscount != 0) {
+
+       if (sc->beacon.bmisscnt != 0) {
                if (sc->sc_flags & SC_OP_NO_RESET) {
-                       DPRINTF(sc,
-                               ATH_DBG_BEACON,
-                               "%s: resume beacon xmit after %u misses\n",
-                               __func__, sc->sc_bmisscount);
+                       DPRINTF(sc, ATH_DBG_BEACON,
+                               "resume beacon xmit after %u misses\n",
+                               sc->beacon.bmisscnt);
                } else {
                        DPRINTF(sc, ATH_DBG_BEACON,
-                               "%s: resume beacon xmit after %u misses\n",
-                               __func__, sc->sc_bmisscount);
+                               "resume beacon xmit after %u misses\n",
+                               sc->beacon.bmisscnt);
                }
-               sc->sc_bmisscount = 0;
+               sc->beacon.bmisscnt = 0;
        }
 
        /*
@@ -657,11 +542,13 @@ void ath9k_beacon_tasklet(unsigned long data)
        tsf = ath9k_hw_gettsf64(ah);
        tsftu = TSF_TO_TU(tsf>>32, tsf);
        slot = ((tsftu % intval) * ATH_BCBUF) / intval;
-       if_id = sc->sc_bslot[(slot + 1) % ATH_BCBUF];
+       if_id = sc->beacon.bslot[(slot + 1) % ATH_BCBUF];
+
        DPRINTF(sc, ATH_DBG_BEACON,
-                       "%s: slot %d [tsf %llu tsftu %u intval %u] if_id %d\n",
-                       __func__, slot, (unsigned long long) tsf, tsftu,
-                       intval, if_id);
+               "slot %d [tsf %llu tsftu %u intval %u] if_id %d\n",
+               slot, (unsigned long long)tsf, tsftu,
+               intval, if_id);
+
        bfaddr = 0;
        if (if_id != ATH_IF_ID_ANY) {
                bf = ath_beacon_generate(sc, if_id);
@@ -687,49 +574,34 @@ void ath9k_beacon_tasklet(unsigned long data)
         *     set to ATH_BCBUF so this check is a noop.
         */
        /* XXX locking */
-       if (sc->sc_updateslot == UPDATE) {
-               sc->sc_updateslot = COMMIT; /* commit next beacon */
-               sc->sc_slotupdate = slot;
-       } else if (sc->sc_updateslot == COMMIT && sc->sc_slotupdate == slot)
-               ath_setslottime(sc);        /* commit change to hardware */
-
+       if (sc->beacon.updateslot == UPDATE) {
+               sc->beacon.updateslot = COMMIT; /* commit next beacon */
+               sc->beacon.slotupdate = slot;
+       } else if (sc->beacon.updateslot == COMMIT && sc->beacon.slotupdate == slot) {
+               ath9k_hw_setslottime(sc->sc_ah, sc->beacon.slottime);
+               sc->beacon.updateslot = OK;
+       }
        if (bfaddr != 0) {
                /*
                 * Stop any current dma and put the new frame(s) on the queue.
                 * This should never fail since we check above that no frames
                 * are still pending on the queue.
                 */
-               if (!ath9k_hw_stoptxdma(ah, sc->sc_bhalq)) {
+               if (!ath9k_hw_stoptxdma(ah, sc->beacon.beaconq)) {
                        DPRINTF(sc, ATH_DBG_FATAL,
-                               "%s: beacon queue %u did not stop?\n",
-                               __func__, sc->sc_bhalq);
+                               "beacon queue %u did not stop?\n", sc->beacon.beaconq);
                        /* NB: the HAL still stops DMA, so proceed */
                }
 
                /* NB: cabq traffic should already be queued and primed */
-               ath9k_hw_puttxbuf(ah, sc->sc_bhalq, bfaddr);
-               ath9k_hw_txstart(ah, sc->sc_bhalq);
+               ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bfaddr);
+               ath9k_hw_txstart(ah, sc->beacon.beaconq);
 
-               sc->ast_be_xmit += bc;     /* XXX per-vap? */
+               sc->beacon.ast_be_xmit += bc;     /* XXX per-vif? */
        }
 }
 
 /*
- *  Tasklet for Beacon Stuck processing
- *
- *  Processing for Beacon Stuck.
- *  Basically calls the ath_internal_reset function to reset the chip.
-*/
-
-void ath_bstuck_process(struct ath_softc *sc)
-{
-       DPRINTF(sc, ATH_DBG_BEACON,
-               "%s: stuck beacon; resetting (bmiss count %u)\n",
-               __func__, sc->sc_bmisscount);
-       ath_reset(sc, false);
-}
-
-/*
  * Configure the beacon and sleep timers.
  *
  * When operating as an AP this resets the TSF and sets
@@ -744,27 +616,26 @@ void ath_bstuck_process(struct ath_softc *sc)
  * interrupt when we stop seeing beacons from the AP
  * we've associated with.
  */
-
 void ath_beacon_config(struct ath_softc *sc, int if_id)
 {
-       struct ath_hal *ah = sc->sc_ah;
-       u32 nexttbtt, intval;
+       struct ieee80211_vif *vif;
+       struct ath_hw *ah = sc->sc_ah;
        struct ath_beacon_config conf;
-       enum ath9k_opmode av_opmode;
+       struct ath_vif *avp;
+       enum nl80211_iftype opmode;
+       u32 nexttbtt, intval;
 
-       if (if_id != ATH_IF_ID_ANY)
-               av_opmode = sc->sc_vaps[if_id]->av_opmode;
-       else
-               av_opmode = sc->sc_ah->ah_opmode;
+       if (if_id != ATH_IF_ID_ANY) {
+               vif = sc->vifs[if_id];
+               ASSERT(vif);
+               avp = (void *)vif->drv_priv;
+               opmode = avp->av_opmode;
+       } else {
+               opmode = sc->sc_ah->opmode;
+       }
 
-       memzero(&conf, sizeof(struct ath_beacon_config));
+       memset(&conf, 0, sizeof(struct ath_beacon_config));
 
-       /* FIXME: Use default values for now - Sujith */
-       /* Query beacon configuration first */
-       /*
-        * Protocol stack doesn't support dynamic beacon configuration,
-        * use default configurations.
-        */
        conf.beacon_interval = sc->hw->conf.beacon_int ?
                sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
        conf.listen_interval = 1;
@@ -773,10 +644,10 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
        conf.bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf.beacon_interval;
 
        /* extract tstamp from last beacon and convert to TU */
-       nexttbtt = TSF_TO_TU(get_unaligned_le32(conf.u.last_tstamp + 4),
-                            get_unaligned_le32(conf.u.last_tstamp));
+       nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp);
+
        /* XXX conditionalize multi-bss support? */
-       if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) {
+       if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
                /*
                 * For multi-bss ap support beacons are either staggered
                 * evenly over N slots or burst together.  For the former
@@ -790,14 +661,16 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
                intval = conf.beacon_interval & ATH9K_BEACON_PERIOD;
        }
 
-       if (nexttbtt == 0)      /* e.g. for ap mode */
+       if (nexttbtt == 0)      /* e.g. for ap mode */
                nexttbtt = intval;
-       else if (intval)        /* NB: can be 0 for monitor mode */
+       else if (intval)        /* NB: can be 0 for monitor mode */
                nexttbtt = roundup(nexttbtt, intval);
-       DPRINTF(sc, ATH_DBG_BEACON, "%s: nexttbtt %u intval %u (%u)\n",
-               __func__, nexttbtt, intval, conf.beacon_interval);
-       /* Check for ATH9K_M_HOSTAP and sc_nostabeacons for WDS client */
-       if (sc->sc_ah->ah_opmode == ATH9K_M_STA) {
+
+       DPRINTF(sc, ATH_DBG_BEACON, "nexttbtt %u intval %u (%u)\n",
+               nexttbtt, intval, conf.beacon_interval);
+
+       /* Check for NL80211_IFTYPE_AP and sc_nostabeacons for WDS client */
+       if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) {
                struct ath9k_beacon_state bs;
                u64 tsf;
                u32 tsftu;
@@ -809,19 +682,19 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
                 * last beacon we received (which may be none).
                 */
                dtimperiod = conf.dtim_period;
-               if (dtimperiod <= 0)        /* NB: 0 if not known */
+               if (dtimperiod <= 0)            /* NB: 0 if not known */
                        dtimperiod = 1;
                dtimcount = conf.dtim_count;
-               if (dtimcount >= dtimperiod)    /* NB: sanity check */
-                       dtimcount = 0;      /* XXX? */
-               cfpperiod = 1;          /* NB: no PCF support yet */
+               if (dtimcount >= dtimperiod)    /* NB: sanity check */
+                       dtimcount = 0;
+               cfpperiod = 1;                  /* NB: no PCF support yet */
                cfpcount = 0;
 
                sleepduration = conf.listen_interval * intval;
                if (sleepduration <= 0)
                        sleepduration = intval;
 
-#define FUDGE   2
+#define FUDGE 2
                /*
                 * Pull nexttbtt forward to reflect the current
                 * TSF and calculate dtim+cfp state for the result.
@@ -837,7 +710,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
                        }
                } while (nexttbtt < tsftu);
 #undef FUDGE
-               memzero(&bs, sizeof(bs));
+               memset(&bs, 0, sizeof(bs));
                bs.bs_intval = intval;
                bs.bs_nexttbtt = nexttbtt;
                bs.bs_dtimperiod = dtimperiod*intval;
@@ -845,6 +718,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
                bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod;
                bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod;
                bs.bs_cfpmaxduration = 0;
+
                /*
                 * Calculate the number of consecutive beacons to miss
                 * before taking a BMISS interrupt.  The configuration
@@ -853,9 +727,8 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
                 * result to at most 15 beacons.
                 */
                if (sleepduration > intval) {
-                       bs.bs_bmissthreshold =
-                               conf.listen_interval *
-                                       ATH_DEFAULT_BMISS_LIMIT / 2;
+                       bs.bs_bmissthreshold = conf.listen_interval *
+                               ATH_DEFAULT_BMISS_LIMIT / 2;
                } else {
                        bs.bs_bmissthreshold =
                                DIV_ROUND_UP(conf.bmiss_timeout, intval);
@@ -875,13 +748,16 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
                 * XXX fixed at 100ms
                 */
 
-               bs.bs_sleepduration =
-                       roundup(IEEE80211_MS_TO_TU(100), sleepduration);
+               bs.bs_sleepduration = roundup(IEEE80211_MS_TO_TU(100),
+                                             sleepduration);
                if (bs.bs_sleepduration > bs.bs_dtimperiod)
                        bs.bs_sleepduration = bs.bs_dtimperiod;
 
+               /* TSF out of range threshold fixed at 1 second */
+               bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD;
+
                DPRINTF(sc, ATH_DBG_BEACON,
-                       "%s: tsf %llu "
+                       "tsf %llu "
                        "tsf:tu %u "
                        "intval %u "
                        "nexttbtt %u "
@@ -893,7 +769,6 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
                        "maxdur %u "
                        "next %u "
                        "timoffset %u\n",
-                       __func__,
                        (unsigned long long)tsf, tsftu,
                        bs.bs_intval,
                        bs.bs_nexttbtt,
@@ -909,20 +784,18 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
 
                ath9k_hw_set_interrupts(ah, 0);
                ath9k_hw_set_sta_beacon_timers(ah, &bs);
-               sc->sc_imask |= ATH9K_INT_BMISS;
-               ath9k_hw_set_interrupts(ah, sc->sc_imask);
+               sc->imask |= ATH9K_INT_BMISS;
+               ath9k_hw_set_interrupts(ah, sc->imask);
        } else {
                u64 tsf;
                u32 tsftu;
                ath9k_hw_set_interrupts(ah, 0);
-               if (nexttbtt == intval)
-                       intval |= ATH9K_BEACON_RESET_TSF;
-               if (sc->sc_ah->ah_opmode == ATH9K_M_IBSS) {
+               if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) {
                        /*
                         * Pull nexttbtt forward to reflect the current
-                        * TSF .
+                        * TSF
                         */
-#define FUDGE   2
+#define FUDGE 2
                        if (!(intval & ATH9K_BEACON_RESET_TSF)) {
                                tsf = ath9k_hw_gettsf64(ah);
                                tsftu = TSF_TO_TU((u32)(tsf>>32),
@@ -933,8 +806,8 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
                        }
 #undef FUDGE
                        DPRINTF(sc, ATH_DBG_BEACON,
-                               "%s: IBSS nexttbtt %u intval %u (%u)\n",
-                               __func__, nexttbtt,
+                               "IBSS nexttbtt %u intval %u (%u)\n",
+                               nexttbtt,
                                intval & ~ATH9K_BEACON_RESET_TSF,
                                conf.beacon_interval);
 
@@ -946,33 +819,34 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
                         * deal with things.
                         */
                        intval |= ATH9K_BEACON_ENA;
-                       if (!(ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL))
-                               sc->sc_imask |= ATH9K_INT_SWBA;
+                       if (!(ah->caps.hw_caps & ATH9K_HW_CAP_VEOL))
+                               sc->imask |= ATH9K_INT_SWBA;
                        ath_beaconq_config(sc);
-               } else if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) {
+               } else if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
+                       if (nexttbtt == intval)
+                               intval |= ATH9K_BEACON_RESET_TSF;
+
                        /*
                         * In AP mode we enable the beacon timers and
                         * SWBA interrupts to prepare beacon frames.
                         */
                        intval |= ATH9K_BEACON_ENA;
-                       sc->sc_imask |= ATH9K_INT_SWBA;   /* beacon prepare */
+                       sc->imask |= ATH9K_INT_SWBA;   /* beacon prepare */
                        ath_beaconq_config(sc);
                }
                ath9k_hw_beaconinit(ah, nexttbtt, intval);
-               sc->sc_bmisscount = 0;
-               ath9k_hw_set_interrupts(ah, sc->sc_imask);
+               sc->beacon.bmisscnt = 0;
+               ath9k_hw_set_interrupts(ah, sc->imask);
                /*
                 * When using a self-linked beacon descriptor in
                 * ibss mode load it once here.
                 */
-               if (sc->sc_ah->ah_opmode == ATH9K_M_IBSS &&
-                   (ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL))
+               if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC &&
+                   (ah->caps.hw_caps & ATH9K_HW_CAP_VEOL))
                        ath_beacon_start_adhoc(sc, 0);
        }
 }
 
-/* Function to collect beacon rssi data and resync beacon if necessary */
-
 void ath_beacon_sync(struct ath_softc *sc, int if_id)
 {
        /*