Parse and add channel information to the periodic scan request. Signed-off-by: Luciano Coelho <luciano.coelho@xxxxxxxxx> --- net/wireless/nl80211.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 71 insertions(+), 2 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index e1d7ab2..d5b9047 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -3004,7 +3004,11 @@ static int nl80211_start_periodic(struct sk_buff *skb, struct cfg80211_periodic_request *request; struct cfg80211_registered_device *rdev; struct net_device *dev; - int err; + struct ieee80211_channel *channel; + struct nlattr *attr; + struct wiphy *wiphy; + int err, tmp, n_channels, i; + enum ieee80211_band band; printk("nl80211_start_periodic\n"); @@ -3029,7 +3033,24 @@ static int nl80211_start_periodic(struct sk_buff *skb, goto out; } - request = kzalloc(sizeof(*request), GFP_KERNEL); + wiphy = &rdev->wiphy; + + if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { + n_channels = validate_scan_freqs( + info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]); + if (!n_channels) + return -EINVAL; + } else { + n_channels = 0; + + for (band = 0; band < IEEE80211_NUM_BANDS; band++) + if (wiphy->bands[band]) + n_channels += wiphy->bands[band]->n_channels; + } + + request = kzalloc(sizeof(*request) + + sizeof(channel) * n_channels, + GFP_KERNEL); if (!request) { err = -ENOMEM; goto out; @@ -3040,8 +3061,56 @@ static int nl80211_start_periodic(struct sk_buff *skb, rdev->periodic_req = request; + i = 0; + if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { + /* user specified, bail out if channel not found */ + nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp) { + struct ieee80211_channel *chan; + + chan = ieee80211_get_channel(wiphy, nla_get_u32(attr)); + + if (!chan) { + err = -EINVAL; + goto out_free; + } + + /* ignore disabled channels */ + if (chan->flags & IEEE80211_CHAN_DISABLED) + continue; + + request->channels[i] = chan; + i++; + } + } else { + /* all channels */ + for (band = 0; band < IEEE80211_NUM_BANDS; band++) { + int j; + if (!wiphy->bands[band]) + continue; + for (j = 0; j < wiphy->bands[band]->n_channels; j++) { + struct ieee80211_channel *chan; + + chan = &wiphy->bands[band]->channels[j]; + + if (chan->flags & IEEE80211_CHAN_DISABLED) + continue; + + request->channels[i] = chan; + i++; + } + } + } + + if (!i) { + err = -EINVAL; + goto out_free; + } + + request->n_channels = i; + err = rdev->ops->periodic_start(&rdev->wiphy, dev, request); if (err) { +out_free: kfree(request); rdev->periodic_req = NULL; goto out; -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html