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 /net/wireless/scan.c | |
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>
Diffstat (limited to 'net/wireless/scan.c')
-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; |