hostapd: Mask out not-supported VHT capabilities

Mask the remote VHT capabilities with our own capabilities, similarly
to what is done for HT capabilities.

Signed-hostap: Eliad Peller <eliadx.peller@intel.com>
This commit is contained in:
Eliad Peller 2013-10-27 19:28:40 +02:00 committed by Jouni Malinen
parent 7f0303d5b0
commit 6b02335a96
2 changed files with 53 additions and 1 deletions

View file

@ -113,9 +113,60 @@ void hostapd_get_vht_capab(struct hostapd_data *hapd,
struct ieee80211_vht_capabilities *vht_cap, struct ieee80211_vht_capabilities *vht_cap,
struct ieee80211_vht_capabilities *neg_vht_cap) struct ieee80211_vht_capabilities *neg_vht_cap)
{ {
u32 cap, own_cap, sym_caps;
if (vht_cap == NULL) if (vht_cap == NULL)
return; return;
os_memcpy(neg_vht_cap, vht_cap, sizeof(*neg_vht_cap)); os_memcpy(neg_vht_cap, vht_cap, sizeof(*neg_vht_cap));
/* TODO: mask own capabilities, like get_ht_capab() */ cap = le_to_host32(neg_vht_cap->vht_capabilities_info);
own_cap = hapd->iconf->vht_capab;
/* mask out symmetric VHT capabilities we don't support */
sym_caps = VHT_CAP_SHORT_GI_80 | VHT_CAP_SHORT_GI_160;
cap &= ~sym_caps | (own_cap & sym_caps);
/* mask out beamformer/beamformee caps if not supported */
if (!(own_cap & VHT_CAP_SU_BEAMFORMER_CAPABLE))
cap &= ~(VHT_CAP_SU_BEAMFORMEE_CAPABLE |
VHT_CAP_BEAMFORMEE_STS_MAX);
if (!(own_cap & VHT_CAP_SU_BEAMFORMEE_CAPABLE))
cap &= ~(VHT_CAP_SU_BEAMFORMER_CAPABLE |
VHT_CAP_SOUNDING_DIMENSION_MAX);
if (!(own_cap & VHT_CAP_MU_BEAMFORMER_CAPABLE))
cap &= ~VHT_CAP_MU_BEAMFORMEE_CAPABLE;
if (!(own_cap & VHT_CAP_MU_BEAMFORMEE_CAPABLE))
cap &= ~VHT_CAP_MU_BEAMFORMER_CAPABLE;
/* mask channel widths we don't support */
switch (own_cap & VHT_CAP_SUPP_CHAN_WIDTH_MASK) {
case VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ:
break;
case VHT_CAP_SUPP_CHAN_WIDTH_160MHZ:
if (cap & VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) {
cap &= ~VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
cap |= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
}
break;
default:
cap &= ~VHT_CAP_SUPP_CHAN_WIDTH_MASK;
break;
}
if (!(cap & VHT_CAP_SUPP_CHAN_WIDTH_MASK))
cap &= ~VHT_CAP_SHORT_GI_160;
/*
* if we don't support RX STBC, mask out TX STBC in the STA's HT caps
* if we don't support TX STBC, mask out RX STBC in the STA's HT caps
*/
if (!(own_cap & VHT_CAP_RXSTBC_MASK))
cap &= ~VHT_CAP_TXSTBC;
if (!(own_cap & VHT_CAP_TXSTBC))
cap &= ~VHT_CAP_RXSTBC_MASK;
neg_vht_cap->vht_capabilities_info = host_to_le32(cap);
} }

View file

@ -707,6 +707,7 @@ struct ieee80211_vht_operation {
#define VHT_CAP_MAX_MPDU_LENGTH_MASK ((u32) BIT(0) | BIT(1)) #define VHT_CAP_MAX_MPDU_LENGTH_MASK ((u32) BIT(0) | BIT(1))
#define VHT_CAP_SUPP_CHAN_WIDTH_160MHZ ((u32) BIT(2)) #define VHT_CAP_SUPP_CHAN_WIDTH_160MHZ ((u32) BIT(2))
#define VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ ((u32) BIT(3)) #define VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ ((u32) BIT(3))
#define VHT_CAP_SUPP_CHAN_WIDTH_MASK ((u32) BIT(2) | BIT(3))
#define VHT_CAP_RXLDPC ((u32) BIT(4)) #define VHT_CAP_RXLDPC ((u32) BIT(4))
#define VHT_CAP_SHORT_GI_80 ((u32) BIT(5)) #define VHT_CAP_SHORT_GI_80 ((u32) BIT(5))
#define VHT_CAP_SHORT_GI_160 ((u32) BIT(6)) #define VHT_CAP_SHORT_GI_160 ((u32) BIT(6))