diff options
author | Luca Coelho <luciano.coelho@intel.com> | 2016-03-11 11:12:16 +0100 |
---|---|---|
committer | Luca Coelho <luciano.coelho@intel.com> | 2016-05-10 21:14:48 +0200 |
commit | 71b1230ca97e60d26b4205ac553af6331724ca60 (patch) | |
tree | 63e522c0a210fcbd7d07df90275157d3c9166860 /drivers/net/wireless/intel/iwlwifi/pcie/tx.c | |
parent | iwlwifi: mvm: allow a debug knob for Tx A-MSDU even if rate control forbids it (diff) | |
download | linux-71b1230ca97e60d26b4205ac553af6331724ca60.tar.xz linux-71b1230ca97e60d26b4205ac553af6331724ca60.zip |
iwlwifi: wake from runtime suspend before sending sync commands
If a host command was queued while in runtime suspend, it would go out
before the D0I3_END_CMD was sent. Sometimes it works, but sometimes
it fails, and it is obviously the wrong thing to do.
To fix this, have the opmode take a reference before sending a SYNC
command and make the pcie trans wait for the runtime state to become
active before actually queueing the command.
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/pcie/tx.c')
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index e2eb130dae98..d6beac9af029 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c @@ -32,6 +32,7 @@ #include <linux/ieee80211.h> #include <linux/slab.h> #include <linux/sched.h> +#include <linux/pm_runtime.h> #include <net/ip6_checksum.h> #include <net/tso.h> @@ -1799,6 +1800,16 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans, IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", iwl_get_cmd_string(trans, cmd->id)); + if (pm_runtime_suspended(&trans_pcie->pci_dev->dev)) { + ret = wait_event_timeout(trans_pcie->d0i3_waitq, + pm_runtime_active(&trans_pcie->pci_dev->dev), + msecs_to_jiffies(IWL_TRANS_IDLE_TIMEOUT)); + if (!ret) { + IWL_ERR(trans, "Timeout exiting D0i3 before hcmd\n"); + return -ETIMEDOUT; + } + } + cmd_idx = iwl_pcie_enqueue_hcmd(trans, cmd); if (cmd_idx < 0) { ret = cmd_idx; |