}
 
 void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
-                                    u16 initiator, u16 reason)
+                                    u16 initiator, u16 reason, bool tx)
 {
        struct ieee80211_local *local = sta->local;
        struct tid_ampdu_rx *tid_rx;
                                "aggregation for tid %d\n", tid);
 
        /* check if this is a self generated aggregation halt */
-       if (initiator == WLAN_BACK_RECIPIENT)
+       if (initiator == WLAN_BACK_RECIPIENT && tx)
                ieee80211_send_delba(sta->sdata, sta->sta.addr,
                                     tid, 0, reason);
 
 }
 
 void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
-                                   u16 initiator, u16 reason)
+                                   u16 initiator, u16 reason, bool tx)
 {
        mutex_lock(&sta->ampdu_mlme.mtx);
-       ___ieee80211_stop_rx_ba_session(sta, tid, initiator, reason);
+       ___ieee80211_stop_rx_ba_session(sta, tid, initiator, reason, tx);
        mutex_unlock(&sta->ampdu_mlme.mtx);
 }
 
 
 }
 
 int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
-                                   enum ieee80211_back_parties initiator)
+                                   enum ieee80211_back_parties initiator,
+                                   bool tx)
 {
        struct ieee80211_local *local = sta->local;
        struct tid_ampdu_tx *tid_tx = sta->ampdu_mlme.tid_tx[tid];
        clear_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state);
 
        tid_tx->stop_initiator = initiator;
+       tid_tx->tx_stop = tx;
 
        ret = drv_ampdu_action(local, sta->sdata,
                               IEEE80211_AMPDU_TX_STOP,
 EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe);
 
 int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
-                                  enum ieee80211_back_parties initiator)
+                                  enum ieee80211_back_parties initiator,
+                                  bool tx)
 {
        int ret;
 
        mutex_lock(&sta->ampdu_mlme.mtx);
 
-       ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator);
+       ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator, tx);
 
        mutex_unlock(&sta->ampdu_mlme.mtx);
 
                goto unlock_sta;
        }
 
-       if (tid_tx->stop_initiator == WLAN_BACK_INITIATOR)
+       if (tid_tx->stop_initiator == WLAN_BACK_INITIATOR && tid_tx->tx_stop)
                ieee80211_send_delba(sta->sdata, ra, tid,
                        WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
 
 
                sta->ampdu_mlme.addba_req_num[tid] = 0;
        } else {
-               ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR);
+               ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR,
+                                               true);
        }
 
  out:
 
                else
                        ret = ieee80211_stop_tx_ba_session(&sta->sta, tid);
        } else {
-               __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT, 3);
+               __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT,
+                                              3, true);
                ret = 0;
        }
 
 
                ht_cap->mcs.rx_mask[32/8] |= 1;
 }
 
-void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta)
+void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, bool tx)
 {
        int i;
 
        cancel_work_sync(&sta->ampdu_mlme.work);
 
        for (i = 0; i <  STA_TID_NUM; i++) {
-               __ieee80211_stop_tx_ba_session(sta, i, WLAN_BACK_INITIATOR);
+               __ieee80211_stop_tx_ba_session(sta, i, WLAN_BACK_INITIATOR, tx);
                __ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT,
-                                              WLAN_REASON_QSTA_LEAVE_QBSS);
+                                              WLAN_REASON_QSTA_LEAVE_QBSS, tx);
        }
 }
 
                if (test_and_clear_bit(tid, sta->ampdu_mlme.tid_rx_timer_expired))
                        ___ieee80211_stop_rx_ba_session(
                                sta, tid, WLAN_BACK_RECIPIENT,
-                               WLAN_REASON_QSTA_TIMEOUT);
+                               WLAN_REASON_QSTA_TIMEOUT, true);
 
                tid_tx = sta->ampdu_mlme.tid_tx[tid];
                if (!tid_tx)
                else if (test_and_clear_bit(HT_AGG_STATE_WANT_STOP,
                                            &tid_tx->state))
                        ___ieee80211_stop_tx_ba_session(sta, tid,
-                                                       WLAN_BACK_INITIATOR);
+                                                       WLAN_BACK_INITIATOR,
+                                                       true);
        }
        mutex_unlock(&sta->ampdu_mlme.mtx);
 }
 #endif /* CONFIG_MAC80211_HT_DEBUG */
 
        if (initiator == WLAN_BACK_INITIATOR)
-               __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_INITIATOR, 0);
+               __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_INITIATOR, 0,
+                                              true);
        else
-               __ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_RECIPIENT);
+               __ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_RECIPIENT,
+                                              true);
 }
 
 int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata,
 
 void ieee80211_request_smps_work(struct work_struct *work);
 
 void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
-                                    u16 initiator, u16 reason);
+                                    u16 initiator, u16 reason, bool stop);
 void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
-                                   u16 initiator, u16 reason);
-void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta);
+                                   u16 initiator, u16 reason, bool stop);
+void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, bool tx);
 void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
                             struct sta_info *sta,
                             struct ieee80211_mgmt *mgmt, size_t len);
                                     size_t len);
 
 int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
-                                  enum ieee80211_back_parties initiator);
+                                  enum ieee80211_back_parties initiator,
+                                  bool tx);
 int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
-                                   enum ieee80211_back_parties initiator);
+                                   enum ieee80211_back_parties initiator,
+                                   bool tx);
 void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid);
 void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid);
 void ieee80211_ba_session_work(struct work_struct *work);
 
 
                                __ieee80211_stop_rx_ba_session(
                                        sta, tid, WLAN_BACK_RECIPIENT,
-                                       WLAN_REASON_QSTA_REQUIRE_SETUP);
+                                       WLAN_REASON_QSTA_REQUIRE_SETUP,
+                                       true);
                        }
                        mutex_unlock(&local->sta_mtx);
                } else switch (sdata->vif.type) {
 
 }
 
 static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
-                                  bool remove_sta)
+                                  bool remove_sta, bool tx)
 {
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
        struct ieee80211_local *local = sdata->local;
        sta = sta_info_get(sdata, bssid);
        if (sta) {
                set_sta_flags(sta, WLAN_STA_BLOCK_BA);
-               ieee80211_sta_tear_down_BA_sessions(sta);
+               ieee80211_sta_tear_down_BA_sessions(sta, tx);
        }
        mutex_unlock(&local->sta_mtx);
 
 
        printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid);
 
-       ieee80211_set_disassoc(sdata, true);
+       ieee80211_set_disassoc(sdata, true, true);
        mutex_unlock(&ifmgd->mtx);
 
        mutex_lock(&local->mtx);
        printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n",
                        sdata->name, bssid, reason_code);
 
-       ieee80211_set_disassoc(sdata, true);
+       ieee80211_set_disassoc(sdata, true, false);
        mutex_lock(&sdata->local->mtx);
        ieee80211_recalc_idle(sdata->local);
        mutex_unlock(&sdata->local->mtx);
        printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n",
                        sdata->name, mgmt->sa, reason_code);
 
-       ieee80211_set_disassoc(sdata, true);
+       ieee80211_set_disassoc(sdata, true, false);
        mutex_lock(&sdata->local->mtx);
        ieee80211_recalc_idle(sdata->local);
        mutex_unlock(&sdata->local->mtx);
                        printk(KERN_DEBUG "No probe response from AP %pM"
                                " after %dms, disconnecting.\n",
                                bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
-                       ieee80211_set_disassoc(sdata, true);
+                       ieee80211_set_disassoc(sdata, true, true);
                        mutex_unlock(&ifmgd->mtx);
                        mutex_lock(&local->mtx);
                        ieee80211_recalc_idle(local);
                }
 
                /* Trying to reassociate - clear previous association state */
-               ieee80211_set_disassoc(sdata, true);
+               ieee80211_set_disassoc(sdata, true, false);
        }
        mutex_unlock(&ifmgd->mtx);
 
 
        memcpy(bssid, req->bss->bssid, ETH_ALEN);
        if (ifmgd->associated == req->bss) {
-               ieee80211_set_disassoc(sdata, false);
+               ieee80211_set_disassoc(sdata, false, true);
                mutex_unlock(&ifmgd->mtx);
                assoc_bss = true;
        } else {
               sdata->name, req->bss->bssid, req->reason_code);
 
        memcpy(bssid, req->bss->bssid, ETH_ALEN);
-       ieee80211_set_disassoc(sdata, false);
+       ieee80211_set_disassoc(sdata, false, true);
 
        mutex_unlock(&ifmgd->mtx);
 
 
        list_for_each_entry(sta, &local->sta_list, list) {
                if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
                        set_sta_flags(sta, WLAN_STA_BLOCK_BA);
-                       ieee80211_sta_tear_down_BA_sessions(sta);
+                       ieee80211_sta_tear_down_BA_sessions(sta, true);
                }
 
                if (sta->uploaded) {
 
         * will be sufficient.
         */
        set_sta_flags(sta, WLAN_STA_BLOCK_BA);
-       ieee80211_sta_tear_down_BA_sessions(sta);
+       ieee80211_sta_tear_down_BA_sessions(sta, true);
 
        spin_lock_irqsave(&local->sta_lock, flags);
        ret = sta_info_hash_del(local, sta);
 
  * @dialog_token: dialog token for aggregation session
  * @state: session state (see above)
  * @stop_initiator: initiator of a session stop
+ * @tx_stop: TX DelBA frame when stopping
  *
  * This structure is protected by RCU and the per-station
  * spinlock. Assignments to the array holding it must hold
        unsigned long state;
        u8 dialog_token;
        u8 stop_initiator;
+       bool tx_stop;
 };
 
 /**
 
                mutex_lock(&local->sta_mtx);
 
                list_for_each_entry(sta, &local->sta_list, list) {
-                       ieee80211_sta_tear_down_BA_sessions(sta);
+                       ieee80211_sta_tear_down_BA_sessions(sta, true);
                        clear_sta_flags(sta, WLAN_STA_BLOCK_BA);
                }