summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
authorEyal Shapira <eyal@wizery.com>2014-04-06 18:13:22 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-06-07 10:28:09 -0700
commit8d9d04e946c2b4b3742fb20c98610e3109bdb478 (patch)
treeb391ae66f63b94e65d255c71d782bafebf07f3b7 /drivers/net
parent0046274a882836ade933319d179a7e436cf5c971 (diff)
iwlwifi: mvm: rs: reinit rs if no tx for a long time
commit 87d5e4155c0088e6766b4f0193b63fa0eab71220 upstream. After being idle for a long time (>5sec) the rs statistics will be stale so we prefer to reset rs and start from legacy rates again. This gives better results when the attenuation increased signficantly (e.g. we got further from the AP) and after a while we start Tx Note that the first Tx after the idle period will still go out in the old modulation and rate but this seemed a simpler approach compared to adding a timer or modifying mac80211 for this. The negative impact is negligble as we'll recover quickly. Signed-off-by: Eyal Shapira <eyalx.shapira@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c22
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.h1
2 files changed, 22 insertions, 1 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index a934f5710244..754007e4d13e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -59,7 +59,7 @@
/* max allowed rate miss before sync LQ cmd */
#define IWL_MISSED_RATE_MAX 15
#define RS_STAY_IN_COLUMN_TIMEOUT (5*HZ)
-
+#define RS_IDLE_TIMEOUT (5*HZ)
static u8 rs_ht_to_legacy[] = {
[IWL_RATE_MCS_0_INDEX] = IWL_RATE_6M_INDEX,
@@ -991,6 +991,13 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
return;
}
+#ifdef CPTCFG_MAC80211_DEBUGFS
+ /* Disable last tx check if we are debugging with fixed rate */
+ if (lq_sta->dbg_fixed_rate) {
+ IWL_DEBUG_RATE(mvm, "Fixed rate. avoid rate scaling\n");
+ return;
+ }
+#endif
if (!ieee80211_is_data(hdr->frame_control) ||
info->flags & IEEE80211_TX_CTL_NO_ACK)
return;
@@ -1033,6 +1040,18 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
mac_index++;
}
+ if (time_after(jiffies,
+ (unsigned long)(lq_sta->last_tx + RS_IDLE_TIMEOUT))) {
+ int tid;
+ IWL_DEBUG_RATE(mvm, "Tx idle for too long. reinit rs\n");
+ for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++)
+ ieee80211_stop_tx_ba_session(sta, tid);
+
+ iwl_mvm_rs_rate_init(mvm, sta, sband->band, false);
+ return;
+ }
+ lq_sta->last_tx = jiffies;
+
/* Here we actually compare this rate to the latest LQ command */
if ((mac_index < 0) ||
(rate.sgi != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) ||
@@ -2286,6 +2305,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
lq_sta->flush_timer = 0;
+ lq_sta->last_tx = jiffies;
IWL_DEBUG_RATE(mvm,
"LQ: *** rate scale station global init for station %d ***\n",
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h
index 690fbf5a2ce6..f23b68b8eeff 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.h
@@ -311,6 +311,7 @@ struct iwl_lq_sta {
u32 visited_columns; /* Bitmask marking which Tx columns were
* explored during a search cycle
*/
+ u64 last_tx;
bool is_vht;
enum ieee80211_band band;