u16 tids, int nframes,
                                  enum ieee80211_frame_release_type reason,
                                  bool more_data);
+bool mt76_has_tx_pending(struct mt76_dev *dev);
 void mt76_set_channel(struct mt76_dev *dev);
 int mt76_get_survey(struct ieee80211_hw *hw, int idx,
                    struct survey_info *survey);
 void mt76u_single_wr(struct mt76_dev *dev, const u8 req,
                     const u16 offset, const u32 val);
 int mt76u_init(struct mt76_dev *dev, struct usb_interface *intf);
-int mt76u_submit_rx_buffers(struct mt76_dev *dev);
 int mt76u_alloc_queues(struct mt76_dev *dev);
-void mt76u_stop_queues(struct mt76_dev *dev);
-void mt76u_stop_stat_wk(struct mt76_dev *dev);
+void mt76u_stop_tx(struct mt76_dev *dev);
+void mt76u_stop_rx(struct mt76_dev *dev);
+int mt76u_resume_rx(struct mt76_dev *dev);
 void mt76u_queues_deinit(struct mt76_dev *dev);
 
 struct sk_buff *
 
        clear_bit(MT76_STATE_RUNNING, &dev->mt76.state);
        cancel_delayed_work_sync(&dev->cal_work);
        cancel_delayed_work_sync(&dev->mt76.mac_work);
-       mt76u_stop_stat_wk(&dev->mt76);
+       mt76u_stop_tx(&dev->mt76);
        mt76x02u_exit_beacon_config(dev);
 
        if (test_bit(MT76_REMOVED, &dev->mt76.state))
 {
        struct mt76x02_dev *dev = usb_get_intfdata(usb_intf);
 
-       mt76u_stop_queues(&dev->mt76);
+       mt76u_stop_rx(&dev->mt76);
        clear_bit(MT76_STATE_MCU_RUNNING, &dev->mt76.state);
        mt76x0_chip_onoff(dev, false, false);
 
 static int __maybe_unused mt76x0_resume(struct usb_interface *usb_intf)
 {
        struct mt76x02_dev *dev = usb_get_intfdata(usb_intf);
-       struct mt76_usb *usb = &dev->mt76.usb;
        int ret;
 
-       ret = mt76u_submit_rx_buffers(&dev->mt76);
+       ret = mt76u_resume_rx(&dev->mt76);
        if (ret < 0)
                goto err;
 
-       tasklet_enable(&usb->rx_tasklet);
-       tasklet_enable(&dev->mt76.tx_tasklet);
-
        ret = mt76x0u_init_hardware(dev);
        if (ret)
                goto err;
 
        rcu_read_unlock();
 }
 
-int mt76u_submit_rx_buffers(struct mt76_dev *dev)
+static int mt76u_submit_rx_buffers(struct mt76_dev *dev)
 {
        struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
        unsigned long flags;
 
        return err;
 }
-EXPORT_SYMBOL_GPL(mt76u_submit_rx_buffers);
 
 static int mt76u_alloc_rx(struct mt76_dev *dev)
 {
        memset(&q->rx_page, 0, sizeof(q->rx_page));
 }
 
-static void mt76u_stop_rx(struct mt76_dev *dev)
+void mt76u_stop_rx(struct mt76_dev *dev)
 {
        struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
        int i;
 
        for (i = 0; i < q->ndesc; i++)
-               usb_kill_urb(q->entry[i].urb);
+               usb_poison_urb(q->entry[i].urb);
+
+       tasklet_kill(&dev->usb.rx_tasklet);
+}
+EXPORT_SYMBOL_GPL(mt76u_stop_rx);
+
+int mt76u_resume_rx(struct mt76_dev *dev)
+{
+       struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
+       int i;
+
+       for (i = 0; i < q->ndesc; i++)
+               usb_unpoison_urb(q->entry[i].urb);
+
+       return mt76u_submit_rx_buffers(dev);
 }
+EXPORT_SYMBOL_GPL(mt76u_resume_rx);
 
 static void mt76u_tx_tasklet(unsigned long data)
 {
        }
 }
 
-static void mt76u_stop_tx(struct mt76_dev *dev)
+void mt76u_stop_tx(struct mt76_dev *dev)
 {
+       struct mt76_queue_entry entry;
        struct mt76_queue *q;
-       int i, j;
+       int i, j, ret;
 
-       for (i = 0; i < IEEE80211_NUM_ACS; i++) {
-               q = dev->q_tx[i].q;
-               for (j = 0; j < q->ndesc; j++)
-                       usb_kill_urb(q->entry[j].urb);
-       }
-}
+       ret = wait_event_timeout(dev->tx_wait, !mt76_has_tx_pending(dev), HZ/5);
+       if (!ret) {
+               dev_err(dev->dev, "timed out waiting for pending tx\n");
 
-void mt76u_stop_queues(struct mt76_dev *dev)
-{
-       tasklet_disable(&dev->usb.rx_tasklet);
-       tasklet_disable(&dev->tx_tasklet);
+               for (i = 0; i < IEEE80211_NUM_ACS; i++) {
+                       q = dev->q_tx[i].q;
+                       for (j = 0; j < q->ndesc; j++)
+                               usb_kill_urb(q->entry[j].urb);
+               }
 
-       mt76u_stop_rx(dev);
-       mt76u_stop_tx(dev);
-}
-EXPORT_SYMBOL_GPL(mt76u_stop_queues);
+               tasklet_kill(&dev->tx_tasklet);
+
+               /* On device removal we maight queue skb's, but mt76u_tx_kick()
+                * will fail to submit urb, cleanup those skb's manually.
+                */
+               for (i = 0; i < IEEE80211_NUM_ACS; i++) {
+                       q = dev->q_tx[i].q;
+
+                       /* Assure we are in sync with killed tasklet. */
+                       spin_lock_bh(&q->lock);
+                       while (q->queued) {
+                               entry = q->entry[q->head];
+                               q->head = (q->head + 1) % q->ndesc;
+                               q->queued--;
+
+                               dev->drv->tx_complete_skb(dev, i, &entry);
+                       }
+                       spin_unlock_bh(&q->lock);
+               }
+       }
 
-void mt76u_stop_stat_wk(struct mt76_dev *dev)
-{
        cancel_delayed_work_sync(&dev->usb.stat_work);
        clear_bit(MT76_READING_STATS, &dev->state);
+
+       mt76_tx_status_check(dev, NULL, true);
 }
-EXPORT_SYMBOL_GPL(mt76u_stop_stat_wk);
+EXPORT_SYMBOL_GPL(mt76u_stop_tx);
 
 void mt76u_queues_deinit(struct mt76_dev *dev)
 {
-       mt76u_stop_queues(dev);
+       mt76u_stop_rx(dev);
+       mt76u_stop_tx(dev);
 
        mt76u_free_rx(dev);
        mt76u_free_tx(dev);