diff options
| author | Holger Schurig <hs4233@mail.mn-solutions.de> | 2009-09-09 07:09:54 -0400 |
|---|---|---|
| committer | John W. Linville <linville@tuxdriver.com> | 2009-09-09 11:25:27 -0400 |
| commit | b2e3abdc708f8c0eff194af25362fdb239abe241 (patch) | |
| tree | a17ba8b9bab9078d73b7c452d3fa345d54a4908d | |
| parent | 8c8f9ba7051b017e44124666b41c1dc70333a77c (diff) | |
cfg80211: allow scanning on specified frequencies when using wext-compatibility
Handles the case when SIOCSIWSCAN specified iw_scan_req.num_channels and
iw_scan_req.channels[].
Signed-off-by: Holger Schurig <hs4233@mail.mn-solutions.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
| -rw-r--r-- | net/wireless/scan.c | 41 |
1 files changed, 34 insertions, 7 deletions
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 19c5a9a8d085..4c210c2debc6 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
| @@ -607,6 +607,9 @@ int cfg80211_wext_siwscan(struct net_device *dev, | |||
| 607 | if (!netif_running(dev)) | 607 | if (!netif_running(dev)) |
| 608 | return -ENETDOWN; | 608 | return -ENETDOWN; |
| 609 | 609 | ||
| 610 | if (wrqu->data.length == sizeof(struct iw_scan_req)) | ||
| 611 | wreq = (struct iw_scan_req *)extra; | ||
| 612 | |||
| 610 | rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex); | 613 | rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex); |
| 611 | 614 | ||
| 612 | if (IS_ERR(rdev)) | 615 | if (IS_ERR(rdev)) |
| @@ -619,9 +622,14 @@ int cfg80211_wext_siwscan(struct net_device *dev, | |||
| 619 | 622 | ||
| 620 | wiphy = &rdev->wiphy; | 623 | wiphy = &rdev->wiphy; |
| 621 | 624 | ||
| 622 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) | 625 | /* Determine number of channels, needed to allocate creq */ |
| 623 | if (wiphy->bands[band]) | 626 | if (wreq && wreq->num_channels) |
| 624 | n_channels += wiphy->bands[band]->n_channels; | 627 | n_channels = wreq->num_channels; |
| 628 | else { | ||
| 629 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) | ||
| 630 | if (wiphy->bands[band]) | ||
| 631 | n_channels += wiphy->bands[band]->n_channels; | ||
| 632 | } | ||
| 625 | 633 | ||
| 626 | creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) + | 634 | creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) + |
| 627 | n_channels * sizeof(void *), | 635 | n_channels * sizeof(void *), |
| @@ -638,22 +646,41 @@ int cfg80211_wext_siwscan(struct net_device *dev, | |||
| 638 | creq->n_channels = n_channels; | 646 | creq->n_channels = n_channels; |
| 639 | creq->n_ssids = 1; | 647 | creq->n_ssids = 1; |
| 640 | 648 | ||
| 641 | /* all channels */ | 649 | /* translate "Scan on frequencies" request */ |
| 642 | i = 0; | 650 | i = 0; |
| 643 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 651 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
| 644 | int j; | 652 | int j; |
| 645 | if (!wiphy->bands[band]) | 653 | if (!wiphy->bands[band]) |
| 646 | continue; | 654 | continue; |
| 647 | for (j = 0; j < wiphy->bands[band]->n_channels; j++) { | 655 | for (j = 0; j < wiphy->bands[band]->n_channels; j++) { |
| 656 | |||
| 657 | /* If we have a wireless request structure and the | ||
| 658 | * wireless request specifies frequencies, then search | ||
| 659 | * for the matching hardware channel. | ||
| 660 | */ | ||
| 661 | if (wreq && wreq->num_channels) { | ||
| 662 | int k; | ||
| 663 | int wiphy_freq = wiphy->bands[band]->channels[j].center_freq; | ||
| 664 | for (k = 0; k < wreq->num_channels; k++) { | ||
| 665 | int wext_freq = wreq->channel_list[k].m / 100000; | ||
| 666 | if (wext_freq == wiphy_freq) | ||
| 667 | goto wext_freq_found; | ||
| 668 | } | ||
| 669 | goto wext_freq_not_found; | ||
| 670 | } | ||
| 671 | |||
| 672 | wext_freq_found: | ||
| 648 | creq->channels[i] = &wiphy->bands[band]->channels[j]; | 673 | creq->channels[i] = &wiphy->bands[band]->channels[j]; |
| 649 | i++; | 674 | i++; |
| 675 | wext_freq_not_found: ; | ||
| 650 | } | 676 | } |
| 651 | } | 677 | } |
| 652 | 678 | ||
| 653 | /* translate scan request */ | 679 | /* Set real number of channels specified in creq->channels[] */ |
| 654 | if (wrqu->data.length == sizeof(struct iw_scan_req)) { | 680 | creq->n_channels = i; |
| 655 | wreq = (struct iw_scan_req *)extra; | ||
| 656 | 681 | ||
| 682 | /* translate "Scan for SSID" request */ | ||
| 683 | if (wreq) { | ||
| 657 | if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { | 684 | if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { |
| 658 | if (wreq->essid_len > IEEE80211_MAX_SSID_LEN) | 685 | if (wreq->essid_len > IEEE80211_MAX_SSID_LEN) |
| 659 | return -EINVAL; | 686 | return -EINVAL; |
