summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Sperling <stsp@cvs.openbsd.org>2022-03-23 09:21:48 +0000
committerStefan Sperling <stsp@cvs.openbsd.org>2022-03-23 09:21:48 +0000
commit4e0d43bada1227ebdcb7b372d69b2451803bc1bf (patch)
tree36875d1100d99e03e737d673de6a37a66e4a045b
parenta7cd51de3f845a9911b20dfdc9ef7f638cfdee1d (diff)
Fix a few bugs in the net80211 VHT rate adaptation code.
Actually set rn->best_nss after deciding on a new best rate. We are now switching between SISO and MIMO rates as intended. When switching between ratesets, avoid switching directly to the highest rate in the new rateset, which might be MCS 9 and not work at all from a distance. Instead, use the most recently determined best rate in the set. The bit which corresponds to the current best MS will not be set in the rn->probed_rates[] array while we are probing an MCS other than the best. Checking for this bit was simply wrong and prevented us from probing the next rateset unless we managed to successfully probe up all the way to the highest MCS in the current set. Also fix errors in debug output. Tested by bket, florian, Uwe Werler, and myself. ok bket@
-rw-r--r--sys/net80211/ieee80211_ra_vht.c25
1 files changed, 14 insertions, 11 deletions
diff --git a/sys/net80211/ieee80211_ra_vht.c b/sys/net80211/ieee80211_ra_vht.c
index 643664673d3..76c9b3bfb31 100644
--- a/sys/net80211/ieee80211_ra_vht.c
+++ b/sys/net80211/ieee80211_ra_vht.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_ra_vht.c,v 1.2 2022/03/19 10:28:44 stsp Exp $ */
+/* $OpenBSD: ieee80211_ra_vht.c,v 1.3 2022/03/23 09:21:47 stsp Exp $ */
/*
* Copyright (c) 2021 Christian Ehrhardt <ehrhardt@genua.de>
@@ -48,7 +48,7 @@ void ieee80211_ra_vht_trigger_next_rateset(struct ieee80211_ra_vht_node *,
struct ieee80211_node *);
int ieee80211_ra_vht_inter_mode_ra_finished(
struct ieee80211_ra_vht_node *, struct ieee80211_node *);
-int ieee80211_ra_vht_best_rate(struct ieee80211_ra_vht_node *,
+void ieee80211_ra_vht_best_rate(struct ieee80211_ra_vht_node *,
struct ieee80211_node *);
void ieee80211_ra_vht_probe_next_rate(struct ieee80211_ra_vht_node *,
struct ieee80211_node *);
@@ -330,9 +330,9 @@ ieee80211_ra_vht_probe_next_rateset(struct ieee80211_ra_vht_node *rn,
break;
}
}
- /* If all rates are lower the maximum rate is the closest match. */
+ /* If all rates are lower then the best rate is the closest match. */
if (mcs == rsnext->nrates)
- ni->ni_txmcs = rn->max_mcs[rsnext->num_ss - 1];
+ ni->ni_txmcs = ieee80211_ra_vht_best_mcs_in_rateset(rn, rsnext);
/* Add rates from the next rateset as candidates. */
rn->candidate_rates[rsnext->num_ss - 1] |= (1 << ni->ni_txmcs);
@@ -427,8 +427,7 @@ ieee80211_ra_vht_intra_mode_ra_finished(struct ieee80211_ra_vht_node *rn,
/* Check if we had a better measurement at a previously probed MCS. */
best_mcs = ieee80211_ra_vht_best_mcs_in_rateset(rn, rs);
- if (best_mcs != ni->ni_txmcs &&
- (rn->probed_rates[nss - 1] & (1 << best_mcs))) {
+ if (best_mcs != ni->ni_txmcs) {
if ((rn->probing & IEEE80211_RA_PROBING_UP) &&
best_mcs < ni->ni_txmcs) {
ieee80211_ra_vht_trigger_next_rateset(rn, ni);
@@ -473,7 +472,7 @@ ieee80211_ra_vht_inter_mode_ra_finished(struct ieee80211_ra_vht_node *rn,
return ((rn->probing & IEEE80211_RA_PROBING_INTER) == 0);
}
-int
+void
ieee80211_ra_vht_best_rate(struct ieee80211_ra_vht_node *rn,
struct ieee80211_node *ni)
{
@@ -505,13 +504,16 @@ ieee80211_ra_vht_best_rate(struct ieee80211_ra_vht_node *rn,
best_mcs, best_nss));
for (i = 0; i < IEEE80211_VHT_NUM_RATESETS; i++) {
rs = &ieee80211_std_ratesets_11ac[i];
+ if (rs->chan80 == 0 ||
+ rs->sgi != ieee80211_ra_vht_use_sgi(ni))
+ continue;
for (j = 0; j < IEEE80211_VHT_RATESET_MAX_NRATES; j++) {
struct ieee80211_ra_vht_goodput_stats *g;
g = &rn->g[i][j];
if ((rn->valid_rates[rs->num_ss - 1] &
- (1 << i)) == 0)
+ (1 << j)) == 0)
continue;
- DPRINTF((" %d,%d{%s|", i, j,
+ DPRINTF((" %d,%d{%s|", j, rs->num_ss,
ra_vht_fp_sprintf(g->measured)));
DPRINTF(("%s|", ra_vht_fp_sprintf(g->average)));
DPRINTF(("%s%%}", ra_vht_fp_sprintf(g->loss)));
@@ -520,7 +522,8 @@ ieee80211_ra_vht_best_rate(struct ieee80211_ra_vht_node *rn,
DPRINTF(("\n"));
}
#endif
- return best_mcs;
+ rn->best_mcs = best_mcs;
+ rn->best_nss = best_nss;
}
void
@@ -671,7 +674,7 @@ ieee80211_ra_vht_choose(struct ieee80211_ra_vht_node *rn,
DPRINTFN(3, ("probing MCS,NSS %d,%d\n",
ni->ni_txmcs, ni->ni_vht_ss));
} else if (ieee80211_ra_vht_inter_mode_ra_finished(rn, ni)) {
- rn->best_mcs = ieee80211_ra_vht_best_rate(rn, ni);
+ ieee80211_ra_vht_best_rate(rn, ni);
ni->ni_txmcs = rn->best_mcs;
ni->ni_vht_ss = rn->best_nss;
ieee80211_ra_vht_probe_done(rn, nss);