diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c index f2edb4f06..d6aac3e0e 100644 --- a/wpa_supplicant/ap.c +++ b/wpa_supplicant/ap.c @@ -46,16 +46,33 @@ static void wpas_wps_ap_pin_timeout(void *eloop_data, void *user_ctx); #ifdef CONFIG_IEEE80211N static void wpas_conf_ap_vht(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid, struct hostapd_config *conf, struct hostapd_hw_modes *mode) { -#ifdef CONFIG_P2P u8 center_chan = 0; u8 channel = conf->channel; if (!conf->secondary_channel) goto no_vht; + /* Use the maximum oper channel width if it's given. */ + if (ssid->max_oper_chwidth) + conf->vht_oper_chwidth = ssid->max_oper_chwidth; + + ieee80211_freq_to_chan(ssid->vht_center_freq2, + &conf->vht_oper_centr_freq_seg1_idx); + + if (!ssid->p2p_group) { + if (!ssid->vht_center_freq1 || + conf->vht_oper_chwidth == VHT_CHANWIDTH_USE_HT) + goto no_vht; + ieee80211_freq_to_chan(ssid->vht_center_freq1, + &conf->vht_oper_centr_freq_seg0_idx); + return; + } + +#ifdef CONFIG_P2P switch (conf->vht_oper_chwidth) { case VHT_CHANWIDTH_80MHZ: case VHT_CHANWIDTH_80P80MHZ: @@ -84,14 +101,11 @@ static void wpas_conf_ap_vht(struct wpa_supplicant *wpa_s, conf->vht_oper_centr_freq_seg0_idx = center_chan; return; +#endif /* CONFIG_P2P */ no_vht: - conf->vht_oper_centr_freq_seg0_idx = - channel + conf->secondary_channel * 2; -#else /* CONFIG_P2P */ conf->vht_oper_centr_freq_seg0_idx = conf->channel + conf->secondary_channel * 2; -#endif /* CONFIG_P2P */ conf->vht_oper_chwidth = VHT_CHANWIDTH_USE_HT; } #endif /* CONFIG_IEEE80211N */ @@ -141,17 +155,24 @@ int wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s, if (!no_ht && mode && mode->ht_capab) { conf->ieee80211n = 1; #ifdef CONFIG_P2P - if (conf->hw_mode == HOSTAPD_MODE_IEEE80211A && + if (ssid->p2p_group && + conf->hw_mode == HOSTAPD_MODE_IEEE80211A && (mode->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) && ssid->ht40) conf->secondary_channel = wpas_p2p_get_ht40_mode(wpa_s, mode, conf->channel); +#endif /* CONFIG_P2P */ + + if (!ssid->p2p_group && + (mode->ht_capab & + HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) + conf->secondary_channel = ssid->ht40; + if (conf->secondary_channel) conf->ht_capab |= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET; -#endif /* CONFIG_P2P */ /* * white-list capabilities that won't cause issues @@ -169,7 +190,7 @@ int wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s, if (mode->vht_capab && ssid->vht) { conf->ieee80211ac = 1; conf->vht_capab |= mode->vht_capab; - wpas_conf_ap_vht(wpa_s, conf, mode); + wpas_conf_ap_vht(wpa_s, ssid, conf, mode); } } } @@ -693,13 +714,6 @@ int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s, return -1; } - /* Use the maximum oper channel width if it's given. */ - if (ssid->max_oper_chwidth) - conf->vht_oper_chwidth = ssid->max_oper_chwidth; - - ieee80211_freq_to_chan(ssid->vht_center_freq2, - &conf->vht_oper_centr_freq_seg1_idx); - os_memcpy(wpa_s->ap_iface->conf->wmm_ac_params, wpa_s->conf->wmm_ac_params, sizeof(wpa_s->conf->wmm_ac_params)); diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index e3ce6bc1d..95971ea99 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -1995,8 +1995,12 @@ static const struct parse_data ssid_fields[] = { { FUNC(auth_alg) }, { FUNC(scan_freq) }, { FUNC(freq_list) }, + { INT_RANGE(vht, 0, 1) }, + { INT_RANGE(ht40, -1, 1) }, { INT_RANGE(max_oper_chwidth, VHT_CHANWIDTH_USE_HT, VHT_CHANWIDTH_80P80MHZ) }, + { INT(vht_center_freq1) }, + { INT(vht_center_freq2) }, #ifdef IEEE8021X_EAPOL { FUNC(eap) }, { STR_LENe(identity) }, diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index 2b46fed4f..e5808612e 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -792,7 +792,11 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) INT(disabled); INT(peerkey); INT(mixed_cell); + INT(vht); + INT(ht40); INT(max_oper_chwidth); + INT(vht_center_freq1); + INT(vht_center_freq2); INT(pbss); INT(wps_disabled); #ifdef CONFIG_IEEE80211W diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h index 69ace3780..a2482d4d6 100644 --- a/wpa_supplicant/config_ssid.h +++ b/wpa_supplicant/config_ssid.h @@ -476,6 +476,7 @@ struct wpa_ssid { u8 max_oper_chwidth; + unsigned int vht_center_freq1; unsigned int vht_center_freq2; /** diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index 09050d0d0..8ef7f4673 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -1371,7 +1371,8 @@ static const char *network_fields[] = { "ssid", "scan_ssid", "bssid", "bssid_blacklist", "bssid_whitelist", "psk", "proto", "key_mgmt", "bg_scan_period", "pairwise", "group", "auth_alg", "scan_freq", - "freq_list", "max_oper_chwidth", + "freq_list", "max_oper_chwidth", "ht40", "vht", "vht_center_freq1", + "vht_center_freq2", #ifdef IEEE8021X_EAPOL "eap", "identity", "anonymous_identity", "password", "ca_cert", "ca_path", "client_cert", "private_key", "private_key_passwd",