diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/wireless/Kconfig | 11 | ||||
-rw-r--r-- | net/wireless/scan.c | 41 |
2 files changed, 44 insertions, 8 deletions
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig index 68c504fab12..abf7ca3f9ff 100644 --- a/net/wireless/Kconfig +++ b/net/wireless/Kconfig @@ -1,6 +1,15 @@ config CFG80211 - tristate "Improved wireless configuration API" + tristate "cfg80211 - wireless configuration API" depends on RFKILL || !RFKILL + ---help--- + cfg80211 is the Linux wireless LAN (802.11) configuration API. + Enable this if you have a wireless device. + + For more information refer to documentation on the wireless wiki: + + http://wireless.kernel.org/en/developers/Documentation/cfg80211 + + When built as a module it will be called cfg80211. config NL80211_TESTMODE bool "nl80211 testmode command" diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 19c5a9a8d08..4c210c2debc 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -607,6 +607,9 @@ int cfg80211_wext_siwscan(struct net_device *dev, if (!netif_running(dev)) return -ENETDOWN; + if (wrqu->data.length == sizeof(struct iw_scan_req)) + wreq = (struct iw_scan_req *)extra; + rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex); if (IS_ERR(rdev)) @@ -619,9 +622,14 @@ int cfg80211_wext_siwscan(struct net_device *dev, wiphy = &rdev->wiphy; - for (band = 0; band < IEEE80211_NUM_BANDS; band++) - if (wiphy->bands[band]) - n_channels += wiphy->bands[band]->n_channels; + /* Determine number of channels, needed to allocate creq */ + if (wreq && wreq->num_channels) + n_channels = wreq->num_channels; + else { + for (band = 0; band < IEEE80211_NUM_BANDS; band++) + if (wiphy->bands[band]) + n_channels += wiphy->bands[band]->n_channels; + } creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) + n_channels * sizeof(void *), @@ -638,22 +646,41 @@ int cfg80211_wext_siwscan(struct net_device *dev, creq->n_channels = n_channels; creq->n_ssids = 1; - /* all channels */ + /* translate "Scan on frequencies" request */ i = 0; 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++) { + + /* If we have a wireless request structure and the + * wireless request specifies frequencies, then search + * for the matching hardware channel. + */ + if (wreq && wreq->num_channels) { + int k; + int wiphy_freq = wiphy->bands[band]->channels[j].center_freq; + for (k = 0; k < wreq->num_channels; k++) { + int wext_freq = wreq->channel_list[k].m / 100000; + if (wext_freq == wiphy_freq) + goto wext_freq_found; + } + goto wext_freq_not_found; + } + + wext_freq_found: creq->channels[i] = &wiphy->bands[band]->channels[j]; i++; + wext_freq_not_found: ; } } - /* translate scan request */ - if (wrqu->data.length == sizeof(struct iw_scan_req)) { - wreq = (struct iw_scan_req *)extra; + /* Set real number of channels specified in creq->channels[] */ + creq->n_channels = i; + /* translate "Scan for SSID" request */ + if (wreq) { if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { if (wreq->essid_len > IEEE80211_MAX_SSID_LEN) return -EINVAL; |