};
        struct ieee80211_sta *sta;
        struct mt7996_sta *msta;
-       struct rate_info *rate;
        u32 tx_time[IEEE80211_NUM_ACS], rx_time[IEEE80211_NUM_ACS];
        LIST_HEAD(sta_poll_list);
        int i;
                u32 addr, val;
                u16 idx;
                s8 rssi[4];
-               u8 bw;
 
                spin_lock_bh(&dev->mt76.sta_poll_lock);
                if (list_empty(&sta_poll_list)) {
                        ieee80211_sta_register_airtime(sta, tid, tx_cur, rx_cur);
                }
 
-               /* We don't support reading GI info from txs packets.
-                * For accurate tx status reporting and AQL improvement,
-                * we need to make sure that flags match so polling GI
-                * from per-sta counters directly.
-                */
-               rate = &msta->wcid.rate;
-
-               switch (rate->bw) {
-               case RATE_INFO_BW_320:
-                       bw = IEEE80211_STA_RX_BW_320;
-                       break;
-               case RATE_INFO_BW_160:
-                       bw = IEEE80211_STA_RX_BW_160;
-                       break;
-               case RATE_INFO_BW_80:
-                       bw = IEEE80211_STA_RX_BW_80;
-                       break;
-               case RATE_INFO_BW_40:
-                       bw = IEEE80211_STA_RX_BW_40;
-                       break;
-               default:
-                       bw = IEEE80211_STA_RX_BW_20;
-                       break;
-               }
-
-               addr = mt7996_mac_wtbl_lmac_addr(dev, idx, 6);
-               val = mt76_rr(dev, addr);
-               if (rate->flags & RATE_INFO_FLAGS_EHT_MCS) {
-                       addr = mt7996_mac_wtbl_lmac_addr(dev, idx, 5);
-                       val = mt76_rr(dev, addr);
-                       rate->eht_gi = FIELD_GET(GENMASK(25, 24), val);
-               } else if (rate->flags & RATE_INFO_FLAGS_HE_MCS) {
-                       u8 offs = 24 + 2 * bw;
-
-                       rate->he_gi = (val & (0x3 << offs)) >> offs;
-               } else if (rate->flags &
-                          (RATE_INFO_FLAGS_VHT_MCS | RATE_INFO_FLAGS_MCS)) {
-                       if (val & BIT(12 + bw))
-                               rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
-                       else
-                               rate->flags &= ~RATE_INFO_FLAGS_SHORT_GI;
-               }
-
                /* get signal strength of resp frames (CTS/BA/ACK) */
                addr = mt7996_mac_wtbl_lmac_addr(dev, idx, 34);
                val = mt76_rr(dev, addr);
                        goto out;
 
                rate.flags = RATE_INFO_FLAGS_VHT_MCS;
+               if (wcid->rate.flags & RATE_INFO_FLAGS_SHORT_GI)
+                       rate.flags |= RATE_INFO_FLAGS_SHORT_GI;
                break;
        case MT_PHY_TYPE_HE_SU:
        case MT_PHY_TYPE_HE_EXT_SU:
 
                mt7996_mac_update_stats(phy);
 
+               mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_RATE);
                if (mtk_wed_device_active(&phy->dev->mt76.mmio.wed)) {
                        mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_ADM_STAT);
                        mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_MSDU_COUNT);
 
        }
 }
 
+static int
+mt7996_mcu_update_tx_gi(struct rate_info *rate, struct all_sta_trx_rate *mcu_rate)
+{
+       switch (mcu_rate->tx_mode) {
+       case MT_PHY_TYPE_CCK:
+       case MT_PHY_TYPE_OFDM:
+               break;
+       case MT_PHY_TYPE_HT:
+       case MT_PHY_TYPE_HT_GF:
+       case MT_PHY_TYPE_VHT:
+               if (mcu_rate->tx_gi)
+                       rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
+               else
+                       rate->flags &= ~RATE_INFO_FLAGS_SHORT_GI;
+               break;
+       case MT_PHY_TYPE_HE_SU:
+       case MT_PHY_TYPE_HE_EXT_SU:
+       case MT_PHY_TYPE_HE_TB:
+       case MT_PHY_TYPE_HE_MU:
+               if (mcu_rate->tx_gi > NL80211_RATE_INFO_HE_GI_3_2)
+                       return -EINVAL;
+               rate->he_gi = mcu_rate->tx_gi;
+               break;
+       case MT_PHY_TYPE_EHT_SU:
+       case MT_PHY_TYPE_EHT_TRIG:
+       case MT_PHY_TYPE_EHT_MU:
+               if (mcu_rate->tx_gi > NL80211_RATE_INFO_EHT_GI_3_2)
+                       return -EINVAL;
+               rate->eht_gi = mcu_rate->tx_gi;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 static void
 mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
 {
                struct mt76_wcid *wcid;
 
                switch (le16_to_cpu(res->tag)) {
+               case UNI_ALL_STA_TXRX_RATE:
+                       wlan_idx = le16_to_cpu(res->rate[i].wlan_idx);
+                       wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);
+
+                       if (!wcid)
+                               break;
+
+                       if (mt7996_mcu_update_tx_gi(&wcid->rate, &res->rate[i]))
+                               dev_err(dev->mt76.dev, "Failed to update TX GI\n");
+                       break;
                case UNI_ALL_STA_TXRX_ADM_STAT:
                        wlan_idx = le16_to_cpu(res->adm_stat[i].wlan_idx);
                        wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);