提交 d9718da8 编写于 作者: L Luciano Coelho 提交者: Emmanuel Grumbach

iwlwifi: mvm: add SSID match information for net-detect

Add SSID information to the net-detect indication to userspace.  Fetch
the matched profiles from the firmware in order to find the correct
SSIDs in the profiles that matched.

Since the net-detect information is stored in cfg80211, and in theory
it could change while we are waking up and reading the matched
profiles, we need to save it when we enter D3 so it is available
during resume.
Signed-off-by: NLuciano Coelho <luciano.coelho@intel.com>
Reviewed-by: NJohannes Berg <johannes.berg@intel.com>
Signed-off-by: NEmmanuel Grumbach <emmanuel.grumbach@intel.com>
上级 804d4c5a
......@@ -979,8 +979,30 @@ iwl_mvm_netdetect_config(struct iwl_mvm *mvm,
return ret;
ret = iwl_mvm_scan_offload_start(mvm, vif, nd_config, &mvm->nd_ies);
if (ret)
return ret;
return ret;
if (WARN_ON(mvm->nd_match_sets))
return -EBUSY;
/* save the sched scan matchsets for later reporting */
if (nd_config->n_match_sets) {
mvm->nd_match_sets = kmemdup(nd_config->match_sets,
sizeof(*nd_config->match_sets) *
nd_config->n_match_sets,
GFP_KERNEL);
if (mvm->nd_match_sets)
mvm->n_nd_match_sets = nd_config->n_match_sets;
}
return 0;
}
static void iwl_mvm_free_nd(struct iwl_mvm *mvm)
{
kfree(mvm->nd_match_sets);
mvm->nd_match_sets = NULL;
mvm->n_nd_match_sets = 0;
}
static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
......@@ -1094,8 +1116,10 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
iwl_trans_d3_suspend(mvm->trans, test);
out:
if (ret < 0)
if (ret < 0) {
ieee80211_restart_hw(mvm->hw);
iwl_mvm_free_nd(mvm);
}
out_noreset:
mutex_unlock(&mvm->mutex);
......@@ -1653,14 +1677,15 @@ static u32 iwl_mvm_netdetect_query_results(struct iwl_mvm *mvm)
static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm,
struct ieee80211_vif *vif)
{
struct cfg80211_wowlan_nd_info net_detect = {};
struct cfg80211_wowlan_nd_info *net_detect = NULL;
struct cfg80211_wowlan_wakeup wakeup = {
.pattern_idx = -1,
};
struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup;
struct iwl_wowlan_status *fw_status;
u32 matched_profiles;
unsigned long matched_profiles;
u32 reasons = 0;
int i, n_matches;
fw_status = iwl_mvm_get_wakeup_status(mvm, vif);
if (!IS_ERR_OR_NULL(fw_status))
......@@ -1678,10 +1703,46 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm,
goto out;
}
wakeup.net_detect = &net_detect;
if (mvm->n_nd_match_sets) {
n_matches = hweight_long(matched_profiles);
} else {
IWL_ERR(mvm, "no net detect match information available\n");
n_matches = 0;
}
net_detect = kzalloc(sizeof(*net_detect) +
(n_matches * sizeof(net_detect->matches[0])),
GFP_KERNEL);
if (!net_detect || !n_matches)
goto out_report_nd;
for_each_set_bit(i, &matched_profiles, mvm->n_nd_match_sets) {
struct cfg80211_wowlan_nd_match *match;
match = kzalloc(sizeof(*match), GFP_KERNEL);
if (!match)
goto out_report_nd;
match->ssid.ssid_len = mvm->nd_match_sets[i].ssid.ssid_len;
memcpy(match->ssid.ssid, mvm->nd_match_sets[i].ssid.ssid,
match->ssid.ssid_len);
net_detect->matches[net_detect->n_matches++] = match;
}
out_report_nd:
wakeup.net_detect = net_detect;
out:
iwl_mvm_free_nd(mvm);
mutex_unlock(&mvm->mutex);
ieee80211_report_wowlan_wakeup(vif, wakeup_report, GFP_KERNEL);
if (net_detect) {
for (i = 0; i < net_detect->n_matches; i++)
kfree(net_detect->matches[i]);
kfree(net_detect);
}
}
static void iwl_mvm_read_d3_sram(struct iwl_mvm *mvm)
......
......@@ -685,6 +685,8 @@ struct iwl_mvm {
/* sched scan settings for net detect */
struct cfg80211_sched_scan_request *nd_config;
struct ieee80211_scan_ies nd_ies;
struct cfg80211_match_set *nd_match_sets;
int n_nd_match_sets;
bool net_detect;
#ifdef CONFIG_IWLWIFI_DEBUGFS
u32 d3_wake_sysassert; /* must be u32 for debugfs_create_bool */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册