blob: 5cee6a07b86b3eead9dc7dc862160d1b9a08d06a [file] [log] [blame]
From e66867f6acc33faa75e9e301ad64e0903cffd7be Mon Sep 17 00:00:00 2001
From: Benjamin Lin <benjamin-jw.lin@mediatek.com>
Date: Fri, 14 Jul 2023 09:43:53 +0800
Subject: [PATCH 20/98] wifi: mt76: mt7996: fix incorrect report of TX GI
---
mt76_connac_mcu.h | 2 +-
mt7996/mac.c | 48 +++--------------------------------------------
mt7996/main.c | 1 +
mt7996/mcu.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++
mt7996/mcu.h | 22 ++++++++++++++++++++++
5 files changed, 74 insertions(+), 46 deletions(-)
diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
index e9dd9aa..8562ca4 100644
--- a/mt76_connac_mcu.h
+++ b/mt76_connac_mcu.h
@@ -1327,7 +1327,7 @@ enum {
};
enum UNI_ALL_STA_INFO_TAG {
- UNI_ALL_STA_TX_RATE,
+ UNI_ALL_STA_TXRX_RATE,
UNI_ALL_STA_TX_STAT,
UNI_ALL_STA_TXRX_ADM_STAT,
UNI_ALL_STA_TXRX_AIR_TIME,
diff --git a/mt7996/mac.c b/mt7996/mac.c
index 7512147..06c9a14 100644
--- a/mt7996/mac.c
+++ b/mt7996/mac.c
@@ -102,7 +102,6 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev)
};
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;
@@ -118,7 +117,6 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev)
u32 addr, val;
u16 idx;
s8 rssi[4];
- u8 bw;
spin_lock_bh(&dev->mt76.sta_poll_lock);
if (list_empty(&sta_poll_list)) {
@@ -174,49 +172,6 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev)
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);
@@ -1303,6 +1258,8 @@ mt7996_mac_add_txs_skb(struct mt7996_dev *dev, struct mt76_wcid *wcid,
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:
@@ -2282,6 +2239,7 @@ void mt7996_mac_work(struct work_struct *work)
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);
diff --git a/mt7996/main.c b/mt7996/main.c
index e9e1fd9..0b3f8c8 100644
--- a/mt7996/main.c
+++ b/mt7996/main.c
@@ -991,6 +991,7 @@ static void mt7996_sta_statistics(struct ieee80211_hw *hw,
sinfo->txrate.he_gi = txrate->he_gi;
sinfo->txrate.he_dcm = txrate->he_dcm;
sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc;
+ sinfo->txrate.eht_gi = txrate->eht_gi;
}
sinfo->txrate.flags = txrate->flags;
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
diff --git a/mt7996/mcu.c b/mt7996/mcu.c
index 652a600..c190067 100644
--- a/mt7996/mcu.c
+++ b/mt7996/mcu.c
@@ -477,6 +477,43 @@ mt7996_mcu_rx_thermal_notify(struct mt7996_dev *dev, struct sk_buff *skb)
phy->throttle_state = n->duty_percent;
}
+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)
{
@@ -493,6 +530,16 @@ 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]);
diff --git a/mt7996/mcu.h b/mt7996/mcu.h
index 97151d1..376931e 100644
--- a/mt7996/mcu.h
+++ b/mt7996/mcu.h
@@ -191,6 +191,27 @@ struct mt7996_mcu_thermal_notify {
u8 __rsv2[4];
} __packed;
+struct all_sta_trx_rate {
+ __le16 wlan_idx;
+ u8 __rsv1[2];
+ u8 tx_mode;
+ u8 flags;
+ u8 tx_stbc;
+ u8 tx_gi;
+ u8 tx_bw;
+ u8 tx_ldpc;
+ u8 tx_mcs;
+ u8 tx_nss;
+ u8 rx_rate;
+ u8 rx_mode;
+ u8 rx_nsts;
+ u8 rx_gi;
+ u8 rx_coding;
+ u8 rx_stbc;
+ u8 rx_bw;
+ u8 __rsv2;
+} __packed;
+
struct mt7996_mcu_all_sta_info_event {
u8 rsv[4];
__le16 tag;
@@ -201,6 +222,7 @@ struct mt7996_mcu_all_sta_info_event {
u8 rsv3[2];
union {
+ struct all_sta_trx_rate rate[0];
struct {
__le16 wlan_idx;
u8 rsv[2];
--
2.18.0