From: Emmanuel Grumbach <emmanuel.grumb...@intel.com>

In some rare cases, the firmware can put the device to
sleep after the driver requested the access. This is
because the access request can take a short time to be
propagated to the firmware.

If that happens, the driver may think that it has access
since the firmware hasn't put the device to sleep yet, but
right after the driver's check, the firmware might put the
device to sleep.

Warn when this happens by allowing the firmware to finish
the "put the device sleep" flow so that the driver will
not get access to the device. This will make the issue
visible.

This still doesn't fix the race, but at least it makes
it more visible.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/iwlwifi/pcie/trans.c | 5 +++++
 drivers/net/wireless/iwlwifi/pcie/tx.c    | 3 +++
 2 files changed, 8 insertions(+)

diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c 
b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 40a2906..d872749 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -1031,6 +1031,9 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans 
*trans,
        iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
        iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
 
+       if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
+               udelay(2);
+
        ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
                           CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
                           CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
@@ -1233,6 +1236,8 @@ static bool iwl_trans_pcie_grab_nic_access(struct 
iwl_trans *trans, bool silent,
        /* this bit wakes up the NIC */
        __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
                                 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+       if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
+               udelay(2);
 
        /*
         * These bits say the device is running, and should keep running for
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c 
b/drivers/net/wireless/iwlwifi/pcie/tx.c
index eb8e298..4a4104e 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -1431,6 +1431,9 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
                trans_pcie->cmd_in_flight = true;
                __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
                                         CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+               if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
+                       udelay(2);
+
                ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
                                   CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
                                   (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to