#define HTT_TX_WBM_COMP_STATUS_OFFSET 8
 
+#define HTT_INVALID_PEER_ID    0xffff
+
 /* HTT tx completion is overlaid in wbm_release_ring */
 #define HTT_TX_WBM_COMP_INFO0_STATUS           GENMASK(12, 9)
 #define HTT_TX_WBM_COMP_INFO0_REINJECT_REASON  GENMASK(16, 13)
 #define HTT_TX_WBM_COMP_INFO0_REINJECT_REASON  GENMASK(16, 13)
 
 #define HTT_TX_WBM_COMP_INFO1_ACK_RSSI         GENMASK(31, 24)
+#define HTT_TX_WBM_COMP_INFO2_SW_PEER_ID       GENMASK(15, 0)
+#define HTT_TX_WBM_COMP_INFO2_VALID            BIT(21)
 
 struct htt_tx_wbm_completion {
        u32 info0;
 
                                 struct dp_tx_ring *tx_ring,
                                 struct ath11k_dp_htt_wbm_tx_status *ts)
 {
+       struct ieee80211_tx_status status = { 0 };
        struct sk_buff *msdu;
        struct ieee80211_tx_info *info;
        struct ath11k_skb_cb *skb_cb;
        struct ath11k *ar;
+       struct ath11k_peer *peer;
 
        spin_lock(&tx_ring->tx_idr_lock);
        msdu = idr_remove(&tx_ring->txbuf_idr, ts->msdu_id);
 
        dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
 
+       if (!skb_cb->vif) {
+               dev_kfree_skb_any(msdu);
+               return;
+       }
+
        memset(&info->status, 0, sizeof(info->status));
 
        if (ts->acked) {
                }
        }
 
-       ieee80211_tx_status(ar->hw, msdu);
+       spin_lock_bh(&ab->base_lock);
+       peer = ath11k_peer_find_by_id(ab, ts->peer_id);
+       if (!peer || !peer->sta) {
+               ath11k_dbg(ab, ATH11K_DBG_DATA,
+                          "dp_tx: failed to find the peer with peer_id %d\n",
+                           ts->peer_id);
+               spin_unlock_bh(&ab->base_lock);
+               dev_kfree_skb_any(msdu);
+               return;
+       }
+       spin_unlock_bh(&ab->base_lock);
+
+       status.sta = peer->sta;
+       status.info = info;
+       status.skb = msdu;
+
+       ieee80211_tx_status_ext(ar->hw, &status);
 }
 
 static void
                ts.msdu_id = msdu_id;
                ts.ack_rssi = FIELD_GET(HTT_TX_WBM_COMP_INFO1_ACK_RSSI,
                                        status_desc->info1);
+
+               if (FIELD_GET(HTT_TX_WBM_COMP_INFO2_VALID, status_desc->info2))
+                       ts.peer_id = FIELD_GET(HTT_TX_WBM_COMP_INFO2_SW_PEER_ID,
+                                              status_desc->info2);
+               else
+                       ts.peer_id = HTT_INVALID_PEER_ID;
+
                ath11k_dp_tx_htt_tx_complete_buf(ab, tx_ring, &ts);
+
                break;
        case HAL_WBM_REL_HTT_TX_COMP_STATUS_REINJ:
        case HAL_WBM_REL_HTT_TX_COMP_STATUS_INSPECT: