From patchwork Tue Nov 1 12:08:17 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xinming Hu X-Patchwork-Id: 9407281 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 BAE9C60585 for ; Tue, 1 Nov 2016 12:09:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A55262984F for ; Tue, 1 Nov 2016 12:09:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9959829856; Tue, 1 Nov 2016 12:09:24 +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, FREEMAIL_FROM, RCVD_IN_DNSWL_HI autolearn=ham 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 610D32984F for ; Tue, 1 Nov 2016 12:09:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965917AbcKAMIh (ORCPT ); Tue, 1 Nov 2016 08:08:37 -0400 Received: from mail-pf0-f196.google.com ([209.85.192.196]:32888 "EHLO mail-pf0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965912AbcKAMIg (ORCPT ); Tue, 1 Nov 2016 08:08:36 -0400 Received: by mail-pf0-f196.google.com with SMTP id a136so8165455pfa.0 for ; Tue, 01 Nov 2016 05:08:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=03KmNf3EIKRS52McnFGvjx7Art+zVVemcImUYM0dNSk=; b=OEbiqOOK3dekLj4zBhaNLviTMNrdlyOLLHT5AY5omUO0IzKpxO1Wrfgx/E8oFdSqzV aNlFY1tnG8lxuTJNTUTt/oWFw0OGoto77HVgt8AVmurjTA/mn9tAtaXnQJ7zWISfGLl6 Qdq+/sJDTnBmp+9+6eLm2+FOxINN6RxC3TxFQRUetDcnAV46ysECb7kJzRRVboan54X7 EhLqW4a9fWHAJVHQO6khQqOlASJ3DNVybhPj2kjCn6fcQS/vcmbHe0zQdi1CLdP+CrJm +wkkXxh5SaIMuR8lW+lD8f+s7ylSJOdU9U44373yU4HuCornQkJWtiV7tRN+r9OdL05J fSvQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=03KmNf3EIKRS52McnFGvjx7Art+zVVemcImUYM0dNSk=; b=fqXQPCXg+M/WOEADB5lTnUOOsd/542JQ6S3lRYnJEE68ePPbT2IMNSWYJOF+WqrA2v XKzkqz1pNqEUt5PpRiyWfbfL7gQv4I/NpyooC+Ej+lujU6Q+MUmdxg9NaLf6xTeTqIwY duFMK6i7XQszzcsiwSq8u/G5PpXhF12otX32MiuFk5SsgcujT1nV67Ut0Htdv/kVoqlr B8i3RmME4vt+xcihh+1SNXgwFhV7RxJtjKkHClCu5Ph42gm0G68NMz6GAry8yIy8LUeB BbUU7RC9MyLmTtP7bSqe6A8cGt8xOrMxcBmNJWvj9oCzA8XkQZxUrE9CskOGZXgshWc8 S+Zw== X-Gm-Message-State: ABUngvfvraQYpVGaYemMaaZEox8WRiYkviVVL+W8t/cPJOem6zEUmealr3rbkGc447e7Mg== X-Received: by 10.98.48.69 with SMTP id w66mr59889664pfw.0.1478002115969; Tue, 01 Nov 2016 05:08:35 -0700 (PDT) Received: from localhost.localdomain ([216.207.47.6]) by smtp.gmail.com with ESMTPSA id e7sm41905019pfa.65.2016.11.01.05.08.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 01 Nov 2016 05:08:35 -0700 (PDT) From: Xinming Hu X-Google-Original-From: Xinming Hu To: Linux Wireless Cc: Kalle Valo , Brian Norris , Dmitry Torokhov , Amitkumar Karwar , Cathy Luo , Shengzhen Li , Xinming Hu Subject: [PATCH v2 01/12] mwifiex: check tx_hw_pending before downloading sleep confirm Date: Tue, 1 Nov 2016 20:08:17 +0800 Message-Id: <1478002098-14189-1-git-send-email-huxinming820@marvell.com> X-Mailer: git-send-email 1.9.1 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 From: Shengzhen Li We may get SLEEP event from firmware even if TXDone interrupt for last Tx packet is still pending. In this case, we may end up accessing PCIe memory for handling TXDone after power save handshake is completed. This causes kernel crash with external abort. This patch will only allow downloading sleep confirm when no tx done interrupt is pending in the hardware. --- v2: address format issues(Brain) --- Signed-off-by: Cathy Luo Signed-off-by: Shengzhen Li Signed-off-by: Xinming Hu Signed-off-by: Amitkumar Karwar --- drivers/net/wireless/marvell/mwifiex/cmdevt.c | 5 +++-- drivers/net/wireless/marvell/mwifiex/init.c | 1 + drivers/net/wireless/marvell/mwifiex/main.h | 1 + drivers/net/wireless/marvell/mwifiex/pcie.c | 5 +++++ 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/marvell/mwifiex/cmdevt.c b/drivers/net/wireless/marvell/mwifiex/cmdevt.c index 5347728..25a7475 100644 --- a/drivers/net/wireless/marvell/mwifiex/cmdevt.c +++ b/drivers/net/wireless/marvell/mwifiex/cmdevt.c @@ -1118,13 +1118,14 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter) void mwifiex_check_ps_cond(struct mwifiex_adapter *adapter) { - if (!adapter->cmd_sent && + if (!adapter->cmd_sent && !atomic_read(&adapter->tx_hw_pending) && !adapter->curr_cmd && !IS_CARD_RX_RCVD(adapter)) mwifiex_dnld_sleep_confirm_cmd(adapter); else mwifiex_dbg(adapter, CMD, - "cmd: Delay Sleep Confirm (%s%s%s)\n", + "cmd: Delay Sleep Confirm (%s%s%s%s)\n", (adapter->cmd_sent) ? "D" : "", + atomic_read(&adapter->tx_hw_pending) ? "T" : "", (adapter->curr_cmd) ? "C" : "", (IS_CARD_RX_RCVD(adapter)) ? "R" : ""); } diff --git a/drivers/net/wireless/marvell/mwifiex/init.c b/drivers/net/wireless/marvell/mwifiex/init.c index 82839d9..b36cb3f 100644 --- a/drivers/net/wireless/marvell/mwifiex/init.c +++ b/drivers/net/wireless/marvell/mwifiex/init.c @@ -270,6 +270,7 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) adapter->adhoc_11n_enabled = false; mwifiex_wmm_init(adapter); + atomic_set(&adapter->tx_hw_pending, 0); sleep_cfm_buf = (struct mwifiex_opt_sleep_confirm *) adapter->sleep_cfm->data; diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h index d61fe3a..7f67f23 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.h +++ b/drivers/net/wireless/marvell/mwifiex/main.h @@ -857,6 +857,7 @@ struct mwifiex_adapter { atomic_t rx_pending; atomic_t tx_pending; atomic_t cmd_pending; + atomic_t tx_hw_pending; struct workqueue_struct *workqueue; struct work_struct main_work; struct workqueue_struct *rx_workqueue; diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c index 063c707..4aa5d91 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie.c +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c @@ -516,6 +516,7 @@ static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter) } } + atomic_set(&adapter->tx_hw_pending, 0); return 0; } @@ -689,6 +690,7 @@ static void mwifiex_cleanup_txq_ring(struct mwifiex_adapter *adapter) card->tx_buf_list[i] = NULL; } + atomic_set(&adapter->tx_hw_pending, 0); return; } @@ -1126,6 +1128,7 @@ static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter) -1); else mwifiex_write_data_complete(adapter, skb, 0, 0); + atomic_dec(&adapter->tx_hw_pending); } card->tx_buf_list[wrdoneidx] = NULL; @@ -1218,6 +1221,7 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb, wrindx = (card->txbd_wrptr & reg->tx_mask) >> reg->tx_start_ptr; buf_pa = MWIFIEX_SKB_DMA_ADDR(skb); card->tx_buf_list[wrindx] = skb; + atomic_inc(&adapter->tx_hw_pending); if (reg->pfu_enabled) { desc2 = card->txbd_ring[wrindx]; @@ -1295,6 +1299,7 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb, done_unmap: mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE); card->tx_buf_list[wrindx] = NULL; + atomic_dec(&adapter->tx_hw_pending); if (reg->pfu_enabled) memset(desc2, 0, sizeof(*desc2)); else