@@ -149,6 +149,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
149149 const struct ieee80211_ht_operation * ht_oper ,
150150 const struct ieee80211_vht_operation * vht_oper ,
151151 const struct ieee80211_he_operation * he_oper ,
152+ const struct ieee80211_eht_operation * eht_oper ,
152153 const struct ieee80211_s1g_oper_ie * s1g_oper ,
153154 struct cfg80211_chan_def * chandef , bool tracking )
154155{
@@ -164,12 +165,14 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
164165 chandef -> freq1_offset = channel -> freq_offset ;
165166
166167 if (channel -> band == NL80211_BAND_6GHZ ) {
167- if (!ieee80211_chandef_he_6ghz_oper (sdata , he_oper , chandef )) {
168+ if (!ieee80211_chandef_he_6ghz_oper (sdata , he_oper , eht_oper ,
169+ chandef )) {
168170 mlme_dbg (sdata ,
169- "bad 6 GHz operation, disabling HT/VHT/HE\n" );
171+ "bad 6 GHz operation, disabling HT/VHT/HE/EHT \n" );
170172 ret = IEEE80211_STA_DISABLE_HT |
171173 IEEE80211_STA_DISABLE_VHT |
172- IEEE80211_STA_DISABLE_HE ;
174+ IEEE80211_STA_DISABLE_HE |
175+ IEEE80211_STA_DISABLE_EHT ;
173176 } else {
174177 ret = 0 ;
175178 }
@@ -196,7 +199,8 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
196199 mlme_dbg (sdata , "HT operation missing / HT not supported\n" );
197200 ret = IEEE80211_STA_DISABLE_HT |
198201 IEEE80211_STA_DISABLE_VHT |
199- IEEE80211_STA_DISABLE_HE ;
202+ IEEE80211_STA_DISABLE_HE |
203+ IEEE80211_STA_DISABLE_EHT ;
200204 goto out ;
201205 }
202206
@@ -219,7 +223,8 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
219223 ht_oper -> primary_chan , channel -> band );
220224 ret = IEEE80211_STA_DISABLE_HT |
221225 IEEE80211_STA_DISABLE_VHT |
222- IEEE80211_STA_DISABLE_HE ;
226+ IEEE80211_STA_DISABLE_HE |
227+ IEEE80211_STA_DISABLE_EHT ;
223228 goto out ;
224229 }
225230
@@ -260,7 +265,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
260265 if (!(ifmgd -> flags & IEEE80211_STA_DISABLE_HE ))
261266 sdata_info (sdata ,
262267 "HE AP VHT information is invalid, disabling HE\n" );
263- ret = IEEE80211_STA_DISABLE_HE ;
268+ ret = IEEE80211_STA_DISABLE_HE | IEEE80211_STA_DISABLE_EHT ;
264269 goto out ;
265270 }
266271 } else if (!ieee80211_chandef_vht_oper (& sdata -> local -> hw ,
@@ -340,7 +345,8 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
340345 if (WARN_ON (chandef -> width == NL80211_CHAN_WIDTH_20_NOHT )) {
341346 ret = IEEE80211_STA_DISABLE_HT |
342347 IEEE80211_STA_DISABLE_VHT |
343- IEEE80211_STA_DISABLE_HE ;
348+ IEEE80211_STA_DISABLE_HE |
349+ IEEE80211_STA_DISABLE_EHT ;
344350 break ;
345351 }
346352
@@ -349,7 +355,11 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
349355
350356 if (!he_oper || !cfg80211_chandef_usable (sdata -> wdev .wiphy , chandef ,
351357 IEEE80211_CHAN_NO_HE ))
352- ret |= IEEE80211_STA_DISABLE_HE ;
358+ ret |= IEEE80211_STA_DISABLE_HE | IEEE80211_STA_DISABLE_EHT ;
359+
360+ if (!eht_oper || !cfg80211_chandef_usable (sdata -> wdev .wiphy , chandef ,
361+ IEEE80211_CHAN_NO_EHT ))
362+ ret |= IEEE80211_STA_DISABLE_EHT ;
353363
354364 if (chandef -> width != vht_chandef .width && !tracking )
355365 sdata_info (sdata ,
@@ -366,6 +376,7 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
366376 const struct ieee80211_ht_operation * ht_oper ,
367377 const struct ieee80211_vht_operation * vht_oper ,
368378 const struct ieee80211_he_operation * he_oper ,
379+ const struct ieee80211_eht_operation * eht_oper ,
369380 const struct ieee80211_s1g_oper_ie * s1g_oper ,
370381 const u8 * bssid , u32 * changed )
371382{
@@ -391,9 +402,16 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
391402 /* don't check HE if we associated as non-HE station */
392403 if (ifmgd -> flags & IEEE80211_STA_DISABLE_HE ||
393404 !ieee80211_get_he_iftype_cap (sband ,
394- ieee80211_vif_type_p2p (& sdata -> vif )))
395-
405+ ieee80211_vif_type_p2p (& sdata -> vif ))) {
396406 he_oper = NULL ;
407+ eht_oper = NULL ;
408+ }
409+
410+ /* don't check EHT if we associated as non-EHT station */
411+ if (ifmgd -> flags & IEEE80211_STA_DISABLE_EHT ||
412+ !ieee80211_get_eht_iftype_cap (sband ,
413+ ieee80211_vif_type_p2p (& sdata -> vif )))
414+ eht_oper = NULL ;
397415
398416 if (WARN_ON_ONCE (!sta ))
399417 return - EINVAL ;
@@ -413,7 +431,8 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
413431
414432 /* calculate new channel (type) based on HT/VHT/HE operation IEs */
415433 flags = ieee80211_determine_chantype (sdata , sband , chan , vht_cap_info ,
416- ht_oper , vht_oper , he_oper ,
434+ ht_oper , vht_oper ,
435+ he_oper , eht_oper ,
417436 s1g_oper , & chandef , true);
418437
419438 /*
@@ -447,9 +466,11 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
447466 if (flags != (ifmgd -> flags & (IEEE80211_STA_DISABLE_HT |
448467 IEEE80211_STA_DISABLE_VHT |
449468 IEEE80211_STA_DISABLE_HE |
469+ IEEE80211_STA_DISABLE_EHT |
450470 IEEE80211_STA_DISABLE_40MHZ |
451471 IEEE80211_STA_DISABLE_80P80MHZ |
452- IEEE80211_STA_DISABLE_160MHZ )) ||
472+ IEEE80211_STA_DISABLE_160MHZ |
473+ IEEE80211_STA_DISABLE_320MHZ )) ||
453474 !cfg80211_chandef_valid (& chandef )) {
454475 sdata_info (sdata ,
455476 "AP %pM changed caps/bw in a way we can't support (0x%x/0x%x) - disconnect\n" ,
@@ -990,13 +1011,14 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
9901011 & assoc_data -> ap_vht_cap );
9911012
9921013 /*
993- * If AP doesn't support HT, mark HE as disabled.
1014+ * If AP doesn't support HT, mark HE and EHT as disabled.
9941015 * If on the 5GHz band, make sure it supports VHT.
9951016 */
9961017 if (ifmgd -> flags & IEEE80211_STA_DISABLE_HT ||
9971018 (sband -> band == NL80211_BAND_5GHZ &&
9981019 ifmgd -> flags & IEEE80211_STA_DISABLE_VHT ))
999- ifmgd -> flags |= IEEE80211_STA_DISABLE_HE ;
1020+ ifmgd -> flags |= IEEE80211_STA_DISABLE_HE |
1021+ IEEE80211_STA_DISABLE_EHT ;
10001022
10011023 if (!(ifmgd -> flags & IEEE80211_STA_DISABLE_HE ))
10021024 ieee80211_add_he_ie (sdata , skb , sband );
@@ -4258,6 +4280,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
42584280 if (ieee80211_config_bw (sdata , sta , elems -> ht_cap_elem ,
42594281 elems -> vht_cap_elem , elems -> ht_operation ,
42604282 elems -> vht_operation , elems -> he_operation ,
4283+ elems -> eht_operation ,
42614284 elems -> s1g_oper , bssid , & changed )) {
42624285 mutex_unlock (& local -> sta_mtx );
42634286 sdata_info (sdata ,
@@ -5185,6 +5208,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
51855208 const struct ieee80211_ht_operation * ht_oper = NULL ;
51865209 const struct ieee80211_vht_operation * vht_oper = NULL ;
51875210 const struct ieee80211_he_operation * he_oper = NULL ;
5211+ const struct ieee80211_eht_operation * eht_oper = NULL ;
51885212 const struct ieee80211_s1g_oper_ie * s1g_oper = NULL ;
51895213 struct ieee80211_supported_band * sband ;
51905214 struct cfg80211_chan_def chandef ;
@@ -5215,22 +5239,31 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
52155239
52165240 /* disable HT/VHT/HE if we don't support them */
52175241 if (!sband -> ht_cap .ht_supported && !is_6ghz ) {
5218- mlme_dbg (sdata , "HT not supported, disabling HT/VHT/HE\n" );
5242+ mlme_dbg (sdata , "HT not supported, disabling HT/VHT/HE/EHT \n" );
52195243 ifmgd -> flags |= IEEE80211_STA_DISABLE_HT ;
52205244 ifmgd -> flags |= IEEE80211_STA_DISABLE_VHT ;
52215245 ifmgd -> flags |= IEEE80211_STA_DISABLE_HE ;
5246+ ifmgd -> flags |= IEEE80211_STA_DISABLE_EHT ;
52225247 }
52235248
52245249 if (!sband -> vht_cap .vht_supported && is_5ghz ) {
5225- mlme_dbg (sdata , "VHT not supported, disabling VHT/HE\n" );
5250+ mlme_dbg (sdata , "VHT not supported, disabling VHT/HE/EHT \n" );
52265251 ifmgd -> flags |= IEEE80211_STA_DISABLE_VHT ;
52275252 ifmgd -> flags |= IEEE80211_STA_DISABLE_HE ;
5253+ ifmgd -> flags |= IEEE80211_STA_DISABLE_EHT ;
52285254 }
52295255
52305256 if (!ieee80211_get_he_iftype_cap (sband ,
52315257 ieee80211_vif_type_p2p (& sdata -> vif ))) {
5232- mlme_dbg (sdata , "HE not supported, disabling it \n" );
5258+ mlme_dbg (sdata , "HE not supported, disabling HE and EHT \n" );
52335259 ifmgd -> flags |= IEEE80211_STA_DISABLE_HE ;
5260+ ifmgd -> flags |= IEEE80211_STA_DISABLE_EHT ;
5261+ }
5262+
5263+ if (!ieee80211_get_eht_iftype_cap (sband ,
5264+ ieee80211_vif_type_p2p (& sdata -> vif ))) {
5265+ mlme_dbg (sdata , "EHT not supported, disabling EHT\n" );
5266+ ifmgd -> flags |= IEEE80211_STA_DISABLE_EHT ;
52345267 }
52355268
52365269 if (!(ifmgd -> flags & IEEE80211_STA_DISABLE_HT ) && !is_6ghz ) {
@@ -5252,6 +5285,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
52525285 ifmgd -> flags |= IEEE80211_STA_DISABLE_HT ;
52535286 ifmgd -> flags |= IEEE80211_STA_DISABLE_VHT ;
52545287 ifmgd -> flags |= IEEE80211_STA_DISABLE_HE ;
5288+ ifmgd -> flags |= IEEE80211_STA_DISABLE_EHT ;
52555289 }
52565290
52575291 if (!elems -> vht_cap_elem ) {
@@ -5291,7 +5325,29 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
52915325
52925326 if (!ieee80211_verify_peer_he_mcs_support (sdata , ies , he_oper ) ||
52935327 !ieee80211_verify_sta_he_mcs_support (sdata , sband , he_oper ))
5294- ifmgd -> flags |= IEEE80211_STA_DISABLE_HE ;
5328+ ifmgd -> flags |= IEEE80211_STA_DISABLE_HE |
5329+ IEEE80211_STA_DISABLE_EHT ;
5330+ }
5331+
5332+ /*
5333+ * EHT requires HE to be supported as well. Specifically for 6 GHz
5334+ * channels, the operation channel information can only be deduced from
5335+ * both the 6 GHz operation information (from the HE operation IE) and
5336+ * EHT operation.
5337+ */
5338+ if (!(ifmgd -> flags & (IEEE80211_STA_DISABLE_HE |
5339+ IEEE80211_STA_DISABLE_EHT )) && he_oper ) {
5340+ const struct cfg80211_bss_ies * ies ;
5341+ const u8 * eht_oper_ie ;
5342+
5343+ ies = rcu_dereference (cbss -> ies );
5344+ eht_oper_ie = cfg80211_find_ext_ie (WLAN_EID_EXT_EHT_OPERATION ,
5345+ ies -> data , ies -> len );
5346+ if (eht_oper_ie && eht_oper_ie [1 ] >=
5347+ 1 + sizeof (struct ieee80211_eht_operation ))
5348+ eht_oper = (void * )(eht_oper_ie + 3 );
5349+ else
5350+ eht_oper = NULL ;
52955351 }
52965352
52975353 /* Allow VHT if at least one channel on the sband supports 80 MHz */
@@ -5320,7 +5376,8 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
53205376 ifmgd -> flags |= ieee80211_determine_chantype (sdata , sband ,
53215377 cbss -> channel ,
53225378 bss -> vht_cap_info ,
5323- ht_oper , vht_oper , he_oper ,
5379+ ht_oper , vht_oper ,
5380+ he_oper , eht_oper ,
53245381 s1g_oper ,
53255382 & chandef , false);
53265383
@@ -5811,18 +5868,20 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
58115868 ifmgd -> flags |= IEEE80211_STA_DISABLE_HT ;
58125869 ifmgd -> flags |= IEEE80211_STA_DISABLE_VHT ;
58135870 ifmgd -> flags |= IEEE80211_STA_DISABLE_HE ;
5871+ ifmgd -> flags |= IEEE80211_STA_DISABLE_EHT ;
58145872 netdev_info (sdata -> dev ,
58155873 "disabling HT/VHT/HE due to WEP/TKIP use\n" );
58165874 }
58175875 }
58185876
58195877 sband = local -> hw .wiphy -> bands [req -> bss -> channel -> band ];
58205878
5821- /* also disable HT/VHT/HE if the AP doesn't use WMM */
5879+ /* also disable HT/VHT/HE/EHT if the AP doesn't use WMM */
58225880 if (!bss -> wmm_used ) {
58235881 ifmgd -> flags |= IEEE80211_STA_DISABLE_HT ;
58245882 ifmgd -> flags |= IEEE80211_STA_DISABLE_VHT ;
58255883 ifmgd -> flags |= IEEE80211_STA_DISABLE_HE ;
5884+ ifmgd -> flags |= IEEE80211_STA_DISABLE_EHT ;
58265885 netdev_info (sdata -> dev ,
58275886 "disabling HT/VHT/HE as WMM/QoS is not supported by the AP\n" );
58285887 }
@@ -5876,9 +5935,11 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
58765935 memcpy (& assoc_data -> ap_vht_cap , vht_elem -> data ,
58775936 sizeof (struct ieee80211_vht_cap ));
58785937 } else if (is_5ghz ) {
5879- sdata_info (sdata , "VHT capa missing/short, disabling VHT/HE\n" );
5938+ sdata_info (sdata ,
5939+ "VHT capa missing/short, disabling VHT/HE/EHT\n" );
58805940 ifmgd -> flags |= IEEE80211_STA_DISABLE_VHT |
5881- IEEE80211_STA_DISABLE_HE ;
5941+ IEEE80211_STA_DISABLE_HE |
5942+ IEEE80211_STA_DISABLE_EHT ;
58825943 }
58835944 rcu_read_unlock ();
58845945
@@ -5957,6 +6018,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
59576018 ifmgd -> flags |= IEEE80211_STA_DISABLE_HT ;
59586019 ifmgd -> flags |= IEEE80211_STA_DISABLE_VHT ;
59596020 ifmgd -> flags |= IEEE80211_STA_DISABLE_HE ;
6021+ ifmgd -> flags |= IEEE80211_STA_DISABLE_EHT ;
59606022 }
59616023
59626024 if (req -> flags & ASSOC_REQ_DISABLE_VHT ) {
@@ -5965,8 +6027,9 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
59656027 }
59666028
59676029 if (req -> flags & ASSOC_REQ_DISABLE_HE ) {
5968- mlme_dbg (sdata , "HE disabled by flag, disabling VHT \n" );
6030+ mlme_dbg (sdata , "HE disabled by flag, disabling HE/EHT \n" );
59696031 ifmgd -> flags |= IEEE80211_STA_DISABLE_HE ;
6032+ ifmgd -> flags |= IEEE80211_STA_DISABLE_EHT ;
59706033 }
59716034
59726035 err = ieee80211_prep_connection (sdata , req -> bss , true, override );
0 commit comments