From d7713b5ca78966dd7ea6a3bdd35511503dc59537 Mon Sep 17 00:00:00 2001 From: Ramya Gnanasekar Date: Thu, 14 Apr 2022 12:14:03 +0530 Subject: [PATCH] mesh: add EHT support Add mesh_eht_enabled and eht ssid config to include EHT capability and EHT operation IEs in mesh PLINK action frames. Update mesh_eht_enabled from EHT capability advertised for mesh mode. Support for mesh channelization in 320MHz. Signed-off-by: Ramya Gnanasekar Signed-off-by: Sathishkumar Muruganandam --- Index: b/wpa_supplicant/ap.c =================================================================== --- a/wpa_supplicant/ap.c 2022-07-08 10:12:42.614954957 +0530 +++ b/wpa_supplicant/ap.c 2022-07-08 10:12:42.586955263 +0530 @@ -324,6 +324,14 @@ int wpa_supplicant_conf_ap_ht(struct wpa if (mode && is_6ghz_freq(ssid->frequency) && conf->hw_mode == HOSTAPD_MODE_IEEE80211A) { + if (mode->eht_capab[wpas_mode_to_ieee80211_mode( + ssid->mode)].eht_supported && + ssid->eht) + conf->ieee80211be = 1; + if (mode->he_capab[wpas_mode_to_ieee80211_mode( + ssid->mode)].he_supported && + ssid->he) + conf->ieee80211ax = 1; #ifdef CONFIG_P2P wpas_conf_ap_he_6ghz(wpa_s, mode, ssid, conf); #endif /* CONFIG_P2P */ @@ -407,6 +415,10 @@ int wpa_supplicant_conf_ap_ht(struct wpa ssid->mode)].he_supported && ssid->he) conf->ieee80211ax = 1; + if (mode->eht_capab[wpas_mode_to_ieee80211_mode( + ssid->mode)].eht_supported && + ssid->eht) + conf->ieee80211be = 1; if (mode->vht_capab && ssid->vht) { conf->ieee80211ac = 1; Index: b/wpa_supplicant/config.c =================================================================== --- a/wpa_supplicant/config.c 2022-07-08 10:12:42.614954957 +0530 +++ b/wpa_supplicant/config.c 2022-07-08 10:12:42.586955263 +0530 @@ -2812,6 +2812,7 @@ static const struct parse_data ssid_fiel { INT_RANGE(disable_40mhz_scan, 0, 1)}, { INT_RANGE(beacon_tx_mode, 1, 2)}, { INT_RANGE(enable_160mhz_bw, 0, 1)}, + { INT_RANGE(enable_320mhz_bw, 0, 1)}, }; #undef OFFSET Index: b/wpa_supplicant/mesh.c =================================================================== --- a/wpa_supplicant/mesh.c 2022-07-08 10:12:42.614954957 +0530 +++ b/wpa_supplicant/mesh.c 2022-07-08 10:12:42.586955263 +0530 @@ -227,7 +227,7 @@ static int wpas_mesh_update_freq_params( ifmsh->conf->ieee80211n, ifmsh->conf->ieee80211ac, ifmsh->conf->ieee80211ax, - 0, + ifmsh->conf->ieee80211be, ifmsh->conf->secondary_channel, hostapd_get_oper_chwidth(ifmsh->conf), hostapd_get_oper_centr_freq_seg0_idx(ifmsh->conf), @@ -468,6 +468,9 @@ static int wpa_supplicant_mesh_init(stru case 160: conf->op_class = 134; break; + case 320: + conf->op_class = 137; + break; default: conf->op_class = 131; break; @@ -659,6 +662,7 @@ int wpa_supplicant_join_mesh(struct wpa_ wpa_s->mesh_ht_enabled = !!params->freq.ht_enabled; wpa_s->mesh_vht_enabled = !!params->freq.vht_enabled; wpa_s->mesh_he_enabled = !!params->freq.he_enabled; + wpa_s->mesh_eht_enabled = !!params->freq.eht_enabled; if (params->freq.ht_enabled && params->freq.sec_channel_offset) ssid->ht40 = params->freq.sec_channel_offset; @@ -678,6 +682,9 @@ int wpa_supplicant_join_mesh(struct wpa_ case 160: ssid->max_oper_chwidth = CHANWIDTH_160MHZ; break; + case 320: + ssid->max_oper_chwidth = CHANWIDTH_320MHZ; + break; default: ssid->max_oper_chwidth = CHANWIDTH_USE_HT; break; @@ -685,6 +692,8 @@ int wpa_supplicant_join_mesh(struct wpa_ } if (wpa_s->mesh_he_enabled) ssid->he = 1; + if (wpa_s->mesh_eht_enabled) + ssid->eht = 1; if (ssid->beacon_int > 0) params->beacon_int = ssid->beacon_int; else if (wpa_s->conf->beacon_int > 0) Index: b/wpa_supplicant/mesh_mpm.c =================================================================== --- a/wpa_supplicant/mesh_mpm.c 2022-07-08 10:12:42.614954957 +0530 +++ b/wpa_supplicant/mesh_mpm.c 2022-07-08 10:12:42.586955263 +0530 @@ -257,6 +257,16 @@ static void mesh_mpm_send_plink_action(s 3 + sizeof(struct ieee80211_he_6ghz_band_cap); } #endif /* CONFIG_IEEE80211AX */ +#ifdef CONFIG_IEEE80211BE + if (type != PLINK_CLOSE && wpa_s->mesh_eht_enabled) { + buf_len += 3 + + EHT_MAC_CAPAB_MAX_LEN + + EHT_PHY_CAPAB_MAX_LEN + + EHT_MCS_NSS_CAPAB_MAX_LEN + + EHT_PPE_THRESH_CAPAB_MAX_LEN; + buf_len += 3 + sizeof(struct ieee80211_eht_operation); + } +#endif /* CONFIG_IEEE80211BE */ if (type != PLINK_CLOSE) buf_len += conf->rsn_ie_len; /* RSN IE */ #ifdef CONFIG_OCV @@ -391,6 +401,20 @@ static void mesh_mpm_send_plink_action(s wpabuf_put_data(buf, he_capa_oper, pos - he_capa_oper); } #endif /* CONFIG_IEEE80211AX */ +#ifdef CONFIG_IEEE80211BE + if (type != PLINK_CLOSE && wpa_s->mesh_eht_enabled) { + u8 eht_capa_oper[3 + + EHT_MAC_CAPAB_MAX_LEN + + EHT_PHY_CAPAB_MAX_LEN + + EHT_MCS_NSS_CAPAB_MAX_LEN + + EHT_PPE_THRESH_CAPAB_MAX_LEN + + 3 + sizeof(struct ieee80211_eht_operation)]; + pos = hostapd_eid_eht_capab(bss, eht_capa_oper, + IEEE80211_MODE_MESH); + pos = hostapd_eid_eht_operation(bss, pos, IEEE80211_MODE_MESH); + wpabuf_put_data(buf, eht_capa_oper, pos - eht_capa_oper); + } +#endif /* CONFIG_IEEE80211BE */ #ifdef CONFIG_OCV if (type != PLINK_CLOSE && conf->ocv) { @@ -760,6 +784,11 @@ static struct sta_info * mesh_mpm_add_pe copy_sta_he_6ghz_capab(data, sta, elems->he_6ghz_band_cap); #endif /* CONFIG_IEEE80211AX */ +#ifdef CONFIG_IEEE80211BE + copy_sta_eht_capab(data, sta, IEEE80211_MODE_MESH, elems->he_capabilities, + elems->eht_capabilities, elems->eht_capabilities_len); +#endif /* CONFIG_IEEE80211BE */ + if (hostapd_get_aid(data, sta) < 0) { wpa_msg(wpa_s, MSG_ERROR, "No AIDs available"); ap_free_sta(data, sta); @@ -780,6 +809,8 @@ static struct sta_info * mesh_mpm_add_pe params.he_capab = sta->he_capab; params.he_capab_len = sta->he_capab_len; params.he_6ghz_capab = sta->he_6ghz_capab; + params.eht_capab = sta->eht_capab; + params.eht_capab_len = sta->eht_capab_len; params.flags |= WPA_STA_WMM; params.flags_mask |= WPA_STA_AUTHENTICATED; if (conf->security == MESH_CONF_SEC_NONE) { Index: b/wpa_supplicant/wpa_supplicant.c =================================================================== --- a/wpa_supplicant/wpa_supplicant.c 2022-07-08 10:12:42.614954957 +0530 +++ b/wpa_supplicant/wpa_supplicant.c 2022-07-08 10:14:31.153768442 +0530 @@ -2478,7 +2478,25 @@ static bool ibss_mesh_is_80mhz_avail(int return true; } +static int ibss_get_center_320mhz(int channel) +{ + int seg0; + + if (channel >= 1 && channel <= 45) + seg0 = 31; + else if (channel >= 49 && channel <= 77) + seg0 = 63; + else if (channel >= 81 && channel <= 109) + seg0 = 95; + else if (channel >= 113 && channel <= 141) + seg0 = 127; + else if (channel >= 145 && channel <= 173) + seg0 = 159; + else + seg0 = 191; + return seg0; +} void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s, const struct wpa_ssid *ssid, struct hostapd_freq_params *freq) @@ -2500,6 +2518,9 @@ void ibss_mesh_setup_freq(struct wpa_sup 6595, 6655, 6675, 6735, 6755, 6815, 6835, 6895, 6915, 6975, 6995, 7055 }; + unsigned int bw_320[] = { 5500, 5720, 5955, 6255, 6115, + 6415, 6275, 6575, 6435, 6735, + 6595, 6895, 6755, 7055}; struct hostapd_channel_data *pri_chan = NULL, *sec_chan = NULL; u8 channel, chan_80mhz; int i, chan_idx, ht40 = -1, res, obss_scan = 1; @@ -2736,8 +2757,9 @@ skip_to_6ghz: if (!vht_freq.vht_enabled && !is_6ghz) return; - /* Enable HE with VHT for 5 GHz */ + /* Enable HE, EHT with VHT for 5 GHz */ vht_freq.he_enabled = mode->he_capab[ieee80211_mode].he_supported; + vht_freq.eht_enabled = mode->eht_capab[ieee80211_mode].eht_supported; #ifdef CONFIG_HE_OVERRIDES if (is_24ghz) @@ -2801,6 +2823,19 @@ skip_to_6ghz: } } + if ((ssid->enable_320mhz_bw) && (mode->eht_capab[ieee80211_mode].phy_cap[EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_IDX] & + EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_MASK) && is_6ghz) { + + for (i = 0; i < ARRAY_SIZE(bw_320); i+=2) { + if (freq->freq >= bw_320[i] && + freq->freq <= bw_320[i+1]) + break; + } + + seg0 = ibss_get_center_320mhz(freq->channel); + chwidth = CHANWIDTH_320MHZ; + } + if (ssid->max_oper_chwidth == CHANWIDTH_80P80MHZ) { /* setup center_freq2, bandwidth */ for (k = 0; k < ARRAY_SIZE(bw_80_160); k++) { @@ -2870,9 +2905,10 @@ skip_to_6ghz: freq->channel, ssid->enable_edmg, ssid->edmg_channel, freq->ht_enabled, vht_freq.vht_enabled, vht_freq.he_enabled, - 0, freq->sec_channel_offset, + vht_freq.eht_enabled, freq->sec_channel_offset, chwidth, seg0, seg1, vht_caps, - &mode->he_capab[ieee80211_mode], NULL, + &mode->he_capab[ieee80211_mode], + &mode->eht_capab[ieee80211_mode], 0, freq->ru_punct_bitmap, freq->ru_punct_ofdma) != 0) return; Index: b/wpa_supplicant/wpa_supplicant_i.h =================================================================== --- a/wpa_supplicant/wpa_supplicant_i.h 2022-07-08 10:12:42.614954957 +0530 +++ b/wpa_supplicant/wpa_supplicant_i.h 2022-07-08 10:12:42.598955132 +0530 @@ -1033,6 +1033,7 @@ struct wpa_supplicant { unsigned int mesh_ht_enabled:1; unsigned int mesh_vht_enabled:1; unsigned int mesh_he_enabled:1; + unsigned int mesh_eht_enabled:1; struct wpa_driver_mesh_join_params *mesh_params; #ifdef CONFIG_PMKSA_CACHE_EXTERNAL /* struct external_pmksa_cache::list */ Index: b/hostapd/config_file.c =================================================================== --- a/hostapd/config_file.c 2022-07-08 10:12:42.614954957 +0530 +++ b/hostapd/config_file.c 2022-07-08 10:12:42.598955132 +0530 @@ -4266,6 +4266,8 @@ static int hostapd_config_fill(struct ho } else if (os_strcmp(buf, "wowlan_triggers") == 0) { os_free(bss->wowlan_triggers); bss->wowlan_triggers = os_strdup(pos); + } else if (os_strcmp(buf, "enable_320mhz_bw") == 0) { + conf->enable_320mhz_bw = atoi(pos); } else if (os_strcmp(buf, "enable_160mhz_bw") == 0) { conf->enable_160mhz_bw = atoi(pos); } else if (os_strcmp(buf, "disable_40mhz_scan") == 0) { Index: b/src/ap/ap_config.h =================================================================== --- a/src/ap/ap_config.h 2022-07-08 10:12:42.614954957 +0530 +++ b/src/ap/ap_config.h 2022-07-08 10:12:42.598955132 +0530 @@ -1152,6 +1152,7 @@ struct hostapd_config { u16 ru_punct_bitmap; u8 ru_punct_ofdma; u8 ru_punct_acs_threshold; + int enable_320mhz_bw; }; static inline u8 hostapd_get_he_6ghz_reg_pwr_type(struct hostapd_config *conf) Index: b/src/drivers/driver.h =================================================================== --- a/src/drivers/driver.h 2022-07-08 10:12:42.614954957 +0530 +++ b/src/drivers/driver.h 2022-07-08 10:12:42.598955132 +0530 @@ -1287,6 +1287,10 @@ struct wpa_driver_associate_params { * Enable 160MHz BW - set it 1 to enable mesh 160MHz 6G */ int enable_160mhz_bw; + /** + * Enable 320MHz BW - set it 1 to enable mesh 320MHz 6G + */ + int enable_320mhz_bw; }; enum hide_ssid { Index: b/wpa_supplicant/config_file.c =================================================================== --- a/wpa_supplicant/config_file.c 2022-07-08 10:12:42.614954957 +0530 +++ b/wpa_supplicant/config_file.c 2022-07-08 10:12:42.606955044 +0530 @@ -893,6 +893,7 @@ static void wpa_config_write_network(FIL INT(disable_40mhz_scan); INT(beacon_tx_mode); INT(enable_160mhz_bw); + INT(enable_320mhz_bw); #undef STR #undef INT #undef INT_DEF Index: b/wpa_supplicant/config_ssid.h =================================================================== --- a/wpa_supplicant/config_ssid.h 2022-07-08 10:12:42.614954957 +0530 +++ b/wpa_supplicant/config_ssid.h 2022-07-08 10:12:42.610955000 +0530 @@ -1223,6 +1223,10 @@ struct wpa_ssid { * Enable 160MHz BW - set it 1 to enable mesh 160MHz 6G */ int enable_160mhz_bw; + /** + * Enable 320MHz BW - set it 1 to enable mesh 320MHz 6G + */ + int enable_320mhz_bw; }; #endif /* CONFIG_SSID_H */ Index: b/src/drivers/driver_nl80211.c =================================================================== --- a/src/drivers/driver_nl80211.c 2022-07-08 10:12:42.614954957 +0530 +++ b/src/drivers/driver_nl80211.c 2022-07-08 10:12:42.610955000 +0530 @@ -5002,7 +5002,8 @@ static int nl80211_put_freq_params(struc is_24ghz = hw_mode == HOSTAPD_MODE_IEEE80211G || hw_mode == HOSTAPD_MODE_IEEE80211B; - if (freq->vht_enabled || (freq->he_enabled && !is_24ghz)) { + if (freq->vht_enabled || ((freq->he_enabled || freq->eht_enabled) && + !is_24ghz)) { enum nl80211_chan_width cw; wpa_printf(MSG_DEBUG, " * bandwidth=%d", freq->bandwidth);