diff options
Diffstat (limited to 'drivers/net/wireless/ath/wil6210/main.c')
-rw-r--r-- | drivers/net/wireless/ath/wil6210/main.c | 41 |
1 files changed, 31 insertions, 10 deletions
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index 277abfdf3322..6df19a2a6ce7 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c @@ -184,6 +184,28 @@ void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src, } } +/* Device memory access is prohibited while reset or suspend. + * wil_mem_access_lock protects accessing device memory in these cases + */ +int wil_mem_access_lock(struct wil6210_priv *wil) +{ + if (!down_read_trylock(&wil->mem_lock)) + return -EBUSY; + + if (test_bit(wil_status_suspending, wil->status) || + test_bit(wil_status_suspended, wil->status)) { + up_read(&wil->mem_lock); + return -EBUSY; + } + + return 0; +} + +void wil_mem_access_unlock(struct wil6210_priv *wil) +{ + up_read(&wil->mem_lock); +} + static void wil_ring_fini_tx(struct wil6210_priv *wil, int id) { struct wil_ring *ring = &wil->ring_tx[id]; @@ -703,6 +725,7 @@ int wil_priv_init(struct wil6210_priv *wil) spin_lock_init(&wil->wmi_ev_lock); spin_lock_init(&wil->net_queue_lock); init_waitqueue_head(&wil->wq); + init_rwsem(&wil->mem_lock); wil->wmi_wq = create_singlethread_workqueue(WIL_NAME "_wmi"); if (!wil->wmi_wq) @@ -1599,15 +1622,6 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) } set_bit(wil_status_resetting, wil->status); - if (test_bit(wil_status_collecting_dumps, wil->status)) { - /* Device collects crash dump, cancel the reset. - * following crash dump collection, reset would take place. - */ - wil_dbg_misc(wil, "reject reset while collecting crash dump\n"); - rc = -EBUSY; - goto out; - } - mutex_lock(&wil->vif_mutex); wil_abort_scan_all_vifs(wil, false); mutex_unlock(&wil->vif_mutex); @@ -1782,7 +1796,9 @@ int __wil_up(struct wil6210_priv *wil) WARN_ON(!mutex_is_locked(&wil->mutex)); + down_write(&wil->mem_lock); rc = wil_reset(wil, true); + up_write(&wil->mem_lock); if (rc) return rc; @@ -1854,6 +1870,7 @@ int wil_up(struct wil6210_priv *wil) int __wil_down(struct wil6210_priv *wil) { + int rc; WARN_ON(!mutex_is_locked(&wil->mutex)); set_bit(wil_status_resetting, wil->status); @@ -1873,7 +1890,11 @@ int __wil_down(struct wil6210_priv *wil) wil_abort_scan_all_vifs(wil, false); mutex_unlock(&wil->vif_mutex); - return wil_reset(wil, false); + down_write(&wil->mem_lock); + rc = wil_reset(wil, false); + up_write(&wil->mem_lock); + + return rc; } int wil_down(struct wil6210_priv *wil) |