aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorVladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>2014-05-27 07:45:48 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-05-29 13:10:31 -0400
commit047e5d74b6e97ef883f4c8e912bd89451957de2b (patch)
treec68df03a0e463bdbf7f7fd1e9dfc5d042a2d0335 /drivers/net/wireless
parent5bb6423e8f23b755cb20c21aa896cc4d4baf6bc5 (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.c1
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c13
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h2
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c1
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
153static 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
153static void wil_fw_error_worker(struct work_struct *work) 162static 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
281void wil_priv_deinit(struct wil6210_priv *wil) 291void 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 {