Skip to content

Commit

Permalink
mac80211: fix ibss scanning
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Stanislaw Gruszka authored and Johannes Berg committed Jan 3, 2013
1 parent a49f0d1 commit 34bcf71
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 18 deletions.
9 changes: 4 additions & 5 deletions net/mac80211/ibss.c
Original file line number Diff line number Diff line change
Expand Up @@ -703,8 +703,8 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
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)
Expand Down Expand Up @@ -802,9 +802,8 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
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;

Expand Down
6 changes: 3 additions & 3 deletions net/mac80211/ieee80211_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -1329,9 +1329,9 @@ void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,

/* 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);
Expand Down
34 changes: 24 additions & 10 deletions net/mac80211/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -832,9 +832,9 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
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;
Expand All @@ -848,22 +848,36 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,

/* 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;
}
Expand Down

0 comments on commit 34bcf71

Please sign in to comment.