aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/scan.c')
-rw-r--r--net/wireless/scan.c71
1 files changed, 44 insertions, 27 deletions
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index e5f92ee758f4..0c2cbbebca95 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -22,7 +22,7 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak)
22{ 22{
23 struct cfg80211_scan_request *request; 23 struct cfg80211_scan_request *request;
24 struct net_device *dev; 24 struct net_device *dev;
25#ifdef CONFIG_WIRELESS_EXT 25#ifdef CONFIG_CFG80211_WEXT
26 union iwreq_data wrqu; 26 union iwreq_data wrqu;
27#endif 27#endif
28 28
@@ -47,7 +47,7 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak)
47 else 47 else
48 nl80211_send_scan_done(rdev, dev); 48 nl80211_send_scan_done(rdev, dev);
49 49
50#ifdef CONFIG_WIRELESS_EXT 50#ifdef CONFIG_CFG80211_WEXT
51 if (!request->aborted) { 51 if (!request->aborted) {
52 memset(&wrqu, 0, sizeof(wrqu)); 52 memset(&wrqu, 0, sizeof(wrqu));
53 53
@@ -88,7 +88,7 @@ void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
88 WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req); 88 WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req);
89 89
90 request->aborted = aborted; 90 request->aborted = aborted;
91 schedule_work(&wiphy_to_dev(request->wiphy)->scan_done_wk); 91 queue_work(cfg80211_wq, &wiphy_to_dev(request->wiphy)->scan_done_wk);
92} 92}
93EXPORT_SYMBOL(cfg80211_scan_done); 93EXPORT_SYMBOL(cfg80211_scan_done);
94 94
@@ -217,7 +217,7 @@ static bool is_mesh(struct cfg80211_bss *a,
217 a->len_information_elements); 217 a->len_information_elements);
218 if (!ie) 218 if (!ie)
219 return false; 219 return false;
220 if (ie[1] != IEEE80211_MESH_CONFIG_LEN) 220 if (ie[1] != sizeof(struct ieee80211_meshconf_ie))
221 return false; 221 return false;
222 222
223 /* 223 /*
@@ -225,7 +225,8 @@ static bool is_mesh(struct cfg80211_bss *a,
225 * comparing since that may differ between stations taking 225 * comparing since that may differ between stations taking
226 * part in the same mesh. 226 * part in the same mesh.
227 */ 227 */
228 return memcmp(ie + 2, meshcfg, IEEE80211_MESH_CONFIG_LEN - 2) == 0; 228 return memcmp(ie + 2, meshcfg,
229 sizeof(struct ieee80211_meshconf_ie) - 2) == 0;
229} 230}
230 231
231static int cmp_bss(struct cfg80211_bss *a, 232static int cmp_bss(struct cfg80211_bss *a,
@@ -399,7 +400,7 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
399 res->pub.information_elements, 400 res->pub.information_elements,
400 res->pub.len_information_elements); 401 res->pub.len_information_elements);
401 if (!meshid || !meshcfg || 402 if (!meshid || !meshcfg ||
402 meshcfg[1] != IEEE80211_MESH_CONFIG_LEN) { 403 meshcfg[1] != sizeof(struct ieee80211_meshconf_ie)) {
403 /* bogus mesh */ 404 /* bogus mesh */
404 kref_put(&res->ref, bss_release); 405 kref_put(&res->ref, bss_release);
405 return NULL; 406 return NULL;
@@ -592,7 +593,7 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
592} 593}
593EXPORT_SYMBOL(cfg80211_unlink_bss); 594EXPORT_SYMBOL(cfg80211_unlink_bss);
594 595
595#ifdef CONFIG_WIRELESS_EXT 596#ifdef CONFIG_CFG80211_WEXT
596int cfg80211_wext_siwscan(struct net_device *dev, 597int cfg80211_wext_siwscan(struct net_device *dev,
597 struct iw_request_info *info, 598 struct iw_request_info *info,
598 union iwreq_data *wrqu, char *extra) 599 union iwreq_data *wrqu, char *extra)
@@ -600,7 +601,7 @@ int cfg80211_wext_siwscan(struct net_device *dev,
600 struct cfg80211_registered_device *rdev; 601 struct cfg80211_registered_device *rdev;
601 struct wiphy *wiphy; 602 struct wiphy *wiphy;
602 struct iw_scan_req *wreq = NULL; 603 struct iw_scan_req *wreq = NULL;
603 struct cfg80211_scan_request *creq; 604 struct cfg80211_scan_request *creq = NULL;
604 int i, err, n_channels = 0; 605 int i, err, n_channels = 0;
605 enum ieee80211_band band; 606 enum ieee80211_band band;
606 607
@@ -650,9 +651,15 @@ int cfg80211_wext_siwscan(struct net_device *dev,
650 i = 0; 651 i = 0;
651 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 652 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
652 int j; 653 int j;
654
653 if (!wiphy->bands[band]) 655 if (!wiphy->bands[band])
654 continue; 656 continue;
657
655 for (j = 0; j < wiphy->bands[band]->n_channels; j++) { 658 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
659 /* ignore disabled channels */
660 if (wiphy->bands[band]->channels[j].flags &
661 IEEE80211_CHAN_DISABLED)
662 continue;
656 663
657 /* If we have a wireless request structure and the 664 /* If we have a wireless request structure and the
658 * wireless request specifies frequencies, then search 665 * wireless request specifies frequencies, then search
@@ -687,8 +694,10 @@ int cfg80211_wext_siwscan(struct net_device *dev,
687 /* translate "Scan for SSID" request */ 694 /* translate "Scan for SSID" request */
688 if (wreq) { 695 if (wreq) {
689 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { 696 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
690 if (wreq->essid_len > IEEE80211_MAX_SSID_LEN) 697 if (wreq->essid_len > IEEE80211_MAX_SSID_LEN) {
691 return -EINVAL; 698 err = -EINVAL;
699 goto out;
700 }
692 memcpy(creq->ssids[0].ssid, wreq->essid, wreq->essid_len); 701 memcpy(creq->ssids[0].ssid, wreq->essid, wreq->essid_len);
693 creq->ssids[0].ssid_len = wreq->essid_len; 702 creq->ssids[0].ssid_len = wreq->essid_len;
694 } 703 }
@@ -700,12 +709,15 @@ int cfg80211_wext_siwscan(struct net_device *dev,
700 err = rdev->ops->scan(wiphy, dev, creq); 709 err = rdev->ops->scan(wiphy, dev, creq);
701 if (err) { 710 if (err) {
702 rdev->scan_req = NULL; 711 rdev->scan_req = NULL;
703 kfree(creq); 712 /* creq will be freed below */
704 } else { 713 } else {
705 nl80211_send_scan_start(rdev, dev); 714 nl80211_send_scan_start(rdev, dev);
715 /* creq now owned by driver */
716 creq = NULL;
706 dev_hold(dev); 717 dev_hold(dev);
707 } 718 }
708 out: 719 out:
720 kfree(creq);
709 cfg80211_unlock_rdev(rdev); 721 cfg80211_unlock_rdev(rdev);
710 return err; 722 return err;
711} 723}
@@ -859,7 +871,7 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
859 break; 871 break;
860 case WLAN_EID_MESH_CONFIG: 872 case WLAN_EID_MESH_CONFIG:
861 ismesh = true; 873 ismesh = true;
862 if (ie[1] != IEEE80211_MESH_CONFIG_LEN) 874 if (ie[1] != sizeof(struct ieee80211_meshconf_ie))
863 break; 875 break;
864 buf = kmalloc(50, GFP_ATOMIC); 876 buf = kmalloc(50, GFP_ATOMIC);
865 if (!buf) 877 if (!buf)
@@ -867,35 +879,40 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
867 cfg = ie + 2; 879 cfg = ie + 2;
868 memset(&iwe, 0, sizeof(iwe)); 880 memset(&iwe, 0, sizeof(iwe));
869 iwe.cmd = IWEVCUSTOM; 881 iwe.cmd = IWEVCUSTOM;
870 sprintf(buf, "Mesh network (version %d)", cfg[0]); 882 sprintf(buf, "Mesh Network Path Selection Protocol ID: "
883 "0x%02X", cfg[0]);
884 iwe.u.data.length = strlen(buf);
885 current_ev = iwe_stream_add_point(info, current_ev,
886 end_buf,
887 &iwe, buf);
888 sprintf(buf, "Path Selection Metric ID: 0x%02X",
889 cfg[1]);
890 iwe.u.data.length = strlen(buf);
891 current_ev = iwe_stream_add_point(info, current_ev,
892 end_buf,
893 &iwe, buf);
894 sprintf(buf, "Congestion Control Mode ID: 0x%02X",
895 cfg[2]);
871 iwe.u.data.length = strlen(buf); 896 iwe.u.data.length = strlen(buf);
872 current_ev = iwe_stream_add_point(info, current_ev, 897 current_ev = iwe_stream_add_point(info, current_ev,
873 end_buf, 898 end_buf,
874 &iwe, buf); 899 &iwe, buf);
875 sprintf(buf, "Path Selection Protocol ID: " 900 sprintf(buf, "Synchronization ID: 0x%02X", cfg[3]);
876 "0x%02X%02X%02X%02X", cfg[1], cfg[2], cfg[3],
877 cfg[4]);
878 iwe.u.data.length = strlen(buf); 901 iwe.u.data.length = strlen(buf);
879 current_ev = iwe_stream_add_point(info, current_ev, 902 current_ev = iwe_stream_add_point(info, current_ev,
880 end_buf, 903 end_buf,
881 &iwe, buf); 904 &iwe, buf);
882 sprintf(buf, "Path Selection Metric ID: " 905 sprintf(buf, "Authentication ID: 0x%02X", cfg[4]);
883 "0x%02X%02X%02X%02X", cfg[5], cfg[6], cfg[7],
884 cfg[8]);
885 iwe.u.data.length = strlen(buf); 906 iwe.u.data.length = strlen(buf);
886 current_ev = iwe_stream_add_point(info, current_ev, 907 current_ev = iwe_stream_add_point(info, current_ev,
887 end_buf, 908 end_buf,
888 &iwe, buf); 909 &iwe, buf);
889 sprintf(buf, "Congestion Control Mode ID: " 910 sprintf(buf, "Formation Info: 0x%02X", cfg[5]);
890 "0x%02X%02X%02X%02X", cfg[9], cfg[10],
891 cfg[11], cfg[12]);
892 iwe.u.data.length = strlen(buf); 911 iwe.u.data.length = strlen(buf);
893 current_ev = iwe_stream_add_point(info, current_ev, 912 current_ev = iwe_stream_add_point(info, current_ev,
894 end_buf, 913 end_buf,
895 &iwe, buf); 914 &iwe, buf);
896 sprintf(buf, "Channel Precedence: " 915 sprintf(buf, "Capabilities: 0x%02X", cfg[6]);
897 "0x%02X%02X%02X%02X", cfg[13], cfg[14],
898 cfg[15], cfg[16]);
899 iwe.u.data.length = strlen(buf); 916 iwe.u.data.length = strlen(buf);
900 current_ev = iwe_stream_add_point(info, current_ev, 917 current_ev = iwe_stream_add_point(info, current_ev,
901 end_buf, 918 end_buf,
@@ -925,8 +942,8 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
925 ie += ie[1] + 2; 942 ie += ie[1] + 2;
926 } 943 }
927 944
928 if (bss->pub.capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS) 945 if (bss->pub.capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS) ||
929 || ismesh) { 946 ismesh) {
930 memset(&iwe, 0, sizeof(iwe)); 947 memset(&iwe, 0, sizeof(iwe));
931 iwe.cmd = SIOCGIWMODE; 948 iwe.cmd = SIOCGIWMODE;
932 if (ismesh) 949 if (ismesh)