From 2021a89d7b8a26d6fdc66daa51e414193b4cf568 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 20 Nov 2014 08:59:51 +0200 Subject: [PATCH] iwlwifi: mvm: treat netdetect wake up separately When the device wakes up due to netdetect, we need to query different things from the firmware than when it wakes up with a normal WoWLAN. To make this easier, separate the netdetect wake up handling from the rest. For now, we don't send netdetect as a wake up reason, treating it as a non-wireless wake up. Signed-off-by: Luciano Coelho Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/d3.c | 40 ++++++++++++++++++++++++-- drivers/net/wireless/iwlwifi/mvm/mvm.h | 1 + 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index c72d2e98c3f1..176556ea63cb 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c @@ -1048,6 +1048,8 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, mvm, wowlan, wowlan->nd_config ?: mvm->nd_config, vif); if (ret) goto out; + + mvm->net_detect = true; } else { struct iwl_wowlan_config_cmd_v3 wowlan_config_cmd = {}; @@ -1067,6 +1069,8 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, vif, mvmvif, ap_sta); if (ret) goto out; + + mvm->net_detect = false; } ret = iwl_mvm_power_update_device(mvm); @@ -1621,6 +1625,32 @@ out_unlock: return false; } +static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm, + struct ieee80211_vif *vif) +{ + struct cfg80211_wowlan_wakeup wakeup = { + .pattern_idx = -1, + }; + struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup; + struct iwl_wowlan_status *fw_status; + u32 reasons = 0; + + fw_status = iwl_mvm_get_wakeup_status(mvm, vif); + if (!IS_ERR_OR_NULL(fw_status)) + reasons = le32_to_cpu(fw_status->wakeup_reasons); + + 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 */ + wakeup_report = NULL; + } + + mutex_unlock(&mvm->mutex); + ieee80211_report_wowlan_wakeup(vif, wakeup_report, GFP_KERNEL); +} + static void iwl_mvm_read_d3_sram(struct iwl_mvm *mvm) { #ifdef CONFIG_IWLWIFI_DEBUGFS @@ -1678,11 +1708,15 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) /* query SRAM first in case we want event logging */ iwl_mvm_read_d3_sram(mvm); - keep = iwl_mvm_query_wakeup_reasons(mvm, vif); + if (mvm->net_detect) { + iwl_mvm_query_netdetect_reasons(mvm, vif); + } else { + keep = iwl_mvm_query_wakeup_reasons(mvm, vif); #ifdef CONFIG_IWLWIFI_DEBUGFS - if (keep) - mvm->keep_vif = vif; + if (keep) + mvm->keep_vif = vif; #endif + } /* has unlocked the mutex, so skip that */ goto out; diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 7c62f80414ae..e6079f4dc4e1 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -685,6 +685,7 @@ struct iwl_mvm { /* sched scan settings for net detect */ struct cfg80211_sched_scan_request *nd_config; struct ieee80211_scan_ies nd_ies; + bool net_detect; #ifdef CONFIG_IWLWIFI_DEBUGFS u32 d3_wake_sysassert; /* must be u32 for debugfs_create_bool */ bool d3_test_active;