diff options
author | Ahmad Masri <amasri@codeaurora.org> | 2019-02-28 11:34:44 +0200 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2019-04-03 15:34:04 +0300 |
commit | a061894587ef61d19e5196c601ac250cc19f406f (patch) | |
tree | 55bce378d03f1cb909e5891b315c6d24fbc591a9 /drivers/net/wireless/ath/wil6210/pm.c | |
parent | wil6210: align to latest auto generated wmi.h (diff) | |
download | linux-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.c | 29 |
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); |