struct net_device *dev, u8 *mac)
 {
        struct wil6210_priv *wil = wiphy_to_wil(wiphy);
+
+       mutex_lock(&wil->mutex);
        wil6210_disconnect(wil, mac);
+       mutex_unlock(&wil->mutex);
+
        return 0;
 }
 
 
        struct wil6210_priv *wil = container_of(work,
                        struct wil6210_priv, disconnect_worker);
 
+       mutex_lock(&wil->mutex);
        _wil6210_disconnect(wil, NULL);
+       mutex_unlock(&wil->mutex);
 }
 
 static void wil_connect_timer_fn(ulong x)
 {
        cancel_work_sync(&wil->disconnect_worker);
        cancel_work_sync(&wil->fw_error_worker);
+       mutex_lock(&wil->mutex);
        wil6210_disconnect(wil, NULL);
+       mutex_unlock(&wil->mutex);
        wmi_event_flush(wil);
        destroy_workqueue(wil->wmi_wq_conn);
        destroy_workqueue(wil->wmi_wq);
 {
        int rc;
 
+       WARN_ON(!mutex_is_locked(&wil->mutex));
+
+       cancel_work_sync(&wil->disconnect_worker);
+       wil6210_disconnect(wil, NULL);
+
        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);
        }
 
        if (wil->scan_request) {
                wil->scan_request = NULL;
        }
 
-       cancel_work_sync(&wil->disconnect_worker);
-       wil6210_disconnect(wil, NULL);
-
        wil6210_disable_irq(wil);
 
        wmi_event_flush(wil);
        struct wireless_dev *wdev = wil->wdev;
        int rc;
 
+       WARN_ON(!mutex_is_locked(&wil->mutex));
+
        rc = wil_reset(wil);
        if (rc)
                return rc;
 
 static int __wil_down(struct wil6210_priv *wil)
 {
+       WARN_ON(!mutex_is_locked(&wil->mutex));
+
        clear_bit(wil_status_napi_en, &wil->status);
        napi_disable(&wil->napi_rx);
        napi_disable(&wil->napi_tx);
 
                goto stop_master;
 
        /* need reset here to obtain MAC */
+       mutex_lock(&wil->mutex);
        rc = wil_reset(wil);
+       mutex_unlock(&wil->mutex);
        if (rc)
                goto release_irq;
 
 
                struct wmi_vring_cfg_done_event cmd;
        } __packed reply;
        struct vring *vring = &wil->vring_tx[id];
+       struct vring_tx_data *txdata = &wil->vring_tx_data[id];
 
        if (vring->va) {
                wil_err(wil, "Tx ring [%d] already allocated\n", id);
                goto out;
        }
 
+       memset(txdata, 0, sizeof(*txdata));
        vring->size = size;
        rc = wil_vring_alloc(wil, vring);
        if (rc)
        }
        vring->hwtail = le32_to_cpu(reply.cmd.tx_vring_tail_ptr);
 
+       txdata->enabled = 1;
+
        return 0;
  out_free:
        wil_vring_free(wil, vring, 1);
 {
        struct vring *vring = &wil->vring_tx[id];
 
+       WARN_ON(!mutex_is_locked(&wil->mutex));
+
        if (!vring->va)
                return;
 
+       /* make sure NAPI won't touch this vring */
+       wil->vring_tx_data[id].enabled = 0;
+       if (test_bit(wil_status_napi_en, &wil->status))
+               napi_synchronize(&wil->napi_tx);
+
        wil_vring_free(wil, vring, 1);
 }
 
        struct net_device *ndev = wil_to_ndev(wil);
        struct device *dev = wil_to_dev(wil);
        struct vring *vring = &wil->vring_tx[ringid];
+       struct vring_tx_data *txdata = &wil->vring_tx_data[ringid];
        int done = 0;
        int cid = wil->vring2cid_tid[ringid][0];
        struct wil_net_stats *stats = &wil->sta[cid].stats;
                return 0;
        }
 
+       if (!txdata->enabled) {
+               wil_info(wil, "Tx irq[%d]: vring disabled\n", ringid);
+               return 0;
+       }
+
        wil_dbg_txrx(wil, "%s(%d)\n", __func__, ringid);
 
        while (!wil_vring_is_empty(vring)) {
 
        struct wil_ctx *ctx; /* ctx[size] - software context */
 };
 
+/**
+ * Additional data for Tx Vring
+ */
+struct vring_tx_data {
+       int enabled;
+
+};
+
 enum { /* for wil6210_priv.status */
        wil_status_fwready = 0,
        wil_status_fwconnecting,
        /* DMA related */
        struct vring vring_rx;
        struct vring vring_tx[WIL6210_MAX_TX_RINGS];
+       struct vring_tx_data vring_tx_data[WIL6210_MAX_TX_RINGS];
        u8 vring2cid_tid[WIL6210_MAX_TX_RINGS][2]; /* [0] - CID, [1] - TID */
        struct wil_sta_info sta[WIL6210_MAX_CID];
        /* scan */
 
 
        wil->sinfo_gen++;
 
+       mutex_lock(&wil->mutex);
        wil6210_disconnect(wil, evt->bssid);
+       mutex_unlock(&wil->mutex);
 }
 
 static void wmi_evt_notify(struct wil6210_priv *wil, int id, void *d, int len)