Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

wifi: cfg80211: Fix bitrate calculation overflow for HE rates

An integer overflow occurs in cfg80211_calculate_bitrate_he() when
calculating bitrates for high throughput HE configurations.
For example, with 160 MHz bandwidth, HE-MCS 13, HE-NSS 4, and HE-GI 0,
the multiplication (result * rate->nss) overflows the 32-bit 'result'
variable before division by 8, leading to significantly underestimated
bitrate values.

The overflow occurs because the NSS multiplication operates on a 32-bit
integer that cannot accommodate intermediate values exceeding
4,294,967,295. When overflow happens, the value wraps around, producing
incorrect bitrates for high MCS and NSS combinations.

Fix this by utilizing the 64-bit 'tmp' variable for the NSS
multiplication and subsequent divisions via do_div(). This approach
preserves full precision throughout the entire calculation, with the
final value assigned to 'result' only after completing all operations.

Signed-off-by: Veerendranath Jakkam <veerendranath.jakkam@oss.qualcomm.com>
Link: https://patch.msgid.link/20260109-he_bitrate_overflow-v1-1-95575e466b6e@oss.qualcomm.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>

authored by

Veerendranath Jakkam and committed by
Johannes Berg
a3034bf0 4f431d88

+5 -3
+5 -3
net/wireless/util.c
··· 1561 1561 tmp = result; 1562 1562 tmp *= SCALE; 1563 1563 do_div(tmp, mcs_divisors[rate->mcs]); 1564 - result = tmp; 1565 1564 1566 1565 /* and take NSS, DCM into account */ 1567 - result = (result * rate->nss) / 8; 1566 + tmp *= rate->nss; 1567 + do_div(tmp, 8); 1568 1568 if (rate->he_dcm) 1569 - result /= 2; 1569 + do_div(tmp, 2); 1570 + 1571 + result = tmp; 1570 1572 1571 1573 return result / 10000; 1572 1574 }