mac80211/ath9k: some more performance improvements
SVN-Revision: 30866
This commit is contained in:
parent
7dff84b670
commit
f728469200
5 changed files with 415 additions and 0 deletions
129
package/mac80211/patches/560-ath9k_optimize_beacon_tx.patch
Normal file
129
package/mac80211/patches/560-ath9k_optimize_beacon_tx.patch
Normal file
|
@ -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,
|
32
package/mac80211/patches/561-ath9k_optimize_hw_check.patch
Normal file
32
package/mac80211/patches/561-ath9k_optimize_hw_check.patch
Normal file
|
@ -0,0 +1,32 @@
|
|||
--- a/drivers/net/wireless/ath/ath9k/beacon.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
|
||||
@@ -421,6 +421,9 @@ void ath_beacon_tasklet(unsigned long da
|
||||
if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) {
|
||||
sc->beacon.bmisscnt++;
|
||||
|
||||
+ if (!ath9k_hw_check_alive(ah))
|
||||
+ ieee80211_queue_work(sc->hw, &sc->hw_check_work);
|
||||
+
|
||||
if (sc->beacon.bmisscnt < BSTUCK_THRESH * sc->nbcnvifs) {
|
||||
ath_dbg(common, BSTUCK,
|
||||
"missed %u consecutive beacons\n",
|
||||
--- a/drivers/net/wireless/ath/ath9k/main.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
||||
@@ -695,17 +695,6 @@ void ath9k_tasklet(unsigned long data)
|
||||
goto out;
|
||||
}
|
||||
|
||||
- /*
|
||||
- * Only run the baseband hang check if beacons stop working in AP or
|
||||
- * IBSS mode, because it has a high false positive rate. For station
|
||||
- * mode it should not be necessary, since the upper layers will detect
|
||||
- * this through a beacon miss automatically and the following channel
|
||||
- * change will trigger a hardware reset anyway
|
||||
- */
|
||||
- if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0 &&
|
||||
- !ath9k_hw_check_alive(ah))
|
||||
- ieee80211_queue_work(sc->hw, &sc->hw_check_work);
|
||||
-
|
||||
if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) {
|
||||
/*
|
||||
* TSF sync does not look correct; remain awake to sync with
|
|
@ -0,0 +1,127 @@
|
|||
--- a/net/mac80211/debugfs_netdev.c
|
||||
+++ b/net/mac80211/debugfs_netdev.c
|
||||
@@ -445,26 +445,23 @@ IEEE80211_IF_FILE(dot11MeshHWMPRannInter
|
||||
IEEE80211_IF_FILE(dot11MeshForwarding, u.mesh.mshcfg.dot11MeshForwarding, DEC);
|
||||
#endif
|
||||
|
||||
-
|
||||
-#define DEBUGFS_ADD(name) \
|
||||
- debugfs_create_file(#name, 0400, sdata->debugfs.dir, \
|
||||
- sdata, &name##_ops);
|
||||
-
|
||||
#define DEBUGFS_ADD_MODE(name, mode) \
|
||||
debugfs_create_file(#name, mode, sdata->debugfs.dir, \
|
||||
sdata, &name##_ops);
|
||||
|
||||
-static void add_sta_files(struct ieee80211_sub_if_data *sdata)
|
||||
+#define DEBUGFS_ADD(name) DEBUGFS_ADD_MODE(name, 0400)
|
||||
+
|
||||
+static void add_common_files(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
DEBUGFS_ADD(drop_unencrypted);
|
||||
- DEBUGFS_ADD(flags);
|
||||
- DEBUGFS_ADD(state);
|
||||
- DEBUGFS_ADD(channel_type);
|
||||
DEBUGFS_ADD(rc_rateidx_mask_2ghz);
|
||||
DEBUGFS_ADD(rc_rateidx_mask_5ghz);
|
||||
DEBUGFS_ADD(rc_rateidx_mcs_mask_2ghz);
|
||||
DEBUGFS_ADD(rc_rateidx_mcs_mask_5ghz);
|
||||
+}
|
||||
|
||||
+static void add_sta_files(struct ieee80211_sub_if_data *sdata)
|
||||
+{
|
||||
DEBUGFS_ADD(bssid);
|
||||
DEBUGFS_ADD(aid);
|
||||
DEBUGFS_ADD(last_beacon);
|
||||
@@ -475,15 +472,6 @@ static void add_sta_files(struct ieee802
|
||||
|
||||
static void add_ap_files(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
- DEBUGFS_ADD(drop_unencrypted);
|
||||
- DEBUGFS_ADD(flags);
|
||||
- DEBUGFS_ADD(state);
|
||||
- DEBUGFS_ADD(channel_type);
|
||||
- DEBUGFS_ADD(rc_rateidx_mask_2ghz);
|
||||
- DEBUGFS_ADD(rc_rateidx_mask_5ghz);
|
||||
- DEBUGFS_ADD(rc_rateidx_mcs_mask_2ghz);
|
||||
- DEBUGFS_ADD(rc_rateidx_mcs_mask_5ghz);
|
||||
-
|
||||
DEBUGFS_ADD(num_sta_authorized);
|
||||
DEBUGFS_ADD(num_sta_ps);
|
||||
DEBUGFS_ADD(dtim_count);
|
||||
@@ -493,48 +481,14 @@ static void add_ap_files(struct ieee8021
|
||||
|
||||
static void add_ibss_files(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
- DEBUGFS_ADD(channel_type);
|
||||
- DEBUGFS_ADD(rc_rateidx_mask_2ghz);
|
||||
- DEBUGFS_ADD(rc_rateidx_mask_5ghz);
|
||||
- DEBUGFS_ADD(rc_rateidx_mcs_mask_2ghz);
|
||||
- DEBUGFS_ADD(rc_rateidx_mcs_mask_5ghz);
|
||||
-
|
||||
DEBUGFS_ADD_MODE(tsf, 0600);
|
||||
}
|
||||
|
||||
static void add_wds_files(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
- DEBUGFS_ADD(drop_unencrypted);
|
||||
- DEBUGFS_ADD(flags);
|
||||
- DEBUGFS_ADD(state);
|
||||
- DEBUGFS_ADD(channel_type);
|
||||
- DEBUGFS_ADD(rc_rateidx_mask_2ghz);
|
||||
- DEBUGFS_ADD(rc_rateidx_mask_5ghz);
|
||||
- DEBUGFS_ADD(rc_rateidx_mcs_mask_2ghz);
|
||||
- DEBUGFS_ADD(rc_rateidx_mcs_mask_5ghz);
|
||||
-
|
||||
DEBUGFS_ADD(peer);
|
||||
}
|
||||
|
||||
-static void add_vlan_files(struct ieee80211_sub_if_data *sdata)
|
||||
-{
|
||||
- DEBUGFS_ADD(drop_unencrypted);
|
||||
- DEBUGFS_ADD(flags);
|
||||
- DEBUGFS_ADD(state);
|
||||
- DEBUGFS_ADD(channel_type);
|
||||
- DEBUGFS_ADD(rc_rateidx_mask_2ghz);
|
||||
- DEBUGFS_ADD(rc_rateidx_mask_5ghz);
|
||||
- DEBUGFS_ADD(rc_rateidx_mcs_mask_2ghz);
|
||||
- DEBUGFS_ADD(rc_rateidx_mcs_mask_5ghz);
|
||||
-}
|
||||
-
|
||||
-static void add_monitor_files(struct ieee80211_sub_if_data *sdata)
|
||||
-{
|
||||
- DEBUGFS_ADD(flags);
|
||||
- DEBUGFS_ADD(state);
|
||||
- DEBUGFS_ADD(channel_type);
|
||||
-}
|
||||
-
|
||||
#ifdef CONFIG_MAC80211_MESH
|
||||
|
||||
static void add_mesh_stats(struct ieee80211_sub_if_data *sdata)
|
||||
@@ -590,6 +544,13 @@ static void add_files(struct ieee80211_s
|
||||
if (!sdata->debugfs.dir)
|
||||
return;
|
||||
|
||||
+ DEBUGFS_ADD(flags);
|
||||
+ DEBUGFS_ADD(state);
|
||||
+ DEBUGFS_ADD(channel_type);
|
||||
+
|
||||
+ if (sdata->vif.type != NL80211_IFTYPE_MONITOR)
|
||||
+ add_common_files(sdata);
|
||||
+
|
||||
switch (sdata->vif.type) {
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
#ifdef CONFIG_MAC80211_MESH
|
||||
@@ -609,12 +570,6 @@ static void add_files(struct ieee80211_s
|
||||
case NL80211_IFTYPE_WDS:
|
||||
add_wds_files(sdata);
|
||||
break;
|
||||
- case NL80211_IFTYPE_MONITOR:
|
||||
- add_monitor_files(sdata);
|
||||
- break;
|
||||
- case NL80211_IFTYPE_AP_VLAN:
|
||||
- add_vlan_files(sdata);
|
||||
- break;
|
||||
default:
|
||||
break;
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -656,6 +656,8 @@ struct ieee80211_sub_if_data {
|
||||
|
||||
/* bitmap of allowed (non-MCS) rate indexes for rate control */
|
||||
u32 rc_rateidx_mask[IEEE80211_NUM_BANDS];
|
||||
+
|
||||
+ bool rc_has_mcs_mask[IEEE80211_NUM_BANDS];
|
||||
u8 rc_rateidx_mcs_mask[IEEE80211_NUM_BANDS][IEEE80211_HT_MCS_MASK_LEN];
|
||||
|
||||
union {
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -1887,9 +1887,20 @@ static int ieee80211_set_bitrate_mask(st
|
||||
}
|
||||
|
||||
for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
|
||||
+ struct ieee80211_supported_band *sband = wiphy->bands[i];
|
||||
+
|
||||
sdata->rc_rateidx_mask[i] = mask->control[i].legacy;
|
||||
memcpy(sdata->rc_rateidx_mcs_mask[i], mask->control[i].mcs,
|
||||
sizeof(mask->control[i].mcs));
|
||||
+
|
||||
+ sdata->rc_has_mcs_mask[i] = false;
|
||||
+ if (!sband)
|
||||
+ continue;
|
||||
+
|
||||
+ if (memcmp(sdata->rc_rateidx_mcs_mask[i],
|
||||
+ sband->ht_cap.mcs.rx_mask,
|
||||
+ sizeof(sband->ht_cap.mcs.rx_mask)) != 0)
|
||||
+ sdata->rc_has_mcs_mask[i] = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -3590,6 +3590,7 @@ enum rate_control_changed {
|
||||
* (deprecated; this will be removed once drivers get updated to use
|
||||
* rate_idx_mask)
|
||||
* @rate_idx_mask: user-requested rate mask (not MCS for now)
|
||||
+ * @rate_idx_mcs_mask: user-requested MCS rate mask (NULL if not in use)
|
||||
* @skb: the skb that will be transmitted, the control information in it needs
|
||||
* to be filled in
|
||||
* @bss: whether this frame is sent out in AP or IBSS mode
|
||||
@@ -3603,7 +3604,7 @@ struct ieee80211_tx_rate_control {
|
||||
bool rts, short_preamble;
|
||||
u8 max_rate_idx;
|
||||
u32 rate_idx_mask;
|
||||
- u8 rate_idx_mcs_mask[IEEE80211_HT_MCS_MASK_LEN];
|
||||
+ u8 *rate_idx_mcs_mask;
|
||||
bool bss;
|
||||
};
|
||||
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -640,9 +640,11 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021
|
||||
txrc.max_rate_idx = -1;
|
||||
else
|
||||
txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
|
||||
- memcpy(txrc.rate_idx_mcs_mask,
|
||||
- tx->sdata->rc_rateidx_mcs_mask[tx->channel->band],
|
||||
- sizeof(txrc.rate_idx_mcs_mask));
|
||||
+
|
||||
+ if (tx->sdata->rc_has_mcs_mask[tx->channel->band])
|
||||
+ txrc.rate_idx_mcs_mask =
|
||||
+ tx->sdata->rc_rateidx_mcs_mask[tx->channel->band];
|
||||
+
|
||||
txrc.bss = (tx->sdata->vif.type == NL80211_IFTYPE_AP ||
|
||||
tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
|
||||
tx->sdata->vif.type == NL80211_IFTYPE_ADHOC);
|
||||
@@ -2455,8 +2457,6 @@ struct sk_buff *ieee80211_beacon_get_tim
|
||||
txrc.max_rate_idx = -1;
|
||||
else
|
||||
txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
|
||||
- memcpy(txrc.rate_idx_mcs_mask, sdata->rc_rateidx_mcs_mask[band],
|
||||
- sizeof(txrc.rate_idx_mcs_mask));
|
||||
txrc.bss = true;
|
||||
rate_control_get_rate(sdata, NULL, &txrc);
|
||||
|
||||
--- a/net/mac80211/rate.c
|
||||
+++ b/net/mac80211/rate.c
|
||||
@@ -461,9 +461,12 @@ void rate_control_get_rate(struct ieee80
|
||||
* the common case.
|
||||
*/
|
||||
mask = sdata->rc_rateidx_mask[info->band];
|
||||
- memcpy(mcs_mask, sdata->rc_rateidx_mcs_mask[info->band],
|
||||
- sizeof(mcs_mask));
|
||||
- if (mask != (1 << txrc->sband->n_bitrates) - 1) {
|
||||
+ if (mask != (1 << txrc->sband->n_bitrates) - 1 || txrc->rate_idx_mcs_mask) {
|
||||
+ if (txrc->rate_idx_mcs_mask)
|
||||
+ memcpy(mcs_mask, txrc->rate_idx_mcs_mask, sizeof(mcs_mask));
|
||||
+ else
|
||||
+ memset(mcs_mask, 0xff, sizeof(mcs_mask));
|
||||
+
|
||||
if (sta) {
|
||||
/* Filter out rates that the STA does not support */
|
||||
mask &= sta->sta.supp_rates[info->band];
|
|
@ -0,0 +1,30 @@
|
|||
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
|
||||
@@ -237,21 +237,19 @@ static bool ar9003_hw_get_isr(struct ath
|
||||
|
||||
*masked = isr & ATH9K_INT_COMMON;
|
||||
|
||||
- if (ah->config.rx_intr_mitigation)
|
||||
+ if (ah->config.rx_intr_mitigation) {
|
||||
if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
|
||||
*masked |= ATH9K_INT_RXLP;
|
||||
-
|
||||
- if (ah->config.tx_intr_mitigation)
|
||||
- if (isr & (AR_ISR_TXMINTR | AR_ISR_TXINTM))
|
||||
- *masked |= ATH9K_INT_TX;
|
||||
-
|
||||
- if (isr & (AR_ISR_LP_RXOK | AR_ISR_RXERR))
|
||||
+ } else if (isr & (AR_ISR_LP_RXOK | AR_ISR_RXERR))
|
||||
*masked |= ATH9K_INT_RXLP;
|
||||
|
||||
if (isr & AR_ISR_HP_RXOK)
|
||||
*masked |= ATH9K_INT_RXHP;
|
||||
|
||||
- if (isr & (AR_ISR_TXOK | AR_ISR_TXERR | AR_ISR_TXEOL)) {
|
||||
+ if (ah->config.tx_intr_mitigation) {
|
||||
+ if (isr & (AR_ISR_TXMINTR | AR_ISR_TXINTM))
|
||||
+ *masked |= ATH9K_INT_TX;
|
||||
+ } else if (isr & (AR_ISR_TXOK | AR_ISR_TXERR | AR_ISR_TXEOL)) {
|
||||
*masked |= ATH9K_INT_TX;
|
||||
|
||||
if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
|
Loading…
Reference in a new issue