Verify that driver supports configured HT capabilities
This commit is contained in:
parent
e80e5163f8
commit
30fd5f1467
3 changed files with 109 additions and 0 deletions
|
@ -1378,6 +1378,11 @@ static int phy_info_handler(struct nl_msg *msg, void *arg)
|
|||
nla_parse(tb_band, NL80211_BAND_ATTR_MAX, nla_data(nl_band),
|
||||
nla_len(nl_band), NULL);
|
||||
|
||||
if (tb_band[NL80211_BAND_ATTR_HT_CAPA]) {
|
||||
mode->ht_capab = nla_get_u16(
|
||||
tb_band[NL80211_BAND_ATTR_HT_CAPA]);
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
|
@ -234,6 +234,107 @@ static int ieee80211n_allowed_ht40_channel_pair(struct hostapd_iface *iface)
|
|||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int ieee80211n_supported_ht_capab(struct hostapd_iface *iface)
|
||||
{
|
||||
u16 hw = iface->current_mode->ht_capab;
|
||||
u16 conf = iface->conf->ht_capab;
|
||||
|
||||
if (!iface->conf->ieee80211n)
|
||||
return 1;
|
||||
|
||||
if ((conf & HT_CAP_INFO_LDPC_CODING_CAP) &&
|
||||
!(hw & HT_CAP_INFO_LDPC_CODING_CAP)) {
|
||||
wpa_printf(MSG_ERROR, "Driver does not support configured "
|
||||
"HT capability [LDPC]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((conf & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) &&
|
||||
!(hw & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) {
|
||||
wpa_printf(MSG_ERROR, "Driver does not support configured "
|
||||
"HT capability [HT40*]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((conf & HT_CAP_INFO_SMPS_MASK) != (hw & HT_CAP_INFO_SMPS_MASK) &&
|
||||
(conf & HT_CAP_INFO_SMPS_MASK) != HT_CAP_INFO_SMPS_DISABLED) {
|
||||
wpa_printf(MSG_ERROR, "Driver does not support configured "
|
||||
"HT capability [SMPS-*]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((conf & HT_CAP_INFO_GREEN_FIELD) &&
|
||||
!(hw & HT_CAP_INFO_GREEN_FIELD)) {
|
||||
wpa_printf(MSG_ERROR, "Driver does not support configured "
|
||||
"HT capability [GF]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((conf & HT_CAP_INFO_SHORT_GI20MHZ) &&
|
||||
!(hw & HT_CAP_INFO_SHORT_GI20MHZ)) {
|
||||
wpa_printf(MSG_ERROR, "Driver does not support configured "
|
||||
"HT capability [SHORT-GI-20]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((conf & HT_CAP_INFO_SHORT_GI40MHZ) &&
|
||||
!(hw & HT_CAP_INFO_SHORT_GI40MHZ)) {
|
||||
wpa_printf(MSG_ERROR, "Driver does not support configured "
|
||||
"HT capability [SHORT-GI-40]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((conf & HT_CAP_INFO_TX_STBC) && !(hw & HT_CAP_INFO_TX_STBC)) {
|
||||
wpa_printf(MSG_ERROR, "Driver does not support configured "
|
||||
"HT capability [TX-STBC]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((conf & HT_CAP_INFO_RX_STBC_MASK) >
|
||||
(hw & HT_CAP_INFO_RX_STBC_MASK)) {
|
||||
wpa_printf(MSG_ERROR, "Driver does not support configured "
|
||||
"HT capability [RX-STBC*]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((conf & HT_CAP_INFO_DELAYED_BA) &&
|
||||
!(hw & HT_CAP_INFO_DELAYED_BA)) {
|
||||
wpa_printf(MSG_ERROR, "Driver does not support configured "
|
||||
"HT capability [DELAYED-BA]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((conf & HT_CAP_INFO_MAX_AMSDU_SIZE) &&
|
||||
!(hw & HT_CAP_INFO_MAX_AMSDU_SIZE)) {
|
||||
wpa_printf(MSG_ERROR, "Driver does not support configured "
|
||||
"HT capability [MAX-AMSDU-7935]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((conf & HT_CAP_INFO_DSSS_CCK40MHZ) &&
|
||||
!(hw & HT_CAP_INFO_DSSS_CCK40MHZ)) {
|
||||
wpa_printf(MSG_ERROR, "Driver does not support configured "
|
||||
"HT capability [DSSS_CCK-40]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((conf & HT_CAP_INFO_PSMP_SUPP) && !(hw & HT_CAP_INFO_PSMP_SUPP)) {
|
||||
wpa_printf(MSG_ERROR, "Driver does not support configured "
|
||||
"HT capability [PSMP]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((conf & HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT) &&
|
||||
!(hw & HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT)) {
|
||||
wpa_printf(MSG_ERROR, "Driver does not support configured "
|
||||
"HT capability [LSIG-TXOP-PROT]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif /* CONFIG_IEEE80211N */
|
||||
|
||||
|
||||
|
@ -303,6 +404,8 @@ int hostapd_select_hw_mode(struct hostapd_iface *iface)
|
|||
#ifdef CONFIG_IEEE80211N
|
||||
if (!ieee80211n_allowed_ht40_channel_pair(iface))
|
||||
return -1;
|
||||
if (!ieee80211n_supported_ht_capab(iface))
|
||||
return -1;
|
||||
#endif /* CONFIG_IEEE80211N */
|
||||
|
||||
if (hostapd_prepare_rates(iface->bss[0], iface->current_mode)) {
|
||||
|
|
|
@ -47,6 +47,7 @@ struct hostapd_hw_modes {
|
|||
struct hostapd_channel_data *channels;
|
||||
int num_rates;
|
||||
struct hostapd_rate_data *rates;
|
||||
u16 ht_capab;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue