summaryrefslogtreecommitdiff
path: root/package/mac80211
diff options
context:
space:
mode:
authornbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73>2012-03-10 12:59:40 +0000
committernbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73>2012-03-10 12:59:40 +0000
commitd7bc8b2f4a54862fbe5823ba2b9453de0e1670e9 (patch)
tree5e6fbb34a22fb5312dfbb10488b1e3092708cf3a /package/mac80211
parent868be35105a6cee47ade2d644241778e01836ea5 (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')
-rw-r--r--package/mac80211/patches/560-ath9k_optimize_beacon_tx.patch129
-rw-r--r--package/mac80211/patches/561-ath9k_optimize_hw_check.patch32
-rw-r--r--package/mac80211/patches/562-mac80211_remove_code_duplication.patch127
-rw-r--r--package/mac80211/patches/563-mac80211_optimize_mcs_rate_mask.patch97
-rw-r--r--package/mac80211/patches/564-ath9k_optimize_interrupt_mitigation.patch30
5 files changed, 415 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 0000000000..cfa1eb7c37
--- /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,
diff --git a/package/mac80211/patches/561-ath9k_optimize_hw_check.patch b/package/mac80211/patches/561-ath9k_optimize_hw_check.patch
new file mode 100644
index 0000000000..d10fbede50
--- /dev/null
+++ b/package/mac80211/patches/561-ath9k_optimize_hw_check.patch
@@ -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
diff --git a/package/mac80211/patches/562-mac80211_remove_code_duplication.patch b/package/mac80211/patches/562-mac80211_remove_code_duplication.patch
new file mode 100644
index 0000000000..e411d766c0
--- /dev/null
+++ b/package/mac80211/patches/562-mac80211_remove_code_duplication.patch
@@ -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;
+ }
diff --git a/package/mac80211/patches/563-mac80211_optimize_mcs_rate_mask.patch b/package/mac80211/patches/563-mac80211_optimize_mcs_rate_mask.patch
new file mode 100644
index 0000000000..316663856c
--- /dev/null
+++ b/package/mac80211/patches/563-mac80211_optimize_mcs_rate_mask.patch
@@ -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];
diff --git a/package/mac80211/patches/564-ath9k_optimize_interrupt_mitigation.patch b/package/mac80211/patches/564-ath9k_optimize_interrupt_mitigation.patch
new file mode 100644
index 0000000000..5674fbb9d3
--- /dev/null
+++ b/package/mac80211/patches/564-ath9k_optimize_interrupt_mitigation.patch
@@ -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)) {