schedule_work(&wil->disconnect_worker);
 }
 
+static void wil_scan_timer_fn(ulong x)
+{
+       struct wil6210_priv *wil = (void *)x;
+
+       clear_bit(wil_status_fwready, &wil->status);
+       wil_err(wil, "Scan timeout detected, start fw error recovery\n");
+       schedule_work(&wil->fw_error_worker);
+}
+
 static void wil_fw_error_worker(struct work_struct *work)
 {
        struct wil6210_priv *wil = container_of(work,
 
        wil->pending_connect_cid = -1;
        setup_timer(&wil->connect_timer, wil_connect_timer_fn, (ulong)wil);
+       setup_timer(&wil->scan_timer, wil_scan_timer_fn, (ulong)wil);
 
        INIT_WORK(&wil->connect_worker, wil_connect_worker);
        INIT_WORK(&wil->disconnect_worker, wil_disconnect_worker);
 
 void wil_priv_deinit(struct wil6210_priv *wil)
 {
+       del_timer_sync(&wil->scan_timer);
        cancel_work_sync(&wil->disconnect_worker);
        cancel_work_sync(&wil->fw_error_worker);
        mutex_lock(&wil->mutex);
        if (wil->scan_request) {
                wil_dbg_misc(wil, "Abort scan_request 0x%p\n",
                             wil->scan_request);
+               del_timer_sync(&wil->scan_timer);
                cfg80211_scan_done(wil->scan_request, true);
                wil->scan_request = NULL;
        }
        napi_disable(&wil->napi_tx);
 
        if (wil->scan_request) {
+               del_timer_sync(&wil->scan_timer);
                cfg80211_scan_done(wil->scan_request, true);
                wil->scan_request = NULL;
        }
 
 #define WIL6210_ITR_TRSH       (10000) /* arbitrary - about 15 IRQs/msec */
 #define WIL6210_FW_RECOVERY_RETRIES    (5) /* try to recover this many times */
 #define WIL6210_FW_RECOVERY_TO msecs_to_jiffies(5000)
+#define WIL6210_SCAN_TO                msecs_to_jiffies(10000)
 
 /* Hardware definitions begin */
 
        struct work_struct disconnect_worker;
        struct work_struct fw_error_worker;     /* for FW error recovery */
        struct timer_list connect_timer;
+       struct timer_list scan_timer; /* detect scan timeout */
        int pending_connect_cid;
        struct list_head pending_wmi_ev;
        /*
 
                bool aborted = (data->status != WMI_SCAN_SUCCESS);
 
                wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", data->status);
+               del_timer_sync(&wil->scan_timer);
                cfg80211_scan_done(wil->scan_request, aborted);
                wil->scan_request = NULL;
        } else {