[PATCH 2/2] wpa_supplicant: Enable VHT automatically based on driver capabilities in AP mode

Jose Blanquicet blanquicet at gmail.com
Thu Aug 25 06:30:39 PDT 2016


This patch aims to automatically enable 802.11ac (VHT) based on driver
capabilities when setting up an AP mode operation. It also allows to
prevent that using the disable_vht network parameter.

---
 wpa_supplicant/ap.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 112 insertions(+), 3 deletions(-)

diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index 2826c28..5693b0e 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -96,6 +96,82 @@ no_vht:
 }
 #endif /* CONFIG_IEEE80211N */
 
+#ifdef CONFIG_IEEE80211AC
+static void wpas_conf_ap_mode_vht_chwidth(struct hostapd_hw_modes *mode,
+									struct hostapd_config *conf)
+{
+	u8 central_channels[] = { 42, 58, 106, 122, 138, 155 };
+	u8 central_channel = 0;
+	int i;
+
+	switch (conf->vht_oper_chwidth) {
+	case VHT_CHANWIDTH_USE_HT:
+		break;
+	case VHT_CHANWIDTH_80P80MHZ:
+	case VHT_CHANWIDTH_160MHZ:
+		conf->vht_oper_chwidth = VHT_CHANWIDTH_USE_HT;
+		break;
+	case VHT_CHANWIDTH_80MHZ:
+		break;
+	default:
+		conf->vht_oper_chwidth = VHT_CHANWIDTH_80MHZ;
+		break;
+	}
+
+	/* TODO: Support 160MHz and 80+80MHz */
+	if (conf->vht_oper_chwidth != VHT_CHANWIDTH_80MHZ)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(central_channels); i++) {
+		if (conf->channel >= central_channels[i] - 6 &&
+				conf->channel <= central_channels[i] + 6) {
+			central_channel = central_channels[i];
+			break;
+		}
+	}
+	if (central_channel == 0)
+		goto no_vht_chwidth;
+
+	/* Check involved channels are available */
+	for (i = 0; i < 4; i++) {
+		int j;
+		struct hostapd_channel_data *chan = NULL;
+		u8 involved_chan = central_channel - 6 + i * 4;
+
+		/* Get channel information */
+		for (j = 0; j < mode->num_channels; j++) {
+			chan = &mode->channels[j];
+			if (chan->chan == involved_chan)
+				break;
+		}
+		if (j == mode->num_channels || !chan)
+			break;
+
+		if (chan->flag & (HOSTAPD_CHAN_DISABLED |
+					  HOSTAPD_CHAN_RADAR | HOSTAPD_CHAN_NO_IR))
+			break;
+
+		if (i == 0 && !(chan->flag & HOSTAPD_CHAN_VHT_10_70))
+			break;
+		if (i == 1 && !(chan->flag & HOSTAPD_CHAN_VHT_30_50))
+			break;
+		if (i == 2 && !(chan->flag & HOSTAPD_CHAN_VHT_50_30))
+			break;
+		if (i == 3 && !(chan->flag & HOSTAPD_CHAN_VHT_70_10))
+			break;
+	}
+	if (i != 4)
+		goto no_vht_chwidth;
+
+	conf->vht_oper_centr_freq_seg0_idx = central_channel;
+	conf->vht_oper_centr_freq_seg1_idx = 0;
+	return;
+
+no_vht_chwidth:
+	conf->vht_oper_chwidth = VHT_CHANWIDTH_USE_HT;
+}
+#endif /* CONFIG_IEEE80211AC */
+
 #ifdef CONFIG_IEEE80211N
 static int wpas_conf_ap_mode_ht_chwidth(struct hostapd_hw_modes *mode, u8 channel)
 {
@@ -233,9 +309,39 @@ int wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s,
 				 HT_CAP_INFO_TX_STBC |
 				 HT_CAP_INFO_MAX_AMSDU_SIZE);
 
-			if (mode->vht_capab && ssid->vht) {
-				conf->ieee80211ac = 1;
-				wpas_conf_ap_vht(wpa_s, conf, mode);
+			if (mode->vht_capab) {
+#ifdef CONFIG_IEEE80211AC
+				if (ssid->mode == WPAS_MODE_AP) {
+					/*
+					 * Enable VHT when AP mode operation if the driver
+					 * supports it unless it was specifically prevented.
+					 */
+					conf->ieee80211ac = 1;
+					conf->vht_capab |= mode->vht_capab &
+								(VHT_CAP_SHORT_GI_80 |
+								 VHT_CAP_MAX_MPDU_LENGTH_MASK |
+								 VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX);
+					wpas_conf_ap_mode_vht_chwidth(mode, conf);
+
+#ifdef CONFIG_VHT_OVERRIDES
+					if (ssid->disable_vht) {
+						conf->vht_oper_chwidth = VHT_CHANWIDTH_USE_HT;
+						conf->ieee80211ac = 0;
+						conf->vht_capab = 0;
+						ssid->vht = 0;
+					}
+#endif /* CONFIG_VHT_OVERRIDES */
+				}
+#endif /* CONFIG_IEEE80211AC */
+
+				/*
+				 * For non-AP use cases, ssid->vht was previously configured
+				 * according their own parameters, do not modify this behavior
+				 */
+				if (ssid->vht) {
+					conf->ieee80211ac = 1;
+					wpas_conf_ap_vht(wpa_s, conf, mode);
+				}
 			}
 		}
 	}
@@ -756,6 +862,9 @@ int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
 		return -1;
 	}
 
+	/* Set 80MHz as default channel width for AP-mode */
+	if (ssid->mode == WPAS_MODE_AP)
+		conf->vht_oper_chwidth = VHT_CHANWIDTH_80MHZ;
 	/* Use the maximum oper channel width if it's given. */
 	if (ssid->max_oper_chwidth)
 		conf->vht_oper_chwidth = ssid->max_oper_chwidth;
-- 
1.9.1




More information about the Hostap mailing list