From patchwork Wed Nov 1 19:23:20 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maya Erez X-Patchwork-Id: 10036939 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 1A9456032D for ; Wed, 1 Nov 2017 19:23:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 20BFD285D8 for ; Wed, 1 Nov 2017 19:23:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 15E2428AC7; Wed, 1 Nov 2017 19:23:48 +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=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID 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 9F10C285D8 for ; Wed, 1 Nov 2017 19:23:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933248AbdKATXq (ORCPT ); Wed, 1 Nov 2017 15:23:46 -0400 Received: from alexa-out.qualcomm.com ([129.46.98.28]:64767 "EHLO alexa-out.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933218AbdKATXo (ORCPT ); Wed, 1 Nov 2017 15:23:44 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=qca.qualcomm.com; i=@qca.qualcomm.com; q=dns/txt; s=qcdkim; t=1509564224; x=1541100224; h=cc:from:to:subject:date:message-id:in-reply-to: references; bh=RQ7v2fqHiH+l0d1ZGLA4WSO1HH+s9+7L2/cOtuDgAxY=; b=S/cd3wmMTOh20khnMXHHWJAZNkjFqVEq2WQBEdYP++pHkNRrVGtwdqkb Ac3tk16mvuLaQdNZAo0m037qKexzLkiJUFtLiM38P/g6erj0MCq3ROZg2 Kfo/nbgEGndN6j7vFFM6SFCb2ad5vlV/lX4EvcEhPtCWGRD/a9uiARUuZ 0=; Received: from ironmsg04-r-new.qualcomm.com (HELO Ironmsg04-R.qualcomm.com) ([10.53.140.108]) by alexa-out.qualcomm.com with ESMTP; 01 Nov 2017 12:23:44 -0700 Cc: Lazar Alexei , linux-wireless@vger.kernel.org, wil6210@qca.qualcomm.com, Maya Erez X-IronPort-AV: E=McAfee;i="5900,7806,8702"; a="1524931197" X-MGA-submission: =?us-ascii?q?MDGXGodBohM+JNJ5zpWDNOIxa2KpW3XN7ZTWrT?= =?us-ascii?q?QwgxeNdX5Sgrb3iyTu2IVC5XES2IfFGvk2amf6of02JypLK4p9xOGk4L?= =?us-ascii?q?3D7kIVf6oXCTjuGCGm6P3WhdhsJgzpcOvM0/UGEPoYVxApDKWeIUKRg0?= =?us-ascii?q?r7?= Received: from lx-merez1.mea.qualcomm.com ([10.18.173.103]) by Ironmsg04-R.qualcomm.com with ESMTP; 01 Nov 2017 12:23:42 -0700 From: Maya Erez To: Kalle Valo Subject: [PATCH v2 10/12] wil6210: fix PCIe bus mastering in case of interface down Date: Wed, 1 Nov 2017 21:23:20 +0200 Message-Id: <1509564202-30078-11-git-send-email-qca_merez@qca.qualcomm.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1509564202-30078-1-git-send-email-qca_merez@qca.qualcomm.com> References: <1509564202-30078-1-git-send-email-qca_merez@qca.qualcomm.com> 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: Lazar Alexei In case of interface down, radio is turned off but PCIe mastering is not cleared. This can cause unexpected PCIe access to the shutdown device. Fix this by clearing PCIe mastering also in case interface is down Signed-off-by: Lazar Alexei Signed-off-by: Maya Erez --- drivers/net/wireless/ath/wil6210/pcie_bus.c | 24 +++++++++++++++--------- drivers/net/wireless/ath/wil6210/pm.c | 10 ++-------- drivers/net/wireless/ath/wil6210/wil6210.h | 4 ++-- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c index b4de001..af062fc 100644 --- a/drivers/net/wireless/ath/wil6210/pcie_bus.c +++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c @@ -385,6 +385,9 @@ static int wil6210_suspend(struct device *dev, bool is_runtime) int rc = 0; struct pci_dev *pdev = to_pci_dev(dev); struct wil6210_priv *wil = pci_get_drvdata(pdev); + struct net_device *ndev = wil_to_ndev(wil); + bool keep_radio_on = ndev->flags & IFF_UP && + wil->keep_radio_on_during_sleep; wil_dbg_pm(wil, "suspend: %s\n", is_runtime ? "runtime" : "system"); @@ -392,14 +395,14 @@ static int wil6210_suspend(struct device *dev, bool is_runtime) if (rc) goto out; - rc = wil_suspend(wil, is_runtime); + rc = wil_suspend(wil, is_runtime, keep_radio_on); if (!rc) { wil->suspend_stats.successful_suspends++; - /* If platform device supports keep_radio_on_during_sleep - * it will control PCIe master + /* In case radio stays on, platform device will control + * PCIe master */ - if (!wil->keep_radio_on_during_sleep) + if (!keep_radio_on) /* disable bus mastering */ pci_clear_master(pdev); } @@ -412,20 +415,23 @@ static int wil6210_resume(struct device *dev, bool is_runtime) int rc = 0; struct pci_dev *pdev = to_pci_dev(dev); struct wil6210_priv *wil = pci_get_drvdata(pdev); + struct net_device *ndev = wil_to_ndev(wil); + bool keep_radio_on = ndev->flags & IFF_UP && + wil->keep_radio_on_during_sleep; wil_dbg_pm(wil, "resume: %s\n", is_runtime ? "runtime" : "system"); - /* If platform device supports keep_radio_on_during_sleep it will - * control PCIe master + /* In case radio stays on, platform device will control + * PCIe master */ - if (!wil->keep_radio_on_during_sleep) + if (!keep_radio_on) /* allow master */ pci_set_master(pdev); - rc = wil_resume(wil, is_runtime); + rc = wil_resume(wil, is_runtime, keep_radio_on); if (rc) { wil_err(wil, "device failed to resume (%d)\n", rc); wil->suspend_stats.failed_resumes++; - if (!wil->keep_radio_on_during_sleep) + if (!keep_radio_on) pci_clear_master(pdev); } else { wil->suspend_stats.successful_resumes++; diff --git a/drivers/net/wireless/ath/wil6210/pm.c b/drivers/net/wireless/ath/wil6210/pm.c index 2ef2f34..ce4f546 100644 --- a/drivers/net/wireless/ath/wil6210/pm.c +++ b/drivers/net/wireless/ath/wil6210/pm.c @@ -300,12 +300,9 @@ static int wil_resume_radio_off(struct wil6210_priv *wil) return rc; } -int wil_suspend(struct wil6210_priv *wil, bool is_runtime) +int wil_suspend(struct wil6210_priv *wil, bool is_runtime, bool keep_radio_on) { int rc = 0; - struct net_device *ndev = wil_to_ndev(wil); - bool keep_radio_on = ndev->flags & IFF_UP && - wil->keep_radio_on_during_sleep; wil_dbg_pm(wil, "suspend: %s\n", is_runtime ? "runtime" : "system"); @@ -328,12 +325,9 @@ int wil_suspend(struct wil6210_priv *wil, bool is_runtime) return rc; } -int wil_resume(struct wil6210_priv *wil, bool is_runtime) +int wil_resume(struct wil6210_priv *wil, bool is_runtime, bool keep_radio_on) { int rc = 0; - struct net_device *ndev = wil_to_ndev(wil); - bool keep_radio_on = ndev->flags & IFF_UP && - wil->keep_radio_on_during_sleep; unsigned long long suspend_time_usec = 0; wil_dbg_pm(wil, "resume: %s\n", is_runtime ? "runtime" : "system"); diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index 2521c7d..2441818 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -1018,8 +1018,8 @@ int wil_request_firmware(struct wil6210_priv *wil, const char *name, void wil_pm_runtime_put(struct wil6210_priv *wil); int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime); -int wil_suspend(struct wil6210_priv *wil, bool is_runtime); -int wil_resume(struct wil6210_priv *wil, bool is_runtime); +int wil_suspend(struct wil6210_priv *wil, bool is_runtime, bool keep_radio_on); +int wil_resume(struct wil6210_priv *wil, bool is_runtime, bool keep_radio_on); bool wil_is_wmi_idle(struct wil6210_priv *wil); int wmi_resume(struct wil6210_priv *wil); int wmi_suspend(struct wil6210_priv *wil);