Commit 99319b8c authored by Gregory Greenman's avatar Gregory Greenman Committed by Emmanuel Grumbach

iwlwifi: mvm: add an option to start rs from HT/VHT rates

Extend the configurable option of setting initial rate to RSSI based.
Make the initial rate to be set to VHT/HT SISO or legacy depending on
the AP capabilities.
Signed-off-by: default avatarGregory Greenman <gregory.greenman@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent a42b2af3
...@@ -2550,6 +2550,8 @@ static const struct rs_init_rate_info rs_optimal_rates_vht_40_80mhz[] = { ...@@ -2550,6 +2550,8 @@ static const struct rs_init_rate_info rs_optimal_rates_vht_40_80mhz[] = {
{ S8_MIN, IWL_RATE_MCS_0_INDEX }, { S8_MIN, IWL_RATE_MCS_0_INDEX },
}; };
#define IWL_RS_LOW_RSSI_THRESHOLD (-76) /* dBm */
/* Init the optimal rate based on STA caps /* Init the optimal rate based on STA caps
* This combined with rssi is used to report the last tx rate * This combined with rssi is used to report the last tx rate
* to userspace when we haven't transmitted enough frames. * to userspace when we haven't transmitted enough frames.
...@@ -2635,11 +2637,13 @@ static struct rs_rate *rs_get_optimal_rate(struct iwl_mvm *mvm, ...@@ -2635,11 +2637,13 @@ static struct rs_rate *rs_get_optimal_rate(struct iwl_mvm *mvm,
* of last Rx * of last Rx
*/ */
static void rs_get_initial_rate(struct iwl_mvm *mvm, static void rs_get_initial_rate(struct iwl_mvm *mvm,
struct ieee80211_sta *sta,
struct iwl_lq_sta *lq_sta, struct iwl_lq_sta *lq_sta,
enum ieee80211_band band, enum ieee80211_band band,
struct rs_rate *rate) struct rs_rate *rate)
{ {
int i, nentries; int i, nentries;
unsigned long active_rate;
s8 best_rssi = S8_MIN; s8 best_rssi = S8_MIN;
u8 best_ant = ANT_NONE; u8 best_ant = ANT_NONE;
u8 valid_tx_ant = iwl_mvm_get_valid_tx_ant(mvm); u8 valid_tx_ant = iwl_mvm_get_valid_tx_ant(mvm);
...@@ -2680,19 +2684,55 @@ static void rs_get_initial_rate(struct iwl_mvm *mvm, ...@@ -2680,19 +2684,55 @@ static void rs_get_initial_rate(struct iwl_mvm *mvm,
nentries = ARRAY_SIZE(rs_optimal_rates_24ghz_legacy); nentries = ARRAY_SIZE(rs_optimal_rates_24ghz_legacy);
} }
if (IWL_MVM_RS_RSSI_BASED_INIT_RATE) { if (!IWL_MVM_RS_RSSI_BASED_INIT_RATE)
goto out;
/* Start from a higher rate if the corresponding debug capability
* is enabled. The rate is chosen according to AP capabilities.
* In case of VHT/HT when the rssi is low fallback to the case of
* legacy rates.
*/
if (sta->vht_cap.vht_supported &&
best_rssi > IWL_RS_LOW_RSSI_THRESHOLD) {
if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) {
initial_rates = rs_optimal_rates_vht_40_80mhz;
nentries = ARRAY_SIZE(rs_optimal_rates_vht_40_80mhz);
if (sta->bandwidth >= IEEE80211_STA_RX_BW_80)
rate->bw = RATE_MCS_CHAN_WIDTH_80;
else
rate->bw = RATE_MCS_CHAN_WIDTH_40;
} else if (sta->bandwidth == IEEE80211_STA_RX_BW_20) {
initial_rates = rs_optimal_rates_vht_20mhz;
nentries = ARRAY_SIZE(rs_optimal_rates_vht_20mhz);
rate->bw = RATE_MCS_CHAN_WIDTH_20;
} else {
IWL_ERR(mvm, "Invalid BW %d\n", sta->bandwidth);
goto out;
}
active_rate = lq_sta->active_siso_rate;
rate->type = LQ_VHT_SISO;
} else if (sta->ht_cap.ht_supported &&
best_rssi > IWL_RS_LOW_RSSI_THRESHOLD) {
initial_rates = rs_optimal_rates_ht;
nentries = ARRAY_SIZE(rs_optimal_rates_ht);
active_rate = lq_sta->active_siso_rate;
rate->type = LQ_HT_SISO;
} else {
active_rate = lq_sta->active_legacy_rate;
}
for (i = 0; i < nentries; i++) { for (i = 0; i < nentries; i++) {
int rate_idx = initial_rates[i].rate_idx; int rate_idx = initial_rates[i].rate_idx;
if ((best_rssi >= initial_rates[i].rssi) && if ((best_rssi >= initial_rates[i].rssi) &&
(BIT(rate_idx) & lq_sta->active_legacy_rate)) { (BIT(rate_idx) & active_rate)) {
rate->index = rate_idx; rate->index = rate_idx;
break; break;
} }
} }
}
IWL_DEBUG_RATE(mvm, "rate_idx %d ANT %s\n", rate->index, out:
rs_pretty_ant(rate->ant)); rs_dump_rate(mvm, rate, "INITIAL");
} }
/* Save info about RSSI of last Rx */ /* Save info about RSSI of last Rx */
...@@ -2752,14 +2792,11 @@ static void rs_initialize_lq(struct iwl_mvm *mvm, ...@@ -2752,14 +2792,11 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
tbl = &(lq_sta->lq_info[active_tbl]); tbl = &(lq_sta->lq_info[active_tbl]);
rate = &tbl->rate; rate = &tbl->rate;
rs_get_initial_rate(mvm, lq_sta, band, rate); rs_get_initial_rate(mvm, sta, lq_sta, band, rate);
rs_init_optimal_rate(mvm, sta, lq_sta); rs_init_optimal_rate(mvm, sta, lq_sta);
WARN_ON_ONCE(rate->ant != ANT_A && rate->ant != ANT_B); WARN_ON_ONCE(rate->ant != ANT_A && rate->ant != ANT_B);
if (rate->ant == ANT_A) tbl->column = rs_get_column_from_rate(rate);
tbl->column = RS_COLUMN_LEGACY_ANT_A;
else
tbl->column = RS_COLUMN_LEGACY_ANT_B;
rs_set_expected_tpt_table(lq_sta, tbl); rs_set_expected_tpt_table(lq_sta, tbl);
rs_fill_lq_cmd(mvm, sta, lq_sta, rate); rs_fill_lq_cmd(mvm, sta, lq_sta, rate);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment