Some OEM ACPI MTGS tables fill unused geo power/offset slots with 0xff. Windows treats that as "no cap". Linux assigned the u8 value to s8 and min()'d it, clamping every rate to about -1 dBm (txpower_sku tmac = 3). Skip geo capping when pwr is 0xff, and do not apply offset when it is 0xff. Tested on ASUS Vivobook S 14 M5406WA (MT7922, mt7921e): - 5 GHz: tmac 3 -> 25, TX ~40 Mbps -> 200-350 Mbps (80 MHz) - 2.4 GHz: tmac 30 after the change (channel 6, 20 MHz) Fixes: f965333e491e ("mt76: mt7921: introduce ACPI SAR support") Signed-off-by: Huy Nguyen Dinh Quang --- drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.c b/drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.c index 946dd79..fa539cd 100644 --- a/drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.c +++ b/drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.c @@ -280,7 +280,15 @@ mt792x_asar_get_geo_pwr(struct mt792x_phy *phy, return dyn_power; geo_power = (band_pwr + idx)->pwr; - dyn_power += (band_pwr + idx)->offset; + /* + * ASUS (and some other OEM) ACPI MTGS tables fill unused geo + * slots with 0xFF. Windows treats that as "no cap". Linux took + * it as s8 -1 dBm and min()'d every rate down to ~3 dBm tmac. + */ + if ((u8)geo_power == 0xff) + return dyn_power; + if ((band_pwr + idx)->offset != 0xff) + dyn_power += (band_pwr + idx)->offset; return min(geo_power, dyn_power); } -- 2.55.0