summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/mvm/d3.c
diff options
context:
space:
mode:
authorLuciano Coelho2014-11-20 14:58:34 +0100
committerEmmanuel Grumbach2014-12-01 11:04:35 +0100
commitb04998f3d57adc9ccde264b125bc4ff00b9993d5 (patch)
tree7a1e2d815448b0733b9c1ece041738f7a0387b18 /drivers/net/wireless/iwlwifi/mvm/d3.c
parentiwlwifi: move firmware file format definitions to correct header (diff)
downloadkernel-qcow2-linux-b04998f3d57adc9ccde264b125bc4ff00b9993d5.tar.gz
kernel-qcow2-linux-b04998f3d57adc9ccde264b125bc4ff00b9993d5.tar.xz
kernel-qcow2-linux-b04998f3d57adc9ccde264b125bc4ff00b9993d5.zip
iwlwifi: mvm: check and report if wake up was due to net detect
Query the firmware for scan offload matches when waking up in order to report net detect as the reason for the wake up. This requires a new command API to be implemented. Additionally, remove some net detect command entries that are not valid anymore. Signed-off-by: Luciano Coelho <luciano.coelho@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm/d3.c')
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c46
1 files changed, 44 insertions, 2 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index 60748bd37954..8970386f6b9f 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -1626,14 +1626,50 @@ out_unlock:
return false;
}
+static u32 iwl_mvm_netdetect_query_results(struct iwl_mvm *mvm)
+{
+ struct iwl_scan_offload_profiles_query *query;
+ struct iwl_host_cmd cmd = {
+ .id = SCAN_OFFLOAD_PROFILES_QUERY_CMD,
+ .flags = CMD_WANT_SKB,
+ };
+ int ret, len;
+
+ ret = iwl_mvm_send_cmd(mvm, &cmd);
+ if (ret) {
+ IWL_ERR(mvm, "failed to query matched profiles (%d)\n", ret);
+ return 0;
+ }
+
+ /* RF-kill already asserted again... */
+ if (!cmd.resp_pkt)
+ goto out_free_resp;
+
+ len = iwl_rx_packet_payload_len(cmd.resp_pkt);
+ if (len < sizeof(*query)) {
+ IWL_ERR(mvm, "Invalid scan offload profiles query response!\n");
+ goto out_free_resp;
+ }
+
+ query = (void *)cmd.resp_pkt->data;
+
+ ret = le32_to_cpu(query->matched_profiles);
+
+out_free_resp:
+ iwl_free_resp(&cmd);
+ return ret;
+}
+
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_wakeup wakeup = {
.pattern_idx = -1,
};
struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup;
struct iwl_wowlan_status *fw_status;
+ u32 matched_profiles;
u32 reasons = 0;
fw_status = iwl_mvm_get_wakeup_status(mvm, vif);
@@ -1643,11 +1679,17 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm,
if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED)
wakeup.rfkill_release = true;
- if (reasons == IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS) {
- /* TODO: read and check if it was netdetect */
+ if (reasons != IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS)
+ goto out;
+
+ matched_profiles = iwl_mvm_netdetect_query_results(mvm);
+ if (!matched_profiles) {
wakeup_report = NULL;
+ goto out;
}
+ wakeup.net_detect = &net_detect;
+out:
mutex_unlock(&mvm->mutex);
ieee80211_report_wowlan_wakeup(vif, wakeup_report, GFP_KERNEL);
}