Merge branch 'timers-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[pandora-kernel.git] / drivers / net / wireless / ath / ath9k / beacon.c
index b4a31a4..f43d85a 100644 (file)
@@ -76,24 +76,13 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
        ds = bf->bf_desc;
        flags = ATH9K_TXDESC_NOACK;
 
-       if (((sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
-            (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) &&
-           (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. */
-               antenna = 0;
-       } else {
-               ds->ds_link = 0;
-               /*
-                * Switch antenna every beacon.
-                * Should only switch every beacon period, not for every SWBA
-                * XXX assumes two antennae
-                */
-               antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1);
-       }
-
-       ds->ds_data = bf->bf_buf_addr;
+       ds->ds_link = 0;
+       /*
+        * Switch antenna every beacon.
+        * Should only switch every beacon period, not for every SWBA
+        * XXX assumes two antennae
+        */
+       antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1);
 
        sband = &sc->sbands[common->hw->conf.channel->band];
        rate = sband->bitrates[rateidx].hw_value;
@@ -109,7 +98,8 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
 
        /* NB: beacon's BufLen must be a multiple of 4 bytes */
        ath9k_hw_filltxdesc(ah, ds, roundup(skb->len, 4),
-                           true, true, ds);
+                           true, true, ds, bf->bf_buf_addr,
+                           sc->beacon.beaconq);
 
        memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
        series[0].Tries = 1;
@@ -216,36 +206,6 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
        return bf;
 }
 
-/*
- * 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,
-                                  struct ieee80211_vif *vif)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_common *common = ath9k_hw_common(ah);
-       struct ath_buf *bf;
-       struct ath_vif *avp;
-       struct sk_buff *skb;
-
-       avp = (void *)vif->drv_priv;
-
-       if (avp->av_bcbuf == NULL)
-               return;
-
-       bf = avp->av_bcbuf;
-       skb = bf->bf_mpdu;
-
-       ath_beacon_setup(sc, avp, bf, 0);
-
-       /* NB: caller is known to have already stopped tx dma */
-       ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr);
-       ath9k_hw_txstart(ah, sc->beacon.beaconq);
-       ath_print(common, ATH_DBG_BEACON, "TXDP%u = %llx (%p)\n",
-                 sc->beacon.beaconq, ito64(bf->bf_daddr), bf->bf_desc);
-}
-
 int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
 {
        struct ath_softc *sc = aphy->sc;
@@ -266,7 +226,8 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
                list_del(&avp->av_bcbuf->list);
 
                if (sc->sc_ah->opmode == NL80211_IFTYPE_AP ||
-                   !(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
+                   sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC ||
+                   sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) {
                        int slot;
                        /*
                         * Assign the vif to a beacon xmit slot. As
@@ -275,17 +236,11 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
                        avp->av_bslot = 0;
                        for (slot = 0; slot < ATH_BCBUF; slot++)
                                if (sc->beacon.bslot[slot] == NULL) {
-                                       /*
-                                        * XXX hack, space out slots to better
-                                        * deal with misses
-                                        */
-                                       if (slot+1 < ATH_BCBUF &&
-                                           sc->beacon.bslot[slot+1] == NULL) {
-                                               avp->av_bslot = slot+1;
-                                               break;
-                                       }
                                        avp->av_bslot = slot;
+
                                        /* NB: keep looking for a double slot */
+                                       if (slot == 0 || !sc->beacon.bslot[slot-1])
+                                               break;
                                }
                        BUG_ON(sc->beacon.bslot[avp->av_bslot] != NULL);
                        sc->beacon.bslot[avp->av_bslot] = vif;
@@ -524,6 +479,7 @@ static void ath9k_beacon_init(struct ath_softc *sc,
 static void ath_beacon_config_ap(struct ath_softc *sc,
                                 struct ath_beacon_config *conf)
 {
+       struct ath_hw *ah = sc->sc_ah;
        u32 nexttbtt, intval;
 
        /* NB: the beacon interval is kept internally in TU's */
@@ -539,15 +495,15 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
         * prepare beacon frames.
         */
        intval |= ATH9K_BEACON_ENA;
-       sc->imask |= ATH9K_INT_SWBA;
+       ah->imask |= ATH9K_INT_SWBA;
        ath_beaconq_config(sc);
 
        /* Set the computed AP beacon timers */
 
-       ath9k_hw_set_interrupts(sc->sc_ah, 0);
+       ath9k_hw_set_interrupts(ah, 0);
        ath9k_beacon_init(sc, nexttbtt, intval);
        sc->beacon.bmisscnt = 0;
-       ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
+       ath9k_hw_set_interrupts(ah, ah->imask);
 
        /* Clear the reset TSF flag, so that subsequent beacon updation
           will not reset the HW TSF. */
@@ -566,7 +522,8 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
 static void ath_beacon_config_sta(struct ath_softc *sc,
                                  struct ath_beacon_config *conf)
 {
-       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
        struct ath9k_beacon_state bs;
        int dtimperiod, dtimcount, sleepduration;
        int cfpperiod, cfpcount;
@@ -605,7 +562,7 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
         * Pull nexttbtt forward to reflect the current
         * TSF and calculate dtim+cfp state for the result.
         */
-       tsf = ath9k_hw_gettsf64(sc->sc_ah);
+       tsf = ath9k_hw_gettsf64(ah);
        tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
 
        num_beacons = tsftu / intval + 1;
@@ -678,17 +635,18 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
 
        /* Set the computed STA beacon timers */
 
-       ath9k_hw_set_interrupts(sc->sc_ah, 0);
-       ath9k_hw_set_sta_beacon_timers(sc->sc_ah, &bs);
-       sc->imask |= ATH9K_INT_BMISS;
-       ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
+       ath9k_hw_set_interrupts(ah, 0);
+       ath9k_hw_set_sta_beacon_timers(ah, &bs);
+       ah->imask |= ATH9K_INT_BMISS;
+       ath9k_hw_set_interrupts(ah, ah->imask);
 }
 
 static void ath_beacon_config_adhoc(struct ath_softc *sc,
                                    struct ath_beacon_config *conf,
                                    struct ieee80211_vif *vif)
 {
-       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
        u64 tsf;
        u32 tsftu, intval, nexttbtt;
 
@@ -703,7 +661,7 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
         else if (intval)
                 nexttbtt = roundup(nexttbtt, intval);
 
-       tsf = ath9k_hw_gettsf64(sc->sc_ah);
+       tsf = ath9k_hw_gettsf64(ah);
        tsftu = TSF_TO_TU((u32)(tsf>>32), (u32)tsf) + FUDGE;
        do {
                nexttbtt += intval;
@@ -719,21 +677,16 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
         * self-linked tx descriptor and let the hardware deal with things.
         */
        intval |= ATH9K_BEACON_ENA;
-       if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL))
-               sc->imask |= ATH9K_INT_SWBA;
+       ah->imask |= ATH9K_INT_SWBA;
 
        ath_beaconq_config(sc);
 
        /* Set the computed ADHOC beacon timers */
 
-       ath9k_hw_set_interrupts(sc->sc_ah, 0);
+       ath9k_hw_set_interrupts(ah, 0);
        ath9k_beacon_init(sc, nexttbtt, intval);
        sc->beacon.bmisscnt = 0;
-       ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
-
-       /* FIXME: Handle properly when vif is NULL */
-       if (vif && sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)
-               ath_beacon_start_adhoc(sc, vif);
+       ath9k_hw_set_interrupts(ah, ah->imask);
 }
 
 void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)