wpa_supplicant: Allow explicit wide channel configuration for AP mode

Instead of deducing the wide (HT, VHT) channel configuration only
automatically in P2P mode, allow it to be configured in the network
in non-P2P mode.

Also allow all of these parameters to be configured through the control
interface or the configuration file.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Johannes Berg 2017-03-07 18:20:57 +02:00 committed by Jouni Malinen
parent 57ee04dc7d
commit 2124a615e3
5 changed files with 40 additions and 16 deletions

View file

@ -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));

View file

@ -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) },

View file

@ -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

View file

@ -476,6 +476,7 @@ struct wpa_ssid {
u8 max_oper_chwidth;
unsigned int vht_center_freq1;
unsigned int vht_center_freq2;
/**

View file

@ -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",