void ath10k_htt_tx_txq_recalc(struct ieee80211_hw *hw,
                              struct ieee80211_txq *txq);
 void ath10k_htt_tx_txq_sync(struct ath10k *ar);
-void ath10k_htt_tx_dec_pending(struct ath10k_htt *htt,
-                              bool is_mgmt);
-int ath10k_htt_tx_inc_pending(struct ath10k_htt *htt,
-                             bool is_mgmt,
-                             bool is_presp);
+void ath10k_htt_tx_dec_pending(struct ath10k_htt *htt);
+int ath10k_htt_tx_inc_pending(struct ath10k_htt *htt);
+void ath10k_htt_tx_mgmt_dec_pending(struct ath10k_htt *htt);
+int ath10k_htt_tx_mgmt_inc_pending(struct ath10k_htt *htt, bool is_mgmt,
+                                  bool is_presp);
 
 int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt, struct sk_buff *skb);
 void ath10k_htt_tx_free_msdu_id(struct ath10k_htt *htt, u16 msdu_id);
 
                        break;
                }
 
-               ath10k_txrx_tx_unref(htt, &tx_done);
+               status = ath10k_txrx_tx_unref(htt, &tx_done);
+               if (!status) {
+                       spin_lock_bh(&htt->tx_lock);
+                       ath10k_htt_tx_mgmt_dec_pending(htt);
+                       spin_unlock_bh(&htt->tx_lock);
+               }
                ath10k_mac_tx_push_pending(ar);
                break;
        }
 
        spin_unlock_bh(&ar->htt.tx_lock);
 }
 
-void ath10k_htt_tx_dec_pending(struct ath10k_htt *htt,
-                              bool is_mgmt)
+void ath10k_htt_tx_dec_pending(struct ath10k_htt *htt)
 {
        lockdep_assert_held(&htt->tx_lock);
 
-       if (is_mgmt)
-               htt->num_pending_mgmt_tx--;
-
        htt->num_pending_tx--;
        if (htt->num_pending_tx == htt->max_num_pending_tx - 1)
                ath10k_mac_tx_unlock(htt->ar, ATH10K_TX_PAUSE_Q_FULL);
 }
 
-int ath10k_htt_tx_inc_pending(struct ath10k_htt *htt,
-                             bool is_mgmt,
-                             bool is_presp)
+int ath10k_htt_tx_inc_pending(struct ath10k_htt *htt)
 {
-       struct ath10k *ar = htt->ar;
-
        lockdep_assert_held(&htt->tx_lock);
 
        if (htt->num_pending_tx >= htt->max_num_pending_tx)
                return -EBUSY;
 
-       if (is_mgmt &&
-           is_presp &&
-           ar->hw_params.max_probe_resp_desc_thres &&
-           ar->hw_params.max_probe_resp_desc_thres < htt->num_pending_mgmt_tx)
-               return -EBUSY;
-
-       if (is_mgmt)
-               htt->num_pending_mgmt_tx++;
-
        htt->num_pending_tx++;
        if (htt->num_pending_tx == htt->max_num_pending_tx)
                ath10k_mac_tx_lock(htt->ar, ATH10K_TX_PAUSE_Q_FULL);
        return 0;
 }
 
+int ath10k_htt_tx_mgmt_inc_pending(struct ath10k_htt *htt, bool is_mgmt,
+                                  bool is_presp)
+{
+       struct ath10k *ar = htt->ar;
+
+       lockdep_assert_held(&htt->tx_lock);
+
+       if (!is_mgmt || !ar->hw_params.max_probe_resp_desc_thres)
+               return 0;
+
+       if (is_presp &&
+           ar->hw_params.max_probe_resp_desc_thres < htt->num_pending_mgmt_tx)
+               return -EBUSY;
+
+       htt->num_pending_mgmt_tx++;
+
+       return 0;
+}
+
+void ath10k_htt_tx_mgmt_dec_pending(struct ath10k_htt *htt)
+{
+       lockdep_assert_held(&htt->tx_lock);
+
+       if (!htt->ar->hw_params.max_probe_resp_desc_thres)
+               return;
+
+       htt->num_pending_mgmt_tx--;
+}
+
 int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt, struct sk_buff *skb)
 {
        struct ath10k *ar = htt->ar;
 
 int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
                           struct ieee80211_txq *txq)
 {
-       const bool is_mgmt = false;
-       const bool is_presp = false;
        struct ath10k *ar = hw->priv;
        struct ath10k_htt *htt = &ar->htt;
        struct ath10k_txq *artxq = (void *)txq->drv_priv;
        int ret;
 
        spin_lock_bh(&ar->htt.tx_lock);
-       ret = ath10k_htt_tx_inc_pending(htt, is_mgmt, is_presp);
+       ret = ath10k_htt_tx_inc_pending(htt);
        spin_unlock_bh(&ar->htt.tx_lock);
 
        if (ret)
        skb = ieee80211_tx_dequeue(hw, txq);
        if (!skb) {
                spin_lock_bh(&ar->htt.tx_lock);
-               ath10k_htt_tx_dec_pending(htt, is_mgmt);
+               ath10k_htt_tx_dec_pending(htt);
                spin_unlock_bh(&ar->htt.tx_lock);
 
                return -ENOENT;
                ath10k_warn(ar, "failed to push frame: %d\n", ret);
 
                spin_lock_bh(&ar->htt.tx_lock);
-               ath10k_htt_tx_dec_pending(htt, is_mgmt);
+               ath10k_htt_tx_dec_pending(htt);
                spin_unlock_bh(&ar->htt.tx_lock);
 
                return ret;
        txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
        is_htt = (txpath == ATH10K_MAC_TX_HTT ||
                  txpath == ATH10K_MAC_TX_HTT_MGMT);
+       is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);
 
        if (is_htt) {
                spin_lock_bh(&ar->htt.tx_lock);
-
-               is_mgmt = ieee80211_is_mgmt(hdr->frame_control);
                is_presp = ieee80211_is_probe_resp(hdr->frame_control);
 
-               ret = ath10k_htt_tx_inc_pending(htt, is_mgmt, is_presp);
+               ret = ath10k_htt_tx_inc_pending(htt);
                if (ret) {
                        ath10k_warn(ar, "failed to increase tx pending count: %d, dropping\n",
                                    ret);
                        return;
                }
 
+               ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp);
+               if (ret) {
+                       ath10k_warn(ar, "failed to increase tx mgmt pending count: %d, dropping\n",
+                                   ret);
+                       ath10k_htt_tx_dec_pending(htt);
+                       spin_unlock_bh(&ar->htt.tx_lock);
+                       ieee80211_free_txskb(ar->hw, skb);
+                       return;
+               }
                spin_unlock_bh(&ar->htt.tx_lock);
        }
 
                ath10k_warn(ar, "failed to transmit frame: %d\n", ret);
                if (is_htt) {
                        spin_lock_bh(&ar->htt.tx_lock);
-                       ath10k_htt_tx_dec_pending(htt, is_mgmt);
+                       ath10k_htt_tx_dec_pending(htt);
+                       if (is_mgmt)
+                               ath10k_htt_tx_mgmt_dec_pending(htt);
                        spin_unlock_bh(&ar->htt.tx_lock);
                }
                return;
 
        spin_unlock_bh(&ar->data_lock);
 }
 
-void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
-                         const struct htt_tx_done *tx_done)
+int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
+                        const struct htt_tx_done *tx_done)
 {
        struct ath10k *ar = htt->ar;
        struct device *dev = ar->dev;
        struct ath10k_skb_cb *skb_cb;
        struct ath10k_txq *artxq;
        struct sk_buff *msdu;
-       bool limit_mgmt_desc = false;
 
        ath10k_dbg(ar, ATH10K_DBG_HTT,
                   "htt tx completion msdu_id %u discard %d no_ack %d success %d\n",
        if (tx_done->msdu_id >= htt->max_num_pending_tx) {
                ath10k_warn(ar, "warning: msdu_id %d too big, ignoring\n",
                            tx_done->msdu_id);
-               return;
+               return -EINVAL;
        }
 
        spin_lock_bh(&htt->tx_lock);
                ath10k_warn(ar, "received tx completion for invalid msdu_id: %d\n",
                            tx_done->msdu_id);
                spin_unlock_bh(&htt->tx_lock);
-               return;
+               return -ENOENT;
        }
 
        skb_cb = ATH10K_SKB_CB(msdu);
        txq = skb_cb->txq;
        artxq = (void *)txq->drv_priv;
 
-       if (unlikely(skb_cb->flags & ATH10K_SKB_F_MGMT) &&
-           ar->hw_params.max_probe_resp_desc_thres)
-               limit_mgmt_desc = true;
-
        if (txq)
                artxq->num_fw_queued--;
 
        ath10k_htt_tx_free_msdu_id(htt, tx_done->msdu_id);
-       ath10k_htt_tx_dec_pending(htt, limit_mgmt_desc);
+       ath10k_htt_tx_dec_pending(htt);
        if (htt->num_pending_tx == 0)
                wake_up(&htt->empty_tx_wq);
        spin_unlock_bh(&htt->tx_lock);
 
        if (tx_done->discard) {
                ieee80211_free_txskb(htt->ar->hw, msdu);
-               return;
+               return 0;
        }
 
        if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
 
        ieee80211_tx_status(htt->ar->hw, msdu);
        /* we do not own the msdu anymore */
+       return 0;
 }
 
 struct ath10k_peer *ath10k_peer_find(struct ath10k *ar, int vdev_id,
 
 
 #include "htt.h"
 
-void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
-                         const struct htt_tx_done *tx_done);
+int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
+                        const struct htt_tx_done *tx_done);
 
 struct ath10k_peer *ath10k_peer_find(struct ath10k *ar, int vdev_id,
                                     const u8 *addr);