* queues.
                 */
                synchronize_net();
-               ieee80211_flush_queues(local, sdata);
+               ieee80211_flush_queues(local, sdata, false);
 
                /* restore the normal QoS parameters
                 * (unconditionally to avoid races)
 
 void ieee80211_add_pending_skbs(struct ieee80211_local *local,
                                struct sk_buff_head *skbs);
 void ieee80211_flush_queues(struct ieee80211_local *local,
-                           struct ieee80211_sub_if_data *sdata);
+                           struct ieee80211_sub_if_data *sdata, bool drop);
 void __ieee80211_flush_queues(struct ieee80211_local *local,
                              struct ieee80211_sub_if_data *sdata,
-                             unsigned int queues);
+                             unsigned int queues, bool drop);
 
 void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
                         u16 transaction, u16 auth_alg, u16 status,
 
        if (local->hw.conf.flags & IEEE80211_CONF_IDLE)
                return 0;
 
-       ieee80211_flush_queues(local, NULL);
+       ieee80211_flush_queues(local, NULL, false);
 
        local->hw.conf.flags |= IEEE80211_CONF_IDLE;
        return IEEE80211_CONF_CHANGE_IDLE;
 
                } else {
                        ieee80211_send_nullfunc(local, sdata, 1);
                        /* Flush to get the tx status of nullfunc frame */
-                       ieee80211_flush_queues(local, sdata);
+                       ieee80211_flush_queues(local, sdata, false);
                }
        }
 
        /* disable per-vif ps */
        ieee80211_recalc_ps_vif(sdata);
 
-       /* flush out any pending frame (e.g. DELBA) before deauth/disassoc */
+       /*
+        * drop any frame before deauth/disassoc, this can be data or
+        * management frame. Since we are disconnecting, we should not
+        * insist sending these frames which can take time and delay
+        * the disconnection and possible the roaming.
+        */
        if (tx)
-               ieee80211_flush_queues(local, sdata);
+               ieee80211_flush_queues(local, sdata, true);
 
        /* deauthenticate/disassociate now */
        if (tx || frame_buf)
                ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid, stype,
                                               reason, tx, frame_buf);
 
-       /* flush out frame */
+       /* flush out frame - make sure the deauth was actually sent */
        if (tx)
-               ieee80211_flush_queues(local, sdata);
+               ieee80211_flush_queues(local, sdata, false);
 
        /* clear bssid only after building the needed mgmt frames */
        memset(ifmgd->bssid, 0, ETH_ALEN);
 
        ieee80211_stop_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP,
                                        IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL,
                                        false);
-       ieee80211_flush_queues(local, NULL);
+       ieee80211_flush_queues(local, NULL, false);
 
        mutex_lock(&local->iflist_mtx);
        list_for_each_entry(sdata, &local->interfaces, list) {
                ieee80211_roc_notify_destroy(roc, !roc->abort);
 
                if (started && !on_channel) {
-                       ieee80211_flush_queues(local, NULL);
+                       ieee80211_flush_queues(local, NULL, false);
 
                        local->tmp_channel = NULL;
                        ieee80211_hw_config(local, 0);
 
        /* flush out all packets */
        synchronize_net();
 
-       ieee80211_flush_queues(local, NULL);
+       ieee80211_flush_queues(local, NULL, true);
 
        local->quiescing = true;
        /* make quiescing visible to timers everywhere */
 
        ieee80211_offchannel_stop_vifs(local);
 
        /* ensure nullfunc is transmitted before leaving operating channel */
-       ieee80211_flush_queues(local, NULL);
+       ieee80211_flush_queues(local, NULL, false);
 
        ieee80211_configure_filter(local);
 
        ieee80211_offchannel_stop_vifs(local);
 
        if (local->ops->flush) {
-               ieee80211_flush_queues(local, NULL);
+               ieee80211_flush_queues(local, NULL, false);
                *next_delay = 0;
        } else
                *next_delay = HZ / 10;
 
                rcu_read_unlock();
        }
 
-       ieee80211_flush_queues(local, sdata);
+       ieee80211_flush_queues(local, sdata, false);
 
        ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code,
                                              dialog_token, status_code,
         */
        ieee80211_stop_vif_queues(local, sdata,
                                  IEEE80211_QUEUE_STOP_REASON_TDLS_TEARDOWN);
-       ieee80211_flush_queues(local, sdata);
+       ieee80211_flush_queues(local, sdata, false);
 
        ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code,
                                              dialog_token, status_code,
                 */
                tasklet_kill(&local->tx_pending_tasklet);
                /* flush a potentially queued teardown packet */
-               ieee80211_flush_queues(local, sdata);
+               ieee80211_flush_queues(local, sdata, false);
 
                ret = sta_info_destroy_addr(sdata, peer);
                break;
 
        }
 
        queues = BIT(sdata->vif.hw_queue[ieee802_1d_to_ac[tid]]);
-       __ieee80211_flush_queues(local, sdata, queues);
+       __ieee80211_flush_queues(local, sdata, queues, false);
 
        sta->reserved_tid = tid;
 
 
 
 void __ieee80211_flush_queues(struct ieee80211_local *local,
                              struct ieee80211_sub_if_data *sdata,
-                             unsigned int queues)
+                             unsigned int queues, bool drop)
 {
        if (!local->ops->flush)
                return;
                                        IEEE80211_QUEUE_STOP_REASON_FLUSH,
                                        false);
 
-       drv_flush(local, sdata, queues, false);
+       drv_flush(local, sdata, queues, drop);
 
        ieee80211_wake_queues_by_reason(&local->hw, queues,
                                        IEEE80211_QUEUE_STOP_REASON_FLUSH,
 }
 
 void ieee80211_flush_queues(struct ieee80211_local *local,
-                           struct ieee80211_sub_if_data *sdata)
+                           struct ieee80211_sub_if_data *sdata, bool drop)
 {
-       __ieee80211_flush_queues(local, sdata, 0);
+       __ieee80211_flush_queues(local, sdata, 0, drop);
 }
 
 void ieee80211_stop_vif_queues(struct ieee80211_local *local,