aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/wil6210/pcie_bus.c
diff options
context:
space:
mode:
authorLazar Alexei <qca_ailizaro@qca.qualcomm.com>2017-11-14 15:25:42 +0200
committerKalle Valo <kvalo@qca.qualcomm.com>2017-12-02 16:19:03 +0200
commit680c242dc25e036265793edc7d755cfc15afd231 (patch)
treedcf2c13227bfee364aa06aad4e921265d478109a /drivers/net/wireless/ath/wil6210/pcie_bus.c
parentwil6210: get suspend reject reason and resume triggers from FW (diff)
downloadlinux-dev-680c242dc25e036265793edc7d755cfc15afd231.tar.xz
linux-dev-680c242dc25e036265793edc7d755cfc15afd231.zip
wil6210: fix PCIe bus mastering in case of interface down
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 <qca_ailizaro@qca.qualcomm.com> Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers/net/wireless/ath/wil6210/pcie_bus.c')
-rw-r--r--drivers/net/wireless/ath/wil6210/pcie_bus.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c
index fdab8a534daa..0592c73745cb 100644
--- a/drivers/net/wireless/ath/wil6210/pcie_bus.c
+++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c
@@ -379,6 +379,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");
@@ -386,14 +389,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);
}
@@ -406,20 +409,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++;