| 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 |
| |