#define MT_TXS4_TIMESTAMP              GENMASK(31, 0)
 
+/* MPDU based TXS */
 #define MT_TXS5_F0_FINAL_MPDU          BIT(31)
 #define MT_TXS5_F0_QOS                 BIT(30)
 #define MT_TXS5_F0_TX_COUNT            GENMASK(29, 25)
 #define MT_TXS7_F1_MPDU_RETRY_COUNT    GENMASK(31, 24)
 #define MT_TXS7_F1_MPDU_RETRY_BYTES    GENMASK(23, 0)
 
+/* PPDU based TXS */
+#define MT_TXS5_MPDU_TX_CNT            GENMASK(30, 20)
+#define MT_TXS5_MPDU_TX_BYTE_SCALE     BIT(15)
+#define MT_TXS5_MPDU_TX_BYTE           GENMASK(14, 0)
+
+#define MT_TXS6_MPDU_FAIL_CNT          GENMASK(30, 20)
+#define MT_TXS6_MPDU_FAIL_BYTE_SCALE   BIT(15)
+#define MT_TXS6_MPDU_FAIL_BYTE         GENMASK(14, 0)
+
+#define MT_TXS7_MPDU_RETRY_CNT         GENMASK(30, 20)
+#define MT_TXS7_MPDU_RETRY_BYTE_SCALE  BIT(15)
+#define MT_TXS7_MPDU_RETRY_BYTE                GENMASK(14, 0)
+
 #endif /* __MT76_CONNAC3_MAC_H */
 
        set = FIELD_PREP(MT_WTBLOFF_RSCR_RCPI_MODE, 0) |
              FIELD_PREP(MT_WTBLOFF_RSCR_RCPI_PARAM, 0x3);
        mt76_rmw(dev, MT_WTBLOFF_RSCR(band), mask, set);
+
+       /* MT_TXD5_TX_STATUS_HOST (MPDU format) has higher priority than
+        * MT_AGG_ACR_PPDU_TXS2H (PPDU format) even though ACR bit is set.
+        */
+       mt76_set(dev, MT_AGG_ACR4(band), MT_AGG_ACR_PPDU_TXS2H);
 }
 
 static void mt7996_mac_init_basic_rates(struct mt7996_dev *dev)
 
        bool cck = false;
        u32 txrate, txs, mode, stbc;
 
+       txs = le32_to_cpu(txs_data[0]);
+
        mt76_tx_status_lock(mdev, &list);
        skb = mt76_tx_status_skb_get(mdev, wcid, pid, &list);
-       if (!skb)
-               goto out_no_skb;
 
-       txs = le32_to_cpu(txs_data[0]);
+       if (skb) {
+               info = IEEE80211_SKB_CB(skb);
+               if (!(txs & MT_TXS0_ACK_ERROR_MASK))
+                       info->flags |= IEEE80211_TX_STAT_ACK;
 
-       info = IEEE80211_SKB_CB(skb);
-       if (!(txs & MT_TXS0_ACK_ERROR_MASK))
-               info->flags |= IEEE80211_TX_STAT_ACK;
+               info->status.ampdu_len = 1;
+               info->status.ampdu_ack_len =
+                       !!(info->flags & IEEE80211_TX_STAT_ACK);
 
-       info->status.ampdu_len = 1;
-       info->status.ampdu_ack_len = !!(info->flags &
-                                       IEEE80211_TX_STAT_ACK);
+               info->status.rates[0].idx = -1;
+       }
 
-       info->status.rates[0].idx = -1;
+       if (mtk_wed_device_active(&dev->mt76.mmio.wed) && wcid->sta) {
+               struct ieee80211_sta *sta;
+               u8 tid;
+
+               sta = container_of((void *)wcid, struct ieee80211_sta, drv_priv);
+               tid = FIELD_GET(MT_TXS0_TID, txs);
+               ieee80211_refresh_tx_agg_session_timer(sta, tid);
+       }
 
        txrate = FIELD_GET(MT_TXS0_TX_RATE, txs);
 
        wcid->rate = rate;
 
 out:
-       mt76_tx_status_skb_done(mdev, skb, &list);
-
-out_no_skb:
+       if (skb)
+               mt76_tx_status_skb_done(mdev, skb, &list);
        mt76_tx_status_unlock(mdev, &list);
 
        return !!skb;
        u16 wcidx;
        u8 pid;
 
-       if (le32_get_bits(txs_data[0], MT_TXS0_TXS_FORMAT) > 1)
-               return;
-
        wcidx = le32_get_bits(txs_data[2], MT_TXS2_WCID);
        pid = le32_get_bits(txs_data[3], MT_TXS3_PID);
 
-       if (pid < MT_PACKET_ID_FIRST)
+       if (pid < MT_PACKET_ID_WED)
                return;
 
        if (wcidx >= mt7996_wtbl_size(dev))
 
                                                 FIELD_PREP(MT_WTBL_LMAC_ID, _id) | \
                                                 FIELD_PREP(MT_WTBL_LMAC_DW, _dw))
 
+/* AGG: band 0(0x820e2000), band 1(0x820f2000), band 2(0x830e2000) */
+#define MT_WF_AGG_BASE(_band)                  __BASE(WF_AGG_BASE, (_band))
+#define MT_WF_AGG(_band, ofs)                  (MT_WF_AGG_BASE(_band) + (ofs))
+
+#define MT_AGG_ACR4(_band)                     MT_WF_AGG(_band, 0x3c)
+#define MT_AGG_ACR_PPDU_TXS2H                  BIT(1)
+
 /* ARB: band 0(0x820e3000), band 1(0x820f3000), band 2(0x830e3000) */
 #define MT_WF_ARB_BASE(_band)                  __BASE(WF_ARB_BASE, (_band))
 #define MT_WF_ARB(_band, ofs)                  (MT_WF_ARB_BASE(_band) + (ofs))