[][mac80211][Rebase][rebase to the latest codebase]

[Description]
Fix and rebase to the latest mt76 master codebase.

[Release-log]
N/A

Change-Id: I57c4592b44a50cd8aa508b6a80376240b725eee1
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/7664456
diff --git a/autobuild_mac80211_release/package/kernel/mt76/patches/2006-wifi-mt76-add-debugfs-knob-to-show-packet-error-rate.patch b/autobuild_mac80211_release/package/kernel/mt76/patches/2006-wifi-mt76-add-debugfs-knob-to-show-packet-error-rate.patch
new file mode 100644
index 0000000..8f61926
--- /dev/null
+++ b/autobuild_mac80211_release/package/kernel/mt76/patches/2006-wifi-mt76-add-debugfs-knob-to-show-packet-error-rate.patch
@@ -0,0 +1,295 @@
+From 3a498fb75b2f609a41019f844873496117b1fff6 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] wifi: mt76: add debugfs knob to show packet error rate
+
+Get tx count and tx failed from mcu command
+---
+ mt76.h               |   2 +
+ mt76_connac_mcu.h    |   1 +
+ mt7915/mcu.c         | 108 +++++++++++++++++++++++++++++++++++++++++++
+ mt7915/mcu.h         |  21 ++++++++-
+ mt7915/mt7915.h      |   1 +
+ mt7915/mtk_debugfs.c |  62 +++++++++++++++++++++++++
+ 6 files changed, 194 insertions(+), 1 deletion(-)
+
+diff --git a/mt76.h b/mt76.h
+index 6c488bd1..cbd63695 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -297,8 +297,10 @@ struct mt76_sta_stats {
+ 	u64 tx_bytes;
+ 	/* WED TX */
+ 	u32 tx_packets;		/* unit: MSDU */
++	u32 tx_mpdu_cnt;
+ 	u32 tx_retries;
+ 	u32 tx_failed;
++	u32 tx_failed_wm;
+ 	/* WED RX */
+ 	u64 rx_bytes;
+ 	u32 rx_packets;
+diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
+index 1257dfa1..cfdee7c1 100644
+--- a/mt76_connac_mcu.h
++++ b/mt76_connac_mcu.h
+@@ -1162,6 +1162,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/mcu.c b/mt7915/mcu.c
+index 74728252..07a4b085 100644
+--- a/mt7915/mcu.c
++++ b/mt7915/mcu.c
+@@ -4214,6 +4214,114 @@ int mt7915_mcu_get_tx_rate(struct mt7915_phy *phy, u16 wcidx)
+ 		return mt7915_mcu_get_tx_rate_v2(phy, wcidx);
+ }
+ 
++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_wm += 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_wm += 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 82b0847d..d6849797 100644
+--- a/mt7915/mcu.h
++++ b/mt7915/mcu.h
+@@ -790,7 +790,8 @@ mt7915_get_power_bound(struct mt7915_phy *phy, s8 txpower)
+ }
+ 
+ enum {
+-	MCU_GET_TX_RATE = 4
++	MCU_GET_TX_RATE = 4,
++	MCU_GET_TX_STAT_CNT = 8
+ };
+ 
+ #ifdef CONFIG_MTK_VENDOR
+@@ -1069,6 +1070,24 @@ 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 {
+    CAPI_SU,
+    CAPI_MU,
+diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
+index 0153e5fe..85c5c95c 100644
+--- a/mt7915/mt7915.h
++++ b/mt7915/mt7915.h
+@@ -661,6 +661,7 @@ int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif,
+ int mt7915_mcu_rdd_background_enable(struct mt7915_phy *phy,
+ 				     struct cfg80211_chan_def *chandef);
+ int mt7915_mcu_wed_wa_tx_stats(struct mt7915_dev *dev, u16 wcid);
++int mt7915_get_tx_stat(struct mt7915_phy *phy, u16 wlan_idx);
+ int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set);
+ int mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
+ int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl);
+diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
+index 3eeb921f..da33578c 100644
+--- a/mt7915/mtk_debugfs.c
++++ b/mt7915/mtk_debugfs.c
+@@ -3790,6 +3790,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_wed_wa_tx_stats(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_wm,
++		   stats->tx_mpdu_cnt ? stats->tx_failed_wm * 1000 / stats->tx_mpdu_cnt / 10 : 0,
++		   stats->tx_mpdu_cnt ? stats->tx_failed_wm * 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;
+@@ -3880,6 +3940,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
+