wifi: iwlwifi: mvm: Introduce internal MLO passive scan
Add a new scan type that can be used for internal MLO purposes, i.e., in case updated BSS information is required. Currently only passive scanning is supported. Signed-off-by: Ilan Peer <ilan.peer@intel.com> Reviewed-by: Johannes Berg <johannes.berg@intel.com> Reviewed-by: Ayala Beker <ayala.beker@intel.com> Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> Link: https://msgid.link/20240319100755.5ce3e756cf8f.I4a41065f6b3a6ec6c6e44e83bc97c277ff7c599e@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
a17a58ad2f
commit
38b3998dfb
3 changed files with 88 additions and 10 deletions
|
@ -1340,6 +1340,11 @@ void iwl_mvm_mac_stop(struct ieee80211_hw *hw)
|
||||||
{
|
{
|
||||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||||
|
|
||||||
|
/* Stop internal MLO scan, if running */
|
||||||
|
mutex_lock(&mvm->mutex);
|
||||||
|
iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_INT_MLO, false);
|
||||||
|
mutex_unlock(&mvm->mutex);
|
||||||
|
|
||||||
flush_work(&mvm->async_handlers_wk);
|
flush_work(&mvm->async_handlers_wk);
|
||||||
flush_work(&mvm->add_stream_wk);
|
flush_work(&mvm->add_stream_wk);
|
||||||
|
|
||||||
|
|
|
@ -493,10 +493,12 @@ enum iwl_scan_status {
|
||||||
IWL_MVM_SCAN_REGULAR = BIT(0),
|
IWL_MVM_SCAN_REGULAR = BIT(0),
|
||||||
IWL_MVM_SCAN_SCHED = BIT(1),
|
IWL_MVM_SCAN_SCHED = BIT(1),
|
||||||
IWL_MVM_SCAN_NETDETECT = BIT(2),
|
IWL_MVM_SCAN_NETDETECT = BIT(2),
|
||||||
|
IWL_MVM_SCAN_INT_MLO = BIT(3),
|
||||||
|
|
||||||
IWL_MVM_SCAN_STOPPING_REGULAR = BIT(8),
|
IWL_MVM_SCAN_STOPPING_REGULAR = BIT(8),
|
||||||
IWL_MVM_SCAN_STOPPING_SCHED = BIT(9),
|
IWL_MVM_SCAN_STOPPING_SCHED = BIT(9),
|
||||||
IWL_MVM_SCAN_STOPPING_NETDETECT = BIT(10),
|
IWL_MVM_SCAN_STOPPING_NETDETECT = BIT(10),
|
||||||
|
IWL_MVM_SCAN_STOPPING_INT_MLO = BIT(11),
|
||||||
|
|
||||||
IWL_MVM_SCAN_REGULAR_MASK = IWL_MVM_SCAN_REGULAR |
|
IWL_MVM_SCAN_REGULAR_MASK = IWL_MVM_SCAN_REGULAR |
|
||||||
IWL_MVM_SCAN_STOPPING_REGULAR,
|
IWL_MVM_SCAN_STOPPING_REGULAR,
|
||||||
|
@ -504,6 +506,8 @@ enum iwl_scan_status {
|
||||||
IWL_MVM_SCAN_STOPPING_SCHED,
|
IWL_MVM_SCAN_STOPPING_SCHED,
|
||||||
IWL_MVM_SCAN_NETDETECT_MASK = IWL_MVM_SCAN_NETDETECT |
|
IWL_MVM_SCAN_NETDETECT_MASK = IWL_MVM_SCAN_NETDETECT |
|
||||||
IWL_MVM_SCAN_STOPPING_NETDETECT,
|
IWL_MVM_SCAN_STOPPING_NETDETECT,
|
||||||
|
IWL_MVM_SCAN_INT_MLO_MASK = IWL_MVM_SCAN_INT_MLO |
|
||||||
|
IWL_MVM_SCAN_STOPPING_INT_MLO,
|
||||||
|
|
||||||
IWL_MVM_SCAN_STOPPING_MASK = 0xff << IWL_MVM_SCAN_STOPPING_SHIFT,
|
IWL_MVM_SCAN_STOPPING_MASK = 0xff << IWL_MVM_SCAN_STOPPING_SHIFT,
|
||||||
IWL_MVM_SCAN_MASK = 0xff,
|
IWL_MVM_SCAN_MASK = 0xff,
|
||||||
|
@ -2007,6 +2011,10 @@ int iwl_mvm_reg_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||||
struct ieee80211_scan_ies *ies);
|
struct ieee80211_scan_ies *ies);
|
||||||
size_t iwl_mvm_scan_size(struct iwl_mvm *mvm);
|
size_t iwl_mvm_scan_size(struct iwl_mvm *mvm);
|
||||||
int iwl_mvm_scan_stop(struct iwl_mvm *mvm, int type, bool notify);
|
int iwl_mvm_scan_stop(struct iwl_mvm *mvm, int type, bool notify);
|
||||||
|
int iwl_mvm_int_mlo_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||||
|
struct ieee80211_channel **channels,
|
||||||
|
size_t n_channels);
|
||||||
|
|
||||||
int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm);
|
int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm);
|
||||||
void iwl_mvm_report_scan_aborted(struct iwl_mvm *mvm);
|
void iwl_mvm_report_scan_aborted(struct iwl_mvm *mvm);
|
||||||
void iwl_mvm_scan_timeout_wk(struct work_struct *work);
|
void iwl_mvm_scan_timeout_wk(struct work_struct *work);
|
||||||
|
|
|
@ -1377,11 +1377,14 @@ static void iwl_mvm_scan_umac_dwell(struct iwl_mvm *mvm,
|
||||||
cmd->ooc_priority = cpu_to_le32(IWL_SCAN_PRIORITY_EXT_2);
|
cmd->ooc_priority = cpu_to_le32(IWL_SCAN_PRIORITY_EXT_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 iwl_mvm_scan_umac_ooc_priority(struct iwl_mvm_scan_params *params)
|
static u32 iwl_mvm_scan_umac_ooc_priority(int type)
|
||||||
{
|
{
|
||||||
return iwl_mvm_is_regular_scan(params) ?
|
if (type == IWL_MVM_SCAN_REGULAR)
|
||||||
IWL_SCAN_PRIORITY_EXT_6 :
|
return IWL_SCAN_PRIORITY_EXT_6;
|
||||||
IWL_SCAN_PRIORITY_EXT_2;
|
if (type == IWL_MVM_SCAN_INT_MLO)
|
||||||
|
return IWL_SCAN_PRIORITY_EXT_4;
|
||||||
|
|
||||||
|
return IWL_SCAN_PRIORITY_EXT_2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2452,7 +2455,7 @@ static int iwl_mvm_scan_umac_v12(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||||
|
|
||||||
mvm->scan_uid_status[uid] = type;
|
mvm->scan_uid_status[uid] = type;
|
||||||
|
|
||||||
cmd->ooc_priority = cpu_to_le32(iwl_mvm_scan_umac_ooc_priority(params));
|
cmd->ooc_priority = cpu_to_le32(iwl_mvm_scan_umac_ooc_priority(type));
|
||||||
cmd->uid = cpu_to_le32(uid);
|
cmd->uid = cpu_to_le32(uid);
|
||||||
|
|
||||||
gen_flags = iwl_mvm_scan_umac_flags_v2(mvm, params, vif, type);
|
gen_flags = iwl_mvm_scan_umac_flags_v2(mvm, params, vif, type);
|
||||||
|
@ -2489,7 +2492,7 @@ static int iwl_mvm_scan_umac_v14_and_above(struct iwl_mvm *mvm,
|
||||||
|
|
||||||
mvm->scan_uid_status[uid] = type;
|
mvm->scan_uid_status[uid] = type;
|
||||||
|
|
||||||
cmd->ooc_priority = cpu_to_le32(iwl_mvm_scan_umac_ooc_priority(params));
|
cmd->ooc_priority = cpu_to_le32(iwl_mvm_scan_umac_ooc_priority(type));
|
||||||
cmd->uid = cpu_to_le32(uid);
|
cmd->uid = cpu_to_le32(uid);
|
||||||
|
|
||||||
gen_flags = iwl_mvm_scan_umac_flags_v2(mvm, params, vif, type);
|
gen_flags = iwl_mvm_scan_umac_flags_v2(mvm, params, vif, type);
|
||||||
|
@ -3006,14 +3009,16 @@ static int _iwl_mvm_single_scan_start(struct iwl_mvm *mvm,
|
||||||
|
|
||||||
IWL_DEBUG_SCAN(mvm, "Scan request was sent successfully\n");
|
IWL_DEBUG_SCAN(mvm, "Scan request was sent successfully\n");
|
||||||
mvm->scan_status |= type;
|
mvm->scan_status |= type;
|
||||||
|
|
||||||
|
if (type == IWL_MVM_SCAN_REGULAR) {
|
||||||
mvm->scan_vif = iwl_mvm_vif_from_mac80211(vif);
|
mvm->scan_vif = iwl_mvm_vif_from_mac80211(vif);
|
||||||
|
schedule_delayed_work(&mvm->scan_timeout_dwork,
|
||||||
|
msecs_to_jiffies(SCAN_TIMEOUT));
|
||||||
|
}
|
||||||
|
|
||||||
if (params.enable_6ghz_passive)
|
if (params.enable_6ghz_passive)
|
||||||
mvm->last_6ghz_passive_scan_jiffies = jiffies;
|
mvm->last_6ghz_passive_scan_jiffies = jiffies;
|
||||||
|
|
||||||
schedule_delayed_work(&mvm->scan_timeout_dwork,
|
|
||||||
msecs_to_jiffies(SCAN_TIMEOUT));
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3189,6 +3194,8 @@ void iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm,
|
||||||
} else if (mvm->scan_uid_status[uid] == IWL_MVM_SCAN_SCHED) {
|
} else if (mvm->scan_uid_status[uid] == IWL_MVM_SCAN_SCHED) {
|
||||||
ieee80211_sched_scan_stopped(mvm->hw);
|
ieee80211_sched_scan_stopped(mvm->hw);
|
||||||
mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
|
mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
|
||||||
|
} else if (mvm->scan_uid_status[uid] == IWL_MVM_SCAN_INT_MLO) {
|
||||||
|
IWL_DEBUG_SCAN(mvm, "Internal MLO scan completed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
mvm->scan_status &= ~mvm->scan_uid_status[uid];
|
mvm->scan_status &= ~mvm->scan_uid_status[uid];
|
||||||
|
@ -3375,6 +3382,12 @@ void iwl_mvm_report_scan_aborted(struct iwl_mvm *mvm)
|
||||||
mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
|
mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
|
||||||
mvm->scan_uid_status[uid] = 0;
|
mvm->scan_uid_status[uid] = 0;
|
||||||
}
|
}
|
||||||
|
uid = iwl_mvm_scan_uid_by_status(mvm, IWL_MVM_SCAN_INT_MLO);
|
||||||
|
if (uid >= 0) {
|
||||||
|
IWL_DEBUG_SCAN(mvm, "Internal MLO scan aborted\n");
|
||||||
|
mvm->scan_uid_status[uid] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
uid = iwl_mvm_scan_uid_by_status(mvm,
|
uid = iwl_mvm_scan_uid_by_status(mvm,
|
||||||
IWL_MVM_SCAN_STOPPING_REGULAR);
|
IWL_MVM_SCAN_STOPPING_REGULAR);
|
||||||
if (uid >= 0)
|
if (uid >= 0)
|
||||||
|
@ -3385,6 +3398,11 @@ void iwl_mvm_report_scan_aborted(struct iwl_mvm *mvm)
|
||||||
if (uid >= 0)
|
if (uid >= 0)
|
||||||
mvm->scan_uid_status[uid] = 0;
|
mvm->scan_uid_status[uid] = 0;
|
||||||
|
|
||||||
|
uid = iwl_mvm_scan_uid_by_status(mvm,
|
||||||
|
IWL_MVM_SCAN_STOPPING_INT_MLO);
|
||||||
|
if (uid >= 0)
|
||||||
|
mvm->scan_uid_status[uid] = 0;
|
||||||
|
|
||||||
/* We shouldn't have any UIDs still set. Loop over all the
|
/* We shouldn't have any UIDs still set. Loop over all the
|
||||||
* UIDs to make sure there's nothing left there and warn if
|
* UIDs to make sure there's nothing left there and warn if
|
||||||
* any is found.
|
* any is found.
|
||||||
|
@ -3456,3 +3474,50 @@ out:
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iwl_mvm_int_mlo_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||||
|
struct ieee80211_channel **channels,
|
||||||
|
size_t n_channels)
|
||||||
|
{
|
||||||
|
struct cfg80211_scan_request *req = NULL;
|
||||||
|
struct ieee80211_scan_ies ies = {};
|
||||||
|
size_t size, i;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
lockdep_assert_held(&mvm->mutex);
|
||||||
|
|
||||||
|
IWL_DEBUG_SCAN(mvm, "Starting Internal MLO scan: n_channels=%zu\n",
|
||||||
|
n_channels);
|
||||||
|
|
||||||
|
if (!vif->cfg.assoc || !ieee80211_vif_is_mld(vif))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
size = struct_size(req, channels, n_channels);
|
||||||
|
req = kzalloc(size, GFP_KERNEL);
|
||||||
|
if (!req)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
/* set the requested channels */
|
||||||
|
for (i = 0; i < n_channels; i++)
|
||||||
|
req->channels[i] = channels[i];
|
||||||
|
|
||||||
|
req->n_channels = n_channels;
|
||||||
|
|
||||||
|
/* set the rates */
|
||||||
|
for (i = 0; i < NUM_NL80211_BANDS; i++)
|
||||||
|
if (mvm->hw->wiphy->bands[i])
|
||||||
|
req->rates[i] =
|
||||||
|
(1 << mvm->hw->wiphy->bands[i]->n_bitrates) - 1;
|
||||||
|
|
||||||
|
req->wdev = ieee80211_vif_to_wdev(vif);
|
||||||
|
req->wiphy = mvm->hw->wiphy;
|
||||||
|
req->scan_start = jiffies;
|
||||||
|
req->tsf_report_link_id = -1;
|
||||||
|
|
||||||
|
ret = _iwl_mvm_single_scan_start(mvm, vif, req, &ies,
|
||||||
|
IWL_MVM_SCAN_INT_MLO);
|
||||||
|
kfree(req);
|
||||||
|
|
||||||
|
IWL_DEBUG_SCAN(mvm, "Internal MLO scan: ret=%d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue