Verify that driver supports configured HT capabilities

This commit is contained in:
Jouni Malinen 2009-02-04 12:49:23 +02:00 committed by Jouni Malinen
parent e80e5163f8
commit 30fd5f1467
3 changed files with 109 additions and 0 deletions

View file

@ -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);

View file

@ -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)) {

View file

@ -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;
}; };