Commit a615323f authored by Benjamin Berg's avatar Benjamin Berg Committed by Johannes Berg

wifi: iwlwifi: mvm: always apply 6 GHz probe limitations

When scanning on 6 GHz we allocate a set of short-SSIDs and BSSIDs to
probe. However, when we need to do an active scan because of a hidden
SSID, then we could add too many entries for probing causing an
assertion in the firmware input validation.

Reshuffle the code a bit to first calculate the maximum number of
short-SSIDs and BSSIDs that are permitted for the channel. Then ensure
that we do not set more than the permitted number of bits in the
bitmasks and turn on force_passive when we have surpassed the limit.

While at it, also change the logic so that allow_passive is always
disabled in case a hidden SSID is included. Previously, we might not
have done so if we added the short-SSID based on the number of BSSIDs
already in the request.
Signed-off-by: default avatarBenjamin Berg <benjamin.berg@intel.com>
Reviewed-by: default avatarIlan Peer <ilan.peer@intel.com>
Signed-off-by: default avatarMiri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://msgid.link/20240319100755.e0b114b68d1d.Ib86afccdb955f0d221ef5d7b8afdc1d67c3542ef@changeidSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 8f892e22
......@@ -1750,8 +1750,9 @@ iwl_mvm_umac_scan_cfg_channels_v7_6g(struct iwl_mvm *mvm,
&cp->channel_config[ch_cnt];
u32 s_ssid_bitmap = 0, bssid_bitmap = 0, flags = 0;
u8 j, k, s_max = 0, b_max = 0, n_used_bssid_entries;
bool force_passive, found = false, allow_passive = true,
u8 j, k, n_s_ssids = 0, n_bssids = 0;
u8 max_s_ssids, max_bssids;
bool force_passive = false, found = false, allow_passive = true,
unsolicited_probe_on_chan = false, psc_no_listen = false;
s8 psd_20 = IEEE80211_RNR_TBTT_PARAMS_PSD_RESERVED;
......@@ -1774,20 +1775,15 @@ iwl_mvm_umac_scan_cfg_channels_v7_6g(struct iwl_mvm *mvm,
cfg->v5.iter_count = 1;
cfg->v5.iter_interval = 0;
/*
* The optimize the scan time, i.e., reduce the scan dwell time
* on each channel, the below logic tries to set 3 direct BSSID
* probe requests for each broadcast probe request with a short
* SSID.
* TODO: improve this logic
*/
n_used_bssid_entries = 3;
for (j = 0; j < params->n_6ghz_params; j++) {
s8 tmp_psd_20;
if (!(scan_6ghz_params[j].channel_idx == i))
continue;
unsolicited_probe_on_chan |=
scan_6ghz_params[j].unsolicited_probe;
/* Use the highest PSD value allowed as advertised by
* APs for this channel
*/
......@@ -1799,12 +1795,69 @@ iwl_mvm_umac_scan_cfg_channels_v7_6g(struct iwl_mvm *mvm,
psd_20 < tmp_psd_20))
psd_20 = tmp_psd_20;
found = false;
unsolicited_probe_on_chan |=
scan_6ghz_params[j].unsolicited_probe;
psc_no_listen |= scan_6ghz_params[j].psc_no_listen;
}
/*
* In the following cases apply passive scan:
* 1. Non fragmented scan:
* - PSC channel with NO_LISTEN_FLAG on should be treated
* like non PSC channel
* - Non PSC channel with more than 3 short SSIDs or more
* than 9 BSSIDs.
* - Non PSC Channel with unsolicited probe response and
* more than 2 short SSIDs or more than 6 BSSIDs.
* - PSC channel with more than 2 short SSIDs or more than
* 6 BSSIDs.
* 3. Fragmented scan:
* - PSC channel with more than 1 SSID or 3 BSSIDs.
* - Non PSC channel with more than 2 SSIDs or 6 BSSIDs.
* - Non PSC channel with unsolicited probe response and
* more than 1 SSID or more than 3 BSSIDs.
*/
if (!iwl_mvm_is_scan_fragmented(params->type)) {
if (!cfg80211_channel_is_psc(params->channels[i]) ||
flags & IWL_UHB_CHAN_CFG_FLAG_PSC_CHAN_NO_LISTEN) {
if (unsolicited_probe_on_chan) {
max_s_ssids = 2;
max_bssids = 6;
} else {
max_s_ssids = 3;
max_bssids = 9;
}
} else {
max_s_ssids = 2;
max_bssids = 6;
}
} else if (cfg80211_channel_is_psc(params->channels[i])) {
max_s_ssids = 1;
max_bssids = 3;
} else {
if (unsolicited_probe_on_chan) {
max_s_ssids = 1;
max_bssids = 3;
} else {
max_s_ssids = 2;
max_bssids = 6;
}
}
/*
* The optimize the scan time, i.e., reduce the scan dwell time
* on each channel, the below logic tries to set 3 direct BSSID
* probe requests for each broadcast probe request with a short
* SSID.
* TODO: improve this logic
*/
for (j = 0; j < params->n_6ghz_params; j++) {
if (!(scan_6ghz_params[j].channel_idx == i))
continue;
found = false;
for (k = 0; k < pp->short_ssid_num; k++) {
for (k = 0;
k < pp->short_ssid_num && n_s_ssids < max_s_ssids;
k++) {
if (!scan_6ghz_params[j].unsolicited_probe &&
le32_to_cpu(pp->short_ssid[k]) ==
scan_6ghz_params[j].short_ssid) {
......@@ -1815,25 +1868,25 @@ iwl_mvm_umac_scan_cfg_channels_v7_6g(struct iwl_mvm *mvm,
}
/*
* Use short SSID only to create a new
* iteration during channel dwell or in
* case that the short SSID has a
* matching SSID, i.e., scan for hidden
* APs.
* Prefer creating BSSID entries unless
* the short SSID probe can be done in
* the same channel dwell iteration.
*
* We also need to create a short SSID
* entry for any hidden AP.
*/
if (n_used_bssid_entries >= 3) {
s_ssid_bitmap |= BIT(k);
s_max++;
n_used_bssid_entries -= 3;
found = true;
if (3 * n_s_ssids > n_bssids &&
!pp->direct_scan[k].len)
break;
} else if (pp->direct_scan[k].len) {
s_ssid_bitmap |= BIT(k);
s_max++;
found = true;
/* Hidden AP, cannot do passive scan */
if (pp->direct_scan[k].len)
allow_passive = false;
break;
}
s_ssid_bitmap |= BIT(k);
n_s_ssids++;
found = true;
break;
}
}
......@@ -1845,9 +1898,12 @@ iwl_mvm_umac_scan_cfg_channels_v7_6g(struct iwl_mvm *mvm,
scan_6ghz_params[j].bssid,
ETH_ALEN)) {
if (!(bssid_bitmap & BIT(k))) {
bssid_bitmap |= BIT(k);
b_max++;
n_used_bssid_entries++;
if (n_bssids < max_bssids) {
bssid_bitmap |= BIT(k);
n_bssids++;
} else {
force_passive = TRUE;
}
}
break;
}
......@@ -1861,39 +1917,6 @@ iwl_mvm_umac_scan_cfg_channels_v7_6g(struct iwl_mvm *mvm,
if (unsolicited_probe_on_chan)
flags |= IWL_UHB_CHAN_CFG_FLAG_UNSOLICITED_PROBE_RES;
/*
* In the following cases apply passive scan:
* 1. Non fragmented scan:
* - PSC channel with NO_LISTEN_FLAG on should be treated
* like non PSC channel
* - Non PSC channel with more than 3 short SSIDs or more
* than 9 BSSIDs.
* - Non PSC Channel with unsolicited probe response and
* more than 2 short SSIDs or more than 6 BSSIDs.
* - PSC channel with more than 2 short SSIDs or more than
* 6 BSSIDs.
* 3. Fragmented scan:
* - PSC channel with more than 1 SSID or 3 BSSIDs.
* - Non PSC channel with more than 2 SSIDs or 6 BSSIDs.
* - Non PSC channel with unsolicited probe response and
* more than 1 SSID or more than 3 BSSIDs.
*/
if (!iwl_mvm_is_scan_fragmented(params->type)) {
if (!cfg80211_channel_is_psc(params->channels[i]) ||
flags & IWL_UHB_CHAN_CFG_FLAG_PSC_CHAN_NO_LISTEN) {
force_passive = (s_max > 3 || b_max > 9);
force_passive |= (unsolicited_probe_on_chan &&
(s_max > 2 || b_max > 6));
} else {
force_passive = (s_max > 2 || b_max > 6);
}
} else if (cfg80211_channel_is_psc(params->channels[i])) {
force_passive = (s_max > 1 || b_max > 3);
} else {
force_passive = (s_max > 2 || b_max > 6);
force_passive |= (unsolicited_probe_on_chan &&
(s_max > 1 || b_max > 3));
}
if ((allow_passive && force_passive) ||
(!(bssid_bitmap | s_ssid_bitmap) &&
!cfg80211_channel_is_psc(params->channels[i])))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment