Commit e8fe3b41 authored by Ilan Peer's avatar Ilan Peer Committed by Luca Coelho

iwlwifi: mvm: Add support for 6GHz passive scan

When doing scan while 6GHz channels are not enabled, the 6GHz band
is not scanned. Thus, if there are no APs on the 2GHz and 5GHz bands
(that will allow discovery of geographic location etc. that would
allow enabling the 6GHz channels) but there are non collocated APs
on 6GHz PSC channels these would never be discovered.

To overcome this, FW added support for performing passive UHB scan
in case no APs were discovered during scan on the 2GHz and 5GHz
channels.

Add support for enabling such scan when the following conditions are
met:

- 6GHz channels are supported but not enabled by regulatory.
- Station interface is not associated or less than a defined time
  interval passed from the last resume or HW reset flows.
- At least 4 channels are included in the scan request
- The scan request includes the widlcard SSID.
- At least 50 minutes passed from the last 6GHz passive scan.
Signed-off-by: default avatarIlan Peer <ilan.peer@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/iwlwifi.20210331121101.7c7bd00e0aeb.Ib226ad57e416b43a710c36a78a617d4243458b99@changeidSigned-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent 85b5fd94
...@@ -634,6 +634,12 @@ enum iwl_umac_scan_general_flags2 { ...@@ -634,6 +634,12 @@ enum iwl_umac_scan_general_flags2 {
* @IWL_UMAC_SCAN_GEN_FLAGS_V2_TRIGGER_UHB_SCAN: at the end of 2.4GHz and * @IWL_UMAC_SCAN_GEN_FLAGS_V2_TRIGGER_UHB_SCAN: at the end of 2.4GHz and
* 5.2Ghz bands scan, trigger scan on 6GHz band to discover * 5.2Ghz bands scan, trigger scan on 6GHz band to discover
* the reported collocated APs * the reported collocated APs
* @IWL_UMAC_SCAN_GEN_FLAGS_V2_6GHZ_PASSIVE_SCAN: at the end of 2.4GHz and 5GHz
* bands scan, if not APs were discovered, allow scan to conitnue and scan
* 6GHz PSC channels in order to discover country information.
* @IWL_UMAC_SCAN_GEN_FLAGS_V2_6GHZ_PASSIVE_SCAN_FILTER_IN: in case
* &IWL_UMAC_SCAN_GEN_FLAGS_V2_6GHZ_PASSIVE_SCAN is enabled and scan is
* activated over 6GHz PSC channels, filter in beacons and probe responses.
*/ */
enum iwl_umac_scan_general_flags_v2 { enum iwl_umac_scan_general_flags_v2 {
IWL_UMAC_SCAN_GEN_FLAGS_V2_PERIODIC = BIT(0), IWL_UMAC_SCAN_GEN_FLAGS_V2_PERIODIC = BIT(0),
...@@ -649,6 +655,8 @@ enum iwl_umac_scan_general_flags_v2 { ...@@ -649,6 +655,8 @@ enum iwl_umac_scan_general_flags_v2 {
IWL_UMAC_SCAN_GEN_FLAGS_V2_MULTI_SSID = BIT(10), IWL_UMAC_SCAN_GEN_FLAGS_V2_MULTI_SSID = BIT(10),
IWL_UMAC_SCAN_GEN_FLAGS_V2_FORCE_PASSIVE = BIT(11), IWL_UMAC_SCAN_GEN_FLAGS_V2_FORCE_PASSIVE = BIT(11),
IWL_UMAC_SCAN_GEN_FLAGS_V2_TRIGGER_UHB_SCAN = BIT(12), IWL_UMAC_SCAN_GEN_FLAGS_V2_TRIGGER_UHB_SCAN = BIT(12),
IWL_UMAC_SCAN_GEN_FLAGS_V2_6GHZ_PASSIVE_SCAN = BIT(13),
IWL_UMAC_SCAN_GEN_FLAGS_V2_6GHZ_PASSIVE_SCAN_FILTER_IN = BIT(14),
}; };
/** /**
......
...@@ -362,6 +362,8 @@ typedef unsigned int __bitwise iwl_ucode_tlv_capa_t; ...@@ -362,6 +362,8 @@ typedef unsigned int __bitwise iwl_ucode_tlv_capa_t;
* @IWL_UCODE_TLV_CAPA_PROTECTED_TWT: Supports protection of TWT action frames * @IWL_UCODE_TLV_CAPA_PROTECTED_TWT: Supports protection of TWT action frames
* @IWL_UCODE_TLV_CAPA_FW_RESET_HANDSHAKE: Supports the firmware handshake in * @IWL_UCODE_TLV_CAPA_FW_RESET_HANDSHAKE: Supports the firmware handshake in
* reset flow * reset flow
* @IWL_UCODE_TLV_CAPA_PASSIVE_6GHZ_SCAN: Support for passive scan on 6GHz PSC
* channels even when these are not enabled.
* *
* @NUM_IWL_UCODE_TLV_CAPA: number of bits used * @NUM_IWL_UCODE_TLV_CAPA: number of bits used
*/ */
...@@ -408,6 +410,7 @@ enum iwl_ucode_tlv_capa { ...@@ -408,6 +410,7 @@ enum iwl_ucode_tlv_capa {
IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD = (__force iwl_ucode_tlv_capa_t)54, IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD = (__force iwl_ucode_tlv_capa_t)54,
IWL_UCODE_TLV_CAPA_PROTECTED_TWT = (__force iwl_ucode_tlv_capa_t)56, IWL_UCODE_TLV_CAPA_PROTECTED_TWT = (__force iwl_ucode_tlv_capa_t)56,
IWL_UCODE_TLV_CAPA_FW_RESET_HANDSHAKE = (__force iwl_ucode_tlv_capa_t)57, IWL_UCODE_TLV_CAPA_FW_RESET_HANDSHAKE = (__force iwl_ucode_tlv_capa_t)57,
IWL_UCODE_TLV_CAPA_PASSIVE_6GHZ_SCAN = (__force iwl_ucode_tlv_capa_t)58,
/* set 2 */ /* set 2 */
IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE = (__force iwl_ucode_tlv_capa_t)64, IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE = (__force iwl_ucode_tlv_capa_t)64,
......
...@@ -117,5 +117,7 @@ ...@@ -117,5 +117,7 @@
#define IWL_MVM_FTM_INITIATOR_SMOOTH_OVERSHOOT 20016 #define IWL_MVM_FTM_INITIATOR_SMOOTH_OVERSHOOT 20016
#define IWL_MVM_FTM_INITIATOR_SMOOTH_AGE_SEC 2 #define IWL_MVM_FTM_INITIATOR_SMOOTH_AGE_SEC 2
#define IWL_MVM_DISABLE_AP_FILS false #define IWL_MVM_DISABLE_AP_FILS false
#define IWL_MVM_6GHZ_PASSIVE_SCAN_TIMEOUT 3000 /* in seconds */
#define IWL_MVM_6GHZ_PASSIVE_SCAN_ASSOC_TIMEOUT 60 /* in seconds */
#endif /* __MVM_CONSTANTS_H */ #endif /* __MVM_CONSTANTS_H */
...@@ -2028,6 +2028,8 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) ...@@ -2028,6 +2028,8 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
mutex_lock(&mvm->mutex); mutex_lock(&mvm->mutex);
mvm->last_reset_or_resume_time_jiffies = jiffies;
/* get the BSS vif pointer again */ /* get the BSS vif pointer again */
vif = iwl_mvm_get_bss_vif(mvm); vif = iwl_mvm_get_bss_vif(mvm);
if (IS_ERR_OR_NULL(vif)) if (IS_ERR_OR_NULL(vif))
......
...@@ -1099,6 +1099,8 @@ int __iwl_mvm_mac_start(struct iwl_mvm *mvm) ...@@ -1099,6 +1099,8 @@ int __iwl_mvm_mac_start(struct iwl_mvm *mvm)
iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_PERIODIC, iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_PERIODIC,
NULL); NULL);
mvm->last_reset_or_resume_time_jiffies = jiffies;
if (ret && test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { if (ret && test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
/* Something went wrong - we need to finish some cleanup /* Something went wrong - we need to finish some cleanup
* that normally iwl_mvm_mac_restart_complete() below * that normally iwl_mvm_mac_restart_complete() below
......
...@@ -1096,6 +1096,9 @@ struct iwl_mvm { ...@@ -1096,6 +1096,9 @@ struct iwl_mvm {
/* sniffer data to include in radiotap */ /* sniffer data to include in radiotap */
__le16 cur_aid; __le16 cur_aid;
u8 cur_bssid[ETH_ALEN]; u8 cur_bssid[ETH_ALEN];
unsigned long last_6ghz_passive_scan_jiffies;
unsigned long last_reset_or_resume_time_jiffies;
}; };
/* Extract MVM priv from op_mode and _hw */ /* Extract MVM priv from op_mode and _hw */
......
...@@ -43,6 +43,9 @@ ...@@ -43,6 +43,9 @@
/* adaptive dwell number of APs override for social channels */ /* adaptive dwell number of APs override for social channels */
#define IWL_SCAN_ADWELL_N_APS_SOCIAL_CHS 2 #define IWL_SCAN_ADWELL_N_APS_SOCIAL_CHS 2
/* minimal number of 2GHz and 5GHz channels in the regular scan request */
#define IWL_MVM_6GHZ_PASSIVE_SCAN_MIN_CHANS 4
struct iwl_mvm_scan_timing_params { struct iwl_mvm_scan_timing_params {
u32 suspend_time; u32 suspend_time;
u32 max_out_time; u32 max_out_time;
...@@ -94,6 +97,7 @@ struct iwl_mvm_scan_params { ...@@ -94,6 +97,7 @@ struct iwl_mvm_scan_params {
struct cfg80211_scan_6ghz_params *scan_6ghz_params; struct cfg80211_scan_6ghz_params *scan_6ghz_params;
u32 n_6ghz_params; u32 n_6ghz_params;
bool scan_6ghz; bool scan_6ghz;
bool enable_6ghz_passive;
}; };
static inline void *iwl_mvm_get_scan_req_umac_data(struct iwl_mvm *mvm) static inline void *iwl_mvm_get_scan_req_umac_data(struct iwl_mvm *mvm)
...@@ -1873,6 +1877,98 @@ static u8 iwl_mvm_scan_umac_chan_flags_v2(struct iwl_mvm *mvm, ...@@ -1873,6 +1877,98 @@ static u8 iwl_mvm_scan_umac_chan_flags_v2(struct iwl_mvm *mvm,
return flags; return flags;
} }
static void iwl_mvm_scan_6ghz_passive_scan(struct iwl_mvm *mvm,
struct iwl_mvm_scan_params *params,
struct ieee80211_vif *vif)
{
struct ieee80211_supported_band *sband =
&mvm->nvm_data->bands[NL80211_BAND_6GHZ];
u32 n_disabled, i;
params->enable_6ghz_passive = false;
if (params->scan_6ghz)
return;
if (!fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_PASSIVE_6GHZ_SCAN)) {
IWL_DEBUG_SCAN(mvm,
"6GHz passive scan: Not supported by FW\n");
return;
}
/* 6GHz passive scan allowed only on station interface */
if (vif->type != NL80211_IFTYPE_STATION) {
IWL_DEBUG_SCAN(mvm,
"6GHz passive scan: not station interface\n");
return;
}
/*
* 6GHz passive scan is allowed while associated in a defined time
* interval following HW reset or resume flow
*/
if (vif->bss_conf.assoc &&
(time_before(mvm->last_reset_or_resume_time_jiffies +
(IWL_MVM_6GHZ_PASSIVE_SCAN_ASSOC_TIMEOUT * HZ),
jiffies))) {
IWL_DEBUG_SCAN(mvm, "6GHz passive scan: associated\n");
return;
}
/* No need for 6GHz passive scan if not enough time elapsed */
if (time_after(mvm->last_6ghz_passive_scan_jiffies +
(IWL_MVM_6GHZ_PASSIVE_SCAN_TIMEOUT * HZ), jiffies)) {
IWL_DEBUG_SCAN(mvm,
"6GHz passive scan: timeout did not expire\n");
return;
}
/* not enough channels in the regular scan request */
if (params->n_channels < IWL_MVM_6GHZ_PASSIVE_SCAN_MIN_CHANS) {
IWL_DEBUG_SCAN(mvm,
"6GHz passive scan: not enough channels\n");
return;
}
for (i = 0; i < params->n_ssids; i++) {
if (!params->ssids[i].ssid_len)
break;
}
/* not a wildcard scan, so cannot enable passive 6GHz scan */
if (i == params->n_ssids) {
IWL_DEBUG_SCAN(mvm,
"6GHz passive scan: no wildcard SSID\n");
return;
}
if (!sband || !sband->n_channels) {
IWL_DEBUG_SCAN(mvm,
"6GHz passive scan: no 6GHz channels\n");
return;
}
for (i = 0, n_disabled = 0; i < sband->n_channels; i++) {
if (sband->channels[i].flags & (IEEE80211_CHAN_DISABLED))
n_disabled++;
}
/*
* Not all the 6GHz channels are disabled, so no need for 6GHz passive
* scan
*/
if (n_disabled != sband->n_channels) {
IWL_DEBUG_SCAN(mvm,
"6GHz passive scan: 6GHz channels enabled\n");
return;
}
/* all conditions to enable 6ghz passive scan are satisfied */
IWL_DEBUG_SCAN(mvm, "6GHz passive scan: can be enabled\n");
params->enable_6ghz_passive = true;
}
static u16 iwl_mvm_scan_umac_flags_v2(struct iwl_mvm *mvm, static u16 iwl_mvm_scan_umac_flags_v2(struct iwl_mvm *mvm,
struct iwl_mvm_scan_params *params, struct iwl_mvm_scan_params *params,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
...@@ -1911,6 +2007,9 @@ static u16 iwl_mvm_scan_umac_flags_v2(struct iwl_mvm *mvm, ...@@ -1911,6 +2007,9 @@ static u16 iwl_mvm_scan_umac_flags_v2(struct iwl_mvm *mvm,
params->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ) params->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ)
flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_TRIGGER_UHB_SCAN; flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_TRIGGER_UHB_SCAN;
if (params->enable_6ghz_passive)
flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_6GHZ_PASSIVE_SCAN;
return flags; return flags;
} }
...@@ -2183,6 +2282,30 @@ iwl_mvm_scan_umac_fill_ch_p_v6(struct iwl_mvm *mvm, ...@@ -2183,6 +2282,30 @@ iwl_mvm_scan_umac_fill_ch_p_v6(struct iwl_mvm *mvm,
params->n_channels, params->n_channels,
channel_cfg_flags, channel_cfg_flags,
vif->type); vif->type);
if (params->enable_6ghz_passive) {
struct ieee80211_supported_band *sband =
&mvm->nvm_data->bands[NL80211_BAND_6GHZ];
u32 i;
for (i = 0; i < sband->n_channels; i++) {
struct ieee80211_channel *channel =
&sband->channels[i];
struct iwl_scan_channel_cfg_umac *cfg =
&cp->channel_config[cp->count];
if (!cfg80211_channel_is_psc(channel))
continue;
cfg->flags = 0;
cfg->v2.channel_num = channel->hw_value;
cfg->v2.band = PHY_BAND_6;
cfg->v2.iter_count = 1;
cfg->v2.iter_interval = 0;
cp->count++;
}
}
} }
static int iwl_mvm_scan_umac_v12(struct iwl_mvm *mvm, struct ieee80211_vif *vif, static int iwl_mvm_scan_umac_v12(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
...@@ -2500,6 +2623,8 @@ int iwl_mvm_reg_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, ...@@ -2500,6 +2623,8 @@ int iwl_mvm_reg_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
iwl_mvm_build_scan_probe(mvm, vif, ies, &params); iwl_mvm_build_scan_probe(mvm, vif, ies, &params);
iwl_mvm_scan_6ghz_passive_scan(mvm, &params, vif);
uid = iwl_mvm_build_scan_cmd(mvm, vif, &hcmd, &params, uid = iwl_mvm_build_scan_cmd(mvm, vif, &hcmd, &params,
IWL_MVM_SCAN_REGULAR); IWL_MVM_SCAN_REGULAR);
...@@ -2524,6 +2649,9 @@ int iwl_mvm_reg_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, ...@@ -2524,6 +2649,9 @@ int iwl_mvm_reg_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
mvm->scan_status |= IWL_MVM_SCAN_REGULAR; mvm->scan_status |= IWL_MVM_SCAN_REGULAR;
mvm->scan_vif = iwl_mvm_vif_from_mac80211(vif); mvm->scan_vif = iwl_mvm_vif_from_mac80211(vif);
if (params.enable_6ghz_passive)
mvm->last_6ghz_passive_scan_jiffies = jiffies;
schedule_delayed_work(&mvm->scan_timeout_dwork, schedule_delayed_work(&mvm->scan_timeout_dwork,
msecs_to_jiffies(SCAN_TIMEOUT)); msecs_to_jiffies(SCAN_TIMEOUT));
......
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