aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2011-05-17 15:09:54 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-05-19 13:54:11 -0400
commitba4903f97a275ed0967b58ff882f8ab41bec24ad (patch)
treecdf31a122856af814c3ffbf9978211f4a8b98d97
parent755173291a86c6e77414e1eaf22279fde88ccd86 (diff)
ath9k: implement .tx_last_beacon()
Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c40
3 files changed, 55 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index b070f404e8f..f75068b4b31 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -397,6 +397,9 @@ struct ath_beacon {
397 struct ath_descdma bdma; 397 struct ath_descdma bdma;
398 struct ath_txq *cabq; 398 struct ath_txq *cabq;
399 struct list_head bbuf; 399 struct list_head bbuf;
400
401 bool tx_processed;
402 bool tx_last;
400}; 403};
401 404
402void ath_beacon_tasklet(unsigned long data); 405void ath_beacon_tasklet(unsigned long data);
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 61b501aae5e..d4d8ceced89 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -18,6 +18,12 @@
18 18
19#define FUDGE 2 19#define FUDGE 2
20 20
21static void ath9k_reset_beacon_status(struct ath_softc *sc)
22{
23 sc->beacon.tx_processed = false;
24 sc->beacon.tx_last = false;
25}
26
21/* 27/*
22 * This function will modify certain transmit queue properties depending on 28 * This function will modify certain transmit queue properties depending on
23 * the operating mode of the station (AP or AdHoc). Parameters are AIFS 29 * the operating mode of the station (AP or AdHoc). Parameters are AIFS
@@ -72,6 +78,8 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
72 struct ieee80211_supported_band *sband; 78 struct ieee80211_supported_band *sband;
73 u8 rate = 0; 79 u8 rate = 0;
74 80
81 ath9k_reset_beacon_status(sc);
82
75 ds = bf->bf_desc; 83 ds = bf->bf_desc;
76 flags = ATH9K_TXDESC_NOACK; 84 flags = ATH9K_TXDESC_NOACK;
77 85
@@ -134,6 +142,8 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
134 struct ieee80211_tx_info *info; 142 struct ieee80211_tx_info *info;
135 int cabq_depth; 143 int cabq_depth;
136 144
145 ath9k_reset_beacon_status(sc);
146
137 avp = (void *)vif->drv_priv; 147 avp = (void *)vif->drv_priv;
138 cabq = sc->beacon.cabq; 148 cabq = sc->beacon.cabq;
139 149
@@ -644,6 +654,8 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
644 struct ath_common *common = ath9k_hw_common(ah); 654 struct ath_common *common = ath9k_hw_common(ah);
645 u32 tsf, delta, intval, nexttbtt; 655 u32 tsf, delta, intval, nexttbtt;
646 656
657 ath9k_reset_beacon_status(sc);
658
647 tsf = ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE); 659 tsf = ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE);
648 intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD); 660 intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD);
649 661
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 8635cd22956..bd18b1d01be 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2324,6 +2324,45 @@ static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw)
2324 return false; 2324 return false;
2325} 2325}
2326 2326
2327int ath9k_tx_last_beacon(struct ieee80211_hw *hw)
2328{
2329 struct ath_softc *sc = hw->priv;
2330 struct ath_hw *ah = sc->sc_ah;
2331 struct ieee80211_vif *vif;
2332 struct ath_vif *avp;
2333 struct ath_buf *bf;
2334 struct ath_tx_status ts;
2335 int status;
2336
2337 vif = sc->beacon.bslot[0];
2338 if (!vif)
2339 return 0;
2340
2341 avp = (void *)vif->drv_priv;
2342 if (!avp->is_bslot_active)
2343 return 0;
2344
2345 if (!sc->beacon.tx_processed) {
2346 tasklet_disable(&sc->bcon_tasklet);
2347
2348 bf = avp->av_bcbuf;
2349 if (!bf || !bf->bf_mpdu)
2350 goto skip;
2351
2352 status = ath9k_hw_txprocdesc(ah, bf->bf_desc, &ts);
2353 if (status == -EINPROGRESS)
2354 goto skip;
2355
2356 sc->beacon.tx_processed = true;
2357 sc->beacon.tx_last = !(ts.ts_status & ATH9K_TXERR_MASK);
2358
2359skip:
2360 tasklet_enable(&sc->bcon_tasklet);
2361 }
2362
2363 return sc->beacon.tx_last;
2364}
2365
2327struct ieee80211_ops ath9k_ops = { 2366struct ieee80211_ops ath9k_ops = {
2328 .tx = ath9k_tx, 2367 .tx = ath9k_tx,
2329 .start = ath9k_start, 2368 .start = ath9k_start,
@@ -2348,4 +2387,5 @@ struct ieee80211_ops ath9k_ops = {
2348 .set_coverage_class = ath9k_set_coverage_class, 2387 .set_coverage_class = ath9k_set_coverage_class,
2349 .flush = ath9k_flush, 2388 .flush = ath9k_flush,
2350 .tx_frames_pending = ath9k_tx_frames_pending, 2389 .tx_frames_pending = ath9k_tx_frames_pending,
2390 .tx_last_beacon = ath9k_tx_last_beacon,
2351}; 2391};