summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/mvm/rs.c
diff options
context:
space:
mode:
authorEyal Shapira <eyal@wizery.com>2014-11-05 12:03:59 +0200
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-11-11 17:15:05 +0200
commit26a2cc016f59839afb665ab29c7a40b91bcedf42 (patch)
tree33d2386d7e314223abb6991d0e5b9aeaecb669f1 /drivers/net/wireless/iwlwifi/mvm/rs.c
parentf4cf8680dfa42c80476a9cc5b90f933b12cf6d29 (diff)
downloadlinux-stable-26a2cc016f59839afb665ab29c7a40b91bcedf42.tar.gz
linux-stable-26a2cc016f59839afb665ab29c7a40b91bcedf42.tar.bz2
linux-stable-26a2cc016f59839afb665ab29c7a40b91bcedf42.zip
iwlwifi: mvm: rs: fix getting stuck in a test window
When Tx STBC is being used and RS switches to a search column using the alternate antenna from the current one there is a problem with using rs_rate_match to figure out which table is the active and which one is the search one. The root cause is because in STBC the antenna mask in the ucode rate is set to ANT_AB and in this specific scenario it matches both the active and search table (e.g. SISO_ANT_A and SISO_ANT_B). This leads to tx stats being updated in the wrong table and later on to getting stuck in a test window and not moving on to other columns. If this happens during the initial search cycle we never end it and therefore never enable aggregation which leads naturally to severe througput degradation. Fix it by deducing which table is which by knowing whether we're in a search or not like it's being done in rs_rate_scale_perform Signed-off-by: Eyal Shapira <eyalx.shapira@intel.com> Reviewed-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm/rs.c')
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index cb18b609255d..bbd2f9b90688 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -506,7 +506,7 @@ static inline void rs_dump_rate(struct iwl_mvm *mvm, const struct rs_rate *rate,
const char *prefix)
{
IWL_DEBUG_RATE(mvm,
- "%s: (%s: %d) ANT: %s BW: %d SGI: %d LDPC: %d STBC %d\n",
+ "%s: (%s: %d) ANT: %s BW: %d SGI: %d LDPC: %d STBC: %d\n",
prefix, rs_pretty_lq_type(rate->type),
rate->index, rs_pretty_ant(rate->ant),
rate->bw, rate->sgi, rate->ldpc, rate->stbc);
@@ -1155,16 +1155,15 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
/* Rate did match, so reset the missed_rate_counter */
lq_sta->missed_rate_counter = 0;
- /* Figure out if rate scale algorithm is in active or search table */
- if (rs_rate_match(&rate,
- &(lq_sta->lq_info[lq_sta->active_tbl].rate))) {
+ if (!lq_sta->search_better_tbl) {
curr_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
other_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
- } else if (rs_rate_match(&rate,
- &lq_sta->lq_info[1 - lq_sta->active_tbl].rate)) {
+ } else {
curr_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
- } else {
+ }
+
+ if (WARN_ON_ONCE(!rs_rate_match(&rate, &curr_tbl->rate))) {
IWL_DEBUG_RATE(mvm,
"Neither active nor search matches tx rate\n");
tmp_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);