| From eb824d2b3b30afc97387d9f94e6e5b075cc9c843 Mon Sep 17 00:00:00 2001 |
| From: Peter Chiu <chui-hao.chiu@mediatek.com> |
| Date: Wed, 11 Jan 2023 10:56:27 +0800 |
| Subject: [PATCH 3008/3012] wifi: mt76: get tx count and tx failed from mcu |
| command |
| |
| --- |
| mt76.h | 1 + |
| mt76_connac_mac.c | 2 - |
| mt76_connac_mcu.h | 1 + |
| mt7915/main.c | 8 ++-- |
| mt7915/mcu.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++ |
| mt7915/mcu.h | 22 ++++++++++ |
| mt7915/mt7915.h | 1 + |
| 7 files changed, 138 insertions(+), 5 deletions(-) |
| |
| diff --git a/mt76.h b/mt76.h |
| index f95a73cf..d17650d0 100644 |
| --- a/mt76.h |
| +++ b/mt76.h |
| @@ -285,6 +285,7 @@ struct mt76_sta_stats { |
| u64 tx_bytes; |
| /* WED TX */ |
| u32 tx_packets; /* unit: MSDU */ |
| + u32 tx_mpdu_cnt; |
| u32 tx_retries; |
| u32 tx_failed; |
| /* WED RX */ |
| diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c |
| index 1816bcbc..abcb9a27 100644 |
| --- a/mt76_connac_mac.c |
| +++ b/mt76_connac_mac.c |
| @@ -579,8 +579,6 @@ bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid, |
| stats->tx_bytes += |
| le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_BYTE) - |
| le32_get_bits(txs_data[7], MT_TXS7_MPDU_RETRY_BYTE); |
| - stats->tx_failed += |
| - le32_get_bits(txs_data[6], MT_TXS6_MPDU_FAIL_CNT); |
| stats->tx_retries += |
| le32_get_bits(txs_data[7], MT_TXS7_MPDU_RETRY_CNT); |
| |
| diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h |
| index dd7ee32f..b80a1011 100644 |
| --- a/mt76_connac_mcu.h |
| +++ b/mt76_connac_mcu.h |
| @@ -1160,6 +1160,7 @@ enum { |
| MCU_EXT_CMD_EDCA_UPDATE = 0x27, |
| MCU_EXT_CMD_DEV_INFO_UPDATE = 0x2A, |
| MCU_EXT_CMD_THERMAL_CTRL = 0x2c, |
| + MCU_EXT_CMD_GET_TX_STAT = 0x30, |
| MCU_EXT_CMD_WTBL_UPDATE = 0x32, |
| MCU_EXT_CMD_SET_DRR_CTRL = 0x36, |
| MCU_EXT_CMD_SET_FEATURE_CTRL = 0x38, |
| diff --git a/mt7915/main.c b/mt7915/main.c |
| index 4c9090a4..e7c3bc04 100644 |
| --- a/mt7915/main.c |
| +++ b/mt7915/main.c |
| @@ -1103,9 +1103,6 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw, |
| sinfo->tx_bytes = msta->wcid.stats.tx_bytes; |
| sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64); |
| |
| - sinfo->tx_failed = msta->wcid.stats.tx_failed; |
| - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); |
| - |
| sinfo->tx_retries = msta->wcid.stats.tx_retries; |
| sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); |
| |
| @@ -1123,6 +1120,11 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw, |
| sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS); |
| } |
| |
| + if (!mt7915_get_tx_stat(phy, msta->wcid.idx)) { |
| + sinfo->tx_failed = msta->wcid.stats.tx_failed; |
| + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); |
| + } |
| + |
| sinfo->ack_signal = (s8)msta->ack_signal; |
| sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL); |
| |
| diff --git a/mt7915/mcu.c b/mt7915/mcu.c |
| index 8e340f5b..58b884ca 100644 |
| --- a/mt7915/mcu.c |
| +++ b/mt7915/mcu.c |
| @@ -4148,6 +4148,114 @@ out: |
| return ret; |
| } |
| |
| +static int mt7915_mcu_get_tx_stat_v1(struct mt7915_phy *phy, |
| + u16 wlan_idx) |
| +{ |
| +#define to_wcid(hi, lo) (hi << 8 | lo) |
| + struct mt7915_dev *dev = phy->dev; |
| + struct mt76_phy *mphy = phy->mt76; |
| + struct mt7915_mcu_tx_stat_v1 *res; |
| + struct mt76_wcid *wcid; |
| + struct sk_buff *skb; |
| + struct { |
| + __le32 category; |
| + u8 wlan_idx_lo; |
| + u8 band; |
| + u8 wlan_idx_hi; |
| + u8 __rsv[5]; |
| + } __packed req = { |
| + .category = cpu_to_le32(MCU_GET_TX_STAT_CNT), |
| + .band = mphy->band_idx, |
| + .wlan_idx_lo = to_wcid_lo(wlan_idx), |
| + .wlan_idx_hi = to_wcid_hi(wlan_idx), |
| + }; |
| + int ret; |
| + |
| + ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_QUERY(GET_TX_STAT), |
| + &req, sizeof(req), true, &skb); |
| + if (ret) |
| + return ret; |
| + |
| + res = (struct mt7915_mcu_tx_stat_v1 *)skb->data; |
| + |
| + if (to_wcid(res->wlan_idx_hi, res->wlan_idx_lo) != wlan_idx) { |
| + ret = -EINVAL; |
| + goto out; |
| + } |
| + |
| + rcu_read_lock(); |
| + |
| + wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]); |
| + if (wcid) { |
| + wcid->stats.tx_mpdu_cnt += le32_to_cpu(res->tx_cnt); |
| + wcid->stats.tx_failed += le32_to_cpu(res->tx_failed); |
| + } else { |
| + ret = -EINVAL; |
| + } |
| + |
| + rcu_read_unlock(); |
| +out: |
| + dev_kfree_skb(skb); |
| + |
| + return ret; |
| +} |
| + |
| +static int mt7915_mcu_get_tx_stat_v2(struct mt7915_phy *phy, |
| + u16 wlan_idx) |
| +{ |
| + struct mt7915_dev *dev = phy->dev; |
| + struct mt76_phy *mphy = phy->mt76; |
| + struct mt7915_mcu_tx_stat_v2 *res; |
| + struct mt76_wcid *wcid; |
| + struct sk_buff *skb; |
| + struct { |
| + u8 category; |
| + u8 band; |
| + __le16 wcid; |
| + } __packed req = { |
| + .category = MCU_GET_TX_STAT_CNT, |
| + .band = mphy->band_idx, |
| + .wcid = cpu_to_le16(wlan_idx), |
| + }; |
| + int ret; |
| + |
| + ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_QUERY(GET_TX_STAT), |
| + &req, sizeof(req), true, &skb); |
| + if (ret) |
| + return ret; |
| + |
| + res = (struct mt7915_mcu_tx_stat_v2 *)skb->data; |
| + |
| + if (le16_to_cpu(res->wlan_idx) != wlan_idx) { |
| + ret = -EINVAL; |
| + goto out; |
| + } |
| + |
| + rcu_read_lock(); |
| + |
| + wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]); |
| + if (wcid) { |
| + wcid->stats.tx_mpdu_cnt += le32_to_cpu(res->tx_cnt); |
| + wcid->stats.tx_failed += le32_to_cpu(res->tx_failed); |
| + } else { |
| + ret = -EINVAL; |
| + } |
| + |
| + rcu_read_unlock(); |
| +out: |
| + dev_kfree_skb(skb); |
| + |
| + return ret; |
| +} |
| + |
| +int mt7915_get_tx_stat(struct mt7915_phy *phy, u16 wlan_idx) |
| +{ |
| + if (is_mt7915(&phy->dev->mt76)) |
| + return mt7915_mcu_get_tx_stat_v1(phy, wlan_idx); |
| + |
| + return mt7915_mcu_get_tx_stat_v2(phy, wlan_idx); |
| +} |
| + |
| int mt7915_mcu_update_bss_color(struct mt7915_dev *dev, struct ieee80211_vif *vif, |
| struct cfg80211_he_bss_color *he_bss_color) |
| { |
| diff --git a/mt7915/mcu.h b/mt7915/mcu.h |
| index 768c7d74..ce02bd9b 100644 |
| --- a/mt7915/mcu.h |
| +++ b/mt7915/mcu.h |
| @@ -1017,6 +1017,28 @@ struct mt7915_muru { |
| /* DL&UL User config */ |
| #define MURU_USER_CNT BIT(4) |
| |
| +struct mt7915_mcu_tx_stat_v1 { |
| + u8 wlan_idx_lo; |
| + u8 band_idx; |
| + u8 wlan_idx_hi; |
| + u8 __rsv1[29]; |
| + __le32 tx_cnt; |
| + __le32 tx_failed; |
| + u8 __rsv2[26]; |
| +}; |
| + |
| +struct mt7915_mcu_tx_stat_v2 { |
| + u8 __rsv1[4]; |
| + __le16 wlan_idx; |
| + u8 __rsv2[2]; |
| + __le32 tx_cnt; |
| + __le32 tx_failed; |
| +}; |
| + |
| +enum { |
| + MCU_GET_TX_STAT_CNT = 8, |
| +}; |
| + |
| enum { |
| CAPI_SU, |
| CAPI_MU, |
| diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h |
| index 80d6a43c..66dd79f3 100644 |
| --- a/mt7915/mt7915.h |
| +++ b/mt7915/mt7915.h |
| @@ -716,6 +716,7 @@ int mt7915_mcu_set_thermal_protect(struct mt7915_phy *phy); |
| int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif, |
| struct ieee80211_sta *sta, struct rate_info *rate); |
| int mt7915_mcu_get_tx_stat_wa(struct mt7915_dev *dev, u16 wcid); |
| +int mt7915_get_tx_stat(struct mt7915_phy *phy, u16 wlan_idx); |
| int mt7915_mcu_rdd_background_enable(struct mt7915_phy *phy, |
| struct cfg80211_chan_def *chandef); |
| int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set); |
| -- |
| 2.39.0 |
| |