diff options
author | Felix Fietkau <nbd@openwrt.org> | 2011-05-17 15:09:54 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-05-19 13:54:11 -0400 |
commit | ba4903f97a275ed0967b58ff882f8ab41bec24ad (patch) | |
tree | cdf31a122856af814c3ffbf9978211f4a8b98d97 /drivers/net | |
parent | 755173291a86c6e77414e1eaf22279fde88ccd86 (diff) |
ath9k: implement .tx_last_beacon()
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ath9k.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/beacon.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 40 |
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 b070f404e8f4..f75068b4b310 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 | ||
402 | void ath_beacon_tasklet(unsigned long data); | 405 | void 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 61b501aae5e9..d4d8ceced89b 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 | ||
21 | static 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 8635cd229561..bd18b1d01be7 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 | ||
2327 | int 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 | |||
2359 | skip: | ||
2360 | tasklet_enable(&sc->bcon_tasklet); | ||
2361 | } | ||
2362 | |||
2363 | return sc->beacon.tx_last; | ||
2364 | } | ||
2365 | |||
2327 | struct ieee80211_ops ath9k_ops = { | 2366 | struct 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 | }; |