Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+52 −15
Original line number Diff line number Diff line
@@ -2550,6 +2550,8 @@ static const struct rs_init_rate_info rs_optimal_rates_vht_40_80mhz[] = {
	{ S8_MIN, IWL_RATE_MCS_0_INDEX },
};

#define IWL_RS_LOW_RSSI_THRESHOLD (-76) /* dBm */

/* Init the optimal rate based on STA caps
 * This combined with rssi is used to report the last tx rate
 * 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,
 * of last Rx
 */
static void rs_get_initial_rate(struct iwl_mvm *mvm,
				struct ieee80211_sta *sta,
				struct iwl_lq_sta *lq_sta,
				enum ieee80211_band band,
				struct rs_rate *rate)
{
	int i, nentries;
	unsigned long active_rate;
	s8 best_rssi = S8_MIN;
	u8 best_ant = ANT_NONE;
	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,
		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++) {
		int rate_idx = initial_rates[i].rate_idx;

		if ((best_rssi >= initial_rates[i].rssi) &&
			    (BIT(rate_idx) & lq_sta->active_legacy_rate)) {
		    (BIT(rate_idx) & active_rate)) {
			rate->index = rate_idx;
			break;
		}
	}
	}

	IWL_DEBUG_RATE(mvm, "rate_idx %d ANT %s\n", rate->index,
		       rs_pretty_ant(rate->ant));
out:
	rs_dump_rate(mvm, rate, "INITIAL");
}

/* Save info about RSSI of last Rx */
@@ -2752,14 +2792,11 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
	tbl = &(lq_sta->lq_info[active_tbl]);
	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);

	WARN_ON_ONCE(rate->ant != ANT_A && rate->ant != ANT_B);
	if (rate->ant == ANT_A)
		tbl->column = RS_COLUMN_LEGACY_ANT_A;
	else
		tbl->column = RS_COLUMN_LEGACY_ANT_B;
	tbl->column = rs_get_column_from_rate(rate);

	rs_set_expected_tpt_table(lq_sta, tbl);
	rs_fill_lq_cmd(mvm, sta, lq_sta, rate);