Page MenuHomeFreeBSD

D48611.diff
No OneTemporary

D48611.diff

diff --git a/sys/net80211/ieee80211_amrr.h b/sys/net80211/ieee80211_amrr.h
--- a/sys/net80211/ieee80211_amrr.h
+++ b/sys/net80211/ieee80211_amrr.h
@@ -49,6 +49,10 @@
struct ieee80211_amrr *amn_amrr;/* backpointer */
int amn_rix; /* current rate index */
int amn_ticks; /* time of last update */
+ /* for VHT, since there's no VHT RIX right now */
+ int amn_vht_mcs;
+ int amn_vht_nss;
+
/* statistics */
u_int amn_txcnt;
u_int amn_success;
diff --git a/sys/net80211/ieee80211_amrr.c b/sys/net80211/ieee80211_amrr.c
--- a/sys/net80211/ieee80211_amrr.c
+++ b/sys/net80211/ieee80211_amrr.c
@@ -49,6 +49,7 @@
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_ht.h>
+#include <net80211/ieee80211_vht.h>
#include <net80211/ieee80211_amrr.h>
#include <net80211/ieee80211_ratectl.h>
@@ -138,6 +139,24 @@
nrefs--; /* XXX locking */
}
+static void
+amrr_node_init_vht(struct ieee80211_node *ni)
+{
+ struct ieee80211_amrr_node *amn = ni->ni_rctls;
+
+ /* Default to VHT NSS 1 MCS 2; should be reliable! */
+ amn->amn_vht_mcs = 2;
+ amn->amn_vht_nss = 1;
+ ieee80211_node_set_txrate_vht_rate(ni, amn->amn_vht_nss,
+ amn->amn_vht_mcs);
+ amn->amn_ticks = ticks;
+
+ IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
+ "AMRR: VHT: initial rate NSS %d MCS %d",
+ amn->amn_vht_nss,
+ amn->amn_vht_mcs);
+}
+
static void
amrr_node_init_ht(struct ieee80211_node *ni)
{
@@ -241,6 +260,8 @@
/* 11n or not? Pick the right rateset */
if (ieee80211_ht_check_tx_ht(ni))
+ amrr_node_init_vht(ni);
+ else if (ieee80211_ht_check_tx_ht(ni))
amrr_node_init_ht(ni);
else
amrr_node_init_legacy(ni);
@@ -252,6 +273,139 @@
IEEE80211_FREE(ni->ni_rctls, M_80211_RATECTL);
}
+static void
+amrr_update_vht_inc(struct ieee80211_node *ni)
+{
+ struct ieee80211_amrr_node *amn = ni->ni_rctls;
+ uint8_t nss, mcs;
+
+ /*
+ * For now just keep looping over MCS to 9,
+ * then NSS up, until we hit max. This at least
+ * tests the VHT MCS rates, but definitely is
+ * suboptimal (in the same way the 11n MCS selection
+ * is suboptimal.)
+ */
+ nss = amn->amn_vht_nss;
+ mcs = amn->amn_vht_mcs;
+
+ while (nss <= 8 && mcs <= 9) {
+ /* Increment MCS 0..9, NSS 1..8 */
+ if (mcs == 9) {
+ mcs = 0;
+ nss++;
+ } else
+ mcs++;
+ if (nss > 8)
+ break;
+
+ if (ieee80211_vht_node_check_valid_mcs(ni, ni->ni_chw, nss,
+ mcs)) {
+ amn->amn_vht_nss = nss;
+ amn->amn_vht_mcs = mcs;
+ break;
+ }
+ }
+}
+
+static void
+amrr_update_vht_dec(struct ieee80211_node *ni)
+{
+ struct ieee80211_amrr_node *amn = ni->ni_rctls;
+ uint8_t nss, mcs;
+
+ /*
+ * For now just keep looping over MCS 9 .. 0
+ * then NSS down, until we hit min. This at least
+ * tests the VHT MCS rates, but definitely is
+ * suboptimal (in the same way the 11n MCS selection
+ * is suboptimal.)
+ */
+ nss = amn->amn_vht_nss;
+ mcs = amn->amn_vht_mcs;
+
+ while (nss >= 1 && mcs >= 0) {
+
+ if (mcs == 0) {
+ mcs = 9;
+ nss--;
+ } else
+ mcs--;
+ if (nss < 1)
+ break;
+
+ if (ieee80211_vht_node_check_valid_mcs(ni, ni->ni_chw, nss,
+ mcs)) {
+ amn->amn_vht_nss = nss;
+ amn->amn_vht_mcs = mcs;
+ break;
+ }
+ }
+}
+
+/*
+ * A placeholder / temporary hack VHT rate control.
+ *
+ * Use the available MCS rates at the current node bandwidth
+ * and configured / negotiated MCS rates.
+ */
+static int
+amrr_update_vht(struct ieee80211_node *ni)
+{
+ struct ieee80211_amrr_node *amn = ni->ni_rctls;
+ struct ieee80211_amrr *amrr = ni->ni_vap->iv_rs;
+
+ IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
+ "AMRR: VHT: current rate NSS %d MCS %d, txcnt=%d, retrycnt=%d",
+ amn->amn_vht_nss,
+ amn->amn_vht_mcs,
+ amn->amn_txcnt,
+ amn->amn_retrycnt);
+
+ if (is_success(amn)) {
+ amn->amn_success++;
+ if (amn->amn_success >= amn->amn_success_threshold) {
+ amn->amn_recovery = 1;
+ amn->amn_success = 0;
+
+ IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
+ "AMRR: VHT: increase rate (txcnt=%d retrycnt=%d)",
+ amn->amn_txcnt, amn->amn_retrycnt);
+
+ amrr_update_vht_inc(ni);
+ } else {
+ amn->amn_recovery = 0;
+ }
+ } else if (is_failure(amn)) {
+ amn->amn_success = 0;
+
+ if (amn->amn_recovery) {
+ amn->amn_success_threshold *= 2;
+ if (amn->amn_success_threshold >
+ amrr->amrr_max_success_threshold)
+ amn->amn_success_threshold =
+ amrr->amrr_max_success_threshold;
+ } else {
+ amn->amn_success_threshold =
+ amrr->amrr_min_success_threshold;
+ }
+ IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
+ "AMRR: VHT: decreasing rate (txcnt=%d retrycnt=%d)",
+ amn->amn_txcnt, amn->amn_retrycnt);
+
+ amrr_update_vht_dec(ni);
+
+ amn->amn_recovery = 0;
+ }
+
+ /* reset counters */
+ amn->amn_txcnt = 0;
+ amn->amn_retrycnt = 0;
+
+ /* Return 0, not useful anymore */
+ return (0);
+}
+
static int
amrr_update_ht(struct ieee80211_amrr *amrr, struct ieee80211_amrr_node *amn,
struct ieee80211_node *ni)
@@ -385,7 +539,9 @@
KASSERT(is_enough(amn), ("txcnt %d", amn->amn_txcnt));
/* 11n or not? Pick the right rateset */
- if (ieee80211_ht_check_tx_ht(ni))
+ if (ieee80211_vht_check_tx_vht(ni))
+ rix = amrr_update_vht(ni);
+ else if (ieee80211_ht_check_tx_ht(ni))
rix = amrr_update_ht(amrr, amn, ni);
else
rix = amrr_update_legacy(amrr, amn, ni);
@@ -397,6 +553,23 @@
return (rix);
}
+static int
+amrr_rate_vht(struct ieee80211_node *ni)
+{
+ struct ieee80211_amrr *amrr = ni->ni_vap->iv_rs;
+ struct ieee80211_amrr_node *amn = ni->ni_rctls;
+
+ if (is_enough(amn) && (ticks - amn->amn_ticks) > amrr->amrr_interval) {
+ amrr_update_vht(ni);
+ }
+
+ ieee80211_node_set_txrate_vht_rate(ni, amn->amn_vht_nss,
+ amn->amn_vht_mcs);
+
+ /* There's no need for it anymore */
+ return (0);
+}
+
/*
* Return the rate index to use in sending a data frame.
* Update our internal state if it's been long enough.
@@ -418,6 +591,9 @@
return 0;
}
+ if (ieee80211_vht_check_tx_vht(ni))
+ return amrr_rate_vht(ni);
+
amrr = amn->amn_amrr;
/* 11n or not? Pick the right rateset */

File Metadata

Mime Type
text/plain
Expires
Fri, Jan 24, 2:54 AM (13 h, 27 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16072198
Default Alt Text
D48611.diff (5 KB)

Event Timeline