summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ath/wil6210/main.c
diff options
context:
space:
mode:
authorVladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>2014-03-17 15:34:18 +0200
committerJohn W. Linville <linville@tuxdriver.com>2014-03-17 13:44:18 -0400
commit0fef1818d0888067f1231b05a08b2d56f017a169 (patch)
tree369f16d78e2cdcdd0a1490cc36c976e999c7b03e /drivers/net/wireless/ath/wil6210/main.c
parent8bf6adb988c6843f0e58d2b210526cf947a8a746 (diff)
downloadlwn-0fef1818d0888067f1231b05a08b2d56f017a169.tar.gz
lwn-0fef1818d0888067f1231b05a08b2d56f017a169.zip
wil6210: Fix kernel oops in reset flow
wil_reset() removes vring's At the same time NAPI may be active performing Rx/Tx completion. If this happens, Rx/Tx polling functions going to access already removed vrings Make sure NAPI is idle and won't be started prior to vring removal. For this, track NAPI enabled state Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/wil6210/main.c')
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index de952ab78607..0831d4cd173b 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -329,11 +329,16 @@ int wil_reset(struct wil6210_priv *wil)
{
int rc;
+ wil->status = 0; /* prevent NAPI from being scheduled */
+ if (test_bit(wil_status_napi_en, &wil->status)) {
+ napi_synchronize(&wil->napi_rx);
+ napi_synchronize(&wil->napi_tx);
+ }
+
cancel_work_sync(&wil->disconnect_worker);
wil6210_disconnect(wil, NULL);
wil6210_disable_irq(wil);
- wil->status = 0;
wmi_event_flush(wil);
@@ -426,6 +431,7 @@ static int __wil_up(struct wil6210_priv *wil)
napi_enable(&wil->napi_rx);
napi_enable(&wil->napi_tx);
+ set_bit(wil_status_napi_en, &wil->status);
return 0;
}
@@ -443,6 +449,7 @@ int wil_up(struct wil6210_priv *wil)
static int __wil_down(struct wil6210_priv *wil)
{
+ clear_bit(wil_status_napi_en, &wil->status);
napi_disable(&wil->napi_rx);
napi_disable(&wil->napi_tx);