Received: by 2002:a25:ad19:0:0:0:0:0 with SMTP id y25csp4284229ybi; Mon, 15 Jul 2019 06:42:40 -0700 (PDT) X-Google-Smtp-Source: APXvYqyLqr+fOTujcCWovHJbnNtWUhEG9KPnVH/oyrHll4Fj6xygLXhsv09RgrD9J6Z5vusJm2iy X-Received: by 2002:a63:505a:: with SMTP id q26mr26354918pgl.18.1563198160452; Mon, 15 Jul 2019 06:42:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1563198160; cv=none; d=google.com; s=arc-20160816; b=ZpfDy9mhWXmYmmMiW+5sVd36NHTD178D7Eii+Yrd6lS6lOwVBinyp2Gez2C9OFKwO4 VeVMdoOLs2ujfoktSRwpQY7aspvoETP3qV2UWceZewcgdCavvuZGlfwYWVNZCGsF7hbb vZDNldw5RyscavgvROez2w+qgIDi1j/r51QVu1M0VYQ9x4ag1NNJhxFOmksuIArGtF/v y8aPaNlYxAYSd8jmsv10mDaGLJLnelrOF0eSTDMfz4hxpX54+6Z/vts9baSpnSiHuGwA MINNPGpbBHFxoHC8+2MKJueL8dvTfzqwbNssPyY799KsVM1IMj2N7FBYtnxkP0f1a6dn DmcQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=l/MPwTDH8TW8/HFoNY1+NaULYTo+Y/+x5xC2joxawnI=; b=SO7639eTfUcnaen55x8+f4+JI0I7Zr7QBvVs24D+NCv7sTSQsGWvG2vpwPKKSArLsg OpCBLFisvdEKlH5X1mS0iXhqH1ExBakO/Ut4nrxlV3eU1fFQGYgirQ7lJ6eMKXUGT720 KI/c8zv/Qs7Sqce8xj00enm7MD96cbEhgogWNPzqFhUCYU8kQEXnGouZqi9Ie+/TVhss 5y7uaChfEZT4BnPC652MstQPzJYCZl6dhvAWzzztjjCtuiLShZDvAtdn0h9I5yNw6y3Z cI5zH0Sze6EFfEQRQA9eQYd4P9DMdF4sbI5K5Je/Jut2GW8HRZKCPUElSX6dpjCKUKwo OWbA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=bKJXbVsc; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z191si16733930pgd.572.2019.07.15.06.42.23; Mon, 15 Jul 2019 06:42:40 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=bKJXbVsc; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731079AbfGONix (ORCPT + 99 others); Mon, 15 Jul 2019 09:38:53 -0400 Received: from mail.kernel.org ([198.145.29.99]:39582 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730548AbfGONiu (ORCPT ); Mon, 15 Jul 2019 09:38:50 -0400 Received: from sasha-vm.mshome.net (unknown [73.61.17.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id D487F212F5; Mon, 15 Jul 2019 13:38:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1563197929; bh=cwj2TV8aNs6LySxy/LCnHOPVV990P3iZxrVcTKjb4l0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bKJXbVscCDYda05+squ4q4So5gfbbX+bd+ZgozMocvXpMuerK983Iwai5GT+w+WDS jmY5oOQs/uiRMYPTRN3Pn+zV7CP81sGu/QNHtIjSthCLMybX828ZOhWHiFwpy2LYj9 o1NATQf720NoVRffVPOVqyrizCb8seosmtVBAjQc= From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Maya Erez , Kalle Valo , Sasha Levin , linux-wireless@vger.kernel.org, wil6210@qti.qualcomm.com, netdev@vger.kernel.org Subject: [PATCH AUTOSEL 5.1 014/219] wil6210: fix spurious interrupts in 3-msi Date: Mon, 15 Jul 2019 09:34:46 -0400 Message-Id: <20190715133811.2441-14-sashal@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190715133811.2441-1-sashal@kernel.org> References: <20190715133811.2441-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Maya Erez [ Upstream commit e10b0eddd5235aa5aef4e40b970e34e735611a80 ] Interrupt is set in ICM (ICR & ~IMV) rising trigger. As the driver masks the IRQ after clearing it, there can be a race where an additional spurious interrupt is triggered when the driver unmask the IRQ. This can happen in case HW triggers an interrupt after the clear and before the mask. To prevent the second spurious interrupt the driver needs to mask the IRQ before reading and clearing it. Signed-off-by: Maya Erez Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/wil6210/interrupt.c | 65 ++++++++++++-------- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c index e41ba24011d8..b00a13d6d530 100644 --- a/drivers/net/wireless/ath/wil6210/interrupt.c +++ b/drivers/net/wireless/ath/wil6210/interrupt.c @@ -296,21 +296,24 @@ void wil_configure_interrupt_moderation(struct wil6210_priv *wil) static irqreturn_t wil6210_irq_rx(int irq, void *cookie) { struct wil6210_priv *wil = cookie; - u32 isr = wil_ioread32_and_clear(wil->csr + - HOSTADDR(RGF_DMA_EP_RX_ICR) + - offsetof(struct RGF_ICR, ICR)); + u32 isr; bool need_unmask = true; + wil6210_mask_irq_rx(wil); + + isr = wil_ioread32_and_clear(wil->csr + + HOSTADDR(RGF_DMA_EP_RX_ICR) + + offsetof(struct RGF_ICR, ICR)); + trace_wil6210_irq_rx(isr); wil_dbg_irq(wil, "ISR RX 0x%08x\n", isr); if (unlikely(!isr)) { wil_err_ratelimited(wil, "spurious IRQ: RX\n"); + wil6210_unmask_irq_rx(wil); return IRQ_NONE; } - wil6210_mask_irq_rx(wil); - /* RX_DONE and RX_HTRSH interrupts are the same if interrupt * moderation is not used. Interrupt moderation may cause RX * buffer overflow while RX_DONE is delayed. The required @@ -355,21 +358,24 @@ static irqreturn_t wil6210_irq_rx(int irq, void *cookie) static irqreturn_t wil6210_irq_rx_edma(int irq, void *cookie) { struct wil6210_priv *wil = cookie; - u32 isr = wil_ioread32_and_clear(wil->csr + - HOSTADDR(RGF_INT_GEN_RX_ICR) + - offsetof(struct RGF_ICR, ICR)); + u32 isr; bool need_unmask = true; + wil6210_mask_irq_rx_edma(wil); + + isr = wil_ioread32_and_clear(wil->csr + + HOSTADDR(RGF_INT_GEN_RX_ICR) + + offsetof(struct RGF_ICR, ICR)); + trace_wil6210_irq_rx(isr); wil_dbg_irq(wil, "ISR RX 0x%08x\n", isr); if (unlikely(!isr)) { wil_err(wil, "spurious IRQ: RX\n"); + wil6210_unmask_irq_rx_edma(wil); return IRQ_NONE; } - wil6210_mask_irq_rx_edma(wil); - if (likely(isr & BIT_RX_STATUS_IRQ)) { wil_dbg_irq(wil, "RX status ring\n"); isr &= ~BIT_RX_STATUS_IRQ; @@ -403,21 +409,24 @@ static irqreturn_t wil6210_irq_rx_edma(int irq, void *cookie) static irqreturn_t wil6210_irq_tx_edma(int irq, void *cookie) { struct wil6210_priv *wil = cookie; - u32 isr = wil_ioread32_and_clear(wil->csr + - HOSTADDR(RGF_INT_GEN_TX_ICR) + - offsetof(struct RGF_ICR, ICR)); + u32 isr; bool need_unmask = true; + wil6210_mask_irq_tx_edma(wil); + + isr = wil_ioread32_and_clear(wil->csr + + HOSTADDR(RGF_INT_GEN_TX_ICR) + + offsetof(struct RGF_ICR, ICR)); + trace_wil6210_irq_tx(isr); wil_dbg_irq(wil, "ISR TX 0x%08x\n", isr); if (unlikely(!isr)) { wil_err(wil, "spurious IRQ: TX\n"); + wil6210_unmask_irq_tx_edma(wil); return IRQ_NONE; } - wil6210_mask_irq_tx_edma(wil); - if (likely(isr & BIT_TX_STATUS_IRQ)) { wil_dbg_irq(wil, "TX status ring\n"); isr &= ~BIT_TX_STATUS_IRQ; @@ -446,21 +455,24 @@ static irqreturn_t wil6210_irq_tx_edma(int irq, void *cookie) static irqreturn_t wil6210_irq_tx(int irq, void *cookie) { struct wil6210_priv *wil = cookie; - u32 isr = wil_ioread32_and_clear(wil->csr + - HOSTADDR(RGF_DMA_EP_TX_ICR) + - offsetof(struct RGF_ICR, ICR)); + u32 isr; bool need_unmask = true; + wil6210_mask_irq_tx(wil); + + isr = wil_ioread32_and_clear(wil->csr + + HOSTADDR(RGF_DMA_EP_TX_ICR) + + offsetof(struct RGF_ICR, ICR)); + trace_wil6210_irq_tx(isr); wil_dbg_irq(wil, "ISR TX 0x%08x\n", isr); if (unlikely(!isr)) { wil_err_ratelimited(wil, "spurious IRQ: TX\n"); + wil6210_unmask_irq_tx(wil); return IRQ_NONE; } - wil6210_mask_irq_tx(wil); - if (likely(isr & BIT_DMA_EP_TX_ICR_TX_DONE)) { wil_dbg_irq(wil, "TX done\n"); isr &= ~BIT_DMA_EP_TX_ICR_TX_DONE; @@ -532,20 +544,23 @@ static bool wil_validate_mbox_regs(struct wil6210_priv *wil) static irqreturn_t wil6210_irq_misc(int irq, void *cookie) { struct wil6210_priv *wil = cookie; - u32 isr = wil_ioread32_and_clear(wil->csr + - HOSTADDR(RGF_DMA_EP_MISC_ICR) + - offsetof(struct RGF_ICR, ICR)); + u32 isr; + + wil6210_mask_irq_misc(wil, false); + + isr = wil_ioread32_and_clear(wil->csr + + HOSTADDR(RGF_DMA_EP_MISC_ICR) + + offsetof(struct RGF_ICR, ICR)); trace_wil6210_irq_misc(isr); wil_dbg_irq(wil, "ISR MISC 0x%08x\n", isr); if (!isr) { wil_err(wil, "spurious IRQ: MISC\n"); + wil6210_unmask_irq_misc(wil, false); return IRQ_NONE; } - wil6210_mask_irq_misc(wil, false); - if (isr & ISR_MISC_FW_ERROR) { u32 fw_assert_code = wil_r(wil, wil->rgf_fw_assert_code_addr); u32 ucode_assert_code = -- 2.20.1