@ -22,12 +22,25 @@
u8 * hostapd_eid_vht_capabilities ( struct hostapd_data * hapd , u8 * eid )
{
struct ieee80211_vht_capabilities * cap ;
struct hostapd_hw_modes * mode = hapd - > iface - > current_mode ;
u8 * pos = eid ;
if ( ! hapd - > iconf - > ieee80211ac | | ! hapd - > iface - > current_mode | |
hapd - > conf - > disable_11ac )
if ( ! mode )
return eid ;
if ( mode - > mode = = HOSTAPD_MODE_IEEE80211G & & hapd - > conf - > vendor_vht & &
mode - > vht_capab = = 0 & & hapd - > iface - > hw_features ) {
int i ;
for ( i = 0 ; i < hapd - > iface - > num_hw_features ; i + + ) {
if ( hapd - > iface - > hw_features [ i ] . mode = =
HOSTAPD_MODE_IEEE80211A ) {
mode = & hapd - > iface - > hw_features [ i ] ;
break ;
}
}
}
* pos + + = WLAN_EID_VHT_CAP ;
* pos + + = sizeof ( * cap ) ;
@ -37,8 +50,7 @@ u8 * hostapd_eid_vht_capabilities(struct hostapd_data *hapd, u8 *eid)
hapd - > iface - > conf - > vht_capab ) ;
/* Supported MCS set comes from hw */
os_memcpy ( & cap - > vht_supported_mcs_set ,
hapd - > iface - > current_mode - > vht_mcs_set , 8 ) ;
os_memcpy ( & cap - > vht_supported_mcs_set , mode - > vht_mcs_set , 8 ) ;
pos + = sizeof ( * cap ) ;
@ -51,9 +63,6 @@ u8 * hostapd_eid_vht_operation(struct hostapd_data *hapd, u8 *eid)
struct ieee80211_vht_operation * oper ;
u8 * pos = eid ;
if ( ! hapd - > iconf - > ieee80211ac | | hapd - > conf - > disable_11ac )
return eid ;
* pos + + = WLAN_EID_VHT_OPERATION ;
* pos + + = sizeof ( * oper ) ;
@ -109,6 +118,66 @@ u16 copy_sta_vht_capab(struct hostapd_data *hapd, struct sta_info *sta,
}
u16 copy_sta_vendor_vht ( struct hostapd_data * hapd , struct sta_info * sta ,
const u8 * ie , size_t len )
{
const u8 * vht_capab ;
unsigned int vht_capab_len ;
if ( ! ie | | len < 5 + 2 + sizeof ( struct ieee80211_vht_capabilities ) | |
hapd - > conf - > disable_11ac )
goto no_capab ;
/* The VHT Capabilities element embedded in vendor VHT */
vht_capab = ie + 5 ;
if ( vht_capab [ 0 ] ! = WLAN_EID_VHT_CAP )
goto no_capab ;
vht_capab_len = vht_capab [ 1 ] ;
if ( vht_capab_len < sizeof ( struct ieee80211_vht_capabilities ) | |
vht_capab_len > ie + len - vht_capab - 2 )
goto no_capab ;
vht_capab + = 2 ;
if ( sta - > vht_capabilities = = NULL ) {
sta - > vht_capabilities =
os_zalloc ( sizeof ( struct ieee80211_vht_capabilities ) ) ;
if ( sta - > vht_capabilities = = NULL )
return WLAN_STATUS_UNSPECIFIED_FAILURE ;
}
sta - > flags | = WLAN_STA_VHT | WLAN_STA_VENDOR_VHT ;
os_memcpy ( sta - > vht_capabilities , vht_capab ,
sizeof ( struct ieee80211_vht_capabilities ) ) ;
return WLAN_STATUS_SUCCESS ;
no_capab :
sta - > flags & = ~ WLAN_STA_VENDOR_VHT ;
return WLAN_STATUS_SUCCESS ;
}
u8 * hostapd_eid_vendor_vht ( struct hostapd_data * hapd , u8 * eid )
{
u8 * pos = eid ;
if ( ! hapd - > iface - > current_mode )
return eid ;
* pos + + = WLAN_EID_VENDOR_SPECIFIC ;
* pos + + = ( 5 + /* The Vendor OUI, type and subtype */
2 + sizeof ( struct ieee80211_vht_capabilities ) +
2 + sizeof ( struct ieee80211_vht_operation ) ) ;
WPA_PUT_BE32 ( pos , ( OUI_BROADCOM < < 8 ) | VENDOR_VHT_TYPE ) ;
pos + = 4 ;
* pos + + = VENDOR_VHT_SUBTYPE ;
pos = hostapd_eid_vht_capabilities ( hapd , pos ) ;
pos = hostapd_eid_vht_operation ( hapd , pos ) ;
return pos ;
}
u16 set_sta_vht_opmode ( struct hostapd_data * hapd , struct sta_info * sta ,
const u8 * vht_oper_notif )
{