[PATCH] wpa_supplicant: support VHT capability overrides
Johannes Berg
johannes
Fri Mar 1 08:45:22 PST 2013
From: Johannes Berg <johannes.berg at intel.com>
Add support for VHT capability overrides to allow testing connections
with a subset of the VHT capabilities that are actually supported by
the device. The only thing that isn't currently supported (by mac80211
and this code) is the RX/TX highest rate field.
Signed-hostap: Johannes Berg <johannes.berg at intel.com>
---
src/drivers/driver.h | 13 +++++++++++
src/drivers/driver_nl80211.c | 28 +++++++++++++++++++++++
wpa_supplicant/Makefile | 4 ++++
wpa_supplicant/android.config | 3 +++
wpa_supplicant/config.c | 39 ++++++++++++++++++++++++++++++++
wpa_supplicant/config_ssid.h | 29 ++++++++++++++++++++++++
wpa_supplicant/defconfig | 3 +++
wpa_supplicant/sme.c | 11 +++++++++
wpa_supplicant/wpa_supplicant.c | 46 ++++++++++++++++++++++++++++++++++++++
wpa_supplicant/wpa_supplicant.conf | 14 ++++++++++++
wpa_supplicant/wpa_supplicant_i.h | 3 +++
11 files changed, 193 insertions(+)
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index bb373be..16795d3 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -568,6 +568,19 @@ struct wpa_driver_associate_params {
*/
const u8 *htcaps; /* struct ieee80211_ht_capabilities * */
const u8 *htcaps_mask; /* struct ieee80211_ht_capabilities * */
+
+#ifdef CONFIG_VHT_OVERRIDES
+ /**
+ * disable_vht - Disable VHT for this connection
+ */
+ int disable_vht;
+
+ /**
+ * VHT capability overrides.
+ */
+ const struct ieee80211_vht_capabilities *vhtcaps;
+ const struct ieee80211_vht_capabilities *vhtcaps_mask;
+#endif
};
enum hide_ssid {
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 191e1d6..3b253b4 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -7043,6 +7043,20 @@ skip_auth_type:
params->htcaps_mask);
}
+#ifdef CONFIG_VHT_OVERRIDES
+ if (params->disable_vht) {
+ wpa_printf(MSG_DEBUG, " * VHT disabled\n");
+ NLA_PUT_FLAG(msg, NL80211_ATTR_DISABLE_VHT);
+ }
+
+ if (params->vhtcaps && params->vhtcaps_mask) {
+ int sz = sizeof(struct ieee80211_vht_capabilities);
+ NLA_PUT(msg, NL80211_ATTR_VHT_CAPABILITY, sz, params->vhtcaps);
+ NLA_PUT(msg, NL80211_ATTR_VHT_CAPABILITY_MASK, sz,
+ params->vhtcaps_mask);
+ }
+#endif
+
ret = nl80211_set_conn_keys(params, msg);
if (ret)
goto nla_put_failure;
@@ -7229,6 +7243,20 @@ static int wpa_driver_nl80211_associate(
params->htcaps_mask);
}
+#ifdef CONFIG_VHT_OVERRIDES
+ if (params->disable_vht) {
+ wpa_printf(MSG_DEBUG, " * VHT disabled\n");
+ NLA_PUT_FLAG(msg, NL80211_ATTR_DISABLE_VHT);
+ }
+
+ if (params->vhtcaps && params->vhtcaps_mask) {
+ int sz = sizeof(struct ieee80211_vht_capabilities);
+ NLA_PUT(msg, NL80211_ATTR_VHT_CAPABILITY, sz, params->vhtcaps);
+ NLA_PUT(msg, NL80211_ATTR_VHT_CAPABILITY_MASK, sz,
+ params->vhtcaps_mask);
+ }
+#endif
+
if (params->p2p)
wpa_printf(MSG_DEBUG, " * P2P group");
diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
index da2abfc..0634219 100644
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -126,6 +126,10 @@ ifdef CONFIG_HT_OVERRIDES
CFLAGS += -DCONFIG_HT_OVERRIDES
endif
+ifdef CONFIG_VHT_OVERRIDES
+CFLAGS += -DCONFIG_VHT_OVERRIDES
+endif
+
ifndef CONFIG_BACKEND
CONFIG_BACKEND=file
endif
diff --git a/wpa_supplicant/android.config b/wpa_supplicant/android.config
index 43881fe..df5efe2 100644
--- a/wpa_supplicant/android.config
+++ b/wpa_supplicant/android.config
@@ -224,6 +224,9 @@ CONFIG_SMARTCARD=y
# Support HT overrides (disable HT/HT40, mask MCS rates, etc.)
#CONFIG_HT_OVERRIDES=y
+# Support VHT overrides (disable VHT, mask MCS rates, etc.)
+#CONFIG_VHT_OVERRIDES=y
+
# Development testing
#CONFIG_EAPOL_TEST=y
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index ee634a5..5da2d56 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -1543,6 +1543,27 @@ static const struct parse_data ssid_fields[] = {
{ INT_RANGE(ampdu_density, -1, 7) },
{ STR(ht_mcs) },
#endif /* CONFIG_HT_OVERRIDES */
+#ifdef CONFIG_VHT_OVERRIDES
+ { INT_RANGE(disable_vht, 0, 1) },
+ { INT(vht_capa) },
+ { INT(vht_capa_mask) },
+ { INT_RANGE(vht_rx_mcs_nss_1, -1, 3) },
+ { INT_RANGE(vht_rx_mcs_nss_2, -1, 3) },
+ { INT_RANGE(vht_rx_mcs_nss_3, -1, 3) },
+ { INT_RANGE(vht_rx_mcs_nss_4, -1, 3) },
+ { INT_RANGE(vht_rx_mcs_nss_5, -1, 3) },
+ { INT_RANGE(vht_rx_mcs_nss_6, -1, 3) },
+ { INT_RANGE(vht_rx_mcs_nss_7, -1, 3) },
+ { INT_RANGE(vht_rx_mcs_nss_8, -1, 3) },
+ { INT_RANGE(vht_tx_mcs_nss_1, -1, 3) },
+ { INT_RANGE(vht_tx_mcs_nss_2, -1, 3) },
+ { INT_RANGE(vht_tx_mcs_nss_3, -1, 3) },
+ { INT_RANGE(vht_tx_mcs_nss_4, -1, 3) },
+ { INT_RANGE(vht_tx_mcs_nss_5, -1, 3) },
+ { INT_RANGE(vht_tx_mcs_nss_6, -1, 3) },
+ { INT_RANGE(vht_tx_mcs_nss_7, -1, 3) },
+ { INT_RANGE(vht_tx_mcs_nss_8, -1, 3) },
+#endif /* CONFIG_VHT_OVERRIDES */
{ INT(ap_max_inactivity) },
{ INT(dtim_period) },
};
@@ -1945,6 +1966,24 @@ void wpa_config_set_network_defaults(struct wpa_ssid *ssid)
ssid->ampdu_factor = DEFAULT_AMPDU_FACTOR;
ssid->ampdu_density = DEFAULT_AMPDU_DENSITY;
#endif /* CONFIG_HT_OVERRIDES */
+#ifdef CONFIG_VHT_OVERRIDES
+ ssid->vht_rx_mcs_nss_1 = -1;
+ ssid->vht_rx_mcs_nss_2 = -1;
+ ssid->vht_rx_mcs_nss_3 = -1;
+ ssid->vht_rx_mcs_nss_4 = -1;
+ ssid->vht_rx_mcs_nss_5 = -1;
+ ssid->vht_rx_mcs_nss_6 = -1;
+ ssid->vht_rx_mcs_nss_7 = -1;
+ ssid->vht_rx_mcs_nss_8 = -1;
+ ssid->vht_tx_mcs_nss_1 = -1;
+ ssid->vht_tx_mcs_nss_2 = -1;
+ ssid->vht_tx_mcs_nss_3 = -1;
+ ssid->vht_tx_mcs_nss_4 = -1;
+ ssid->vht_tx_mcs_nss_5 = -1;
+ ssid->vht_tx_mcs_nss_6 = -1;
+ ssid->vht_tx_mcs_nss_7 = -1;
+ ssid->vht_tx_mcs_nss_8 = -1;
+#endif /* CONFIG_VHT_OVERRIDES */
ssid->proactive_key_caching = -1;
#ifdef CONFIG_IEEE80211W
ssid->ieee80211w = MGMT_FRAME_PROTECTION_DEFAULT;
diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
index 9ac67c7..e09139d 100644
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
@@ -534,6 +534,35 @@ struct wpa_ssid {
char *ht_mcs;
#endif /* CONFIG_HT_OVERRIDES */
+#ifdef CONFIG_VHT_OVERRIDES
+ /**
+ * disable_vht - Disable VHT (IEEE 802.11ac) for this network
+ *
+ * By default, use it if it is available, but this can be configured
+ * to 1 to have it disabled.
+ */
+ int disable_vht;
+
+ /**
+ * vht_capa - VHT capabilities to use
+ */
+ unsigned int vht_capa;
+
+ /**
+ * vht_capa_mask - mask for VHT capabilities
+ */
+ unsigned int vht_capa_mask;
+
+ int vht_rx_mcs_nss_1, vht_rx_mcs_nss_2,
+ vht_rx_mcs_nss_3, vht_rx_mcs_nss_4,
+ vht_rx_mcs_nss_5, vht_rx_mcs_nss_6,
+ vht_rx_mcs_nss_7, vht_rx_mcs_nss_8;
+ int vht_tx_mcs_nss_1, vht_tx_mcs_nss_2,
+ vht_tx_mcs_nss_3, vht_tx_mcs_nss_4,
+ vht_tx_mcs_nss_5, vht_tx_mcs_nss_6,
+ vht_tx_mcs_nss_7, vht_tx_mcs_nss_8;
+#endif /* CONFIG_VHT_OVERRIDES */
+
/**
* ap_max_inactivity - Timeout in seconds to detect STA's inactivity
*
diff --git a/wpa_supplicant/defconfig b/wpa_supplicant/defconfig
index 711b407..e867bae 100644
--- a/wpa_supplicant/defconfig
+++ b/wpa_supplicant/defconfig
@@ -225,6 +225,9 @@ CONFIG_SMARTCARD=y
# Support HT overrides (disable HT/HT40, mask MCS rates, etc.)
#CONFIG_HT_OVERRIDES=y
+# Support VHT overrides (disable VHT, mask MCS rates, etc.)
+#CONFIG_VHT_OVERRIDES=y
+
# Development testing
#CONFIG_EAPOL_TEST=y
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index 30f9779..92762ef 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -632,6 +632,10 @@ void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode,
struct ieee80211_ht_capabilities htcaps;
struct ieee80211_ht_capabilities htcaps_mask;
#endif /* CONFIG_HT_OVERRIDES */
+#ifdef CONFIG_VHT_OVERRIDES
+ struct ieee80211_vht_capabilities vhtcaps;
+ struct ieee80211_vht_capabilities vhtcaps_mask;
+#endif /* CONFIG_VHT_OVERRIDES */
os_memset(¶ms, 0, sizeof(params));
params.bssid = bssid;
@@ -653,6 +657,13 @@ void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode,
params.htcaps_mask = (u8 *) &htcaps_mask;
wpa_supplicant_apply_ht_overrides(wpa_s, wpa_s->current_ssid, ¶ms);
#endif /* CONFIG_HT_OVERRIDES */
+#ifdef CONFIG_VHT_OVERRIDES
+ os_memset(&vhtcaps, 0, sizeof(vhtcaps));
+ os_memset(&vhtcaps_mask, 0, sizeof(vhtcaps_mask));
+ params.vhtcaps = &vhtcaps;
+ params.vhtcaps_mask = &vhtcaps_mask;
+ wpa_supplicant_apply_vht_overrides(wpa_s, wpa_s->current_ssid, ¶ms);
+#endif /* CONFIG_VHT_OVERRIDES */
#ifdef CONFIG_IEEE80211R
if (auth_type == WLAN_AUTH_FT && wpa_s->sme.ft_ies) {
params.wpa_ie = wpa_s->sme.ft_ies;
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index fc23c8c..6695d66 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -2646,6 +2646,52 @@ void wpa_supplicant_apply_ht_overrides(
#endif /* CONFIG_HT_OVERRIDES */
+#ifdef CONFIG_VHT_OVERRIDES
+void wpa_supplicant_apply_vht_overrides(
+ struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
+ struct wpa_driver_associate_params *params)
+{
+ struct ieee80211_vht_capabilities *vhtcaps;
+ struct ieee80211_vht_capabilities *vhtcaps_mask;
+
+ if (!ssid)
+ return;
+
+ params->disable_vht = ssid->disable_vht;
+
+ vhtcaps = (void *)params->vhtcaps;
+ vhtcaps_mask = (void *)params->vhtcaps_mask;
+
+ if (!vhtcaps || !vhtcaps_mask)
+ return;
+
+ vhtcaps->vht_capabilities_info = ssid->vht_capa;
+ vhtcaps_mask->vht_capabilities_info = ssid->vht_capa_mask;
+
+#define OVERRIDE_MCS(i) \
+ if (ssid->vht_tx_mcs_nss_ ##i >= 0) { \
+ vhtcaps_mask->vht_supported_mcs_set.tx_map |= \
+ 3 << 2 * (i - 1); \
+ vhtcaps->vht_supported_mcs_set.tx_map |= \
+ ssid->vht_tx_mcs_nss_ ##i << 2 * (i - 1); \
+ } \
+ if (ssid->vht_rx_mcs_nss_ ##i >= 0) { \
+ vhtcaps_mask->vht_supported_mcs_set.rx_map |= \
+ 3 << 2 * (i - 1); \
+ vhtcaps->vht_supported_mcs_set.rx_map |= \
+ ssid->vht_rx_mcs_nss_ ##i << 2 * (i - 1); \
+ }
+
+ OVERRIDE_MCS(1);
+ OVERRIDE_MCS(2);
+ OVERRIDE_MCS(3);
+ OVERRIDE_MCS(4);
+ OVERRIDE_MCS(5);
+ OVERRIDE_MCS(6);
+ OVERRIDE_MCS(7);
+ OVERRIDE_MCS(8);
+}
+#endif /* CONFIG_VHT_OVERRIDES */
static int pcsc_reader_init(struct wpa_supplicant *wpa_s)
{
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index 18460b8..273281e 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -860,6 +860,20 @@ fast_reauth=1
# -1 = Do not make any changes.
# 0-3 = Set AMPDU density (aka factor) to specified value.
+# disable_vht: Whether VHT should be disabled.
+# 0 = VHT enabled (if AP supports it)
+# 1 = VHT disabled
+#
+# vht_capa: VHT capabilities to set in the override
+# vht_capa_mask: mask of VHT capabilities
+#
+# vht_rx_mcs_nss_1/2/3/4/5/6/7/8: override the MCS set for RX NSS 1-8
+# vht_tx_mcs_nss_1/2/3/4/5/6/7/8: override the MCS set for TX NSS 1-8
+# 0: MCS 0-7
+# 1: MCS 0-8
+# 2: MCS 0-9
+# 3: not supported
+
# Example blocks:
# Simple case: WPA-PSK, PSK as an ASCII passphrase, allow all valid ciphers
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 63808ab..9f278de 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -685,6 +685,9 @@ struct wpa_supplicant {
void wpa_supplicant_apply_ht_overrides(
struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
struct wpa_driver_associate_params *params);
+void wpa_supplicant_apply_vht_overrides(
+ struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
+ struct wpa_driver_associate_params *params);
int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
--
1.8.0
More information about the Hostap
mailing list