ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab,
                                 struct ath12k_tx_desc_params *desc_params,
                                 struct dp_tx_ring *tx_ring,
-                                struct ath12k_dp_htt_wbm_tx_status *ts)
+                                struct ath12k_dp_htt_wbm_tx_status *ts,
+                                u16 peer_id)
 {
        struct ieee80211_tx_info *info;
        struct ath12k_link_vif *arvif;
        struct ath12k *ar;
        struct sk_buff *msdu = desc_params->skb;
        s32 noise_floor;
+       struct ieee80211_tx_status status = {};
+       struct ath12k_peer *peer;
 
        skb_cb = ATH12K_SKB_CB(msdu);
        info = IEEE80211_SKB_CB(msdu);
                        info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
                }
        }
+       rcu_read_lock();
+       spin_lock_bh(&ab->base_lock);
+       peer = ath12k_peer_find_by_id(ab, peer_id);
+       if (!peer || !peer->sta) {
+               ath12k_dbg(ab, ATH12K_DBG_DATA,
+                          "dp_tx: failed to find the peer with peer_id %d\n", peer_id);
+               spin_unlock_bh(&ab->base_lock);
+               ieee80211_free_txskb(ath12k_ar_to_hw(ar), msdu);
+               goto exit;
+       } else {
+               status.sta = peer->sta;
+       }
+       spin_unlock_bh(&ab->base_lock);
 
-       ieee80211_tx_status_skb(ath12k_ar_to_hw(ar), msdu);
+       status.info = info;
+       status.skb = msdu;
+       ieee80211_tx_status_ext(ath12k_ar_to_hw(ar), &status);
+exit:
+       rcu_read_unlock();
 }
 
 static void
        struct htt_tx_wbm_completion *status_desc;
        struct ath12k_dp_htt_wbm_tx_status ts = {0};
        enum hal_wbm_htt_tx_comp_status wbm_status;
+       u16 peer_id;
 
        status_desc = desc;
 
                ts.acked = (wbm_status == HAL_WBM_REL_HTT_TX_COMP_STATUS_OK);
                ts.ack_rssi = le32_get_bits(status_desc->info2,
                                            HTT_TX_WBM_COMP_INFO2_ACK_RSSI);
-               ath12k_dp_tx_htt_tx_complete_buf(ab, desc_params, tx_ring, &ts);
+
+               peer_id = le32_get_bits(((struct hal_wbm_completion_ring_tx *)desc)->
+                               info3, HAL_WBM_COMPL_TX_INFO3_PEER_ID);
+
+               ath12k_dp_tx_htt_tx_complete_buf(ab, desc_params, tx_ring, &ts, peer_id);
                break;
        case HAL_WBM_REL_HTT_TX_COMP_STATUS_DROP:
        case HAL_WBM_REL_HTT_TX_COMP_STATUS_TTL:
        struct ath12k_vif *ahvif;
        struct sk_buff *msdu = desc_params->skb;
        s32 noise_floor;
+       struct ieee80211_tx_status status = {};
+       struct ieee80211_rate_status status_rate = {};
+       struct ath12k_peer *peer;
+       struct ath12k_link_sta *arsta;
+       struct ath12k_sta *ahsta;
+       struct rate_info rate;
 
        if (WARN_ON_ONCE(ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)) {
                /* Must not happen */
 
        ath12k_dp_tx_update_txcompl(ar, ts);
 
-       ieee80211_tx_status_skb(ath12k_ar_to_hw(ar), msdu);
+       spin_lock_bh(&ab->base_lock);
+       peer = ath12k_peer_find_by_id(ab, ts->peer_id);
+       if (!peer || !peer->sta) {
+               ath12k_err(ab,
+                          "dp_tx: failed to find the peer with peer_id %d\n",
+                          ts->peer_id);
+               spin_unlock_bh(&ab->base_lock);
+               ieee80211_free_txskb(ath12k_ar_to_hw(ar), msdu);
+               goto exit;
+       }
+       ahsta = ath12k_sta_to_ahsta(peer->sta);
+       arsta = &ahsta->deflink;
+
+       spin_unlock_bh(&ab->base_lock);
+
+       status.sta = peer->sta;
+       status.info = info;
+       status.skb = msdu;
+       rate = arsta->last_txrate;
+
+       status_rate.rate_idx = rate;
+       status_rate.try_count = 1;
+
+       status.rates = &status_rate;
+       status.n_rates = 1;
+       ieee80211_tx_status_ext(ath12k_ar_to_hw(ar), &status);
 
 exit:
        rcu_read_unlock();