Patchwork [RFC1/2] 11ac changes - VHT IEs in beacons

login
register
mail settings
Submitter Mahesh Palivela
Date June 4, 2012, 7:13 a.m.
Message ID <952C5D5D0470AE4FB7D8A75C6ADC71CA0A42AD@mbx022-e1-nj-10.exch022.domain.local>
Download mbox | patch
Permalink /patch/162662/
State Changes Requested
Headers show

Comments

Mahesh Palivela - June 4, 2012, 7:13 a.m.
Hi,

I had modified hostapd code to include VHT IEs as part of 11ac changes.
Please review and let me know your comments.

Signed of by: Mahesh Palivela

--------------------------------------------------------------------------------------------------------------------
 hostapd/Makefile             |    8 +++
 hostapd/config_file.c        |   75 ++++++++++++++++++++++++
 hostapd/defconfig            |    3 +
 hostapd/hostapd.conf         |  131 +++++++++++++++++++++++++++++++++++++++++-
 src/ap/ap_config.h           |    4 +
 src/ap/beacon.c              |   10 +++
 src/ap/ieee802_11.h          |    2 +
 src/common/ieee802_11_defs.h |   54 +++++++++++++++++
 src/drivers/driver.h         |   10 +++
 src/drivers/driver_nl80211.c |   12 ++++
 src/drivers/nl80211_copy.h   |    6 ++
 11 files changed, 313 insertions(+), 2 deletions(-)
Johannes Berg - June 4, 2012, 7:27 a.m.
On Mon, 2012-06-04 at 07:13 +0000, Mahesh Palivela wrote:
> Hi,
> 
> I had modified hostapd code to include VHT IEs as part of 11ac changes.
> Please review and let me know your comments.

VHT is complicated enough that I think we should take the HW
capabilities (as will be advertised by nl80211) into account more when
configuring this. Hardly anyone will ever be able to come up with a
correct configuration and they shouldn't have to unless overriding
specific things for testing?

johannes
Johannes Berg - June 4, 2012, 7:28 a.m.
On Mon, 2012-06-04 at 07:13 +0000, Mahesh Palivela wrote:

> --- a/src/drivers/nl80211_copy.h
> +++ b/src/drivers/nl80211_copy.h
> @@ -1786,6 +1786,9 @@ enum nl80211_mpath_info {
>   * @NL80211_BAND_ATTR_HT_CAPA: HT capabilities, as in the HT information IE
>   * @NL80211_BAND_ATTR_HT_AMPDU_FACTOR: A-MPDU factor, as in 11n
>   * @NL80211_BAND_ATTR_HT_AMPDU_DENSITY: A-MPDU density, as in 11n
> + * @NL80211_BAND_ATTR_VHT_MCS_SET: 8-byte attribute containing the MCS set as
> + *	defined in 802.11ac
> + * @NL80211_BAND_ATTR_VHT_CAPA: VHT capabilities, as in the VHT capabilities IE
>   * @NL80211_BAND_ATTR_MAX: highest band attribute currently defined
>   * @__NL80211_BAND_ATTR_AFTER_LAST: internal use
>   */
> @@ -1799,6 +1802,9 @@ enum nl80211_band_attr {
>  	NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
>  	NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
>  
> +	NL80211_BAND_ATTR_VHT_MCS_SET,
> +	NL80211_BAND_ATTR_VHT_CAPA,
> +
>  	/* keep last */
>  	__NL80211_BAND_ATTR_AFTER_LAST,
>  	NL80211_BAND_ATTR_MAX = __NL80211_BAND_ATTR_AFTER_LAST - 1

And this, of course, is pure heresy. Don't change nl80211.h in hostapd
when you haven't proposed any kernel patches.

johannes
Mahesh Palivela - June 5, 2012, 9:51 a.m.
Johannes,

That's where even I have the confusion. I will modify to fill it from nl data.

Thanks,
Mahesh
Jouni Malinen - June 9, 2012, 9:19 a.m.
On Mon, Jun 04, 2012 at 07:13:16AM +0000, Mahesh Palivela wrote:
> I had modified hostapd code to include VHT IEs as part of 11ac changes.
> Please review and let me know your comments.
> 
> Signed of by: Mahesh Palivela

Please read the CONTRIBUTIONS file (*) and use the Signed-hostap: line
with correct format.

(*)
http://w1.fi/gitweb/gitweb.cgi?p=hostap.git;a=blob_plain;f=CONTRIBUTIONS


>  src/drivers/driver_nl80211.c |   12 ++++
>  src/drivers/nl80211_copy.h   |    6 ++

I cannot take changes to nl80211_copy.h before they have been included
in the wireless-testing.git include/linux/nl80211.h. If you want to get
the other parts of the 802.11ac changes into hostapd first, it could be
useful to split the patch into two pieces and leave these nl80211
changes waiting for the kernel changes to get approved.

> diff --git a/hostapd/Makefile b/hostapd/Makefile
> @@ -173,6 +173,10 @@ ifdef CONFIG_WNM
>  CFLAGS += -DCONFIG_WNM
>  endif
>  
> +ifdef CONFIG_IEEE80211AC
> +CFLAGS += -DCONFIG_IEEE80211AC
> +endif

This could be in the same ifdef block with the change below to keep
related entries next to each other.

> @@ -757,6 +761,10 @@ ifdef CONFIG_IEEE80211N
>  OBJS += ../src/ap/ieee802_11_ht.o
>  endif
>  
> +ifdef CONFIG_IEEE80211AC
> +OBJS += ../src/ap/ieee802_11_vht.o
> +endif

This new file is added in a separate patch which would result in build
failure if this were to be applied first.. Please add the new file and
the Makefile entry in the same patch.

> diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
> @@ -99,13 +99,13 @@ ssid=test
> -hw_mode=g
> +hw_mode=a

> -channel=1
> +channel=36

Please don't change these values.

> @@ -416,6 +416,133 @@ wmm_ac_vo_acm=0
> +# ieee80211ac: Whether IEEE 802.11ac (VHT) is enabled
> +# 0 = disabled (default)
> +# 1 = enabled
> +# Note: You will also need to enable WMM for full VHT functionality.
> +ieee80211ac=1

This should be commented out by default in the example configuration
file.

> +# vht_capab: VHT capabilities (list of flags)
> +#
> +# maxMpduLength: [MAX-MPDU-7991] [MAX-MPDU-11454]
> +# Indicates maximum MPDU length
> +# 0 = 3895 octets (default)
> +# 1 = 7991 octets
> +# 2 = 11454 octets
> +# 3 = reserved
...

While this style is used with ht_capab, I'm not sure where this is
really the most convenient way for managing the configuration file.. As
such, separate items like vht_max_mpdu_len here could be more
convenient.

> +# 0 = 160Mhz & 80+80 channel widths are not supported (default)

"160Mhz" --> "160 MHz"

> +vht_capab=[SHORT-GI-80][HTC-VHT]
> +vht_oper_chwidth=1

These needs to be commented out by default.

> diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
> @@ -359,6 +359,7 @@ struct hostapd_bss_config {
>  	int tdls;
>  	int disable_11n;
> +    int disable_11ac;

Please use consistent indentation (one tab instead of four spaces).

> diff --git a/src/ap/beacon.c b/src/ap/beacon.c
> @@ -253,6 +253,11 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
>  	pos = hostapd_eid_ht_operation(hapd, pos);
>  #endif /* CONFIG_IEEE80211N */
>  
> +#ifdef CONFIG_IEEE80211AC
> +	pos = hostapd_eid_vht_capabilities(hapd, pos);
> +	pos = hostapd_eid_vht_operation(hapd, pos);
> +#endif /* CONFIG_IEEE80211AC */
> +
>  	pos = hostapd_eid_ext_capab(hapd, pos);

The VHT elements are not in the correct location - they should be after
all the non-vendor specific elements in the current implementation
(i.e., after hostapd_eid_roaming_consortium).

> @@ -583,6 +588,11 @@ void ieee802_11_set_beacon(struct hostapd_data *hapd)
>  	tailpos = hostapd_eid_ht_operation(hapd, tailpos);
>  #endif /* CONFIG_IEEE80211N */
>  
> +#ifdef CONFIG_IEEE80211AC
> +	tailpos = hostapd_eid_vht_capabilities(hapd, tailpos);
> +	tailpos = hostapd_eid_vht_operation(hapd, tailpos);
> +#endif /* CONFIG_IEEE80211AC */
> +
>  	tailpos = hostapd_eid_ext_capab(hapd, tailpos);

Same here for Beacon frame.

> diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
> @@ -238,6 +238,15 @@
> +#define WLAN_EID_VHT_EXTENDED_POWER_CONSTRAINT 196

That does not match with P802.11ac/D3.0 (196 = Channel Switch Wrapper).

> @@ -550,6 +559,24 @@ struct ieee80211_ht_operation {
> +struct ieee80211_vht_tx_power_envelope {
> +    u8 vht_max_tx_power;
> +    u8 vht_chan_center_freq_segment;
> +    u8 vht_segment_chan_width;
> +} STRUCT_PACKED;

This does not match with P802.11ac/D3.0.

Patch

diff --git a/hostapd/Makefile b/hostapd/Makefile
index 2a82920..b43aa75 100644
--- a/hostapd/Makefile
+++ b/hostapd/Makefile
@@ -173,6 +173,10 @@  ifdef CONFIG_WNM
 CFLAGS += -DCONFIG_WNM
 endif
 
+ifdef CONFIG_IEEE80211AC
+CFLAGS += -DCONFIG_IEEE80211AC
+endif
+
 include ../src/drivers/drivers.mak
 OBJS += $(DRV_AP_OBJS)
 CFLAGS += $(DRV_AP_CFLAGS)
@@ -757,6 +761,10 @@  ifdef CONFIG_IEEE80211N
 OBJS += ../src/ap/ieee802_11_ht.o
 endif
 
+ifdef CONFIG_IEEE80211AC
+OBJS += ../src/ap/ieee802_11_vht.o
+endif
+
 ifdef CONFIG_P2P_MANAGER
 CFLAGS += -DCONFIG_P2P_MANAGER
 OBJS += ../src/ap/p2p_hostapd.o
diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index eab8ad4..188a0de 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -1131,6 +1131,69 @@  static int hostapd_config_ht_capab(struct hostapd_config *conf,
 }
 #endif /* CONFIG_IEEE80211N */
 
+#ifdef CONFIG_IEEE80211AC
+static int hostapd_config_vht_capab(struct hostapd_config *conf,
+				   const char *capab)
+{
+	if (os_strstr(capab, "[MAX-MPDU-7991]"))
+		conf->vht_capab |= VHT_CAP_MAX_MPDU_LENGTH_7991;
+	if (os_strstr(capab, "[MAX-MPDU-11454]"))
+		conf->vht_capab |= VHT_CAP_MAX_MPDU_LENGTH_11454;
+	if (os_strstr(capab, "[VHT160]"))
+		conf->vht_capab |= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
+	if (os_strstr(capab, "[VHT160-80PLUS80]"))
+		conf->vht_capab |= VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
+	if (os_strstr(capab, "[VHT160-80PLUS80]"))
+		conf->vht_capab |= VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
+	if (os_strstr(capab, "[RXLDPC]"))
+		conf->vht_capab |= VHT_CAP_RXLDPC;
+	if (os_strstr(capab, "[SHORT-GI-80]"))
+		conf->vht_capab |= VHT_CAP_SHORT_GI_80;
+	if (os_strstr(capab, "[SHORT-GI-160]"))
+		conf->vht_capab |= VHT_CAP_SHORT_GI_160;
+	if (os_strstr(capab, "[TX-STBC-2BY1]"))
+		conf->vht_capab |= VHT_CAP_TXSTBC;
+	if (os_strstr(capab, "[RX-STBC-1]"))
+		conf->vht_capab |= VHT_CAP_RXSTBC_1;
+	if (os_strstr(capab, "[RX-STBC-12]"))
+		conf->vht_capab |= VHT_CAP_RXSTBC_2;
+	if (os_strstr(capab, "[RX-STBC-123]"))
+		conf->vht_capab |= VHT_CAP_RXSTBC_3;
+	if (os_strstr(capab, "[RX-STBC-1234]"))
+		conf->vht_capab |= VHT_CAP_RXSTBC_4;
+	if (os_strstr(capab, "[SU-BEAMFORMER]"))
+		conf->vht_capab |= VHT_CAP_MU_BEAMFORMER_CAPABLE;
+	if (os_strstr(capab, "[SU-BEAMFORMEE]"))
+		conf->vht_capab |= VHT_CAP_MU_BEAMFORMEE_CAPABLE;
+	if (os_strstr(capab, "[BF-ANTENNA-2]") &&
+	    (conf->vht_capab & VHT_CAP_MU_BEAMFORMER_CAPABLE))
+		conf->vht_capab |= VHT_CAP_BEAMFORMER_ANTENNAS_MAX;
+	if (os_strstr(capab, "[SOUNDING-DIMENSION-2]") &&
+	    (conf->vht_capab & VHT_CAP_MU_BEAMFORMER_CAPABLE))
+		conf->vht_capab |= VHT_CAP_SOUNDING_DIMENTION_MAX;
+	if (os_strstr(capab, "[MU-BEAMFORMER]"))
+		conf->vht_capab |= VHT_CAP_MU_BEAMFORMER_CAPABLE;
+	if (os_strstr(capab, "[MU-BEAMFORMEE]"))
+		conf->vht_capab |= VHT_CAP_MU_BEAMFORMEE_CAPABLE;
+	if (os_strstr(capab, "[VHT-TXOP-PS]"))
+		conf->vht_capab |= VHT_CAP_VHT_TXOP_PS;
+	if (os_strstr(capab, "[HTC-VHT]"))
+		conf->vht_capab |= VHT_CAP_HTC_VHT;
+	if (os_strstr(capab, "[MAX-A-MPDU-LEN-EXP0]"))
+		conf->vht_capab |= VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT;
+	if (os_strstr(capab, "[VHT-LINK-ADAPT2]") &&
+	    (conf->vht_capab & VHT_CAP_HTC_VHT))
+		conf->vht_capab |= VHT_CAP_VHT_LINK_ADAPTATION_VHT_UNSOL_MFB;
+	if (os_strstr(capab, "[VHT-LINK-ADAPT3]") &&
+	    (conf->vht_capab & VHT_CAP_HTC_VHT))
+		conf->vht_capab |= VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB;
+	if (os_strstr(capab, "[RX-ANTENNA-PATTERN]"))
+		conf->vht_capab |= VHT_CAP_RX_ANTENNA_PATTERN;
+	if (os_strstr(capab, "[TX-ANTENNA-PATTERN]"))
+		conf->vht_capab |= VHT_CAP_TX_ANTENNA_PATTERN;
+	return 0;
+}
+#endif /* CONFIG_IEEE80211AC */
 
 static int hostapd_config_check_bss(struct hostapd_bss_config *bss,
 				    struct hostapd_config *conf)
@@ -2096,6 +2159,18 @@  static int hostapd_config_fill(struct hostapd_config *conf,
 		} else if (os_strcmp(buf, "require_ht") == 0) {
 			conf->require_ht = atoi(pos);
 #endif /* CONFIG_IEEE80211N */
+#ifdef CONFIG_IEEE80211AC
+		} else if (os_strcmp(buf, "ieee80211ac") == 0) {
+			conf->ieee80211ac = atoi(pos);
+		} else if (os_strcmp(buf, "vht_capab") == 0) {
+			if (hostapd_config_vht_capab(conf, pos) < 0) {
+				wpa_printf(MSG_ERROR, "Line %d: invalid "
+					   "vht_capab", line);
+				errors++;
+			}
+		} else if (os_strcmp(buf, "vht_oper_chwidth") == 0) {
+		    conf->vht_oper_chwidth = atoi(pos);
+#endif /* CONFIG_IEEE80211AC */
 		} else if (os_strcmp(buf, "max_listen_interval") == 0) {
 			bss->max_listen_interval = atoi(pos);
 		} else if (os_strcmp(buf, "disable_pmksa_caching") == 0) {
diff --git a/hostapd/defconfig b/hostapd/defconfig
index dea296c..10b023a 100644
--- a/hostapd/defconfig
+++ b/hostapd/defconfig
@@ -140,6 +140,9 @@  CONFIG_IPV6=y
 # Note: This is experimental and not complete implementation.
 #CONFIG_WNM=y
 
+# IEEE 802.11ac (Very High Throughput) support
+#CONFIG_IEEE80211AC=y
+
 # Remove debugging code that is printing out debug messages to stdout.
 # This can be used to reduce the size of the hostapd considerably if debugging
 # code is not needed.
diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
index 611ce95..3dc438a 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -99,13 +99,13 @@  ssid=test
 
 # Operation mode (a = IEEE 802.11a, b = IEEE 802.11b, g = IEEE 802.11g,
 # Default: IEEE 802.11b
-hw_mode=g
+hw_mode=a
 
 # Channel number (IEEE 802.11)
 # (default: 0, i.e., not set)
 # Please note that some drivers do not use this value from hostapd and the
 # channel will need to be configured separately with iwconfig.
-channel=1
+channel=36
 
 # Beacon interval in kus (1.024 ms) (default: 100; range 15..65535)
 beacon_int=100
@@ -416,6 +416,133 @@  wmm_ac_vo_acm=0
 # Require stations to support HT PHY (reject association if they do not)
 #require_ht=1
 
+##### IEEE 802.11ac related configuration ######################################
+
+# ieee80211ac: Whether IEEE 802.11ac (VHT) is enabled
+# 0 = disabled (default)
+# 1 = enabled
+# Note: You will also need to enable WMM for full VHT functionality.
+ieee80211ac=1
+
+# vht_capab: VHT capabilities (list of flags)
+#
+# maxMpduLength: [MAX-MPDU-7991] [MAX-MPDU-11454]
+# Indicates maximum MPDU length
+# 0 = 3895 octets (default)
+# 1 = 7991 octets
+# 2 = 11454 octets
+# 3 = reserved
+#
+# suppChanWidth: [VHT160] [VHT160-80PLUS80]
+# Indicates supported Channel widths
+# 0 = 160Mhz & 80+80 channel widths are not supported (default)
+# 1 = 160Mhz channel width is supported
+# 2 = 160Mhz & 80+80 channel widths are supported
+# 3 = reserved
+#
+# Rx LDPC coding capability: [RXLDPC]
+# Indicates support for receiving LDPC coded pkts
+# 0 = Not supported (default)
+# 1 = Supported
+#
+# Short GI for 80 MHz: [SHORT-GI-80]
+# Indicates short GI support for reception of packets transmitted with TXVECTOR
+# params format equal to VHT and CBW = 80Mhz
+# 0 = Not supported (default)
+# 1 = Supported
+#
+# Short GI for 160 MHz: [SHORT-GI-160]
+# Indicates short GI support for reception of packets transmitted with TXVECTOR
+# params format equal to VHT and CBW = 160Mhz
+# 0 = Not supported (default)
+# 1 = Supported
+#
+# Tx STBC: [TX-STBC-2BY1]
+# Indicates support for the transmission of at least 2x1 STBC 
+# 0 = Not supported (default)
+# 1 = Supported
+#
+# Rx STBC: [RX-STBC-1] [RX-STBC-12] [RX-STBC-123] [RX-STBC-1234]
+# Indicates support for the reception of PPDUs using STBC 
+# 0 = Not supported (default)
+# 1 = support of one spatial stream
+# 2 = support of one and two spatial streams
+# 3 = support of one, two and three spatial streams
+# 4 = support of one, two, three and four spatial streams
+# 5,6,7 = reserved
+#
+# SU Beamformer Capable: [SU-BEAMFORMER]
+# Indicates support for operation as a single user beamformer
+# 0 = Not supported (default)
+# 1 = Supported
+#
+# SU Beamformee Capable: [SU-BEAMFORMEE]
+# Indicates support for operation as a single user beamformee
+# 0 = Not supported (default)
+# 1 = Supported
+#
+# Compressed Steering Number of Beamformer Antennas Supported: [BF-ANTENNA-2]
+#   Beamformee’s capability indicating the maximum number of beamformer anten- 
+#   nas the beamformee can support when sending compressed beamforming feedback 
+# If SU beamformer capable, set to maximum value minus 1
+# else reserved (default)
+#
+# Number of Sounding Dimensions: [SOUNDING-DIMENSION-2]
+# Beamformer’s capability indicating the maximum value of the NUM_STS parameter
+# in the TXVECTOR of a VHT NDP
+# If SU beamformer capable, set to maximum value minus 1
+# else reserved (default)
+#
+# MU Beamformer Capable: [MU-BEAMFORMER]
+# Indicates support for operation as an MU beamformer 
+# 0 = Not supported or sent by Non-AP STA (default)
+# 1 = Supported
+# 
+# MU Beamformee Capable: [MU-BEAMFORMEE]
+# Indicates support for operation as an MU beamformee 
+# 0 = Not supported or sent by AP (default)
+# 1 = Supported
+#
+# VHT TXOP PS: [VHT-TXOP-PS]
+# Indicates whether or not the AP supports VHT TXOP Power Save Mode
+#  or whether or not the STA is in VHT TXOP Power Save mode 
+# 0 = VHT AP doesnt support VHT TXOP PS mode (OR) VHT Sta not in VHT TXOP PS mode
+# 1 = VHT AP supports VHT TXOP PS mode (OR) VHT Sta is in VHT TXOP power save mode
+# 
+# +HTC-VHT Capable: [HTC-VHT]
+# Indicates whether or not the STA supports receiving a VHT variant HT Control field.
+# 0 = Not supported (default)
+# 1 = supported
+#
+# Maximum A-MPDU Length Exponent: [MAX-A-MPDU-LEN-EXP0] TO [MAX-A-MPDU-LEN-EXP7]
+# Indicates the maximum length of A-MPDU pre-EOF padding that the STA can recv
+# This field is an integer in the range of 0 to 7.
+# The length defined by this field is equal to 
+# 2 pow(13 + Maximum A-MPDU Length Exponent) –1 octets
+#
+# VHT Link Adaptation Capable: [VHT-LINK-ADAPT2] [VHT-LINK-ADAPT3]
+# Indicates whether or not the STA supports link adaptation using VHT variant 
+# HT Control field
+# If +HTC-VHTcapable is 1
+#  0 = (no feedback) if the STA does not provide VHT MFB (default)
+#  1 = reserved
+#  2 = (Unsolicited) if the STA provides only unsolicited VHT MFB
+#  3 = (Both) if the STA can provide VHT MFB in response to VHT MRQ and if the
+#      STA provides unsolicited VHT MFB
+# Reserved if +HTC-VHTcapable is 0
+#
+# Rx Antenna Pattern Consistency: [RX-ANTENNA-PATTERN]
+# Indicates the possibility of Rx antenna pattern change
+# 0 = Rx antenna pattern might change during the lifetime of an association
+# 1 = Rx antenna pattern does not change during the lifetime of an association
+#
+# Tx Antenna Pattern Consistency: [TX-ANTENNA-PATTERN]
+# Indicates the possibility of Tx antenna pattern change
+# 0 = Tx antenna pattern might change during the lifetime of an association
+# 1 = Tx antenna pattern does not change during the lifetime of an association
+vht_capab=[SHORT-GI-80][HTC-VHT]
+vht_oper_chwidth=1
+
 ##### IEEE 802.1X-2004 related configuration ##################################
 
 # Require IEEE 802.1X authorization
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index 78c9068..cd92614 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -359,6 +359,7 @@  struct hostapd_bss_config {
 #define TDLS_PROHIBIT_CHAN_SWITCH BIT(1)
 	int tdls;
 	int disable_11n;
+    int disable_11ac;
 
 	/* IEEE 802.11v */
 	int time_advertisement;
@@ -446,6 +447,9 @@  struct hostapd_config {
 	int ieee80211n;
 	int secondary_channel;
 	int require_ht;
+	u32 vht_capab;
+	int ieee80211ac;
+	u8 vht_oper_chwidth;
 };
 
 
diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index b711063..d6c9729 100644
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -253,6 +253,11 @@  static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
 	pos = hostapd_eid_ht_operation(hapd, pos);
 #endif /* CONFIG_IEEE80211N */
 
+#ifdef CONFIG_IEEE80211AC
+	pos = hostapd_eid_vht_capabilities(hapd, pos);
+	pos = hostapd_eid_vht_operation(hapd, pos);
+#endif /* CONFIG_IEEE80211AC */
+
 	pos = hostapd_eid_ext_capab(hapd, pos);
 
 	pos = hostapd_eid_time_adv(hapd, pos);
@@ -583,6 +588,11 @@  void ieee802_11_set_beacon(struct hostapd_data *hapd)
 	tailpos = hostapd_eid_ht_operation(hapd, tailpos);
 #endif /* CONFIG_IEEE80211N */
 
+#ifdef CONFIG_IEEE80211AC
+	tailpos = hostapd_eid_vht_capabilities(hapd, tailpos);
+	tailpos = hostapd_eid_vht_operation(hapd, tailpos);
+#endif /* CONFIG_IEEE80211AC */
+
 	tailpos = hostapd_eid_ext_capab(hapd, tailpos);
 
 	/*
diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h
index b60350f..9993bee 100644
--- a/src/ap/ieee802_11.h
+++ b/src/ap/ieee802_11.h
@@ -45,6 +45,8 @@  u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid);
 u8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid);
 u8 * hostapd_eid_ht_capabilities(struct hostapd_data *hapd, u8 *eid);
 u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid);
+u8 * hostapd_eid_vht_capabilities(struct hostapd_data *hapd, u8 *eid);
+u8 * hostapd_eid_vht_operation(struct hostapd_data *hapd, u8 *eid);
 int hostapd_ht_operation_update(struct hostapd_iface *iface);
 void ieee802_11_send_sa_query_req(struct hostapd_data *hapd,
 				  const u8 *addr, const u8 *trans_id);
diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
index 0206294..3907681 100644
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -238,6 +238,15 @@ 
 #define WLAN_EID_ADV_PROTO 108
 #define WLAN_EID_ROAMING_CONSORTIUM 111
 #define WLAN_EID_EXT_CAPAB 127
+#define WLAN_EID_VHT_CAP 191
+#define WLAN_EID_VHT_OPERATION 192
+#define WLAN_EID_VHT_EXTENDED_BSS_LOAD 193
+#define WLAN_EID_VHT_WIDE_BW_CHSWITCH  194
+#define WLAN_EID_VHT_TRANSMIT_POWER_ENVELOPE 195
+#define WLAN_EID_VHT_EXTENDED_POWER_CONSTRAINT 196
+#define WLAN_EID_VHT_AID 197
+#define WLAN_EID_VHT_QUIET_CHANNEL 198
+#define WLAN_EID_VHT_OPERATING_MODE_NOTIFICATION 199
 #define WLAN_EID_VENDOR_SPECIFIC 221
 
 
@@ -550,6 +559,24 @@  struct ieee80211_ht_operation {
 	u8 basic_set[16];
 } STRUCT_PACKED;
 
+struct ieee80211_vht_capabilities {
+    le32 vht_capabilities_info;
+    u8 vht_supported_mcs_set[8];
+} STRUCT_PACKED;
+
+struct ieee80211_vht_operation {
+    u8 vht_operation_information_chwidth;
+    u8 vht_operation_information_chan_center_freq1;
+    u8 vht_operation_information_chan_center_freq2;
+    le16 vht_basic_mcs_set; 
+} STRUCT_PACKED;
+
+struct ieee80211_vht_tx_power_envelope {
+    u8 vht_max_tx_power;
+    u8 vht_chan_center_freq_segment;
+    u8 vht_segment_chan_width;
+} STRUCT_PACKED;
+
 #ifdef _MSC_VER
 #pragma pack(pop)
 #endif /* _MSC_VER */
@@ -646,6 +673,33 @@  struct ieee80211_ht_operation {
 
 #define BSS_MEMBERSHIP_SELECTOR_HT_PHY 127
 
+/* VHT Defines */
+#define VHT_CAP_MAX_MPDU_LENGTH_7991                ((u32) BIT(0))
+#define VHT_CAP_MAX_MPDU_LENGTH_11454               ((u32) BIT(1))
+#define VHT_CAP_SUPP_CHAN_WIDTH_160MHZ              ((u32) BIT(2))
+#define VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ     ((u32) BIT(3))
+#define VHT_CAP_RXLDPC                              ((u32) BIT(4))
+#define VHT_CAP_SHORT_GI_80                         ((u32) BIT(5))
+#define VHT_CAP_SHORT_GI_160                        ((u32) BIT(6))
+#define VHT_CAP_TXSTBC                              ((u32) BIT(7))
+#define VHT_CAP_RXSTBC_1                            ((u32) BIT(8))
+#define VHT_CAP_RXSTBC_2                            ((u32) BIT(9))
+#define VHT_CAP_RXSTBC_3                            ((u32) BIT(8) | BIT(9))
+#define VHT_CAP_RXSTBC_4                            ((u32) BIT(10))
+#define VHT_CAP_SU_BEAMFORMER_CAPABLE               ((u32) BIT(11))
+#define VHT_CAP_SU_BEAMFORMEE_CAPABLE               ((u32) BIT(12))
+#define VHT_CAP_BEAMFORMER_ANTENNAS_MAX             ((u32) BIT(13) | BIT(14))
+#define VHT_CAP_SOUNDING_DIMENTION_MAX              ((u32) BIT(16) | BIT(17))
+#define VHT_CAP_MU_BEAMFORMER_CAPABLE               ((u32) BIT(19))
+#define VHT_CAP_MU_BEAMFORMEE_CAPABLE               ((u32) BIT(20))
+#define VHT_CAP_VHT_TXOP_PS                         ((u32) BIT(21))
+#define VHT_CAP_HTC_VHT                             ((u32) BIT(22))
+#define VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT          ((u32) BIT(23))
+#define VHT_CAP_VHT_LINK_ADAPTATION_VHT_UNSOL_MFB   ((u32) BIT(27))
+#define VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB     ((u32) BIT(26) | BIT(27))
+#define VHT_CAP_RX_ANTENNA_PATTERN                  ((u32) BIT(28))
+#define VHT_CAP_TX_ANTENNA_PATTERN                  ((u32) BIT(29))
+
 #define OUI_MICROSOFT 0x0050f2 /* Microsoft (also used in Wi-Fi specs)
 				* 00:50:F2 */
 #define WPA_IE_VENDOR_TYPE 0x0050f201
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index f7fb2ef..550f1a4 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -100,6 +100,16 @@  struct hostapd_hw_modes {
 	 */
 	u8 a_mpdu_params;
 
+	/**
+	 * vht_capab - VHT (IEEE 802.11ac) capabilities
+	 */
+	u32 vht_capab;
+
+	/**
+	 * vht_mcs_set - VHT MCS (IEEE 802.11ac) rate parameters
+	 */
+	u8 vht_mcs_set[8];
+
 	unsigned int flags; /* HOSTAPD_MODE_FLAG_* */
 };
 
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 693a885..ac1dc4e 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -4757,6 +4757,18 @@  static int phy_info_handler(struct nl_msg *msg, void *arg)
 			os_memcpy(mode->mcs_set, mcs, 16);
 		}
 
+		if (tb_band[NL80211_BAND_ATTR_VHT_CAPA]) {
+			mode->vht_capab = nla_get_u32(
+				tb_band[NL80211_BAND_ATTR_VHT_CAPA]);
+		}
+
+		if (tb_band[NL80211_BAND_ATTR_VHT_MCS_SET] &&
+		    nla_len(tb_band[NL80211_BAND_ATTR_VHT_MCS_SET])) {
+			u8 *mcs;
+			mcs = nla_data(tb_band[NL80211_BAND_ATTR_VHT_MCS_SET]);
+			os_memcpy(mode->vht_mcs_set, mcs, 8);
+		}
+
 		nla_for_each_nested(nl_freq, tb_band[NL80211_BAND_ATTR_FREQS], rem_freq) {
 			nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX, nla_data(nl_freq),
 				  nla_len(nl_freq), freq_policy);
diff --git a/src/drivers/nl80211_copy.h b/src/drivers/nl80211_copy.h
index 1335084..b75c01e 100644
--- a/src/drivers/nl80211_copy.h
+++ b/src/drivers/nl80211_copy.h
@@ -1786,6 +1786,9 @@  enum nl80211_mpath_info {
  * @NL80211_BAND_ATTR_HT_CAPA: HT capabilities, as in the HT information IE
  * @NL80211_BAND_ATTR_HT_AMPDU_FACTOR: A-MPDU factor, as in 11n
  * @NL80211_BAND_ATTR_HT_AMPDU_DENSITY: A-MPDU density, as in 11n
+ * @NL80211_BAND_ATTR_VHT_MCS_SET: 8-byte attribute containing the MCS set as
+ *	defined in 802.11ac
+ * @NL80211_BAND_ATTR_VHT_CAPA: VHT capabilities, as in the VHT capabilities IE
  * @NL80211_BAND_ATTR_MAX: highest band attribute currently defined
  * @__NL80211_BAND_ATTR_AFTER_LAST: internal use
  */
@@ -1799,6 +1802,9 @@  enum nl80211_band_attr {
 	NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
 	NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
 
+	NL80211_BAND_ATTR_VHT_MCS_SET,
+	NL80211_BAND_ATTR_VHT_CAPA,
+
 	/* keep last */
 	__NL80211_BAND_ATTR_AFTER_LAST,
 	NL80211_BAND_ATTR_MAX = __NL80211_BAND_ATTR_AFTER_LAST - 1