ath10k: improve warm reset reliability
authorMichal Kazior <michal.kazior@tieto.com>
Wed, 14 May 2014 13:56:16 +0000 (16:56 +0300)
committerKalle Valo <kvalo@qca.qualcomm.com>
Fri, 16 May 2014 13:48:01 +0000 (16:48 +0300)
Warm reset is now able to recover after device
crashes which required a cold reset before.

This should greatly reduce chances of getting data
bus errors or host system freezes due to buggy
cold reset on some chips.

kvalo: use ath10k_pci_soc_*()

Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
drivers/net/wireless/ath/ath10k/pci.c

index 66b1f3017f2b4a616da98cf61010987b9a7beb72..02dc4083882d1e5ea7c0c5b1fdaa720140e91a66 100644 (file)
@@ -1802,6 +1802,26 @@ static void ath10k_pci_fw_interrupt_handler(struct ath10k *ar)
        ath10k_pci_sleep(ar);
 }
 
+/* this function effectively clears target memory controller assert line */
+static void ath10k_pci_warm_reset_si0(struct ath10k *ar)
+{
+       u32 val;
+
+       val = ath10k_pci_soc_read32(ar, SOC_RESET_CONTROL_ADDRESS);
+       ath10k_pci_soc_write32(ar, SOC_RESET_CONTROL_ADDRESS,
+                              val | SOC_RESET_CONTROL_SI0_RST_MASK);
+       val = ath10k_pci_soc_read32(ar, SOC_RESET_CONTROL_ADDRESS);
+
+       msleep(10);
+
+       val = ath10k_pci_soc_read32(ar, SOC_RESET_CONTROL_ADDRESS);
+       ath10k_pci_soc_write32(ar, SOC_RESET_CONTROL_ADDRESS,
+                              val & ~SOC_RESET_CONTROL_SI0_RST_MASK);
+       val = ath10k_pci_soc_read32(ar, SOC_RESET_CONTROL_ADDRESS);
+
+       msleep(10);
+}
+
 static int ath10k_pci_warm_reset(struct ath10k *ar)
 {
        int ret = 0;
@@ -1860,6 +1880,8 @@ static int ath10k_pci_warm_reset(struct ath10k *ar)
                                SOC_RESET_CONTROL_ADDRESS);
        msleep(10);
 
+       ath10k_pci_warm_reset_si0(ar);
+
        /* debug */
        val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS +
                                PCIE_INTR_CAUSE_ADDRESS);