aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorHolger Schurig <hs4233@mail.mn-solutions.de>2009-09-09 07:09:54 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-09-09 11:25:27 -0400
commitb2e3abdc708f8c0eff194af25362fdb239abe241 (patch)
treea17ba8b9bab9078d73b7c452d3fa345d54a4908d /net/wireless
parent8c8f9ba7051b017e44124666b41c1dc70333a77c (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')
-rw-r--r--net/wireless/scan.c41
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;