summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
diff options
context:
space:
mode:
authorIlan Peer <ilan.peer@intel.com>2021-08-02 17:09:43 +0300
committerLuca Coelho <luciano.coelho@intel.com>2021-08-26 23:32:22 +0300
commit16cff731a3a17d30b1e556c474b6dddb09c64b41 (patch)
tree472d87070a42f0b3a2a61741853fb19c454e18b2 /drivers/net/wireless/intel/iwlwifi/mvm/scan.c
parentdeedf9b97cd4ef45da476c9bdd2a5f3276053956 (diff)
downloadlinux-16cff731a3a17d30b1e556c474b6dddb09c64b41.tar.xz
iwlwifi: mvm: Add support for hidden network scan on 6GHz band
Add support for discovery of hidden networks on the 6GHz band, by including the scan request direct SSIDs in the FW scan request command: - In case a short SSID matches one of the direct SSIDs in the scan request command, add the matching SSID in the same offset in the 'direct_ssids' array. - Otherwise, add the SSID in one of the available slots. Additionally, as a preparation to handle hidden APs, refactor iwl_mvm_umac_scan_cfg_channels_v6_6g() the function. Signed-off-by: Ilan Peer <ilan.peer@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com> Link: https://lore.kernel.org/r/iwlwifi.20210802170640.ffb540a70212.Ia2bb9bc9435b833820bcc7dc30adcedb5a5a9869@changeid Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/scan.c')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/scan.c90
1 files changed, 75 insertions, 15 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
index 4899d8f90bab..82ab08af0e21 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
@@ -1724,9 +1724,8 @@ iwl_mvm_umac_scan_fill_6g_chan_list(struct iwl_mvm_scan_params *params,
/* 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 +1740,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 +1765,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 +1777,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 +1788,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 +1801,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 +1857,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;
@@ -1857,6 +1865,60 @@ iwl_mvm_umac_scan_cfg_channels_v6_6g(struct iwl_mvm_scan_params *params,
}
}
+static void
+iwl_mvm_umac_scan_cfg_6g_direct_ssids(struct iwl_mvm *mvm,
+ struct iwl_mvm_scan_params *params,
+ struct iwl_scan_probe_params_v4 *pp)
+{
+ u8 next_free_idx = pp->short_ssid_num;
+ int i;
+
+ if (!fw_has_capa(&mvm->fw->ucode_capa,
+ IWL_UCODE_TLV_CAPA_HIDDEN_6GHZ_SCAN)) {
+ IWL_DEBUG_SCAN(mvm,
+ "6GHz hidden scan: Not supported by FW\n");
+ return;
+ }
+
+ for (i = params->n_ssids - 1; i >= 0; i--) {
+ __le32 short_ssid;
+ u8 ssid_idx, j;
+
+ if (!params->ssids[i].ssid_len)
+ continue;
+
+ short_ssid = cpu_to_le32(~crc32_le(~0, params->ssids[i].ssid,
+ params->ssids[i].ssid_len));
+
+ for (j = 0; j < pp->short_ssid_num; j++)
+ if (short_ssid == pp->short_ssid[j])
+ break;
+
+ if (j == pp->short_ssid_num) {
+ /*
+ * If there are no available slots for the short SSID, do not
+ * place it.
+ */
+ if (next_free_idx < SCAN_SHORT_SSID_MAX_SIZE)
+ ssid_idx = next_free_idx++;
+ else
+ continue;
+ } else {
+ ssid_idx = j;
+ }
+
+ if (ssid_idx >= PROBE_OPTION_MAX)
+ continue;
+
+ pp->direct_scan[ssid_idx].id = WLAN_EID_SSID;
+ pp->direct_scan[ssid_idx].len = params->ssids[i].ssid_len;
+ memcpy(pp->direct_scan[ssid_idx].ssid, params->ssids[i].ssid,
+ params->ssids[i].ssid_len);
+ }
+
+ pp->short_ssid_num = next_free_idx;
+}
+
static u8 iwl_mvm_scan_umac_chan_flags_v2(struct iwl_mvm *mvm,
struct iwl_mvm_scan_params *params,
struct ieee80211_vif *vif)
@@ -2390,13 +2452,11 @@ static int iwl_mvm_scan_umac_v14(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
if (ret)
return ret;
+ iwl_mvm_umac_scan_cfg_6g_direct_ssids(mvm, params, pb);
+
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))