aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/wil6210/pm.c
diff options
context:
space:
mode:
authorAhmad Masri <amasri@codeaurora.org>2019-02-28 11:34:44 +0200
committerKalle Valo <kvalo@codeaurora.org>2019-04-03 15:34:04 +0300
commita061894587ef61d19e5196c601ac250cc19f406f (patch)
tree55bce378d03f1cb909e5891b315c6d24fbc591a9 /drivers/net/wireless/ath/wil6210/pm.c
parentwil6210: align to latest auto generated wmi.h (diff)
downloadlinux-dev-a061894587ef61d19e5196c601ac250cc19f406f.tar.xz
linux-dev-a061894587ef61d19e5196c601ac250cc19f406f.zip
wil6210: prevent device memory access while in reset or suspend
Accessing some of the memory of the device while the device is resetting or suspending may cause unexpected error as the HW is still not in a stable state. Prevent this access to guarantee successful read/write memory operations. Signed-off-by: Ahmad Masri <amasri@codeaurora.org> Signed-off-by: Maya Erez <merez@codeaurora.org> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/ath/wil6210/pm.c')
-rw-r--r--drivers/net/wireless/ath/wil6210/pm.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/drivers/net/wireless/ath/wil6210/pm.c b/drivers/net/wireless/ath/wil6210/pm.c
index 75fe9323547c..f307522fa26d 100644
--- a/drivers/net/wireless/ath/wil6210/pm.c
+++ b/drivers/net/wireless/ath/wil6210/pm.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2014,2017 Qualcomm Atheros, Inc.
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -195,14 +195,18 @@ static int wil_suspend_keep_radio_on(struct wil6210_priv *wil)
wil_dbg_pm(wil, "suspend keep radio on\n");
/* Prevent handling of new tx and wmi commands */
- set_bit(wil_status_suspending, wil->status);
- if (test_bit(wil_status_collecting_dumps, wil->status)) {
- /* Device collects crash dump, cancel the suspend */
- wil_dbg_pm(wil, "reject suspend while collecting crash dump\n");
- clear_bit(wil_status_suspending, wil->status);
+ rc = down_write_trylock(&wil->mem_lock);
+ if (!rc) {
+ wil_err(wil,
+ "device is busy. down_write_trylock failed, returned (0x%x)\n",
+ rc);
wil->suspend_stats.rejected_by_host++;
return -EBUSY;
}
+
+ set_bit(wil_status_suspending, wil->status);
+ up_write(&wil->mem_lock);
+
wil_pm_stop_all_net_queues(wil);
if (!wil_is_tx_idle(wil)) {
@@ -310,15 +314,18 @@ static int wil_suspend_radio_off(struct wil6210_priv *wil)
wil_dbg_pm(wil, "suspend radio off\n");
- set_bit(wil_status_suspending, wil->status);
- if (test_bit(wil_status_collecting_dumps, wil->status)) {
- /* Device collects crash dump, cancel the suspend */
- wil_dbg_pm(wil, "reject suspend while collecting crash dump\n");
- clear_bit(wil_status_suspending, wil->status);
+ rc = down_write_trylock(&wil->mem_lock);
+ if (!rc) {
+ wil_err(wil,
+ "device is busy. down_write_trylock failed, returned (0x%x)\n",
+ rc);
wil->suspend_stats.rejected_by_host++;
return -EBUSY;
}
+ set_bit(wil_status_suspending, wil->status);
+ up_write(&wil->mem_lock);
+
/* if netif up, hardware is alive, shut it down */
mutex_lock(&wil->vif_mutex);
active_ifaces = wil_has_active_ifaces(wil, true, false);