[][mac80211][mt76][wifi: mt76: update tx statistics]
[Description]
Add the patches to get per-station tx count/failed and packet error rate.
- Get tx count and tx failed from mcu command.
- Add debugfs knob to calculate and dump PER.
- Add debugfs knob to reset counter.
[Release-log]
N/A
Change-Id: I5b39aaa78208fad5e65287dc18d2dd8a78376018
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/7036844
diff --git a/autobuild_mac80211_release/package/kernel/mt76/patches/3010-wifi-mt76-mt7915-add-wa-command-to-get-tx-msdu-count.patch b/autobuild_mac80211_release/package/kernel/mt76/patches/3010-wifi-mt76-mt7915-add-wa-command-to-get-tx-msdu-count.patch
new file mode 100644
index 0000000..d76e753
--- /dev/null
+++ b/autobuild_mac80211_release/package/kernel/mt76/patches/3010-wifi-mt76-mt7915-add-wa-command-to-get-tx-msdu-count.patch
@@ -0,0 +1,230 @@
+From aecf943a183c8b1e0ea7d503e406b88ebed57d06 Mon Sep 17 00:00:00 2001
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+Date: Wed, 18 Jan 2023 16:37:22 +0800
+Subject: [PATCH 3010/3015] wifi: mt76: mt7915: add wa command to get tx msdu
+ count
+
+---
+ mt76.h | 2 +-
+ mt76_connac2_mac.h | 1 +
+ mt76_connac_mac.c | 9 ++++----
+ mt76_connac_mcu.h | 1 +
+ mt7915/main.c | 8 ++++---
+ mt7915/mcu.c | 56 +++++++++++++++++++++++++++++++++++++++++++---
+ mt7915/mcu.h | 11 +++++++++
+ mt7915/mt7915.h | 1 +
+ 8 files changed, 78 insertions(+), 11 deletions(-)
+
+diff --git a/mt76.h b/mt76.h
+index a36a978b..0d1f3cbf 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -285,7 +285,7 @@ struct mt76_sta_stats {
+ u64 tx_mcs[16]; /* mcs idx */
+ u64 tx_bytes;
+ /* WED TX */
+- u32 tx_packets;
++ u32 tx_packets; /* unit: MSDU */
+ u32 tx_retries;
+ u32 tx_failed;
+ /* WED RX */
+diff --git a/mt76_connac2_mac.h b/mt76_connac2_mac.h
+index f33171bc..101e7602 100644
+--- a/mt76_connac2_mac.h
++++ b/mt76_connac2_mac.h
+@@ -164,6 +164,7 @@ enum {
+
+ #define MT_TXS6_MPDU_FAIL_CNT GENMASK(31, 23)
+
++#define MT_TXS7_MPDU_RETRY_BYTE GENMASK(22, 0)
+ #define MT_TXS7_MPDU_RETRY_CNT GENMASK(31, 23)
+
+ /* RXD DW1 */
+diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c
+index 614df85e..57e02aec 100644
+--- a/mt76_connac_mac.c
++++ b/mt76_connac_mac.c
+@@ -491,7 +491,9 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
+
+ /* counting non-offloading skbs */
+ wcid->stats.tx_bytes += skb->len;
+- wcid->stats.tx_packets++;
++
++ if (is_mt7915(dev))
++ wcid->stats.tx_packets++;
+ }
+
+ val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len + sz_txd) |
+@@ -575,9 +577,8 @@ bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid,
+ /* PPDU based reporting */
+ if (FIELD_GET(MT_TXS0_TXS_FORMAT, txs) > 1) {
+ stats->tx_bytes +=
+- le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_BYTE);
+- stats->tx_packets +=
+- le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_CNT);
++ 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 +=
+diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
+index 130a8d25..34df625a 100644
+--- a/mt76_connac_mcu.h
++++ b/mt76_connac_mcu.h
+@@ -1003,6 +1003,7 @@ enum {
+ MCU_EXT_EVENT_BF_STATUS_READ = 0x35,
+ MCU_EXT_EVENT_RDD_REPORT = 0x3a,
+ MCU_EXT_EVENT_CSA_NOTIFY = 0x4f,
++ MCU_EXT_EVENT_WA_TX_STAT = 0x74,
+ MCU_EXT_EVENT_BCC_NOTIFY = 0x75,
+ MCU_EXT_EVENT_MURU_CTRL = 0x9f,
+ MCU_EXT_EVENT_CSI_REPORT = 0xc2,
+diff --git a/mt7915/main.c b/mt7915/main.c
+index 8ebea612..dca93cd8 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_packets = msta->wcid.stats.tx_packets;
+- sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
+-
+ sinfo->tx_failed = msta->wcid.stats.tx_failed;
+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
+
+@@ -1121,6 +1118,11 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw,
+ }
+ }
+
++ if (!mt7915_mcu_get_tx_stat_wa(phy->dev, msta->wcid.idx)) {
++ sinfo->tx_packets = msta->wcid.stats.tx_packets;
++ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
++ }
++
+ 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 b5a0967b..07681902 100644
+--- a/mt7915/mcu.c
++++ b/mt7915/mcu.c
+@@ -168,7 +168,9 @@ mt7915_mcu_parse_response(struct mt76_dev *mdev, int cmd,
+ }
+
+ rxd = (struct mt76_connac2_mcu_rxd *)skb->data;
+- if (seq != rxd->seq)
++
++ if (seq != rxd->seq &&
++ !(rxd->eid == MCU_CMD_EXT_CID && rxd->ext_eid == MCU_EXT_EVENT_WA_TX_STAT))
+ return -EAGAIN;
+
+ if (cmd == MCU_CMD(PATCH_SEM_CONTROL)) {
+@@ -420,13 +422,14 @@ void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb)
+ struct mt76_connac2_mcu_rxd *rxd;
+
+ rxd = (struct mt76_connac2_mcu_rxd *)skb->data;
+- if (rxd->ext_eid == MCU_EXT_EVENT_THERMAL_PROTECT ||
++ if ((rxd->ext_eid == MCU_EXT_EVENT_THERMAL_PROTECT ||
+ rxd->ext_eid == MCU_EXT_EVENT_FW_LOG_2_HOST ||
+ rxd->ext_eid == MCU_EXT_EVENT_ASSERT_DUMP ||
+ rxd->ext_eid == MCU_EXT_EVENT_PS_SYNC ||
+ rxd->ext_eid == MCU_EXT_EVENT_BCC_NOTIFY ||
+ rxd->ext_eid == MCU_EXT_EVENT_BF_STATUS_READ ||
+- !rxd->seq)
++ !rxd->seq) &&
++ !(rxd->eid == MCU_CMD_EXT_CID && rxd->ext_eid == MCU_EXT_EVENT_WA_TX_STAT))
+ mt7915_mcu_rx_unsolicited_event(dev, skb);
+ else
+ mt76_mcu_rx_event(&dev->mt76, skb);
+@@ -4086,6 +4089,53 @@ out:
+ return ret;
+ }
+
++int mt7915_mcu_get_tx_stat_wa(struct mt7915_dev *dev, u16 wlan_idx)
++{
++ struct {
++ __le32 cmd;
++ __le32 num;
++ __le32 __rsv;
++ __le16 wlan_idx;
++ } req = {
++ .cmd = cpu_to_le32(MCU_WA_QUERY_GET_TX_STAT),
++ .num = cpu_to_le32(1),
++ .wlan_idx = cpu_to_le16(wlan_idx),
++ };
++ struct mt7915_mcu_wa_tx_stat *res;
++ struct mt76_wcid *wcid;
++ struct sk_buff *skb;
++ int ret;
++
++ ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_WA_PARAM_CMD(QUERY),
++ &req, sizeof(req), true, &skb);
++ if (ret)
++ return ret;
++
++ if (!is_mt7915(&dev->mt76))
++ skb_pull(skb, 4);
++
++ res = (struct mt7915_mcu_wa_tx_stat *)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_packets += le32_to_cpu(res->tx_msdu_cnt);
++ else
++ ret = -EINVAL;
++
++ rcu_read_unlock();
++out:
++ dev_kfree_skb(skb);
++
++ return ret;
++}
++
+ 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 24d0efd3..5f6c7c80 100644
+--- a/mt7915/mcu.h
++++ b/mt7915/mcu.h
+@@ -292,6 +292,17 @@ enum {
+ MCU_WA_PARAM_RED_SETTING = 0x40,
+ };
+
++enum {
++ MCU_WA_QUERY_GET_TX_STAT = 0x15,
++};
++
++struct mt7915_mcu_wa_tx_stat {
++ __le16 wlan_idx;
++ u8 __rsv2[2];
++ __le32 tx_bytes;
++ __le32 tx_msdu_cnt;
++};
++
+ enum mcu_mmps_mode {
+ MCU_MMPS_STATIC,
+ MCU_MMPS_DYNAMIC,
+diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
+index 594dfcd5..d76ca390 100644
+--- a/mt7915/mt7915.h
++++ b/mt7915/mt7915.h
+@@ -712,6 +712,7 @@ int mt7915_mcu_set_thermal_throttling(struct mt7915_phy *phy, u8 state);
+ 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_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.18.0
+
diff --git a/autobuild_mac80211_release/package/kernel/mt76/patches/3011-wifi-mt76-get-tx-count-and-tx-failed-from-mcu-comman.patch b/autobuild_mac80211_release/package/kernel/mt76/patches/3011-wifi-mt76-get-tx-count-and-tx-failed-from-mcu-comman.patch
new file mode 100644
index 0000000..64f073e
--- /dev/null
+++ b/autobuild_mac80211_release/package/kernel/mt76/patches/3011-wifi-mt76-get-tx-count-and-tx-failed-from-mcu-comman.patch
@@ -0,0 +1,246 @@
+From 08fd3173f9a7e7b7ae1112f43358068ea83faa56 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 3011/3015] 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 0d1f3cbf..22c6531a 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -286,6 +286,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 57e02aec..05a7a215 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 34df625a..747ae7e9 100644
+--- a/mt76_connac_mcu.h
++++ b/mt76_connac_mcu.h
+@@ -1163,6 +1163,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 dca93cd8..51129341 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 07681902..e9856c1b 100644
+--- a/mt7915/mcu.c
++++ b/mt7915/mcu.c
+@@ -4136,6 +4136,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 5f6c7c80..7b611fb7 100644
+--- a/mt7915/mcu.h
++++ b/mt7915/mcu.h
+@@ -1018,6 +1018,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 d76ca390..ac019270 100644
+--- a/mt7915/mt7915.h
++++ b/mt7915/mt7915.h
+@@ -713,6 +713,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.18.0
+
diff --git a/autobuild_mac80211_release/package/kernel/mt76/patches/3012-wifi-mt76-mt7915-enable-PPDU-TxS-to-host-when-wed-en.patch b/autobuild_mac80211_release/package/kernel/mt76/patches/3012-wifi-mt76-mt7915-enable-PPDU-TxS-to-host-when-wed-en.patch
new file mode 100644
index 0000000..666f277
--- /dev/null
+++ b/autobuild_mac80211_release/package/kernel/mt76/patches/3012-wifi-mt76-mt7915-enable-PPDU-TxS-to-host-when-wed-en.patch
@@ -0,0 +1,122 @@
+From 8af0601319706314171a8f9ed9117dd3fada484f Mon Sep 17 00:00:00 2001
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+Date: Wed, 18 Jan 2023 11:50:38 +0800
+Subject: [PATCH 3012/3015] wifi: mt76: mt7915: enable PPDU-TxS to host when
+ wed enable
+
+Calculate tx bytes and tx retries from PPDU-TxS
+---
+ mt76_connac_mac.c | 2 --
+ mt7915/init.c | 6 ++++++
+ mt7915/mmio.c | 21 ---------------------
+ tx.c | 6 ++++++
+ 4 files changed, 12 insertions(+), 23 deletions(-)
+
+diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c
+index 05a7a215..d7cca351 100644
+--- a/mt76_connac_mac.c
++++ b/mt76_connac_mac.c
+@@ -490,8 +490,6 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
+ mt76_connac_lmac_mapping(skb_get_queue_mapping(skb));
+
+ /* counting non-offloading skbs */
+- wcid->stats.tx_bytes += skb->len;
+-
+ if (is_mt7915(dev))
+ wcid->stats.tx_packets++;
+ }
+diff --git a/mt7915/init.c b/mt7915/init.c
+index 92977b98..f24c45f6 100644
+--- a/mt7915/init.c
++++ b/mt7915/init.c
+@@ -489,6 +489,12 @@ mt7915_mac_init_band(struct mt7915_dev *dev, u8 band)
+ set = FIELD_PREP(MT_WTBLOFF_TOP_RSCR_RCPI_MODE, 0) |
+ FIELD_PREP(MT_WTBLOFF_TOP_RSCR_RCPI_PARAM, 0x3);
+ mt76_rmw(dev, MT_WTBLOFF_TOP_RSCR(band), mask, set);
++
++ /* MT_TXD5_TX_STATUS_HOST (MPDU format) has higher priority than
++ * MT_AGG_ACR_PPDU_TXS2H (PPDU format) even though ACR bit is set.
++ */
++ if (mtk_wed_device_active(&dev->mt76.mmio.wed))
++ mt76_set(dev, MT_AGG_ACR4(band), MT_AGG_ACR_PPDU_TXS2H);
+ }
+
+ static void
+diff --git a/mt7915/mmio.c b/mt7915/mmio.c
+index 6dec9d60..87cff5d4 100644
+--- a/mt7915/mmio.c
++++ b/mt7915/mmio.c
+@@ -551,7 +551,6 @@ static u32 mt7915_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)
+ static int mt7915_mmio_wed_offload_enable(struct mtk_wed_device *wed)
+ {
+ struct mt7915_dev *dev;
+- struct mt7915_phy *phy;
+ int ret;
+
+ dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
+@@ -565,38 +564,18 @@ static int mt7915_mmio_wed_offload_enable(struct mtk_wed_device *wed)
+ if (!ret)
+ return -EAGAIN;
+
+- phy = &dev->phy;
+- mt76_set(dev, MT_AGG_ACR4(phy->mt76->band_idx), MT_AGG_ACR_PPDU_TXS2H);
+-
+- phy = dev->mt76.phys[MT_BAND1] ? dev->mt76.phys[MT_BAND1]->priv : NULL;
+- if (phy)
+- mt76_set(dev, MT_AGG_ACR4(phy->mt76->band_idx),
+- MT_AGG_ACR_PPDU_TXS2H);
+-
+ return 0;
+ }
+
+ static void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed)
+ {
+ struct mt7915_dev *dev;
+- struct mt7915_phy *phy;
+
+ dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
+
+ spin_lock_bh(&dev->mt76.token_lock);
+ dev->mt76.token_size = wed->wlan.token_start;//MT7915_TOKEN_SIZE
+ spin_unlock_bh(&dev->mt76.token_lock);
+-
+- /* MT_TXD5_TX_STATUS_HOST (MPDU format) has higher priority than
+- * MT_AGG_ACR_PPDU_TXS2H (PPDU format) even though ACR bit is set.
+- */
+- phy = &dev->phy;
+- mt76_clear(dev, MT_AGG_ACR4(phy->mt76->band_idx), MT_AGG_ACR_PPDU_TXS2H);
+-
+- phy = dev->mt76.phys[MT_BAND1] ? dev->mt76.phys[MT_BAND1]->priv : NULL;
+- if (phy)
+- mt76_clear(dev, MT_AGG_ACR4(phy->mt76->band_idx),
+- MT_AGG_ACR_PPDU_TXS2H);
+ }
+
+ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
+diff --git a/tx.c b/tx.c
+index a72b7779..36b0f486 100644
+--- a/tx.c
++++ b/tx.c
+@@ -120,6 +120,7 @@ mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid,
+ struct sk_buff *skb)
+ {
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
++ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ struct mt76_tx_cb *cb = mt76_tx_skb_cb(skb);
+ int pid;
+
+@@ -131,6 +132,11 @@ mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid,
+ if (info->flags & IEEE80211_TX_CTL_NO_ACK)
+ return MT_PACKET_ID_NO_ACK;
+
++ if (mtk_wed_device_active(&dev->mmio.wed) &&
++ ((info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) ||
++ ieee80211_is_data(hdr->frame_control)))
++ return MT_PACKET_ID_WED;
++
+ if (!(info->flags & (IEEE80211_TX_CTL_REQ_TX_STATUS |
+ IEEE80211_TX_CTL_RATE_CTRL_PROBE)))
+ return MT_PACKET_ID_NO_SKB;
+--
+2.18.0
+
diff --git a/autobuild_mac80211_release/package/kernel/mt76/patches/3013-wifi-mt76-mt7915-get-tx-retries-from-tx-free-done-ev.patch b/autobuild_mac80211_release/package/kernel/mt76/patches/3013-wifi-mt76-mt7915-get-tx-retries-from-tx-free-done-ev.patch
new file mode 100644
index 0000000..3a1ba99
--- /dev/null
+++ b/autobuild_mac80211_release/package/kernel/mt76/patches/3013-wifi-mt76-mt7915-get-tx-retries-from-tx-free-done-ev.patch
@@ -0,0 +1,102 @@
+From 2d87b4aa84333ffdf4d42c16f5b13bc6c349285c Mon Sep 17 00:00:00 2001
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+Date: Tue, 17 Jan 2023 21:15:00 +0800
+Subject: [PATCH 3013/3015] wifi: mt76: mt7915: get tx retries from tx free
+ done event for sw path
+
+---
+ mt7915/mac.c | 14 +++++++++++---
+ mt7915/mac.h | 5 ++++-
+ mt7915/main.c | 6 +++---
+ 3 files changed, 18 insertions(+), 7 deletions(-)
+
+diff --git a/mt7915/mac.c b/mt7915/mac.c
+index 175498b1..b7559182 100644
+--- a/mt7915/mac.c
++++ b/mt7915/mac.c
+@@ -1005,6 +1005,7 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
+ struct mt76_dev *mdev = &dev->mt76;
+ struct mt76_txwi_cache *txwi;
+ struct ieee80211_sta *sta = NULL;
++ struct mt76_wcid *wcid = NULL;
+ LIST_HEAD(free_list);
+ void *end = data + len;
+ bool v3, wake = false;
+@@ -1019,7 +1020,7 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
+ v3 = (FIELD_GET(MT_TX_FREE_VER, txd) == 0x4);
+
+ for (cur_info = tx_info; count < total; cur_info++) {
+- u32 msdu, info;
++ u32 msdu, info, retries = 0;
+ u8 i;
+
+ if (WARN_ON_ONCE((void *)cur_info >= end))
+@@ -1032,7 +1033,6 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
+ info = le32_to_cpu(*cur_info);
+ if (info & MT_TX_FREE_PAIR) {
+ struct mt7915_sta *msta;
+- struct mt76_wcid *wcid = NULL;
+ u16 idx;
+
+ idx = FIELD_GET(MT_TX_FREE_WLAN_ID, info);
+@@ -1049,7 +1049,15 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
+ continue;
+ }
+
+- if (v3 && (info & MT_TX_FREE_MPDU_HEADER))
++ if (v3 && (info & MT_TX_FREE_MPDU_HEADER_V3))
++ retries = u32_get_bits(info, MT_TX_FREE_TX_COUNT_V3) - 1;
++ else if (!v3 && (info & MT_TX_FREE_MPDU_HEADER))
++ retries = u32_get_bits(info, MT_TX_FREE_TX_COUNT) - 1;
++
++ if (!mtk_wed_device_active(&mdev->mmio.wed))
++ wcid->stats.tx_retries += retries;
++
++ if (v3 && (info & MT_TX_FREE_MPDU_HEADER_V3))
+ continue;
+
+ for (i = 0; i < 1 + v3; i++) {
+diff --git a/mt7915/mac.h b/mt7915/mac.h
+index 6fa9c79f..afadc512 100644
+--- a/mt7915/mac.h
++++ b/mt7915/mac.h
+@@ -36,8 +36,11 @@ enum rx_pkt_type {
+ #define MT_TX_FREE_LATENCY GENMASK(12, 0)
+ /* 0: success, others: dropped */
+ #define MT_TX_FREE_MSDU_ID GENMASK(30, 16)
++#define MT_TX_FREE_TX_COUNT GENMASK(12, 0)
++#define MT_TX_FREE_TX_COUNT_V3 GENMASK(27, 24)
+ #define MT_TX_FREE_PAIR BIT(31)
+-#define MT_TX_FREE_MPDU_HEADER BIT(30)
++#define MT_TX_FREE_MPDU_HEADER BIT(15)
++#define MT_TX_FREE_MPDU_HEADER_V3 BIT(30)
+ #define MT_TX_FREE_MSDU_ID_V3 GENMASK(14, 0)
+
+ /* will support this field in further revision */
+diff --git a/mt7915/main.c b/mt7915/main.c
+index 51129341..ef1cf20c 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_retries = msta->wcid.stats.tx_retries;
+- sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES);
+-
+ if (mtk_wed_get_rx_capa(&phy->dev->mt76.mmio.wed)) {
+ sinfo->rx_bytes = msta->wcid.stats.rx_bytes;
+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES64);
+@@ -1115,6 +1112,9 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw,
+ }
+ }
+
++ sinfo->tx_retries = msta->wcid.stats.tx_retries;
++ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES);
++
+ if (!mt7915_mcu_get_tx_stat_wa(phy->dev, msta->wcid.idx)) {
+ sinfo->tx_packets = msta->wcid.stats.tx_packets;
+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
+--
+2.18.0
+
diff --git a/autobuild_mac80211_release/package/kernel/mt76/patches/3014-wifi-mt76-update-debugfs-knob-for-reset-counter-and-.patch b/autobuild_mac80211_release/package/kernel/mt76/patches/3014-wifi-mt76-update-debugfs-knob-for-reset-counter-and-.patch
new file mode 100644
index 0000000..3707c51
--- /dev/null
+++ b/autobuild_mac80211_release/package/kernel/mt76/patches/3014-wifi-mt76-update-debugfs-knob-for-reset-counter-and-.patch
@@ -0,0 +1,93 @@
+From 5cdb0e4160589abdd04c2a5bdc3bad935e7dbf32 Mon Sep 17 00:00:00 2001
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+Date: Mon, 30 Jan 2023 11:36:32 +0800
+Subject: [PATCH 3014/3015] wifi: mt76: update debugfs knob for reset counter
+ and get tx packet error rate
+
+---
+ mt7915/mtk_debugfs.c | 62 ++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 62 insertions(+)
+
+diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
+index 5e64fe91..dbbf7ecc 100644
+--- a/mt7915/mtk_debugfs.c
++++ b/mt7915/mtk_debugfs.c
+@@ -3190,6 +3190,66 @@ mt7915_sw_aci_set(void *data, u64 val)
+ DEFINE_DEBUGFS_ATTRIBUTE(fops_sw_aci, NULL,
+ mt7915_sw_aci_set, "%llx\n");
+
++static int mt7915_reset_counter(void *data, u64 val)
++{
++ struct mt7915_phy *phy = data;
++ struct mt7915_dev *dev = phy->dev;
++ struct mt76_wcid *wcid;
++
++ /* Clear the firmware counters */
++ mt7915_mcu_get_tx_stat_wa(dev, dev->wlan_idx);
++ mt7915_get_tx_stat(phy, dev->wlan_idx);
++
++ rcu_read_lock();
++ wcid = rcu_dereference(dev->mt76.wcid[dev->wlan_idx]);
++ if (!wcid)
++ return -EINVAL;
++
++ memset(&wcid->stats, 0, sizeof(struct mt76_sta_stats));
++
++ rcu_read_unlock();
++
++ return 0;
++}
++
++DEFINE_DEBUGFS_ATTRIBUTE(fops_reset_counter, NULL,
++ mt7915_reset_counter, "%lld\n");
++
++static int
++mt7915_per_read(struct seq_file *s, void *data)
++{
++ struct mt7915_dev *dev = dev_get_drvdata(s->private);
++ struct mt76_sta_stats *stats;
++ struct mt76_wcid *wcid;
++ int ret;
++ u8 phy_idx;
++
++ if (!dev->mt76.wcid[dev->wlan_idx])
++ return -EINVAL;
++
++ phy_idx = dev->mt76.wcid[dev->wlan_idx]->phy_idx;
++
++ ret = mt7915_get_tx_stat(dev->mt76.phys[phy_idx]->priv, dev->wlan_idx);
++ if (ret)
++ return ret;
++
++ rcu_read_lock();
++ wcid = rcu_dereference(dev->mt76.wcid[dev->wlan_idx]);
++ if (!wcid)
++ return -EINVAL;
++
++ stats = &wcid->stats;
++
++ seq_printf(s, "sta %d, tx_mpdu_cnt = %u, tx_failed = %u, PER = %u.%u%%\n", dev->wlan_idx,
++ stats->tx_mpdu_cnt, stats->tx_failed,
++ stats->tx_mpdu_cnt ? stats->tx_failed * 1000 / stats->tx_mpdu_cnt / 10 : 0,
++ stats->tx_mpdu_cnt ? stats->tx_failed * 1000 / stats->tx_mpdu_cnt % 10 : 0);
++
++ rcu_read_unlock();
++
++ return 0;
++}
++
+ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
+ {
+ struct mt7915_dev *dev = phy->dev;
+@@ -3279,6 +3339,8 @@ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
+ mt7915_show_eeprom_mode);
+ debugfs_create_file("sw_aci", 0600, dir, dev,
+ &fops_sw_aci);
++ debugfs_create_file("reset_counter", 0200, dir, dev, &fops_reset_counter);
++ debugfs_create_devm_seqfile(dev->mt76.dev, "per", dir, mt7915_per_read);
+ return 0;
+ }
+ #endif
+--
+2.18.0
+
diff --git a/autobuild_mac80211_release/package/kernel/mt76/patches/3010-mt76-connac-wed-add-wed-rx-copy-skb-and-revert-page_.patch b/autobuild_mac80211_release/package/kernel/mt76/patches/3015-mt76-connac-wed-add-wed-rx-copy-skb-and-revert-page_.patch
similarity index 96%
rename from autobuild_mac80211_release/package/kernel/mt76/patches/3010-mt76-connac-wed-add-wed-rx-copy-skb-and-revert-page_.patch
rename to autobuild_mac80211_release/package/kernel/mt76/patches/3015-mt76-connac-wed-add-wed-rx-copy-skb-and-revert-page_.patch
index 9bce03a..64743b6 100644
--- a/autobuild_mac80211_release/package/kernel/mt76/patches/3010-mt76-connac-wed-add-wed-rx-copy-skb-and-revert-page_.patch
+++ b/autobuild_mac80211_release/package/kernel/mt76/patches/3015-mt76-connac-wed-add-wed-rx-copy-skb-and-revert-page_.patch
@@ -1,7 +1,7 @@
-From 27b1ad3b825b3208c599330f944fc11c120f3d2e Mon Sep 17 00:00:00 2001
+From 6c1940b9974057133ad6a27509d21547937d2ab6 Mon Sep 17 00:00:00 2001
From: Sujuan Chen <sujuan.chen@mediatek.com>
Date: Thu, 5 Jan 2023 16:43:57 +0800
-Subject: [PATCH 3010/3010] mt76: connac: wed: add wed rx copy skb and revert
+Subject: [PATCH 3015/3015] mt76: connac: wed: add wed rx copy skb and revert
page_pool
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
@@ -401,7 +401,7 @@
{
struct ieee80211_hw *hw = phy->hw;
diff --git a/mt76.h b/mt76.h
-index a36a978b..3911d013 100644
+index 22c6531a..19100d62 100644
--- a/mt76.h
+++ b/mt76.h
@@ -210,7 +210,7 @@ struct mt76_queue {
@@ -413,7 +413,7 @@
};
struct mt76_mcu_ops {
-@@ -1457,7 +1457,6 @@ mt76u_bulk_msg(struct mt76_dev *dev, void *data, int len, int *actual_len,
+@@ -1458,7 +1458,6 @@ mt76u_bulk_msg(struct mt76_dev *dev, void *data, int len, int *actual_len,
return usb_bulk_msg(udev, pipe, data, len, actual_len, timeout);
}
@@ -421,7 +421,7 @@
void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi,
struct mt76_sta_stats *stats, bool eht);
int mt76_skb_adjust_pad(struct sk_buff *skb, int pad);
-@@ -1569,25 +1568,6 @@ void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked);
+@@ -1570,25 +1569,6 @@ void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked);
struct mt76_rxwi_cache *mt76_rx_token_release(struct mt76_dev *dev, int token);
int mt76_rx_token_consume(struct mt76_dev *dev, void *ptr,
struct mt76_rxwi_cache *r, dma_addr_t phys);
@@ -448,10 +448,10 @@
static inline void mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked)
{
diff --git a/mt7915/main.c b/mt7915/main.c
-index 8ebea612..5307e15d 100644
+index ef1cf20c..0a64ef01 100644
--- a/mt7915/main.c
+++ b/mt7915/main.c
-@@ -1357,22 +1357,19 @@ void mt7915_get_et_strings(struct ieee80211_hw *hw,
+@@ -1361,22 +1361,19 @@ void mt7915_get_et_strings(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
u32 sset, u8 *data)
{
@@ -480,7 +480,7 @@
}
static void mt7915_ethtool_worker(void *wi_data, struct ieee80211_sta *sta)
-@@ -1400,7 +1397,7 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
+@@ -1404,7 +1401,7 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
};
struct mib_stats *mib = &phy->mib;
/* See mt7915_ampdu_stat_read_phy, etc */
@@ -489,7 +489,7 @@
mutex_lock(&dev->mt76.mutex);
-@@ -1481,12 +1478,9 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
+@@ -1485,12 +1482,9 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
return;
ei += wi.worker_stat_count;
@@ -506,10 +506,10 @@
static void
diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index 6dec9d60..6b9752b2 100644
+index 87cff5d4..0709f5bc 100644
--- a/mt7915/mmio.c
+++ b/mt7915/mmio.c
-@@ -602,9 +602,14 @@ static void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed)
+@@ -581,9 +581,14 @@ static void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed)
static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
{
struct mt7915_dev *dev;
@@ -524,7 +524,7 @@
for (i = 0; i < dev->mt76.rx_token_size; i++) {
struct mt76_rxwi_cache *r;
-@@ -612,50 +617,82 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
+@@ -591,50 +596,82 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
if (!r || !r->ptr)
continue;
@@ -626,7 +626,7 @@
goto unmap;
}
-@@ -667,8 +704,6 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+@@ -646,8 +683,6 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
return 0;
unmap: