The branch main has been updated by bz: URL: https://cgit.FreeBSD.org/src/commit/?id=654cffe59dd6c8818241bf44eff333af28e10168
commit 654cffe59dd6c8818241bf44eff333af28e10168 Author: Bjoern A. Zeeb <[email protected]> AuthorDate: 2026-08-29 01:56:55 +0000 Commit: Bjoern A. Zeeb <[email protected]> CommitDate: 2026-08-31 21:42:37 +0000 LinuxKPI: 802.11: implement cfg80211_calculate_bitrate() lkpi_cfg80211_calculate_bitrate_vht() was constantly showing up in my debug traces as a TODO with rtw89 so I went ahead and implemented the HT and VHT versions. Realtek seems to limit amsdu sizes based on the value and ask for it whether needed or not. Sponsored by: The FreeBSD Foundation MFC after: 3 days --- sys/compat/linuxkpi/common/src/linux_80211.c | 109 ++++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 4 deletions(-) diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c index f1eef91af0da..ae0c374e2ea6 100644 --- a/sys/compat/linuxkpi/common/src/linux_80211.c +++ b/sys/compat/linuxkpi/common/src/linux_80211.c @@ -8845,15 +8845,116 @@ linuxkpi_80211_wiphy_register(struct wiphy *wiphy) static uint32_t lkpi_cfg80211_calculate_bitrate_ht(struct rate_info *rate) { - TODO("cfg80211_calculate_bitrate_ht"); - return (rate->legacy); + /* + * IEEE Std 802.11-2024, 19.5 Parameters for HT-MCSs; + * Tables Table 19-27-MCS NSS=1 800ns GI, and following. + * We use 100Kbit/s entries, the expacted return scale. + * We can calulate MCS0..31 entries. + */ + uint32_t r; + uint8_t nss, mcsidx; + + if (rate->mcs > 31) + goto inval; + + switch (rate->bw) { + case RATE_INFO_BW_20: + r = 65; + break; + case RATE_INFO_BW_40: + r = 135; + break; + default: + goto inval; + /* NOTREACHED */ + } + + nss = (rate->mcs >> 3) + 1; + mcsidx = rate->mcs & 0x07; + + switch (mcsidx) { + case 0 ... 3: + r *= (mcsidx + 1); + break; + case 4: + r *= (mcsidx + 2); + break; + case 5 ... 7: + r *= (mcsidx + 3); + break; + default: + goto inval; + /* NOTREACHED */ + } + r *= nss; + if ((rate->flags & RATE_INFO_FLAGS_SHORT_GI) != 0) + r = (r * 10) / 9; + + return (r); + +inval: + /* Do not warn every time or we get too much spam on console! */ + WARN_ONCE(1, "%s: rate mcs %u nss %u mcsidx %u invalid!\n", __func__, + rate->mcs, nss, mcsidx); + return (0); } static uint32_t lkpi_cfg80211_calculate_bitrate_vht(struct rate_info *rate) { - TODO("cfg80211_calculate_bitrate_vht"); - return (rate->legacy); + /* + * IEEE Std 802.11-2024, 21.5 Parameters for VHT-MCSs; + * Tables 21-29 NSS=1 800ns GI, and following. + * We use 100Kbit/s entries, the expacted return scale. + */ + static const uint16_t datarate[4][10] = { + /* BW20 */ + { 65, 130, 195, 260, 390, 520, 585, 650, 780, 0 }, + /* BW40 */ + { 135, 270, 405, 540, 810, 1080, 1215, 1350, 1620, 1800 }, + /* BW80 */ + { 293, 585, 878, 1170, 1755, 2340, 2633, 2925, 3510, 3900 }, + /* BW160 */ + { 585, 1170, 1755, 2340, 3510, 4680, 5265, 5850, 7020, 7800 } + }; + uint32_t r; + uint8_t bwidx; + + /* Should we warn about out of bounds values? */ + if (rate->mcs > 9 || rate->nss > 8) + goto inval; + + switch (rate->bw) { + case RATE_INFO_BW_20: + bwidx = 0; + break; + case RATE_INFO_BW_40: + bwidx = 1; + break; + case RATE_INFO_BW_80: + bwidx = 2; + break; + case RATE_INFO_BW_160: + bwidx = 2; + break; + default: + goto inval; + /* NOTREACHED */ + } + + r = datarate[bwidx][rate->mcs]; + /* Calculate the other NSS tables and the SGI column. */ + r *= rate->nss; + if ((rate->flags & RATE_INFO_FLAGS_SHORT_GI) != 0) + r = (r * 10) / 9; + + return (r); + +inval: + /* Do not warn every time or we get too much spam on console! */ + WARN_ONCE(1, "%s: rate mcs %u nss %u bw %d (%s) invalid!\n", __func__, + rate->mcs, rate->nss, rate->bw, lkpi_rate_info_bw_to_str(rate->bw)); + return (0); } uint32_t
