wil6210: fix for HW bug in interrupt setup logic
authorVladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
Mon, 17 Mar 2014 13:34:13 +0000 (15:34 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 17 Mar 2014 17:44:17 +0000 (13:44 -0400)
Hardware bug triggered by the MSI init while INTx asserted for some reason.
De-assert INTx prior to MSI set-up

Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/ath/wil6210/interrupt.c
drivers/net/wireless/ath/wil6210/pcie_bus.c
drivers/net/wireless/ath/wil6210/wil6210.h

index 10919f95a83c19cd744003a2a49022ecda3b2a8c..52c40e1d593a803a05549a741702a0ceaf3e603b 100644 (file)
@@ -493,6 +493,23 @@ free0:
 
        return rc;
 }
+/* can't use wil_ioread32_and_clear because ICC value is not ser yet */
+static inline void wil_clear32(void __iomem *addr)
+{
+       u32 x = ioread32(addr);
+
+       iowrite32(x, addr);
+}
+
+void wil6210_clear_irq(struct wil6210_priv *wil)
+{
+       wil_clear32(wil->csr + HOSTADDR(RGF_DMA_EP_RX_ICR) +
+                   offsetof(struct RGF_ICR, ICR));
+       wil_clear32(wil->csr + HOSTADDR(RGF_DMA_EP_TX_ICR) +
+                   offsetof(struct RGF_ICR, ICR));
+       wil_clear32(wil->csr + HOSTADDR(RGF_DMA_EP_MISC_ICR) +
+                   offsetof(struct RGF_ICR, ICR));
+}
 
 int wil6210_init_irq(struct wil6210_priv *wil, int irq)
 {
index d96e81131132ebc06ba25ec037e4aabf228b7ce3..c60976144db3aed4c019f4d2ed56c8d78b8ac2c6 100644 (file)
@@ -153,6 +153,7 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        pci_set_drvdata(pdev, wil);
        wil->pdev = pdev;
 
+       wil6210_clear_irq(wil);
        /* FW should raise IRQ when ready */
        rc = wil_if_pcie_enable(wil);
        if (rc) {
index 14f861cd295db9df6bf52c118cb082c633c42284..317621c49bf89caa7d79f4c9fbb94d8b7fe8546d 100644 (file)
@@ -476,6 +476,7 @@ int wmi_rxon(struct wil6210_priv *wil, bool on);
 int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r);
 int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, u16 reason);
 
+void wil6210_clear_irq(struct wil6210_priv *wil);
 int wil6210_init_irq(struct wil6210_priv *wil, int irq);
 void wil6210_fini_irq(struct wil6210_priv *wil, int irq);
 void wil6210_disable_irq(struct wil6210_priv *wil);