Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 34bcf715 authored by Stanislaw Gruszka's avatar Stanislaw Gruszka Committed by Johannes Berg
Browse files

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: default avatarJesse Kahtava <jesse_kahtava@f-m.fm>
Reported-by: default avatarMikko Rapeli <mikko.rapeli@iki.fi>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarStanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent a49f0d1e
Loading
Loading
Loading
Loading
+4 −5
Original line number Diff line number Diff line
@@ -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)
@@ -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;

+3 −3
Original line number Diff line number Diff line
@@ -1329,7 +1329,7 @@ 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,
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,
+24 −10
Original line number Diff line number Diff line
@@ -832,7 +832,7 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
	return res;
}

int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
				const u8 *ssid, u8 ssid_len,
				struct ieee80211_channel *chan)
{
@@ -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;
	}