]> Pileus Git - ~andy/linux/blobdiff - drivers/net/wireless/ath/ath9k/beacon.c
ath9k: use the new API for setting tx descriptors
[~andy/linux] / drivers / net / wireless / ath / ath9k / beacon.c
index d4d8ceced89b754c1babef1ba41d11cfe456efcc..9cdeaebc844f4b0064d5edabd0c8d419b4eedc5a 100644 (file)
@@ -14,6 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <linux/dma-mapping.h>
 #include "ath9k.h"
 
 #define FUDGE 2
@@ -72,44 +73,39 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
        struct sk_buff *skb = bf->bf_mpdu;
        struct ath_hw *ah = sc->sc_ah;
        struct ath_common *common = ath9k_hw_common(ah);
-       struct ath_desc *ds;
-       struct ath9k_11n_rate_series series[4];
-       int flags, ctsrate = 0, ctsduration = 0;
+       struct ath_tx_info info;
        struct ieee80211_supported_band *sband;
+       u8 chainmask = ah->txchainmask;
        u8 rate = 0;
 
        ath9k_reset_beacon_status(sc);
 
-       ds = bf->bf_desc;
-       flags = ATH9K_TXDESC_NOACK;
-
-       ds->ds_link = 0;
-
        sband = &sc->sbands[common->hw->conf.channel->band];
        rate = sband->bitrates[rateidx].hw_value;
        if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
                rate |= sband->bitrates[rateidx].hw_value_short;
 
-       ath9k_hw_set11n_txdesc(ah, ds, skb->len + FCS_LEN,
-                              ATH9K_PKT_TYPE_BEACON,
-                              MAX_RATE_POWER,
-                              ATH9K_TXKEYIX_INVALID,
-                              ATH9K_KEY_TYPE_CLEAR,
-                              flags);
-
-       /* NB: beacon's BufLen must be a multiple of 4 bytes */
-       ath9k_hw_filltxdesc(ah, ds, roundup(skb->len, 4),
-                           true, true, ds, bf->bf_buf_addr,
-                           sc->beacon.beaconq);
-
-       memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
-       series[0].Tries = 1;
-       series[0].Rate = rate;
-       series[0].ChSel = ath_txchainmask_reduction(sc,
-                       common->tx_chainmask, series[0].Rate);
-       series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0;
-       ath9k_hw_set11n_ratescenario(ah, ds, ds, 0, ctsrate, ctsduration,
-                                    series, 4, 0);
+       memset(&info, 0, sizeof(info));
+       info.pkt_len = skb->len + FCS_LEN;
+       info.type = ATH9K_PKT_TYPE_BEACON;
+       info.txpower = MAX_RATE_POWER;
+       info.keyix = ATH9K_TXKEYIX_INVALID;
+       info.keytype = ATH9K_KEY_TYPE_CLEAR;
+       info.flags = ATH9K_TXDESC_NOACK;
+
+       info.buf_addr[0] = bf->bf_buf_addr;
+       info.buf_len[0] = roundup(skb->len, 4);
+
+       info.is_first = true;
+       info.is_last = true;
+
+       info.qcu = sc->beacon.beaconq;
+
+       info.rates[0].Tries = 1;
+       info.rates[0].Rate = rate;
+       info.rates[0].ChSel = ath_txchainmask_reduction(sc, chainmask, rate);
+
+       ath9k_hw_set_txdesc(ah, bf->bf_desc, &info);
 }
 
 static void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
@@ -360,6 +356,7 @@ void ath_beacon_tasklet(unsigned long data)
        struct ath_common *common = ath9k_hw_common(ah);
        struct ath_buf *bf = NULL;
        struct ieee80211_vif *vif;
+       struct ath_tx_status ts;
        int slot;
        u32 bfaddr, bc = 0;
 
@@ -384,7 +381,7 @@ void ath_beacon_tasklet(unsigned long data)
                        ath_dbg(common, ATH_DBG_BSTUCK,
                                "beacon is officially stuck\n");
                        sc->sc_flags |= SC_OP_TSF_RESET;
-                       ath_reset(sc, true);
+                       ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
                }
 
                return;
@@ -464,6 +461,11 @@ void ath_beacon_tasklet(unsigned long data)
                ath9k_hw_txstart(ah, sc->beacon.beaconq);
 
                sc->beacon.ast_be_xmit += bc;     /* XXX per-vif? */
+               if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+                       spin_lock_bh(&sc->sc_pcu_lock);
+                       ath9k_hw_txprocdesc(ah, bf->bf_desc, (void *)&ts);
+                       spin_unlock_bh(&sc->sc_pcu_lock);
+               }
        }
 }
 
@@ -496,7 +498,7 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
        u32 nexttbtt, intval;
 
        /* NB: the beacon interval is kept internally in TU's */
-       intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD);
+       intval = TU_TO_USEC(conf->beacon_interval);
        intval /= ATH_BCBUF;    /* for staggered beacons */
        nexttbtt = intval;
 
@@ -510,9 +512,11 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
        /* Set the computed AP beacon timers */
 
        ath9k_hw_disable_interrupts(ah);
+       sc->sc_flags |= SC_OP_TSF_RESET;
        ath9k_beacon_init(sc, nexttbtt, intval);
        sc->beacon.bmisscnt = 0;
        ath9k_hw_set_interrupts(ah, ah->imask);
+       ath9k_hw_enable_interrupts(ah);
 }
 
 /*
@@ -543,7 +547,7 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
        }
 
        memset(&bs, 0, sizeof(bs));
-       intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
+       intval = conf->beacon_interval;
 
        /*
         * Setup dtim and cfp parameters according to
@@ -639,12 +643,8 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
        ath9k_hw_set_sta_beacon_timers(ah, &bs);
        ah->imask |= ATH9K_INT_BMISS;
 
-       /*
-        * If the beacon config is called beacause of TSFOOR,
-        * Interrupts will be enabled back at the end of ath9k_tasklet
-        */
-       if (!(sc->ps_flags & PS_TSFOOR_SYNC))
-               ath9k_hw_set_interrupts(ah, ah->imask);
+       ath9k_hw_set_interrupts(ah, ah->imask);
+       ath9k_hw_enable_interrupts(ah);
 }
 
 static void ath_beacon_config_adhoc(struct ath_softc *sc,
@@ -652,22 +652,13 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
 {
        struct ath_hw *ah = sc->sc_ah;
        struct ath_common *common = ath9k_hw_common(ah);
-       u32 tsf, delta, intval, nexttbtt;
+       u32 tsf, intval, nexttbtt;
 
        ath9k_reset_beacon_status(sc);
 
-       tsf = ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE);
-       intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD);
-
-       if (!sc->beacon.bc_tstamp)
-               nexttbtt = tsf + intval;
-       else {
-               if (tsf > sc->beacon.bc_tstamp)
-                       delta = (tsf - sc->beacon.bc_tstamp);
-               else
-                       delta = (tsf + 1 + (~0U - sc->beacon.bc_tstamp));
-               nexttbtt = tsf + intval - (delta % intval);
-       }
+       intval = TU_TO_USEC(conf->beacon_interval);
+       tsf = roundup(ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE), intval);
+       nexttbtt = tsf + intval;
 
        ath_dbg(common, ATH_DBG_BEACON,
                "IBSS nexttbtt %u intval %u (%u)\n",
@@ -687,12 +678,9 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
        ath9k_hw_disable_interrupts(ah);
        ath9k_beacon_init(sc, nexttbtt, intval);
        sc->beacon.bmisscnt = 0;
-       /*
-        * If the beacon config is called beacause of TSFOOR,
-        * Interrupts will be enabled back at the end of ath9k_tasklet
-        */
-       if (!(sc->ps_flags & PS_TSFOOR_SYNC))
-               ath9k_hw_set_interrupts(ah, ah->imask);
+
+       ath9k_hw_set_interrupts(ah, ah->imask);
+       ath9k_hw_enable_interrupts(ah);
 }
 
 static bool ath9k_allow_beacon_config(struct ath_softc *sc,