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:
parent
7f0303d5b0
commit
6b02335a96
2 changed files with 53 additions and 1 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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))
|
||||||
|
|
Loading…
Reference in a new issue