nl80211: Clean up capability querying
There's no need to store everything once and then copy it. Just fill the capa struct directly in the function that parses the info from nl80211.
This commit is contained in:
parent
9b90955ec7
commit
e8b5e24e04
1 changed files with 57 additions and 70 deletions
|
@ -1704,18 +1704,9 @@ nla_put_failure:
|
|||
|
||||
|
||||
struct wiphy_info_data {
|
||||
int max_scan_ssids;
|
||||
int max_sched_scan_ssids;
|
||||
int ap_supported;
|
||||
int p2p_supported;
|
||||
int p2p_concurrent;
|
||||
int auth_supported;
|
||||
int connect_supported;
|
||||
int offchan_tx_supported;
|
||||
int max_remain_on_chan;
|
||||
int firmware_roam;
|
||||
int sched_scan_supported;
|
||||
int max_match_sets;
|
||||
struct wpa_driver_capa *capa;
|
||||
|
||||
unsigned int error:1;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1725,6 +1716,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
|
|||
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
|
||||
struct wiphy_info_data *info = arg;
|
||||
int p2p_go_supported = 0, p2p_client_supported = 0;
|
||||
int p2p_concurrent = 0;
|
||||
int auth_supported = 0, connect_supported = 0;
|
||||
struct wpa_driver_capa *capa = info->capa;
|
||||
static struct nla_policy
|
||||
iface_combination_policy[NUM_NL80211_IFACE_COMB] = {
|
||||
[NL80211_IFACE_COMB_LIMITS] = { .type = NLA_NESTED },
|
||||
|
@ -1741,15 +1735,15 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
|
|||
genlmsg_attrlen(gnlh, 0), NULL);
|
||||
|
||||
if (tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS])
|
||||
info->max_scan_ssids =
|
||||
capa->max_scan_ssids =
|
||||
nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]);
|
||||
|
||||
if (tb[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS])
|
||||
info->max_sched_scan_ssids =
|
||||
capa->max_sched_scan_ssids =
|
||||
nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS]);
|
||||
|
||||
if (tb[NL80211_ATTR_MAX_MATCH_SETS])
|
||||
info->max_match_sets =
|
||||
capa->max_match_sets =
|
||||
nla_get_u8(tb[NL80211_ATTR_MAX_MATCH_SETS]);
|
||||
|
||||
if (tb[NL80211_ATTR_SUPPORTED_IFTYPES]) {
|
||||
|
@ -1759,7 +1753,7 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
|
|||
tb[NL80211_ATTR_SUPPORTED_IFTYPES], i) {
|
||||
switch (nla_type(nl_mode)) {
|
||||
case NL80211_IFTYPE_AP:
|
||||
info->ap_supported = 1;
|
||||
capa->flags |= WPA_DRIVER_FLAGS_AP;
|
||||
break;
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
p2p_go_supported = 1;
|
||||
|
@ -1819,7 +1813,7 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
|
|||
}
|
||||
|
||||
if (combination_has_p2p && combination_has_mgd) {
|
||||
info->p2p_concurrent = 1;
|
||||
p2p_concurrent = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1828,34 +1822,61 @@ broken_combination:
|
|||
}
|
||||
}
|
||||
|
||||
info->p2p_supported = p2p_go_supported && p2p_client_supported;
|
||||
|
||||
if (tb[NL80211_ATTR_SUPPORTED_COMMANDS]) {
|
||||
struct nlattr *nl_cmd;
|
||||
int i;
|
||||
|
||||
nla_for_each_nested(nl_cmd,
|
||||
tb[NL80211_ATTR_SUPPORTED_COMMANDS], i) {
|
||||
u32 cmd = nla_get_u32(nl_cmd);
|
||||
if (cmd == NL80211_CMD_AUTHENTICATE)
|
||||
info->auth_supported = 1;
|
||||
else if (cmd == NL80211_CMD_CONNECT)
|
||||
info->connect_supported = 1;
|
||||
else if (cmd == NL80211_CMD_START_SCHED_SCAN)
|
||||
info->sched_scan_supported = 1;
|
||||
switch (nla_get_u32(nl_cmd)) {
|
||||
case NL80211_CMD_AUTHENTICATE:
|
||||
auth_supported = 1;
|
||||
break;
|
||||
case NL80211_CMD_CONNECT:
|
||||
connect_supported = 1;
|
||||
break;
|
||||
case NL80211_CMD_START_SCHED_SCAN:
|
||||
capa->sched_scan_supported = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tb[NL80211_ATTR_OFFCHANNEL_TX_OK])
|
||||
info->offchan_tx_supported = 1;
|
||||
if (tb[NL80211_ATTR_OFFCHANNEL_TX_OK]) {
|
||||
wpa_printf(MSG_DEBUG, "nl80211: Using driver-based "
|
||||
"off-channel TX");
|
||||
capa->flags |= WPA_DRIVER_FLAGS_OFFCHANNEL_TX;
|
||||
}
|
||||
|
||||
if (tb[NL80211_ATTR_ROAM_SUPPORT])
|
||||
info->firmware_roam = 1;
|
||||
if (tb[NL80211_ATTR_ROAM_SUPPORT]) {
|
||||
wpa_printf(MSG_DEBUG, "nl80211: Using driver-based roaming");
|
||||
capa->flags |= WPA_DRIVER_FLAGS_BSS_SELECTION;
|
||||
}
|
||||
|
||||
/* default to 5000 since early versions of mac80211 don't set it */
|
||||
capa->max_remain_on_chan = 5000;
|
||||
|
||||
if (tb[NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION])
|
||||
info->max_remain_on_chan =
|
||||
capa->max_remain_on_chan =
|
||||
nla_get_u32(tb[NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION]);
|
||||
|
||||
if (auth_supported)
|
||||
capa->flags |= WPA_DRIVER_FLAGS_SME;
|
||||
else if (!connect_supported) {
|
||||
wpa_printf(MSG_INFO, "nl80211: Driver does not support "
|
||||
"authentication/association or connect commands");
|
||||
info->error = 1;
|
||||
}
|
||||
|
||||
if (p2p_go_supported && p2p_client_supported)
|
||||
capa->flags |= WPA_DRIVER_FLAGS_P2P_CAPABLE;
|
||||
if (p2p_concurrent) {
|
||||
wpa_printf(MSG_DEBUG, "nl80211: Use separate P2P group "
|
||||
"interface (driver advertised support)");
|
||||
capa->flags |= WPA_DRIVER_FLAGS_P2P_CONCURRENT;
|
||||
capa->flags |= WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P;
|
||||
}
|
||||
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
||||
|
@ -1866,9 +1887,7 @@ static int wpa_driver_nl80211_get_info(struct wpa_driver_nl80211_data *drv,
|
|||
struct nl_msg *msg;
|
||||
|
||||
os_memset(info, 0, sizeof(*info));
|
||||
|
||||
/* default to 5000 since early versions of mac80211 don't set it */
|
||||
info->max_remain_on_chan = 5000;
|
||||
info->capa = &drv->capa;
|
||||
|
||||
msg = nlmsg_alloc();
|
||||
if (!msg)
|
||||
|
@ -1893,6 +1912,10 @@ static int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
|
|||
struct wiphy_info_data info;
|
||||
if (wpa_driver_nl80211_get_info(drv, &info))
|
||||
return -1;
|
||||
|
||||
if (info.error)
|
||||
return -1;
|
||||
|
||||
drv->has_capability = 1;
|
||||
/* For now, assume TKIP, CCMP, WPA, WPA2 are supported */
|
||||
drv->capa.key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA |
|
||||
|
@ -1907,46 +1930,10 @@ static int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
|
|||
WPA_DRIVER_AUTH_SHARED |
|
||||
WPA_DRIVER_AUTH_LEAP;
|
||||
|
||||
drv->capa.max_scan_ssids = info.max_scan_ssids;
|
||||
drv->capa.max_sched_scan_ssids = info.max_sched_scan_ssids;
|
||||
drv->capa.sched_scan_supported = info.sched_scan_supported;
|
||||
drv->capa.max_match_sets = info.max_match_sets;
|
||||
|
||||
if (info.ap_supported)
|
||||
drv->capa.flags |= WPA_DRIVER_FLAGS_AP;
|
||||
|
||||
if (info.auth_supported)
|
||||
drv->capa.flags |= WPA_DRIVER_FLAGS_SME;
|
||||
else if (!info.connect_supported) {
|
||||
wpa_printf(MSG_INFO, "nl80211: Driver does not support "
|
||||
"authentication/association or connect commands");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (info.offchan_tx_supported) {
|
||||
wpa_printf(MSG_DEBUG, "nl80211: Using driver-based "
|
||||
"off-channel TX");
|
||||
drv->capa.flags |= WPA_DRIVER_FLAGS_OFFCHANNEL_TX;
|
||||
}
|
||||
|
||||
if (info.firmware_roam) {
|
||||
wpa_printf(MSG_DEBUG, "nl80211: Using driver-based roaming");
|
||||
drv->capa.flags |= WPA_DRIVER_FLAGS_BSS_SELECTION;
|
||||
}
|
||||
|
||||
drv->capa.flags |= WPA_DRIVER_FLAGS_SANE_ERROR_CODES;
|
||||
drv->capa.flags |= WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE;
|
||||
if (info.p2p_supported)
|
||||
drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_CAPABLE;
|
||||
if (info.p2p_concurrent) {
|
||||
wpa_printf(MSG_DEBUG, "nl80211: Use separate P2P group "
|
||||
"interface (driver advertised support)");
|
||||
drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_CONCURRENT;
|
||||
drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P;
|
||||
}
|
||||
drv->capa.flags |= WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
|
||||
drv->capa.flags |= WPA_DRIVER_FLAGS_DEAUTH_TX_STATUS;
|
||||
drv->capa.max_remain_on_chan = info.max_remain_on_chan;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue