#define MT_TXFREE0_MSDU_CNT            GENMASK(25, 16)
 #define MT_TXFREE0_RX_BYTE             GENMASK(15, 0)
 
-#define MT_TXFREE1_VER                 GENMASK(18, 16)
+#define MT_TXFREE1_VER                 GENMASK(19, 16)
 
 #define MT_TXFREE_INFO_PAIR            BIT(31)
 #define MT_TXFREE_INFO_HEADER          BIT(30)
 
        struct mt76_phy *phy3 = mdev->phys[MT_BAND2];
        struct mt76_txwi_cache *txwi;
        struct ieee80211_sta *sta = NULL;
+       struct mt76_wcid *wcid;
        LIST_HEAD(free_list);
        struct sk_buff *skb, *tmp;
        void *end = data + len;
                mt76_queue_tx_cleanup(dev, phy3->q_tx[MT_TXQ_BE], false);
        }
 
-       if (WARN_ON_ONCE(le32_get_bits(tx_free[1], MT_TXFREE1_VER) < 4))
+       if (WARN_ON_ONCE(le32_get_bits(tx_free[1], MT_TXFREE1_VER) < 5))
                return;
 
        total = le32_get_bits(tx_free[0], MT_TXFREE0_MSDU_CNT);
                info = le32_to_cpu(*cur_info);
                if (info & MT_TXFREE_INFO_PAIR) {
                        struct mt7996_sta *msta;
-                       struct mt76_wcid *wcid;
                        u16 idx;
 
                        idx = FIELD_GET(MT_TXFREE_INFO_WLAN_ID, info);
                                              &mdev->sta_poll_list);
                        spin_unlock_bh(&mdev->sta_poll_lock);
                        continue;
-               }
+               } else if (info & MT_TXFREE_INFO_HEADER) {
+                       u32 tx_retries = 0, tx_failed = 0;
+
+                       if (!wcid)
+                               continue;
+
+                       tx_retries =
+                               FIELD_GET(MT_TXFREE_INFO_COUNT, info) - 1;
+                       tx_failed = tx_retries +
+                               !!FIELD_GET(MT_TXFREE_INFO_STAT, info);
 
-               if (info & MT_TXFREE_INFO_HEADER)
+                       wcid->stats.tx_retries += tx_retries;
+                       wcid->stats.tx_failed += tx_failed;
                        continue;
+               }
 
                for (i = 0; i < 2; i++) {
                        msdu = (info >> (15 * i)) & MT_TXFREE_INFO_MSDU_ID;
 
        sinfo->txrate.flags = txrate->flags;
        sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
 
+       sinfo->tx_failed = msta->wcid.stats.tx_failed;
+       sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
+
+       sinfo->tx_retries = msta->wcid.stats.tx_retries;
+       sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES);
+
        sinfo->ack_signal = (s8)msta->ack_signal;
        sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL);