aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorStanislaw Gruszka <sgruszka@redhat.com>2012-12-11 04:48:23 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-01-03 06:59:57 -0500
commit34bcf71502413f8903ade93746f2d0f04b937a78 (patch)
treef29898115ed90311f2f8e9af34825ec77b9f0dbe /net
parenta49f0d1ea3ec94fc7cf33a7c36a16343b74bd565 (diff)
mac80211: fix ibss scanning
Do not scan on no-IBSS and disabled channels in IBSS mode. Doing this can trigger Microcode errors on iwlwifi and iwlegacy drivers. Also rename ieee80211_request_internal_scan() function since it is only used in IBSS mode and simplify calling it from ieee80211_sta_find_ibss(). This patch should address: https://bugzilla.redhat.com/show_bug.cgi?id=883414 https://bugzilla.kernel.org/show_bug.cgi?id=49411 Reported-by: Jesse Kahtava <jesse_kahtava@f-m.fm> Reported-by: Mikko Rapeli <mikko.rapeli@iki.fi> Cc: stable@vger.kernel.org Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/ibss.c9
-rw-r--r--net/mac80211/ieee80211_i.h6
-rw-r--r--net/mac80211/scan.c34
3 files changed, 31 insertions, 18 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 8881fc77fb13..6b7644e818d8 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -703,8 +703,8 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
703 sdata_info(sdata, 703 sdata_info(sdata,
704 "No active IBSS STAs - trying to scan for other IBSS networks with same SSID (merge)\n"); 704 "No active IBSS STAs - trying to scan for other IBSS networks with same SSID (merge)\n");
705 705
706 ieee80211_request_internal_scan(sdata, 706 ieee80211_request_ibss_scan(sdata, ifibss->ssid, ifibss->ssid_len,
707 ifibss->ssid, ifibss->ssid_len, NULL); 707 NULL);
708} 708}
709 709
710static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) 710static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
@@ -802,9 +802,8 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
802 IEEE80211_SCAN_INTERVAL)) { 802 IEEE80211_SCAN_INTERVAL)) {
803 sdata_info(sdata, "Trigger new scan to find an IBSS to join\n"); 803 sdata_info(sdata, "Trigger new scan to find an IBSS to join\n");
804 804
805 ieee80211_request_internal_scan(sdata, 805 ieee80211_request_ibss_scan(sdata, ifibss->ssid,
806 ifibss->ssid, ifibss->ssid_len, 806 ifibss->ssid_len, chan);
807 ifibss->fixed_channel ? ifibss->channel : NULL);
808 } else { 807 } else {
809 int interval = IEEE80211_SCAN_INTERVAL; 808 int interval = IEEE80211_SCAN_INTERVAL;
810 809
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 42d0d0267730..112bb6192399 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1329,9 +1329,9 @@ void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1329 1329
1330/* scan/BSS handling */ 1330/* scan/BSS handling */
1331void ieee80211_scan_work(struct work_struct *work); 1331void ieee80211_scan_work(struct work_struct *work);
1332int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, 1332int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
1333 const u8 *ssid, u8 ssid_len, 1333 const u8 *ssid, u8 ssid_len,
1334 struct ieee80211_channel *chan); 1334 struct ieee80211_channel *chan);
1335int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, 1335int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
1336 struct cfg80211_scan_request *req); 1336 struct cfg80211_scan_request *req);
1337void ieee80211_scan_cancel(struct ieee80211_local *local); 1337void ieee80211_scan_cancel(struct ieee80211_local *local);
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 8ed83dcc149f..de3532d18df1 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -832,9 +832,9 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
832 return res; 832 return res;
833} 833}
834 834
835int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, 835int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
836 const u8 *ssid, u8 ssid_len, 836 const u8 *ssid, u8 ssid_len,
837 struct ieee80211_channel *chan) 837 struct ieee80211_channel *chan)
838{ 838{
839 struct ieee80211_local *local = sdata->local; 839 struct ieee80211_local *local = sdata->local;
840 int ret = -EBUSY; 840 int ret = -EBUSY;
@@ -848,22 +848,36 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
848 848
849 /* fill internal scan request */ 849 /* fill internal scan request */
850 if (!chan) { 850 if (!chan) {
851 int i, nchan = 0; 851 int i, max_n;
852 int n_ch = 0;
852 853
853 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 854 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
854 if (!local->hw.wiphy->bands[band]) 855 if (!local->hw.wiphy->bands[band])
855 continue; 856 continue;
856 for (i = 0; 857
857 i < local->hw.wiphy->bands[band]->n_channels; 858 max_n = local->hw.wiphy->bands[band]->n_channels;
858 i++) { 859 for (i = 0; i < max_n; i++) {
859 local->int_scan_req->channels[nchan] = 860 struct ieee80211_channel *tmp_ch =
860 &local->hw.wiphy->bands[band]->channels[i]; 861 &local->hw.wiphy->bands[band]->channels[i];
861 nchan++; 862
863 if (tmp_ch->flags & (IEEE80211_CHAN_NO_IBSS |
864 IEEE80211_CHAN_DISABLED))
865 continue;
866
867 local->int_scan_req->channels[n_ch] = tmp_ch;
868 n_ch++;
862 } 869 }
863 } 870 }
864 871
865 local->int_scan_req->n_channels = nchan; 872 if (WARN_ON_ONCE(n_ch == 0))
873 goto unlock;
874
875 local->int_scan_req->n_channels = n_ch;
866 } else { 876 } else {
877 if (WARN_ON_ONCE(chan->flags & (IEEE80211_CHAN_NO_IBSS |
878 IEEE80211_CHAN_DISABLED)))
879 goto unlock;
880
867 local->int_scan_req->channels[0] = chan; 881 local->int_scan_req->channels[0] = chan;
868 local->int_scan_req->n_channels = 1; 882 local->int_scan_req->n_channels = 1;
869 } 883 }