nl80211: Add support for sched_scan filtering

Use the SSID filter list passed in the scheduled scan request down to
the kernel driver, so it can use the list to return only the wanted
SSIDs. Some kernel drivers can use this information to offload the
SSID filter to the hardware, helping with reducing the power
consumption.

Signed-off-by: Luciano Coelho <coelho@ti.com>
This commit is contained in:
Luciano Coelho 2011-09-27 22:21:36 +03:00 committed by Jouni Malinen
parent b59e6f267b
commit bd525934e5

View file

@ -1703,6 +1703,7 @@ struct wiphy_info_data {
int max_remain_on_chan; int max_remain_on_chan;
int firmware_roam; int firmware_roam;
int sched_scan_supported; int sched_scan_supported;
int max_match_sets;
}; };
@ -1735,6 +1736,10 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
info->max_sched_scan_ssids = info->max_sched_scan_ssids =
nla_get_u8(tb[NL80211_ATTR_MAX_NUM_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 =
nla_get_u8(tb[NL80211_ATTR_MAX_MATCH_SETS]);
if (tb[NL80211_ATTR_SUPPORTED_IFTYPES]) { if (tb[NL80211_ATTR_SUPPORTED_IFTYPES]) {
struct nlattr *nl_mode; struct nlattr *nl_mode;
int i; int i;
@ -1893,6 +1898,7 @@ static int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
drv->capa.max_scan_ssids = info.max_scan_ssids; drv->capa.max_scan_ssids = info.max_scan_ssids;
drv->capa.max_sched_scan_ssids = info.max_sched_scan_ssids; drv->capa.max_sched_scan_ssids = info.max_sched_scan_ssids;
drv->capa.sched_scan_supported = info.sched_scan_supported; drv->capa.sched_scan_supported = info.sched_scan_supported;
drv->capa.max_match_sets = info.max_match_sets;
if (info.ap_supported) if (info.ap_supported)
drv->capa.flags |= WPA_DRIVER_FLAGS_AP; drv->capa.flags |= WPA_DRIVER_FLAGS_AP;
@ -2651,7 +2657,7 @@ static int wpa_driver_nl80211_sched_scan(void *priv,
struct i802_bss *bss = priv; struct i802_bss *bss = priv;
struct wpa_driver_nl80211_data *drv = bss->drv; struct wpa_driver_nl80211_data *drv = bss->drv;
int ret = 0; int ret = 0;
struct nl_msg *msg, *ssids, *freqs; struct nl_msg *msg, *ssids, *freqs, *match_set_ssid, *match_sets;
size_t i; size_t i;
msg = nlmsg_alloc(); msg = nlmsg_alloc();
@ -2676,6 +2682,31 @@ static int wpa_driver_nl80211_sched_scan(void *priv,
NLA_PUT_U32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL, interval); NLA_PUT_U32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL, interval);
if (drv->num_filter_ssids) {
match_sets = nlmsg_alloc();
for (i = 0; i < drv->num_filter_ssids; i++) {
wpa_hexdump_ascii(MSG_MSGDUMP,
"nl80211: Sched scan filter SSID",
drv->filter_ssids[i].ssid,
drv->filter_ssids[i].ssid_len);
match_set_ssid = nlmsg_alloc();
nla_put(match_set_ssid,
NL80211_ATTR_SCHED_SCAN_MATCH_SSID,
drv->filter_ssids[i].ssid_len,
drv->filter_ssids[i].ssid);
nla_put_nested(match_sets, i + 1, match_set_ssid);
nlmsg_free(match_set_ssid);
}
nla_put_nested(msg, NL80211_ATTR_SCHED_SCAN_MATCH,
match_sets);
nlmsg_free(match_sets);
}
for (i = 0; i < params->num_ssids; i++) { for (i = 0; i < params->num_ssids; i++) {
wpa_hexdump_ascii(MSG_MSGDUMP, "nl80211: Sched scan SSID", wpa_hexdump_ascii(MSG_MSGDUMP, "nl80211: Sched scan SSID",
params->ssids[i].ssid, params->ssids[i].ssid,