The branch main has been updated by adrian: URL: https://cgit.FreeBSD.org/src/commit/?id=1c746222c2ef25d2caa7578217ce92b637a1ee3d
commit 1c746222c2ef25d2caa7578217ce92b637a1ee3d Author: Adrian Chadd <adr...@freebsd.org> AuthorDate: 2025-01-13 05:17:36 +0000 Commit: Adrian Chadd <adr...@freebsd.org> CommitDate: 2025-02-26 19:30:23 +0000 net80211: Implement ieee80211_setup_vht_rates() Implement ieee80211_setup_vht_rates() - calculate the intersection between the peers advertised RX VHT MCS map and the vap's configured TX map. Whilst here, remove the unused vhtcap/vhtinfo fields; they're already populated in the ieee80211_node before ieee80211_setup_vht_rates() is called. Differential Revision: https://reviews.freebsd.org/D48607 Reviewed by: bz --- sys/net80211/ieee80211_ddb.c | 4 +-- sys/net80211/ieee80211_node.c | 7 ++--- sys/net80211/ieee80211_node.h | 4 +-- sys/net80211/ieee80211_sta.c | 2 +- sys/net80211/ieee80211_vht.c | 61 +++++++++++++++++++++++++++++++++++++++---- sys/net80211/ieee80211_vht.h | 3 +-- 6 files changed, 64 insertions(+), 17 deletions(-) diff --git a/sys/net80211/ieee80211_ddb.c b/sys/net80211/ieee80211_ddb.c index 5dbb20dfe8e0..3c57b03ddc65 100644 --- a/sys/net80211/ieee80211_ddb.c +++ b/sys/net80211/ieee80211_ddb.c @@ -317,9 +317,9 @@ _db_show_sta(const struct ieee80211_node *ni) #endif /* VHT state */ - db_printf("\tvhtcap %b vht_basicmcs %#06x vht_pad2 %#06x\n", + db_printf("\tvhtcap %b vht_basicmcs %#06x vht_tx_map %#06x\n", ni->ni_vhtcap, IEEE80211_VHTCAP_BITS, - ni->ni_vht_basicmcs, ni->ni_vht_pad2); + ni->ni_vht_basicmcs, ni->ni_vht_tx_map); db_printf("\tvht_mcsinfo: { rx_mcs_map %#06x rx_highest %#06x " "tx_mcs_map %#06x tx_highest %#06x }\n", ni->ni_vht_mcsinfo.rx_mcs_map, ni->ni_vht_mcsinfo.rx_highest, diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c index c781280d5e8a..5a239bbd30f6 100644 --- a/sys/net80211/ieee80211_node.c +++ b/sys/net80211/ieee80211_node.c @@ -1044,8 +1044,7 @@ ieee80211_sta_join(struct ieee80211vap *vap, struct ieee80211_channel *chan, ieee80211_vht_updateparams(ni, ni->ni_ies.vhtcap_ie, ni->ni_ies.vhtopmode_ie); - ieee80211_setup_vht_rates(ni, ni->ni_ies.vhtcap_ie, - ni->ni_ies.vhtopmode_ie); + ieee80211_setup_vht_rates(ni); do_ht = 1; } } @@ -1874,9 +1873,7 @@ ieee80211_init_neighbor(struct ieee80211_node *ni, ieee80211_vht_updateparams(ni, ni->ni_ies.vhtcap_ie, ni->ni_ies.vhtopmode_ie); - ieee80211_setup_vht_rates(ni, - ni->ni_ies.vhtcap_ie, - ni->ni_ies.vhtopmode_ie); + ieee80211_setup_vht_rates(ni); } } diff --git a/sys/net80211/ieee80211_node.h b/sys/net80211/ieee80211_node.h index bb14c8c4bb42..969d8e563fa9 100644 --- a/sys/net80211/ieee80211_node.h +++ b/sys/net80211/ieee80211_node.h @@ -274,8 +274,8 @@ struct ieee80211_node { /* VHT state */ uint32_t ni_vhtcap; - uint16_t ni_vht_basicmcs; - uint16_t ni_vht_pad2; + uint16_t ni_vht_basicmcs; /* Basic VHT MCS bitmap from IE */ + uint16_t ni_vht_tx_map; /* Negotiated MCS TX map with peer */ struct ieee80211_vht_mcs_info ni_vht_mcsinfo; uint8_t ni_vht_chan1; /* 20/40/80/160 - VHT chan1 */ uint8_t ni_vht_chan2; /* 80+80 - VHT chan2 */ diff --git a/sys/net80211/ieee80211_sta.c b/sys/net80211/ieee80211_sta.c index 96603f339710..48d56d0ad217 100644 --- a/sys/net80211/ieee80211_sta.c +++ b/sys/net80211/ieee80211_sta.c @@ -1875,7 +1875,7 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype, } else { ieee80211_vht_node_init(ni); ieee80211_vht_updateparams(ni, vhtcap, vhtopmode); - ieee80211_setup_vht_rates(ni, vhtcap, vhtopmode); + ieee80211_setup_vht_rates(ni); } } diff --git a/sys/net80211/ieee80211_vht.c b/sys/net80211/ieee80211_vht.c index 82879f90c67b..e704e0cbd176 100644 --- a/sys/net80211/ieee80211_vht.c +++ b/sys/net80211/ieee80211_vht.c @@ -284,14 +284,65 @@ ieee80211_vht_updateparams(struct ieee80211_node *ni, return (0); } +/** + * @brief calculate the supported MCS rates for this node + * + * This is called once a node has finished association / + * joined a BSS. The vhtcap / vhtop IEs are from the + * peer. The transmit rate tables need to be combined + * together to setup the list of available rates. + * + * This must be called after the ieee80211_node VHT fields + * have been parsed / populated by either ieee80211_vht_updateparams() or + * ieee80211_parse_vhtcap(), + * + * This does not take into account the channel bandwidth, + * which (a) may change during operation, and (b) depends + * upon packet to packet rate transmission selection. + * There are various rate combinations which are not + * available in various channel widths and those will + * need to be masked off separately. + * + * (See 802.11-2020 21.5 Parameters for VHT-MCSs for the + * tables and supported rates.) + * + * ALSO: i need to do some filtering based on the HT set too. + * (That should be done here too, and in the negotiation, sigh.) + * (See 802.11-2016 10.7.12.3 Additional rate selection constraints + * for VHT PPDUs) + * + * @param ni struct ieee80211_node to configure + */ void -ieee80211_setup_vht_rates(struct ieee80211_node *ni, - const uint8_t *vhtcap_ie, - const uint8_t *vhtop_ie) +ieee80211_setup_vht_rates(struct ieee80211_node *ni) { + struct ieee80211vap *vap = ni->ni_vap; + uint32_t val, val1, val2; + uint16_t tx_mcs_map = 0; + int i; - //printf("%s: called\n", __func__); - /* XXX TODO */ + /* + * Merge our tx_mcs_map with the peer rx_mcs_map to determine what + * can be actually transmitted to the peer. + */ + + for (i = 0; i < 8; i++) { + /* + * Merge the two together; remember that 0..2 is in order + * of increasing MCS support, but 3 equals + * IEEE80211_VHT_MCS_NOT_SUPPORTED so must "win". + */ + val1 = (vap->iv_vht_cap.supp_mcs.tx_mcs_map >> (i*2)) & 0x3; + val2 = (ni->ni_vht_mcsinfo.rx_mcs_map >> (i*2)) & 0x3; + val = MIN(val1, val2); + if (val1 == IEEE80211_VHT_MCS_NOT_SUPPORTED || + val2 == IEEE80211_VHT_MCS_NOT_SUPPORTED) + val = IEEE80211_VHT_MCS_NOT_SUPPORTED; + tx_mcs_map |= (val << (i*2)); + } + + /* Store the TX MCS map somewhere in the node that can be used */ + ni->ni_vht_tx_map = tx_mcs_map; } void diff --git a/sys/net80211/ieee80211_vht.h b/sys/net80211/ieee80211_vht.h index bcb61020c5a1..a61804a43059 100644 --- a/sys/net80211/ieee80211_vht.h +++ b/sys/net80211/ieee80211_vht.h @@ -40,8 +40,7 @@ void ieee80211_parse_vhtcap(struct ieee80211_node *, const uint8_t *); int ieee80211_vht_updateparams(struct ieee80211_node *, const uint8_t *, const uint8_t *); -void ieee80211_setup_vht_rates(struct ieee80211_node *, - const uint8_t *, const uint8_t *); +void ieee80211_setup_vht_rates(struct ieee80211_node *); void ieee80211_vht_timeout(struct ieee80211vap *vap);