From nobody Wed Feb 26 19:31:48 2025 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4Z34NN6BFvz5nksX; Wed, 26 Feb 2025 19:31:48 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Z34NN2jk2z3dX5; Wed, 26 Feb 2025 19:31:48 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1740598308; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=1RDsHcHHa5AKxLQWBQFb6KrikAnl7TNPWPwkJQV7fvU=; b=lKU54+A0P1Oql7F1xOX4TKCTD4o9Q+OsIgu0D+EH+4I0qwCxsZ1AQiNJy3tnQz0NjNN76H Tr3L7T7TzfnGpJQPk/jpUz6iL11D8JUsNgcXktAlbl2GbOV7TZ1KXjzc8ogS/67Xe+HpF8 eyL4fH7NIos2QA8FIe0tpvycstb6HKnNwYlJwRnOqw5NyQRZiBrcW5cex1HOROoHPXwDBg Wuh2y8Ri2QX7KsJFQ21BPIOMHmPc7tVP212FNCy1vi0PO+8LZ3lN7n51q8+jcniwr0jb+Q P6mo8VDwAgbD/XpHRu6ETyl/QA6cAuavSZjerl+gRPx3VTm5pOmX9X5T7XyFCQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1740598308; a=rsa-sha256; cv=none; b=LMqHVWa5vFBd1QJIPv5Q5057cLruNbcfbZC4uZkgKpGBI7H6IwzAZaUZGfsItfjrHtuvIM LzzH8YlVmiJNKatuVelu9QPw2rzFsESkzdg19rkFxhK3Q5XvKG7Cv3SpZWJes/L52XOszX M/a6NceKO5WgMz8085oH2nHFWV+FesMPJmNUKMT4JvY7qulEe3KRxvTPP2gN631e9Vl6TQ 1JWF0Mn1//lf28zgTzgGWedmmLLvGXtKWN7CczbWfh79v7ZMbN/G+1bSkC/3lVkwmxo1I/ beepQVhqKOWUYRpzIqW8yhLarYLqN23KjXV1bj82BrbFPML/HcFSOeYYRN4ePA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1740598308; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=1RDsHcHHa5AKxLQWBQFb6KrikAnl7TNPWPwkJQV7fvU=; b=ZOlUOqhgIrLnkhh9l0e1iBJGNbbi8vljJpIvzD4KiKCFBwsrrHSrxRuhparYNeK58TISTz vLUwUGwpKAj7Xkti7hT6v6YzpNHE3+RujXuWv/4Ad3B5pysX1EBkwz/ZeFlkCnU7IrRGAV h0JodppwZ6iRvXAC4ZXx/B9AMRJUrb0ALCdMLOjPIanYs2gnYBiotGtY1YgwfgrBUzgaAF 6puIWraUUF1MMejpx5DDyuNG8pNYbsqgreRF7Z4NBvgXMYetGT+nQ1jDuX8pJFJauZTpQO 0SX/KIsalSUIebEwn0NlAyn9miuFxDAMJGJTGCdQ4SdZHsI9Sl7My528vIhb/A== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4Z34NN2HZpz1Pm0; Wed, 26 Feb 2025 19:31:48 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 51QJVmbD018854; Wed, 26 Feb 2025 19:31:48 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 51QJVmsf018851; Wed, 26 Feb 2025 19:31:48 GMT (envelope-from git) Date: Wed, 26 Feb 2025 19:31:48 GMT Message-Id: <202502261931.51QJVmsf018851@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Adrian Chadd Subject: git: 4b2c7dfe768d - main - net80211: add VHT MCS in AMRR rate control List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: adrian X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 4b2c7dfe768d341336f58db3cced9b097e1a6d2d Auto-Submitted: auto-generated The branch main has been updated by adrian: URL: https://cgit.FreeBSD.org/src/commit/?id=4b2c7dfe768d341336f58db3cced9b097e1a6d2d commit 4b2c7dfe768d341336f58db3cced9b097e1a6d2d Author: Adrian Chadd AuthorDate: 2025-01-13 17:05:31 +0000 Commit: Adrian Chadd CommitDate: 2025-02-26 19:31:24 +0000 net80211: add VHT MCS in AMRR rate control This is a simple implementation, similar to HT, to generate VHT MCS rates for testing. I've verified it seems to do the right thing through MCS 0..9 and NSS 1..2. It's not very optimal - same issues as with 11n - but it at least now fully tests the 11ac TX path in rtwn and the tx rate refactoring. Differential Revision: https://reviews.freebsd.org/D48611 --- sys/net80211/ieee80211_amrr.c | 183 ++++++++++++++++++++++++++++++++++++++++-- sys/net80211/ieee80211_amrr.h | 4 + 2 files changed, 181 insertions(+), 6 deletions(-) diff --git a/sys/net80211/ieee80211_amrr.c b/sys/net80211/ieee80211_amrr.c index 352f8df3a03e..1a06303bd2c9 100644 --- a/sys/net80211/ieee80211_amrr.c +++ b/sys/net80211/ieee80211_amrr.c @@ -49,6 +49,7 @@ #include #include +#include #include #include @@ -138,6 +139,23 @@ amrr_deinit(struct ieee80211vap *vap) 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); + + 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) { @@ -237,8 +255,10 @@ amrr_node_init(struct ieee80211_node *ni) amn->amn_success_threshold = amrr->amrr_min_success_threshold; amn->amn_ticks = ticks; - /* 11n or not? Pick the right rateset */ - if (ieee80211_ht_check_tx_ht(ni)) + /* Pick the right rateset */ + if (ieee80211_vht_check_tx_vht(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); @@ -250,6 +270,137 @@ amrr_node_deinit(struct ieee80211_node *ni) 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, checking if + * it's valid via ieee80211_vht_node_check_tx_valid_mcs(), + * 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_tx_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, checking if + * it's valid via ieee80211_vht_node_check_tx_valid_mcs(), + * 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_tx_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) @@ -382,8 +533,10 @@ amrr_update(struct ieee80211_amrr *amrr, struct ieee80211_amrr_node *amn, KASSERT(is_enough(amn), ("txcnt %d", amn->amn_txcnt)); - /* 11n or not? Pick the right rateset */ - if (ieee80211_ht_check_tx_ht(ni)) + /* Pick the right rateset */ + 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); @@ -395,6 +548,22 @@ amrr_update(struct ieee80211_amrr *amrr, struct ieee80211_amrr_node *amn, 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); + + /* Note: There's no vht rs_rates, and the API doesn't use 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. @@ -416,9 +585,10 @@ amrr_rate(struct ieee80211_node *ni, void *arg __unused, uint32_t iarg __unused) return 0; } - amrr = amn->amn_amrr; + if (ieee80211_vht_check_tx_vht(ni)) + return (amrr_rate_vht(ni)); - /* 11n or not? Pick the right rateset */ + /* Pick the right rateset */ if (ieee80211_ht_check_tx_ht(ni)) { /* XXX ew */ rs = (struct ieee80211_rateset *) &ni->ni_htrates; @@ -426,6 +596,7 @@ amrr_rate(struct ieee80211_node *ni, void *arg __unused, uint32_t iarg __unused) rs = &ni->ni_rates; } + amrr = amn->amn_amrr; if (is_enough(amn) && (ticks - amn->amn_ticks) > amrr->amrr_interval) { rix = amrr_update(amrr, amn, ni); if (rix != amn->amn_rix) { diff --git a/sys/net80211/ieee80211_amrr.h b/sys/net80211/ieee80211_amrr.h index 795cbf673e56..49d62953e625 100644 --- a/sys/net80211/ieee80211_amrr.h +++ b/sys/net80211/ieee80211_amrr.h @@ -49,6 +49,10 @@ struct ieee80211_amrr_node { 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;