3.7-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Stanislaw Gruszka <[email protected]>

commit 34bcf71502413f8903ade93746f2d0f04b937a78 upstream.

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 <[email protected]>
Reported-by: Mikko Rapeli  <[email protected]>
Signed-off-by: Stanislaw Gruszka <[email protected]>
Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
 net/mac80211/ibss.c        |    9 ++++-----
 net/mac80211/ieee80211_i.h |    6 +++---
 net/mac80211/scan.c        |   34 ++++++++++++++++++++++++----------
 3 files changed, 31 insertions(+), 18 deletions(-)

--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -678,8 +678,8 @@ static void ieee80211_sta_merge_ibss(str
        sdata_info(sdata,
                   "No active IBSS STAs - trying to scan for other IBSS 
networks with same SSID (merge)\n");
 
-       ieee80211_request_internal_scan(sdata,
-                       ifibss->ssid, ifibss->ssid_len, NULL);
+       ieee80211_request_ibss_scan(sdata, ifibss->ssid, ifibss->ssid_len,
+                                   NULL);
 }
 
 static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
@@ -777,9 +777,8 @@ static void ieee80211_sta_find_ibss(stru
                                        IEEE80211_SCAN_INTERVAL)) {
                sdata_info(sdata, "Trigger new scan to find an IBSS to join\n");
 
-               ieee80211_request_internal_scan(sdata,
-                               ifibss->ssid, ifibss->ssid_len,
-                               ifibss->fixed_channel ? ifibss->channel : NULL);
+               ieee80211_request_ibss_scan(sdata, ifibss->ssid,
+                                           ifibss->ssid_len, chan);
        } else {
                int interval = IEEE80211_SCAN_INTERVAL;
 
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1247,9 +1247,9 @@ void ieee80211_mesh_rx_queued_mgmt(struc
 
 /* scan/BSS handling */
 void ieee80211_scan_work(struct work_struct *work);
-int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
-                                   const u8 *ssid, u8 ssid_len,
-                                   struct ieee80211_channel *chan);
+int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
+                               const u8 *ssid, u8 ssid_len,
+                               struct ieee80211_channel *chan);
 int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
                           struct cfg80211_scan_request *req);
 void ieee80211_scan_cancel(struct ieee80211_local *local);
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -819,9 +819,9 @@ int ieee80211_request_scan(struct ieee80
        return res;
 }
 
-int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
-                                   const u8 *ssid, u8 ssid_len,
-                                   struct ieee80211_channel *chan)
+int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
+                               const u8 *ssid, u8 ssid_len,
+                               struct ieee80211_channel *chan)
 {
        struct ieee80211_local *local = sdata->local;
        int ret = -EBUSY;
@@ -835,22 +835,36 @@ int ieee80211_request_internal_scan(stru
 
        /* fill internal scan request */
        if (!chan) {
-               int i, nchan = 0;
+               int i, max_n;
+               int n_ch = 0;
 
                for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
                        if (!local->hw.wiphy->bands[band])
                                continue;
-                       for (i = 0;
-                            i < local->hw.wiphy->bands[band]->n_channels;
-                            i++) {
-                               local->int_scan_req->channels[nchan] =
+
+                       max_n = local->hw.wiphy->bands[band]->n_channels;
+                       for (i = 0; i < max_n; i++) {
+                               struct ieee80211_channel *tmp_ch =
                                    &local->hw.wiphy->bands[band]->channels[i];
-                               nchan++;
+
+                               if (tmp_ch->flags & (IEEE80211_CHAN_NO_IBSS |
+                                                    IEEE80211_CHAN_DISABLED))
+                                       continue;
+
+                               local->int_scan_req->channels[n_ch] = tmp_ch;
+                               n_ch++;
                        }
                }
 
-               local->int_scan_req->n_channels = nchan;
+               if (WARN_ON_ONCE(n_ch == 0))
+                       goto unlock;
+
+               local->int_scan_req->n_channels = n_ch;
        } else {
+               if (WARN_ON_ONCE(chan->flags & (IEEE80211_CHAN_NO_IBSS |
+                                               IEEE80211_CHAN_DISABLED)))
+                       goto unlock;
+
                local->int_scan_req->channels[0] = chan;
                local->int_scan_req->n_channels = 1;
        }


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to