From patchwork Fri Jan 13 23:35:37 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Norris X-Patchwork-Id: 9516621 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 43A78601DA for ; Fri, 13 Jan 2017 23:36:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 35FC428498 for ; Fri, 13 Jan 2017 23:36:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2B149285F4; Fri, 13 Jan 2017 23:36:35 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A800D28498 for ; Fri, 13 Jan 2017 23:36:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751771AbdAMXgd (ORCPT ); Fri, 13 Jan 2017 18:36:33 -0500 Received: from mail-pf0-f174.google.com ([209.85.192.174]:36419 "EHLO mail-pf0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751523AbdAMXfv (ORCPT ); Fri, 13 Jan 2017 18:35:51 -0500 Received: by mail-pf0-f174.google.com with SMTP id 189so38019481pfu.3 for ; Fri, 13 Jan 2017 15:35:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=wHQg9ZqHWxXJhmeYHR2l17Fm/TIGRY0uhTkqcTNXofM=; b=TqC3QQuyLxrT1VbVMFGsV/5RM+ZmAYSO1rAMufBGXbOVoRdqeF/Pfo5CBbKGBsCZzz JH9qRg2PUfxh8HZ8j8m4EF89jV8hKPJldpb9LyvIXW0leb6e5TDCecrFjMxaylMVGoSz og6QcN4cxxmE8mu6M3xYKLNoOCYvVtUDONbTs= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=wHQg9ZqHWxXJhmeYHR2l17Fm/TIGRY0uhTkqcTNXofM=; b=S3/knh5/uro9Lz4IiHrJZzeCr3LJpMIR+Db37y4zrXcf8RJWXXSFE7jSD17r60WkxK A87XJTBo5DCZjEEGJHewGTLfQWP2ih2tUdK82XU30fV2jAe1L5H9/UeZ1u0uUn98/m8m c9aSG9NjXdGnYzoKlCRKZ9+Rq2sxe9hYZ3IAu1L4Xrca53x6BkMLW47Yy46HA6LR69eR Zr2xtScWzCc2FOS399ccCU7eIkDbbiN7Ti9aEXWO6SjEl7Jg0yOARWRH9DVwNaQvPaqL OkO998yeyzE19iAFcyS7mOa9NOOYzTtLKRXxoj16jyL/MfnGjwuhW+5y4wLIY7AY47lg vFFA== X-Gm-Message-State: AIkVDXKLwXz3NJJSUKK/HkSmROF+Xs4qcQNjYN3j4h/23BIZD++osufmQQR+yBeTZJdj6ZtG X-Received: by 10.98.158.210 with SMTP id f79mr25048689pfk.145.1484350550753; Fri, 13 Jan 2017 15:35:50 -0800 (PST) Received: from ban.mtv.corp.google.com ([172.22.64.120]) by smtp.gmail.com with ESMTPSA id r21sm31515999pfd.95.2017.01.13.15.35.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 13 Jan 2017 15:35:50 -0800 (PST) From: Brian Norris To: Amitkumar Karwar , Nishant Sarmukadam Cc: , Kalle Valo , linux-wireless@vger.kernel.org, Cathy Luo , Dmitry Torokhov , Brian Norris Subject: [PATCH v2 2/3] mwifiex: pcie: don't loop/retry interrupt status checks Date: Fri, 13 Jan 2017 15:35:37 -0800 Message-Id: <20170113233538.36196-2-briannorris@chromium.org> X-Mailer: git-send-email 2.11.0.483.g087da7b7c-goog In-Reply-To: <20170113233538.36196-1-briannorris@chromium.org> References: <20170113233538.36196-1-briannorris@chromium.org> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The following sequence occurs when using IEEE power-save on 8997: (a) driver sees SLEEP event (b) driver issues SLEEP CONFIRM (c) driver recevies CMD interrupt; within the interrupt processing loop, we do (d) and (e): (d) wait for FW sleep cookie (and often time out; it takes a while), FW is putting card into low power mode (e) re-check PCIE_HOST_INT_STATUS register; quit loop with 0 value But at (e), no one actually signaled an interrupt (i.e., we didn't check adapter->int_status). And what's more, because the card is going to sleep, this register read appears to take a very long time in some cases -- 3 milliseconds in my case! Now, I propose that (e) is completely unnecessary. If there were any additional interrupts signaled after the start of this loop, then the interrupt handler would have set adapter->int_status to non-zero and queued more work for the main loop -- and we'd catch it on the next iteration of the main loop. So this patch drops all the looping/re-reading of PCIE_HOST_INT_STATUS, which avoids the problematic (and slow) register read in step (e). Incidentally, this is a very similar issue to the one fixed in commit ec815dd2a5f1 ("mwifiex: prevent register accesses after host is sleeping"), except that the register read is just very slow instead of fatal in this case. Tested on 8997 in both MSI and (though not technically supported at the moment) MSI-X mode. Signed-off-by: Brian Norris --- v2: * new in v2, replacing an attempt to mess with step (d) above --- drivers/net/wireless/marvell/mwifiex/pcie.c | 102 +++++++++------------------- 1 file changed, 32 insertions(+), 70 deletions(-) diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c index 3f4cda2d3b61..194e0e04c3b1 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie.c +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c @@ -2332,79 +2332,41 @@ static int mwifiex_process_pcie_int(struct mwifiex_adapter *adapter) } } } - while (pcie_ireg & HOST_INTR_MASK) { - if (pcie_ireg & HOST_INTR_DNLD_DONE) { - pcie_ireg &= ~HOST_INTR_DNLD_DONE; - mwifiex_dbg(adapter, INTR, - "info: TX DNLD Done\n"); - ret = mwifiex_pcie_send_data_complete(adapter); - if (ret) - return ret; - } - if (pcie_ireg & HOST_INTR_UPLD_RDY) { - pcie_ireg &= ~HOST_INTR_UPLD_RDY; - mwifiex_dbg(adapter, INTR, - "info: Rx DATA\n"); - ret = mwifiex_pcie_process_recv_data(adapter); - if (ret) - return ret; - } - if (pcie_ireg & HOST_INTR_EVENT_RDY) { - pcie_ireg &= ~HOST_INTR_EVENT_RDY; - mwifiex_dbg(adapter, INTR, - "info: Rx EVENT\n"); - ret = mwifiex_pcie_process_event_ready(adapter); - if (ret) - return ret; - } - - if (pcie_ireg & HOST_INTR_CMD_DONE) { - pcie_ireg &= ~HOST_INTR_CMD_DONE; - if (adapter->cmd_sent) { - mwifiex_dbg(adapter, INTR, - "info: CMD sent Interrupt\n"); - adapter->cmd_sent = false; - } - /* Handle command response */ - ret = mwifiex_pcie_process_cmd_complete(adapter); - if (ret) - return ret; - if (adapter->hs_activated) - return ret; - } - - if (card->msi_enable) { - spin_lock_irqsave(&adapter->int_lock, flags); - adapter->int_status = 0; - spin_unlock_irqrestore(&adapter->int_lock, flags); - } - - if (mwifiex_pcie_ok_to_access_hw(adapter)) { - if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS, - &pcie_ireg)) { - mwifiex_dbg(adapter, ERROR, - "Read register failed\n"); - return -1; - } - if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) { - if (mwifiex_write_reg(adapter, - PCIE_HOST_INT_STATUS, - ~pcie_ireg)) { - mwifiex_dbg(adapter, ERROR, - "Write register failed\n"); - return -1; - } - } - - } - if (!card->msi_enable) { - spin_lock_irqsave(&adapter->int_lock, flags); - pcie_ireg |= adapter->int_status; - adapter->int_status = 0; - spin_unlock_irqrestore(&adapter->int_lock, flags); + if (pcie_ireg & HOST_INTR_DNLD_DONE) { + pcie_ireg &= ~HOST_INTR_DNLD_DONE; + mwifiex_dbg(adapter, INTR, "info: TX DNLD Done\n"); + ret = mwifiex_pcie_send_data_complete(adapter); + if (ret) + return ret; + } + if (pcie_ireg & HOST_INTR_UPLD_RDY) { + pcie_ireg &= ~HOST_INTR_UPLD_RDY; + mwifiex_dbg(adapter, INTR, "info: Rx DATA\n"); + ret = mwifiex_pcie_process_recv_data(adapter); + if (ret) + return ret; + } + if (pcie_ireg & HOST_INTR_EVENT_RDY) { + pcie_ireg &= ~HOST_INTR_EVENT_RDY; + mwifiex_dbg(adapter, INTR, "info: Rx EVENT\n"); + ret = mwifiex_pcie_process_event_ready(adapter); + if (ret) + return ret; + } + if (pcie_ireg & HOST_INTR_CMD_DONE) { + pcie_ireg &= ~HOST_INTR_CMD_DONE; + if (adapter->cmd_sent) { + mwifiex_dbg(adapter, INTR, + "info: CMD sent Interrupt\n"); + adapter->cmd_sent = false; } + /* Handle command response */ + ret = mwifiex_pcie_process_cmd_complete(adapter); + if (ret) + return ret; } + mwifiex_dbg(adapter, INTR, "info: cmd_sent=%d data_sent=%d\n", adapter->cmd_sent, adapter->data_sent);