Commit 7f8ae00f authored by Haim Dreyfuss's avatar Haim Dreyfuss Committed by Luca Coelho

iwlwifi: Cancel and set MARKER_CMD timer during suspend-resume

While entering to D3 mode there is a gap between the time the
driver handles the D3_CONFIG_CMD response to the time the host is going
to sleep.
In between there might be cases which MARKER_CMD can tailgate.
Also during resume flow the MARKER_CMD might get sent while D0I3_CMD
is being handled in the FW.
Cancel MARKER_CMD timer and set it again properly during suspend
resume flows to prevent this command from being sent accidentlly.
Signed-off-by: default avatarHaim Dreyfuss <haim.dreyfuss@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent 78dc897b
...@@ -75,6 +75,20 @@ static inline void iwl_fw_cancel_timestamp(struct iwl_fw_runtime *fwrt) ...@@ -75,6 +75,20 @@ static inline void iwl_fw_cancel_timestamp(struct iwl_fw_runtime *fwrt)
cancel_delayed_work_sync(&fwrt->timestamp.wk); cancel_delayed_work_sync(&fwrt->timestamp.wk);
} }
static inline void iwl_fw_suspend_timestamp(struct iwl_fw_runtime *fwrt)
{
cancel_delayed_work_sync(&fwrt->timestamp.wk);
}
static inline void iwl_fw_resume_timestamp(struct iwl_fw_runtime *fwrt)
{
if (!fwrt->timestamp.delay)
return;
schedule_delayed_work(&fwrt->timestamp.wk,
round_jiffies_relative(fwrt->timestamp.delay));
}
#else #else
static inline int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt, static inline int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt,
struct dentry *dbgfs_dir) struct dentry *dbgfs_dir)
...@@ -84,4 +98,8 @@ static inline int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt, ...@@ -84,4 +98,8 @@ static inline int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt,
static inline void iwl_fw_cancel_timestamp(struct iwl_fw_runtime *fwrt) {} static inline void iwl_fw_cancel_timestamp(struct iwl_fw_runtime *fwrt) {}
static inline void iwl_fw_suspend_timestamp(struct iwl_fw_runtime *fwrt) {}
static inline void iwl_fw_resume_timestamp(struct iwl_fw_runtime *fwrt) {}
#endif /* CONFIG_IWLWIFI_DEBUGFS */ #endif /* CONFIG_IWLWIFI_DEBUGFS */
...@@ -76,3 +76,15 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans, ...@@ -76,3 +76,15 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
iwl_fwrt_dbgfs_register(fwrt, dbgfs_dir); iwl_fwrt_dbgfs_register(fwrt, dbgfs_dir);
} }
IWL_EXPORT_SYMBOL(iwl_fw_runtime_init); IWL_EXPORT_SYMBOL(iwl_fw_runtime_init);
void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt)
{
iwl_fw_suspend_timestamp(fwrt);
}
IWL_EXPORT_SYMBOL(iwl_fw_runtime_suspend);
void iwl_fw_runtime_resume(struct iwl_fw_runtime *fwrt)
{
iwl_fw_resume_timestamp(fwrt);
}
IWL_EXPORT_SYMBOL(iwl_fw_runtime_resume);
...@@ -150,6 +150,10 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans, ...@@ -150,6 +150,10 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
void iwl_fw_runtime_exit(struct iwl_fw_runtime *fwrt); void iwl_fw_runtime_exit(struct iwl_fw_runtime *fwrt);
void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt);
void iwl_fw_runtime_resume(struct iwl_fw_runtime *fwrt);
static inline void iwl_fw_set_current_image(struct iwl_fw_runtime *fwrt, static inline void iwl_fw_set_current_image(struct iwl_fw_runtime *fwrt,
enum iwl_ucode_type cur_fw_img) enum iwl_ucode_type cur_fw_img)
{ {
......
...@@ -1098,6 +1098,8 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) ...@@ -1098,6 +1098,8 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
/* make sure the d0i3 exit work is not pending */ /* make sure the d0i3 exit work is not pending */
flush_work(&mvm->d0i3_exit_work); flush_work(&mvm->d0i3_exit_work);
iwl_fw_runtime_suspend(&mvm->fwrt);
ret = iwl_trans_suspend(trans); ret = iwl_trans_suspend(trans);
if (ret) if (ret)
return ret; return ret;
...@@ -2012,6 +2014,8 @@ int iwl_mvm_resume(struct ieee80211_hw *hw) ...@@ -2012,6 +2014,8 @@ int iwl_mvm_resume(struct ieee80211_hw *hw)
mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED;
iwl_fw_runtime_resume(&mvm->fwrt);
return ret; return ret;
} }
...@@ -2038,6 +2042,8 @@ static int iwl_mvm_d3_test_open(struct inode *inode, struct file *file) ...@@ -2038,6 +2042,8 @@ static int iwl_mvm_d3_test_open(struct inode *inode, struct file *file)
mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_D3; mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_D3;
iwl_fw_runtime_suspend(&mvm->fwrt);
/* start pseudo D3 */ /* start pseudo D3 */
rtnl_lock(); rtnl_lock();
err = __iwl_mvm_suspend(mvm->hw, mvm->hw->wiphy->wowlan_config, true); err = __iwl_mvm_suspend(mvm->hw, mvm->hw->wiphy->wowlan_config, true);
...@@ -2098,6 +2104,8 @@ static int iwl_mvm_d3_test_release(struct inode *inode, struct file *file) ...@@ -2098,6 +2104,8 @@ static int iwl_mvm_d3_test_release(struct inode *inode, struct file *file)
__iwl_mvm_resume(mvm, true); __iwl_mvm_resume(mvm, true);
rtnl_unlock(); rtnl_unlock();
iwl_fw_runtime_resume(&mvm->fwrt);
mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED;
iwl_abort_notification_waits(&mvm->notif_wait); iwl_abort_notification_waits(&mvm->notif_wait);
......
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