diff options
author | Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com> | 2014-05-27 07:45:48 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-05-29 13:10:31 -0400 |
commit | 047e5d74b6e97ef883f4c8e912bd89451957de2b (patch) | |
tree | c68df03a0e463bdbf7f7fd1e9dfc5d042a2d0335 /drivers/net/wireless | |
parent | 5bb6423e8f23b755cb20c21aa896cc4d4baf6bc5 (diff) |
wil6210: detect scan timeouts
If scan has not finished in some reasonable time (10sec), interpret it as
if firmware error occurs but was not reported. Firmware should report
scan completion for every scan request, so it is error condition indeed.
Perform firmware recovery procedure.
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')
-rw-r--r-- | drivers/net/wireless/ath/wil6210/cfg80211.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wil6210/main.c | 13 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wil6210/wil6210.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wil6210/wmi.c | 1 |
4 files changed, 17 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index 6e699d050d1e..820d4ebd9322 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c | |||
@@ -288,6 +288,7 @@ static int wil_cfg80211_scan(struct wiphy *wiphy, | |||
288 | } | 288 | } |
289 | 289 | ||
290 | wil->scan_request = request; | 290 | wil->scan_request = request; |
291 | mod_timer(&wil->scan_timer, jiffies + WIL6210_SCAN_TO); | ||
291 | 292 | ||
292 | memset(&cmd, 0, sizeof(cmd)); | 293 | memset(&cmd, 0, sizeof(cmd)); |
293 | cmd.cmd.num_channels = 0; | 294 | cmd.cmd.num_channels = 0; |
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index f24cb92cc185..11e6d9d22eae 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c | |||
@@ -150,6 +150,15 @@ static void wil_connect_timer_fn(ulong x) | |||
150 | schedule_work(&wil->disconnect_worker); | 150 | schedule_work(&wil->disconnect_worker); |
151 | } | 151 | } |
152 | 152 | ||
153 | static void wil_scan_timer_fn(ulong x) | ||
154 | { | ||
155 | struct wil6210_priv *wil = (void *)x; | ||
156 | |||
157 | clear_bit(wil_status_fwready, &wil->status); | ||
158 | wil_err(wil, "Scan timeout detected, start fw error recovery\n"); | ||
159 | schedule_work(&wil->fw_error_worker); | ||
160 | } | ||
161 | |||
153 | static void wil_fw_error_worker(struct work_struct *work) | 162 | static void wil_fw_error_worker(struct work_struct *work) |
154 | { | 163 | { |
155 | struct wil6210_priv *wil = container_of(work, | 164 | struct wil6210_priv *wil = container_of(work, |
@@ -248,6 +257,7 @@ int wil_priv_init(struct wil6210_priv *wil) | |||
248 | 257 | ||
249 | wil->pending_connect_cid = -1; | 258 | wil->pending_connect_cid = -1; |
250 | setup_timer(&wil->connect_timer, wil_connect_timer_fn, (ulong)wil); | 259 | setup_timer(&wil->connect_timer, wil_connect_timer_fn, (ulong)wil); |
260 | setup_timer(&wil->scan_timer, wil_scan_timer_fn, (ulong)wil); | ||
251 | 261 | ||
252 | INIT_WORK(&wil->connect_worker, wil_connect_worker); | 262 | INIT_WORK(&wil->connect_worker, wil_connect_worker); |
253 | INIT_WORK(&wil->disconnect_worker, wil_disconnect_worker); | 263 | INIT_WORK(&wil->disconnect_worker, wil_disconnect_worker); |
@@ -280,6 +290,7 @@ void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid) | |||
280 | 290 | ||
281 | void wil_priv_deinit(struct wil6210_priv *wil) | 291 | void wil_priv_deinit(struct wil6210_priv *wil) |
282 | { | 292 | { |
293 | del_timer_sync(&wil->scan_timer); | ||
283 | cancel_work_sync(&wil->disconnect_worker); | 294 | cancel_work_sync(&wil->disconnect_worker); |
284 | cancel_work_sync(&wil->fw_error_worker); | 295 | cancel_work_sync(&wil->fw_error_worker); |
285 | mutex_lock(&wil->mutex); | 296 | mutex_lock(&wil->mutex); |
@@ -411,6 +422,7 @@ int wil_reset(struct wil6210_priv *wil) | |||
411 | if (wil->scan_request) { | 422 | if (wil->scan_request) { |
412 | wil_dbg_misc(wil, "Abort scan_request 0x%p\n", | 423 | wil_dbg_misc(wil, "Abort scan_request 0x%p\n", |
413 | wil->scan_request); | 424 | wil->scan_request); |
425 | del_timer_sync(&wil->scan_timer); | ||
414 | cfg80211_scan_done(wil->scan_request, true); | 426 | cfg80211_scan_done(wil->scan_request, true); |
415 | wil->scan_request = NULL; | 427 | wil->scan_request = NULL; |
416 | } | 428 | } |
@@ -540,6 +552,7 @@ static int __wil_down(struct wil6210_priv *wil) | |||
540 | napi_disable(&wil->napi_tx); | 552 | napi_disable(&wil->napi_tx); |
541 | 553 | ||
542 | if (wil->scan_request) { | 554 | if (wil->scan_request) { |
555 | del_timer_sync(&wil->scan_timer); | ||
543 | cfg80211_scan_done(wil->scan_request, true); | 556 | cfg80211_scan_done(wil->scan_request, true); |
544 | wil->scan_request = NULL; | 557 | wil->scan_request = NULL; |
545 | } | 558 | } |
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index f8c598ebd9ee..e25edc52398f 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h | |||
@@ -42,6 +42,7 @@ static inline u32 WIL_GET_BITS(u32 x, int b0, int b1) | |||
42 | #define WIL6210_ITR_TRSH (10000) /* arbitrary - about 15 IRQs/msec */ | 42 | #define WIL6210_ITR_TRSH (10000) /* arbitrary - about 15 IRQs/msec */ |
43 | #define WIL6210_FW_RECOVERY_RETRIES (5) /* try to recover this many times */ | 43 | #define WIL6210_FW_RECOVERY_RETRIES (5) /* try to recover this many times */ |
44 | #define WIL6210_FW_RECOVERY_TO msecs_to_jiffies(5000) | 44 | #define WIL6210_FW_RECOVERY_TO msecs_to_jiffies(5000) |
45 | #define WIL6210_SCAN_TO msecs_to_jiffies(10000) | ||
45 | 46 | ||
46 | /* Hardware definitions begin */ | 47 | /* Hardware definitions begin */ |
47 | 48 | ||
@@ -386,6 +387,7 @@ struct wil6210_priv { | |||
386 | struct work_struct disconnect_worker; | 387 | struct work_struct disconnect_worker; |
387 | struct work_struct fw_error_worker; /* for FW error recovery */ | 388 | struct work_struct fw_error_worker; /* for FW error recovery */ |
388 | struct timer_list connect_timer; | 389 | struct timer_list connect_timer; |
390 | struct timer_list scan_timer; /* detect scan timeout */ | ||
389 | int pending_connect_cid; | 391 | int pending_connect_cid; |
390 | struct list_head pending_wmi_ev; | 392 | struct list_head pending_wmi_ev; |
391 | /* | 393 | /* |
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index e9a11cb3428a..037993544764 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c | |||
@@ -351,6 +351,7 @@ static void wmi_evt_scan_complete(struct wil6210_priv *wil, int id, | |||
351 | bool aborted = (data->status != WMI_SCAN_SUCCESS); | 351 | bool aborted = (data->status != WMI_SCAN_SUCCESS); |
352 | 352 | ||
353 | wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", data->status); | 353 | wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", data->status); |
354 | del_timer_sync(&wil->scan_timer); | ||
354 | cfg80211_scan_done(wil->scan_request, aborted); | 355 | cfg80211_scan_done(wil->scan_request, aborted); |
355 | wil->scan_request = NULL; | 356 | wil->scan_request = NULL; |
356 | } else { | 357 | } else { |