diff options
author | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-03-10 12:59:40 +0000 |
---|---|---|
committer | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-03-10 12:59:40 +0000 |
commit | d7bc8b2f4a54862fbe5823ba2b9453de0e1670e9 (patch) | |
tree | 5e6fbb34a22fb5312dfbb10488b1e3092708cf3a /package/mac80211/patches/560-ath9k_optimize_beacon_tx.patch | |
parent | 868be35105a6cee47ade2d644241778e01836ea5 (diff) |
mac80211/ath9k: some more performance improvements
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@30866 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'package/mac80211/patches/560-ath9k_optimize_beacon_tx.patch')
-rw-r--r-- | package/mac80211/patches/560-ath9k_optimize_beacon_tx.patch | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/package/mac80211/patches/560-ath9k_optimize_beacon_tx.patch b/package/mac80211/patches/560-ath9k_optimize_beacon_tx.patch new file mode 100644 index 000000000..cfa1eb7c3 --- /dev/null +++ b/package/mac80211/patches/560-ath9k_optimize_beacon_tx.patch @@ -0,0 +1,129 @@ +--- a/drivers/net/wireless/ath/ath9k/beacon.c ++++ b/drivers/net/wireless/ath/ath9k/beacon.c +@@ -357,41 +357,12 @@ void ath_beacon_tasklet(unsigned long da + struct ieee80211_vif *vif; + bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); + int slot; +- u32 bfaddr, bc = 0; +- +- /* +- * Check if the previous beacon has gone out. If +- * not don't try to post another, skip this period +- * and wait for the next. Missed beacons indicate +- * a problem and should not occur. If we miss too +- * many consecutive beacons reset the device. +- */ +- if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) { +- sc->beacon.bmisscnt++; +- +- if (sc->beacon.bmisscnt < BSTUCK_THRESH * sc->nbcnvifs) { +- ath_dbg(common, BSTUCK, +- "missed %u consecutive beacons\n", +- sc->beacon.bmisscnt); +- ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq); +- if (sc->beacon.bmisscnt > 3) +- ath9k_hw_bstuck_nfcal(ah); +- } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) { +- ath_dbg(common, BSTUCK, "beacon is officially stuck\n"); +- sc->sc_flags |= SC_OP_TSF_RESET; +- ieee80211_queue_work(sc->hw, &sc->hw_reset_work); +- } +- +- return; +- } + + /* + * Generate beacon frames. we are sending frames + * staggered so calculate the slot for this frame based + * on the tsf to safeguard against missing an swba. + */ +- +- + if (ah->opmode == NL80211_IFTYPE_AP) { + u16 intval; + u32 tsftu; +@@ -412,23 +383,6 @@ void ath_beacon_tasklet(unsigned long da + vif = sc->beacon.bslot[slot]; + } + +- +- bfaddr = 0; +- if (vif) { +- bf = ath_beacon_generate(sc->hw, vif); +- if (bf != NULL) { +- bfaddr = bf->bf_daddr; +- bc = 1; +- } +- +- if (sc->beacon.bmisscnt != 0) { +- ath_dbg(common, BSTUCK, +- "resume beacon xmit after %u misses\n", +- sc->beacon.bmisscnt); +- sc->beacon.bmisscnt = 0; +- } +- } +- + /* + * Handle slot time change when a non-ERP station joins/leaves + * an 11g network. The 802.11 layer notifies us via callback, +@@ -453,15 +407,54 @@ void ath_beacon_tasklet(unsigned long da + ath9k_hw_init_global_settings(ah); + sc->beacon.updateslot = OK; + } +- if (bfaddr != 0) { +- /* NB: cabq traffic should already be queued and primed */ +- ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bfaddr); + +- if (!edma) +- ath9k_hw_txstart(ah, sc->beacon.beaconq); ++ if (!vif) ++ return; ++ ++ /* ++ * Check if the previous beacon has gone out. If ++ * not don't try to post another, skip this period ++ * and wait for the next. Missed beacons indicate ++ * a problem and should not occur. If we miss too ++ * many consecutive beacons reset the device. ++ */ ++ if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) { ++ sc->beacon.bmisscnt++; ++ ++ if (sc->beacon.bmisscnt < BSTUCK_THRESH * sc->nbcnvifs) { ++ ath_dbg(common, BSTUCK, ++ "missed %u consecutive beacons\n", ++ sc->beacon.bmisscnt); ++ ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq); ++ if (sc->beacon.bmisscnt > 3) ++ ath9k_hw_bstuck_nfcal(ah); ++ } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) { ++ ath_dbg(common, BSTUCK, "beacon is officially stuck\n"); ++ sc->sc_flags |= SC_OP_TSF_RESET; ++ ieee80211_queue_work(sc->hw, &sc->hw_reset_work); ++ } ++ ++ return; ++ } ++ ++ bf = ath_beacon_generate(sc->hw, vif); ++ if (!bf) ++ return; + +- sc->beacon.ast_be_xmit += bc; /* XXX per-vif? */ ++ if (sc->beacon.bmisscnt != 0) { ++ ath_dbg(common, BSTUCK, ++ "resume beacon xmit after %u misses\n", ++ sc->beacon.bmisscnt); ++ sc->beacon.bmisscnt = 0; + } ++ ++ /* NB: cabq traffic should already be queued and primed */ ++ ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr); ++ ++ if (!edma) ++ ath9k_hw_txstart(ah, sc->beacon.beaconq); ++ ++ sc->beacon.ast_be_xmit++; + } + + static void ath9k_beacon_init(struct ath_softc *sc, |