iwlwifi: fix send hcmd timeout recovery flow
authorShahar S Matityahu <shahar.s.matityahu@intel.com>
Wed, 5 Dec 2018 06:48:26 +0000 (08:48 +0200)
committerLuca Coelho <luciano.coelho@intel.com>
Mon, 4 Feb 2019 10:28:08 +0000 (12:28 +0200)
Both iwl_trans_fw_error and iwl_force_nmi initiate async recovery flow.
Calling them both is redundant and causing a race.

Solve this by removing the call to iwl_trans_fw_error.

Signed-off-by: Shahar S Matityahu <shahar.s.matityahu@intel.com>
Fixes: cfadc3ffccd5 ("iwlwifi: pcie: stop the firmware when we restart it")
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
drivers/net/wireless/intel/iwlwifi/iwl-trans.h
drivers/net/wireless/intel/iwlwifi/pcie/internal.h
drivers/net/wireless/intel/iwlwifi/pcie/trans.c
drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
drivers/net/wireless/intel/iwlwifi/pcie/tx.c

index 36d0add..ef23c6a 100644 (file)
@@ -688,6 +688,9 @@ enum iwl_plat_pm_mode {
  */
 #define IWL_TRANS_IDLE_TIMEOUT 2000
 
+/* Max time to wait for nmi interrupt */
+#define IWL_TRANS_NMI_TIMEOUT (HZ / 4)
+
 /**
  * struct iwl_dram_data
  * @physical: page phy pointer
index ee38ae3..9e1bcaf 100644 (file)
@@ -1036,6 +1036,7 @@ static inline bool iwl_pcie_dbg_on(struct iwl_trans *trans)
 
 void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state);
 void iwl_trans_pcie_dump_regs(struct iwl_trans *trans);
+void iwl_trans_sync_nmi(struct iwl_trans *trans);
 
 #ifdef CONFIG_IWLWIFI_DEBUGFS
 int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans);
index ac82c89..0b29b2e 100644 (file)
@@ -3650,3 +3650,28 @@ out_no_pci:
        iwl_trans_free(trans);
        return ERR_PTR(ret);
 }
+
+void iwl_trans_sync_nmi(struct iwl_trans *trans)
+{
+       unsigned long timeout = jiffies + IWL_TRANS_NMI_TIMEOUT;
+
+       iwl_disable_interrupts(trans);
+       iwl_force_nmi(trans);
+       while (time_after(timeout, jiffies)) {
+               u32 inta_hw = iwl_read32(trans,
+                                        CSR_MSIX_HW_INT_CAUSES_AD);
+
+               /* Error detected by uCode */
+               if (inta_hw & MSIX_HW_INT_CAUSES_REG_SW_ERR) {
+                       /* Clear causes register */
+                       iwl_write32(trans, CSR_MSIX_HW_INT_CAUSES_AD,
+                                   inta_hw &
+                                   MSIX_HW_INT_CAUSES_REG_SW_ERR);
+                       break;
+               }
+
+               mdelay(1);
+       }
+       iwl_enable_interrupts(trans);
+       iwl_trans_fw_error(trans);
+}
index f3d2e8f..88530d9 100644 (file)
@@ -6,7 +6,7 @@
  * GPL LICENSE SUMMARY
  *
  * Copyright(c) 2017 Intel Deutschland GmbH
- * Copyright(c) 2018        Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -20,7 +20,7 @@
  * BSD LICENSE
  *
  * Copyright(c) 2017 Intel Deutschland GmbH
- * Copyright(c) 2018        Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -965,9 +965,7 @@ static int iwl_pcie_gen2_send_hcmd_sync(struct iwl_trans *trans,
                               cmd_str);
                ret = -ETIMEDOUT;
 
-               iwl_force_nmi(trans);
-               iwl_trans_fw_error(trans);
-
+               iwl_trans_sync_nmi(trans);
                goto cancel;
        }
 
index 0739550..28a3718 100644 (file)
@@ -8,7 +8,7 @@
  * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -31,7 +31,7 @@
  * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -1942,9 +1942,7 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans,
                               iwl_get_cmd_string(trans, cmd->id));
                ret = -ETIMEDOUT;
 
-               iwl_force_nmi(trans);
-               iwl_trans_fw_error(trans);
-
+               iwl_trans_sync_nmi(trans);
                goto cancel;
        }