Browse Source

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>
Johannes Berg 8 years ago
parent
commit
2124a615e3

+ 29 - 15
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));

+ 4 - 0
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) },

+ 4 - 0
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

+ 1 - 0
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;
 
 	/**

+ 2 - 1
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",