Commit d57e1b25 authored by Benjamin Lin's avatar Benjamin Lin Committed by Felix Fietkau

wifi: mt76: mt7996: switch to mcu command for TX GI report

During runtime, the GI value in the WTBL is not updated in real-time. To
obtain the latest results for the TX GI, switch to use an MCU command.
Signed-off-by: default avatarBenjamin Lin <benjamin-jw.lin@mediatek.com>
Signed-off-by: default avatarShayne Chen <shayne.chen@mediatek.com>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent 1e12f0f8
......@@ -1328,7 +1328,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,
......
......@@ -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);
......@@ -1298,6 +1253,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:
......@@ -2312,6 +2269,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);
......
......@@ -998,6 +998,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);
......
......@@ -449,6 +449,43 @@ mt7996_mcu_ie_countdown(struct mt7996_dev *dev, struct sk_buff *skb)
}
}
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)
{
......@@ -465,6 +502,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]);
......
......@@ -175,6 +175,27 @@ struct mt7996_mcu_mib {
__le64 data;
} __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;
......@@ -185,6 +206,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];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment