summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/scan.c')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/scan.c93
1 files changed, 54 insertions, 39 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
index 0368b7101222..d78e436fa8b5 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
@@ -1648,7 +1648,7 @@ iwl_mvm_umac_scan_cfg_channels_v6(struct iwl_mvm *mvm,
struct iwl_scan_channel_cfg_umac *cfg = &cp->channel_config[i];
u32 n_aps_flag =
iwl_mvm_scan_ch_n_aps_flag(vif_type,
- cfg->v2.channel_num);
+ channels[i]->hw_value);
cfg->flags = cpu_to_le32(flags | n_aps_flag);
cfg->v2.channel_num = channels[i]->hw_value;
@@ -1661,22 +1661,32 @@ iwl_mvm_umac_scan_cfg_channels_v6(struct iwl_mvm *mvm,
}
static int
-iwl_mvm_umac_scan_fill_6g_chan_list(struct iwl_mvm_scan_params *params,
- __le32 *cmd_short_ssid, u8 *cmd_bssid,
- u8 *scan_ssid_num, u8 *bssid_num)
+iwl_mvm_umac_scan_fill_6g_chan_list(struct iwl_mvm *mvm,
+ struct iwl_mvm_scan_params *params,
+ struct iwl_scan_probe_params_v4 *pp)
{
int j, idex_s = 0, idex_b = 0;
struct cfg80211_scan_6ghz_params *scan_6ghz_params =
params->scan_6ghz_params;
+ bool hidden_supported = fw_has_capa(&mvm->fw->ucode_capa,
+ IWL_UCODE_TLV_CAPA_HIDDEN_6GHZ_SCAN);
- if (!params->n_6ghz_params) {
- for (j = 0; j < params->n_ssids; j++) {
- cmd_short_ssid[idex_s++] =
- cpu_to_le32(~crc32_le(~0, params->ssids[j].ssid,
- params->ssids[j].ssid_len));
- (*scan_ssid_num)++;
+ for (j = 0; j < params->n_ssids && idex_s < SCAN_SHORT_SSID_MAX_SIZE;
+ j++) {
+ if (!params->ssids[j].ssid_len)
+ continue;
+
+ pp->short_ssid[idex_s] =
+ cpu_to_le32(~crc32_le(~0, params->ssids[j].ssid,
+ params->ssids[j].ssid_len));
+
+ if (hidden_supported) {
+ pp->direct_scan[idex_s].id = WLAN_EID_SSID;
+ pp->direct_scan[idex_s].len = params->ssids[j].ssid_len;
+ memcpy(pp->direct_scan[idex_s].ssid, params->ssids[j].ssid,
+ params->ssids[j].ssid_len);
}
- return 0;
+ idex_s++;
}
/*
@@ -1693,40 +1703,40 @@ iwl_mvm_umac_scan_fill_6g_chan_list(struct iwl_mvm_scan_params *params,
/* First, try to place the short SSID */
if (scan_6ghz_params[j].short_ssid_valid) {
for (k = 0; k < idex_s; k++) {
- if (cmd_short_ssid[k] ==
+ if (pp->short_ssid[k] ==
cpu_to_le32(scan_6ghz_params[j].short_ssid))
break;
}
if (k == idex_s && idex_s < SCAN_SHORT_SSID_MAX_SIZE) {
- cmd_short_ssid[idex_s++] =
+ pp->short_ssid[idex_s++] =
cpu_to_le32(scan_6ghz_params[j].short_ssid);
- (*scan_ssid_num)++;
}
}
/* try to place BSSID for the same entry */
for (k = 0; k < idex_b; k++) {
- if (!memcmp(&cmd_bssid[ETH_ALEN * k],
+ if (!memcmp(&pp->bssid_array[k],
scan_6ghz_params[j].bssid, ETH_ALEN))
break;
}
if (k == idex_b && idex_b < SCAN_BSSID_MAX_SIZE) {
- memcpy(&cmd_bssid[ETH_ALEN * idex_b++],
+ memcpy(&pp->bssid_array[idex_b++],
scan_6ghz_params[j].bssid, ETH_ALEN);
- (*bssid_num)++;
}
}
+
+ pp->short_ssid_num = idex_s;
+ pp->bssid_num = idex_b;
return 0;
}
/* TODO: this function can be merged with iwl_mvm_scan_umac_fill_ch_p_v6 */
static void
iwl_mvm_umac_scan_cfg_channels_v6_6g(struct iwl_mvm_scan_params *params,
- u32 n_channels, __le32 *cmd_short_ssid,
- u8 *cmd_bssid, u8 scan_ssid_num,
- u8 bssid_num,
+ u32 n_channels,
+ struct iwl_scan_probe_params_v4 *pp,
struct iwl_scan_channel_params_v6 *cp,
enum nl80211_iftype vif_type)
{
@@ -1741,7 +1751,7 @@ iwl_mvm_umac_scan_cfg_channels_v6_6g(struct iwl_mvm_scan_params *params,
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,
+ bool force_passive, found = false, allow_passive = true,
unsolicited_probe_on_chan = false, psc_no_listen = false;
cfg->v1.channel_num = params->channels[i]->hw_value;
@@ -1766,9 +1776,9 @@ iwl_mvm_umac_scan_cfg_channels_v6_6g(struct iwl_mvm_scan_params *params,
scan_6ghz_params[j].unsolicited_probe;
psc_no_listen |= scan_6ghz_params[j].psc_no_listen;
- for (k = 0; k < scan_ssid_num; k++) {
+ for (k = 0; k < pp->short_ssid_num; k++) {
if (!scan_6ghz_params[j].unsolicited_probe &&
- le32_to_cpu(cmd_short_ssid[k]) ==
+ le32_to_cpu(pp->short_ssid[k]) ==
scan_6ghz_params[j].short_ssid) {
/* Relevant short SSID bit set */
if (s_ssid_bitmap & BIT(k)) {
@@ -1778,7 +1788,10 @@ iwl_mvm_umac_scan_cfg_channels_v6_6g(struct iwl_mvm_scan_params *params,
/*
* Use short SSID only to create a new
- * iteration during channel dwell.
+ * iteration during channel dwell or in
+ * case that the short SSID has a
+ * matching SSID, i.e., scan for hidden
+ * APs.
*/
if (n_used_bssid_entries >= 3) {
s_ssid_bitmap |= BIT(k);
@@ -1786,6 +1799,12 @@ iwl_mvm_umac_scan_cfg_channels_v6_6g(struct iwl_mvm_scan_params *params,
n_used_bssid_entries -= 3;
found = true;
break;
+ } else if (pp->direct_scan[k].len) {
+ s_ssid_bitmap |= BIT(k);
+ s_max++;
+ found = true;
+ allow_passive = false;
+ break;
}
}
}
@@ -1793,8 +1812,8 @@ iwl_mvm_umac_scan_cfg_channels_v6_6g(struct iwl_mvm_scan_params *params,
if (found)
continue;
- for (k = 0; k < bssid_num; k++) {
- if (!memcmp(&cmd_bssid[ETH_ALEN * k],
+ for (k = 0; k < pp->bssid_num; k++) {
+ if (!memcmp(&pp->bssid_array[k],
scan_6ghz_params[j].bssid,
ETH_ALEN)) {
if (!(bssid_bitmap & BIT(k))) {
@@ -1849,7 +1868,7 @@ iwl_mvm_umac_scan_cfg_channels_v6_6g(struct iwl_mvm_scan_params *params,
force_passive |= (unsolicited_probe_on_chan &&
(s_max > 1 || b_max > 3));
}
- if (force_passive ||
+ if ((allow_passive && force_passive) ||
(!flags && !cfg80211_channel_is_psc(params->channels[i])))
flags |= IWL_UHB_CHAN_CFG_FLAG_FORCE_PASSIVE;
@@ -2368,32 +2387,28 @@ static int iwl_mvm_scan_umac_v14(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
if (ret)
return ret;
- iwl_mvm_scan_umac_fill_probe_p_v4(params, &scan_p->probe_params,
- &bitmap_ssid);
if (!params->scan_6ghz) {
+ iwl_mvm_scan_umac_fill_probe_p_v4(params, &scan_p->probe_params,
+ &bitmap_ssid);
iwl_mvm_scan_umac_fill_ch_p_v6(mvm, params, vif,
- &scan_p->channel_params, bitmap_ssid);
+ &scan_p->channel_params, bitmap_ssid);
return 0;
+ } else {
+ pb->preq = params->preq;
}
+
cp->flags = iwl_mvm_scan_umac_chan_flags_v2(mvm, params, vif);
cp->n_aps_override[0] = IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY;
cp->n_aps_override[1] = IWL_SCAN_ADWELL_N_APS_SOCIAL_CHS;
- ret = iwl_mvm_umac_scan_fill_6g_chan_list(params, pb->short_ssid,
- pb->bssid_array[0],
- &pb->short_ssid_num,
- &pb->bssid_num);
+ ret = iwl_mvm_umac_scan_fill_6g_chan_list(mvm, params, pb);
if (ret)
return ret;
iwl_mvm_umac_scan_cfg_channels_v6_6g(params,
params->n_channels,
- pb->short_ssid,
- pb->bssid_array[0],
- pb->short_ssid_num,
- pb->bssid_num, cp,
- vif->type);
+ pb, cp, vif->type);
cp->count = params->n_channels;
if (!params->n_ssids ||
(params->n_ssids == 1 && !params->ssids[0].ssid_len))