iwlwifi: pcie: introduce delay when waking up the device
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Mon, 27 Oct 2014 07:14:32 +0000 (09:14 +0200)
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Tue, 11 Nov 2014 15:15:09 +0000 (17:15 +0200)
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.grumbach@intel.com>
drivers/net/wireless/iwlwifi/pcie/trans.c
drivers/net/wireless/iwlwifi/pcie/tx.c

index 40a290603eade3ffc9eb173e846ad9dd2a711a9f..d8727491fee5b3ae34ab93b0b5ecb7b1b859bdfe 100644 (file)
@@ -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
index eb8e2984c5e90f6d8f498e69b1cee4420dffb85d..4a4104eda9b82add1e9ea55fec8691be96c6a546 100644 (file)
@@ -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 |
This page took 0.028149 seconds and 5 git commands to generate.