aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorBenjamin Berg <benjamin.berg@intel.com>2025-08-26 20:26:01 +0300
committerJohannes Berg <johannes.berg@intel.com>2025-08-28 13:39:16 +0200
commit75575e2d252afb29fdbcbeec4d67e042007add52 (patch)
tree0c9bc6023982f9b203b9e92468de12fa2eb6b493
parentwifi: mac80211: increase scan_ies_len for S1G (diff)
downloadwireguard-linux-75575e2d252afb29fdbcbeec4d67e042007add52.tar.xz
wireguard-linux-75575e2d252afb29fdbcbeec4d67e042007add52.zip
wifi: mac80211: do not permit 40 MHz EHT operation on 5/6 GHz
The EHT PHY requirements state that 80 MHz must be supported on the 5 and 6 GHz bands unless the STA is 20 MHz only. So if the channel width is limited to 40 MHz on a band other than 2.4 GHz, then disable EHT and downgrade to HE. The primary case where this can happen is if the hardware disables puncturing using IEEE80211_HW_DISALLOW_PUNCTURING. Signed-off-by: Benjamin Berg <benjamin.berg@intel.com> Cc: stable@vger.kernel.org Reviewed-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> Link: https://patch.msgid.link/20250826202553.a6582f3abf57.Ic670429dc7127f68c818b4290d950ebfb5a0b9e1@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/mac80211/mlme.c8
-rw-r--r--net/mac80211/tests/chan-mode.c30
2 files changed, 33 insertions, 5 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 1008eb8e9b13..dd650a127a31 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1189,6 +1189,14 @@ again:
"required MCSes not supported, disabling EHT\n");
}
+ if (conn->mode >= IEEE80211_CONN_MODE_EHT &&
+ channel->band != NL80211_BAND_2GHZ &&
+ conn->bw_limit == IEEE80211_CONN_BW_LIMIT_40) {
+ conn->mode = IEEE80211_CONN_MODE_HE;
+ link_id_info(sdata, link_id,
+ "required bandwidth not supported, disabling EHT\n");
+ }
+
/* the mode can only decrease, so this must terminate */
if (ap_mode != conn->mode) {
kfree(elems);
diff --git a/net/mac80211/tests/chan-mode.c b/net/mac80211/tests/chan-mode.c
index 96c7b3ab2744..adc069065e73 100644
--- a/net/mac80211/tests/chan-mode.c
+++ b/net/mac80211/tests/chan-mode.c
@@ -2,7 +2,7 @@
/*
* KUnit tests for channel mode functions
*
- * Copyright (C) 2024 Intel Corporation
+ * Copyright (C) 2024-2025 Intel Corporation
*/
#include <net/cfg80211.h>
#include <kunit/test.h>
@@ -28,6 +28,10 @@ static const struct determine_chan_mode_case {
u8 vht_basic_mcs_1_4, vht_basic_mcs_5_8;
u8 he_basic_mcs_1_4, he_basic_mcs_5_8;
u8 eht_mcs7_min_nss;
+ u16 eht_disabled_subchannels;
+ u8 eht_bw;
+ enum ieee80211_conn_bw_limit conn_bw_limit;
+ enum ieee80211_conn_bw_limit expected_bw_limit;
int error;
} determine_chan_mode_cases[] = {
{
@@ -128,6 +132,14 @@ static const struct determine_chan_mode_case {
.conn_mode = IEEE80211_CONN_MODE_EHT,
.eht_mcs7_min_nss = 0x15,
.error = EINVAL,
+ }, {
+ .desc = "80 MHz EHT is downgraded to 40 MHz HE due to puncturing",
+ .conn_mode = IEEE80211_CONN_MODE_EHT,
+ .expected_mode = IEEE80211_CONN_MODE_HE,
+ .conn_bw_limit = IEEE80211_CONN_BW_LIMIT_80,
+ .expected_bw_limit = IEEE80211_CONN_BW_LIMIT_40,
+ .eht_disabled_subchannels = 0x08,
+ .eht_bw = IEEE80211_EHT_OPER_CHAN_WIDTH_80MHZ,
}
};
KUNIT_ARRAY_PARAM_DESC(determine_chan_mode, determine_chan_mode_cases, desc)
@@ -138,7 +150,7 @@ static void test_determine_chan_mode(struct kunit *test)
struct t_sdata *t_sdata = T_SDATA(test);
struct ieee80211_conn_settings conn = {
.mode = params->conn_mode,
- .bw_limit = IEEE80211_CONN_BW_LIMIT_20,
+ .bw_limit = params->conn_bw_limit,
};
struct cfg80211_bss cbss = {
.channel = &t_sdata->band_5ghz.channels[0],
@@ -191,14 +203,21 @@ static void test_determine_chan_mode(struct kunit *test)
0x7f, 0x01, 0x00, 0x88, 0x88, 0x88, 0x00, 0x00,
0x00,
/* EHT Operation */
- WLAN_EID_EXTENSION, 0x09, WLAN_EID_EXT_EHT_OPERATION,
- 0x01, params->eht_mcs7_min_nss ? params->eht_mcs7_min_nss : 0x11,
- 0x00, 0x00, 0x00, 0x00, 0x24, 0x00,
+ WLAN_EID_EXTENSION, 0x0b, WLAN_EID_EXT_EHT_OPERATION,
+ 0x03, params->eht_mcs7_min_nss ? params->eht_mcs7_min_nss : 0x11,
+ 0x00, 0x00, 0x00, params->eht_bw,
+ params->eht_bw == IEEE80211_EHT_OPER_CHAN_WIDTH_80MHZ ? 42 : 36,
+ 0x00,
+ u16_get_bits(params->eht_disabled_subchannels, 0xff),
+ u16_get_bits(params->eht_disabled_subchannels, 0xff00),
};
struct ieee80211_chan_req chanreq = {};
struct cfg80211_chan_def ap_chandef = {};
struct ieee802_11_elems *elems;
+ /* To force EHT downgrade to HE on punctured 80 MHz downgraded to 40 MHz */
+ set_bit(IEEE80211_HW_DISALLOW_PUNCTURING, t_sdata->local.hw.flags);
+
if (params->strict)
set_bit(IEEE80211_HW_STRICT, t_sdata->local.hw.flags);
else
@@ -237,6 +256,7 @@ static void test_determine_chan_mode(struct kunit *test)
} else {
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, elems);
KUNIT_ASSERT_EQ(test, conn.mode, params->expected_mode);
+ KUNIT_ASSERT_EQ(test, conn.bw_limit, params->expected_bw_limit);
}
}