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_parse(tb_band, NL80211_BAND_ATTR_MAX, nla_data(nl_band),
|
||||||
nla_len(nl_band), NULL);
|
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_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_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX, nla_data(nl_freq),
|
||||||
nla_len(nl_freq), freq_policy);
|
nla_len(nl_freq), freq_policy);
|
||||||
|
|
|
@ -234,6 +234,107 @@ static int ieee80211n_allowed_ht40_channel_pair(struct hostapd_iface *iface)
|
||||||
|
|
||||||
return 1;
|
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 */
|
#endif /* CONFIG_IEEE80211N */
|
||||||
|
|
||||||
|
|
||||||
|
@ -303,6 +404,8 @@ int hostapd_select_hw_mode(struct hostapd_iface *iface)
|
||||||
#ifdef CONFIG_IEEE80211N
|
#ifdef CONFIG_IEEE80211N
|
||||||
if (!ieee80211n_allowed_ht40_channel_pair(iface))
|
if (!ieee80211n_allowed_ht40_channel_pair(iface))
|
||||||
return -1;
|
return -1;
|
||||||
|
if (!ieee80211n_supported_ht_capab(iface))
|
||||||
|
return -1;
|
||||||
#endif /* CONFIG_IEEE80211N */
|
#endif /* CONFIG_IEEE80211N */
|
||||||
|
|
||||||
if (hostapd_prepare_rates(iface->bss[0], iface->current_mode)) {
|
if (hostapd_prepare_rates(iface->bss[0], iface->current_mode)) {
|
||||||
|
|
|
@ -47,6 +47,7 @@ struct hostapd_hw_modes {
|
||||||
struct hostapd_channel_data *channels;
|
struct hostapd_channel_data *channels;
|
||||||
int num_rates;
|
int num_rates;
|
||||||
struct hostapd_rate_data *rates;
|
struct hostapd_rate_data *rates;
|
||||||
|
u16 ht_capab;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue