Skip to content

Commit 2f2a09e

Browse files
benzeagregkh
authored andcommitted
wifi: mac80211: do not permit 40 MHz EHT operation on 5/6 GHz
commit 75575e2 upstream. 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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 6167d72 commit 2f2a09e

File tree

2 files changed

+33
-5
lines changed

2 files changed

+33
-5
lines changed

net/mac80211/mlme.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1193,6 +1193,14 @@ ieee80211_determine_chan_mode(struct ieee80211_sub_if_data *sdata,
11931193
"required MCSes not supported, disabling EHT\n");
11941194
}
11951195

1196+
if (conn->mode >= IEEE80211_CONN_MODE_EHT &&
1197+
channel->band != NL80211_BAND_2GHZ &&
1198+
conn->bw_limit == IEEE80211_CONN_BW_LIMIT_40) {
1199+
conn->mode = IEEE80211_CONN_MODE_HE;
1200+
link_id_info(sdata, link_id,
1201+
"required bandwidth not supported, disabling EHT\n");
1202+
}
1203+
11961204
/* the mode can only decrease, so this must terminate */
11971205
if (ap_mode != conn->mode) {
11981206
kfree(elems);

net/mac80211/tests/chan-mode.c

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/*
33
* KUnit tests for channel mode functions
44
*
5-
* Copyright (C) 2024 Intel Corporation
5+
* Copyright (C) 2024-2025 Intel Corporation
66
*/
77
#include <net/cfg80211.h>
88
#include <kunit/test.h>
@@ -28,6 +28,10 @@ static const struct determine_chan_mode_case {
2828
u8 vht_basic_mcs_1_4, vht_basic_mcs_5_8;
2929
u8 he_basic_mcs_1_4, he_basic_mcs_5_8;
3030
u8 eht_mcs7_min_nss;
31+
u16 eht_disabled_subchannels;
32+
u8 eht_bw;
33+
enum ieee80211_conn_bw_limit conn_bw_limit;
34+
enum ieee80211_conn_bw_limit expected_bw_limit;
3135
int error;
3236
} determine_chan_mode_cases[] = {
3337
{
@@ -128,6 +132,14 @@ static const struct determine_chan_mode_case {
128132
.conn_mode = IEEE80211_CONN_MODE_EHT,
129133
.eht_mcs7_min_nss = 0x15,
130134
.error = EINVAL,
135+
}, {
136+
.desc = "80 MHz EHT is downgraded to 40 MHz HE due to puncturing",
137+
.conn_mode = IEEE80211_CONN_MODE_EHT,
138+
.expected_mode = IEEE80211_CONN_MODE_HE,
139+
.conn_bw_limit = IEEE80211_CONN_BW_LIMIT_80,
140+
.expected_bw_limit = IEEE80211_CONN_BW_LIMIT_40,
141+
.eht_disabled_subchannels = 0x08,
142+
.eht_bw = IEEE80211_EHT_OPER_CHAN_WIDTH_80MHZ,
131143
}
132144
};
133145
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)
138150
struct t_sdata *t_sdata = T_SDATA(test);
139151
struct ieee80211_conn_settings conn = {
140152
.mode = params->conn_mode,
141-
.bw_limit = IEEE80211_CONN_BW_LIMIT_20,
153+
.bw_limit = params->conn_bw_limit,
142154
};
143155
struct cfg80211_bss cbss = {
144156
.channel = &t_sdata->band_5ghz.channels[0],
@@ -191,14 +203,21 @@ static void test_determine_chan_mode(struct kunit *test)
191203
0x7f, 0x01, 0x00, 0x88, 0x88, 0x88, 0x00, 0x00,
192204
0x00,
193205
/* EHT Operation */
194-
WLAN_EID_EXTENSION, 0x09, WLAN_EID_EXT_EHT_OPERATION,
195-
0x01, params->eht_mcs7_min_nss ? params->eht_mcs7_min_nss : 0x11,
196-
0x00, 0x00, 0x00, 0x00, 0x24, 0x00,
206+
WLAN_EID_EXTENSION, 0x0b, WLAN_EID_EXT_EHT_OPERATION,
207+
0x03, params->eht_mcs7_min_nss ? params->eht_mcs7_min_nss : 0x11,
208+
0x00, 0x00, 0x00, params->eht_bw,
209+
params->eht_bw == IEEE80211_EHT_OPER_CHAN_WIDTH_80MHZ ? 42 : 36,
210+
0x00,
211+
u16_get_bits(params->eht_disabled_subchannels, 0xff),
212+
u16_get_bits(params->eht_disabled_subchannels, 0xff00),
197213
};
198214
struct ieee80211_chan_req chanreq = {};
199215
struct cfg80211_chan_def ap_chandef = {};
200216
struct ieee802_11_elems *elems;
201217

218+
/* To force EHT downgrade to HE on punctured 80 MHz downgraded to 40 MHz */
219+
set_bit(IEEE80211_HW_DISALLOW_PUNCTURING, t_sdata->local.hw.flags);
220+
202221
if (params->strict)
203222
set_bit(IEEE80211_HW_STRICT, t_sdata->local.hw.flags);
204223
else
@@ -237,6 +256,7 @@ static void test_determine_chan_mode(struct kunit *test)
237256
} else {
238257
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, elems);
239258
KUNIT_ASSERT_EQ(test, conn.mode, params->expected_mode);
259+
KUNIT_ASSERT_EQ(test, conn.bw_limit, params->expected_bw_limit);
240260
}
241261
}
242262

0 commit comments

Comments
 (0)