1 /* 2 * hostapd / IEEE 802.11ac VHT 3 * Copyright (c) 2002-2009, Jouni Malinen <j (at) w1.fi> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of BSD license 7 * 8 * See README and COPYING for more details. 9 */ 10 11 #include "utils/includes.h" 12 13 #include "utils/common.h" 14 #include "common/ieee802_11_defs.h" 15 #include "drivers/driver.h" 16 #include "hostapd.h" 17 #include "ap_config.h" 18 #include "sta_info.h" 19 #include "beacon.h" 20 #include "ieee802_11.h" 21 22 23 u8 * hostapd_eid_vht_capabilities(struct hostapd_data *hapd, u8 *eid) 24 { 25 struct ieee80211_vht_capabilities *cap; 26 u8 *pos = eid; 27 28 if (!hapd->iconf->ieee80211ac || !hapd->iface->current_mode || 29 hapd->conf->disable_11ac) 30 return eid; 31 32 *pos++ = WLAN_EID_VHT_CAP; 33 *pos++ = sizeof(*cap); 34 35 cap = (struct ieee80211_vht_capabilities *) pos; 36 os_memset(cap, 0, sizeof(*cap)); 37 cap->vht_capabilities_info = host_to_le32( 38 hapd->iface->current_mode->vht_capab); 39 40 /* Supported MCS set comes from hw */ 41 os_memcpy(&cap->vht_supported_mcs_set, 42 hapd->iface->current_mode->vht_mcs_set, 8); 43 44 pos += sizeof(*cap); 45 46 return pos; 47 } 48 49 50 u8 * hostapd_eid_vht_operation(struct hostapd_data *hapd, u8 *eid) 51 { 52 struct ieee80211_vht_operation *oper; 53 u8 *pos = eid; 54 55 if (!hapd->iconf->ieee80211ac || hapd->conf->disable_11ac) 56 return eid; 57 58 *pos++ = WLAN_EID_VHT_OPERATION; 59 *pos++ = sizeof(*oper); 60 61 oper = (struct ieee80211_vht_operation *) pos; 62 os_memset(oper, 0, sizeof(*oper)); 63 64 /* 65 * center freq = 5 GHz + (5 * index) 66 * So index 42 gives center freq 5.210 GHz 67 * which is channel 42 in 5G band 68 */ 69 oper->vht_op_info_chan_center_freq_seg0_idx = 70 hapd->iconf->vht_oper_centr_freq_seg0_idx; 71 oper->vht_op_info_chan_center_freq_seg1_idx = 72 hapd->iconf->vht_oper_centr_freq_seg1_idx; 73 74 oper->vht_op_info_chwidth = hapd->iconf->vht_oper_chwidth; 75 76 /* VHT Basic MCS set comes from hw */ 77 /* Hard code 1 stream, MCS0-7 is a min Basic VHT MCS rates */ 78 oper->vht_basic_mcs_set = host_to_le16(0xfffc); 79 pos += sizeof(*oper); 80 81 return pos; 82 } 83 84 85 u16 copy_sta_vht_capab(struct hostapd_data *hapd, struct sta_info *sta, 86 const u8 *vht_capab, size_t vht_capab_len) 87 { 88 /* Disable VHT caps for STAs associated to no-VHT BSSes. */ 89 if (!vht_capab || 90 vht_capab_len < sizeof(struct ieee80211_vht_capabilities) || 91 hapd->conf->disable_11ac) { 92 sta->flags &= ~WLAN_STA_VHT; 93 os_free(sta->vht_capabilities); 94 sta->vht_capabilities = NULL; 95 return WLAN_STATUS_SUCCESS; 96 } 97 98 if (sta->vht_capabilities == NULL) { 99 sta->vht_capabilities = 100 os_zalloc(sizeof(struct ieee80211_vht_capabilities)); 101 if (sta->vht_capabilities == NULL) 102 return WLAN_STATUS_UNSPECIFIED_FAILURE; 103 } 104 105 sta->flags |= WLAN_STA_VHT; 106 os_memcpy(sta->vht_capabilities, vht_capab, 107 sizeof(struct ieee80211_vht_capabilities)); 108 109 return WLAN_STATUS_SUCCESS; 110 } 111 112 void hostapd_get_vht_capab(struct hostapd_data *hapd, 113 struct ieee80211_vht_capabilities *vht_cap, 114 struct ieee80211_vht_capabilities *neg_vht_cap) 115 { 116 if (vht_cap == NULL) 117 return; 118 os_memcpy(neg_vht_cap, vht_cap, sizeof(*neg_vht_cap)); 119 120 /* TODO: mask own capabilities, like get_ht_capab() */ 121 } 122