[][MAC80211][mt76][Fix incorrect HE TX GI report]

[Description]
Change GI reporting source from static capability to rate-tuning module.

[Release-log]
N/A

Change-Id: I5dbe2190a3599b5206e266917c9dc17e62978f48
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/7430619
diff --git a/autobuild_mac80211_release/package/kernel/mt76/patches/0005-wifi-mt76-fix-incorrect-HE-TX-GI-report.patch b/autobuild_mac80211_release/package/kernel/mt76/patches/0005-wifi-mt76-fix-incorrect-HE-TX-GI-report.patch
index 3a0e69c..07733c3 100644
--- a/autobuild_mac80211_release/package/kernel/mt76/patches/0005-wifi-mt76-fix-incorrect-HE-TX-GI-report.patch
+++ b/autobuild_mac80211_release/package/kernel/mt76/patches/0005-wifi-mt76-fix-incorrect-HE-TX-GI-report.patch
@@ -1,7 +1,7 @@
-From 4edd13ceb916e12acbd91011268e192b867fd747 Mon Sep 17 00:00:00 2001
+From 80765449e32eba36051daeb29824cc011aecd85d Mon Sep 17 00:00:00 2001
 From: Benjamin Lin <benjamin-jw.lin@mediatek.com>
 Date: Fri, 24 Mar 2023 18:01:27 +0800
-Subject: [PATCH 5/5] wifi: mt76: fix incorrect HE TX GI report
+Subject: [PATCH] wifi: mt76: fix incorrect HE TX GI report
 
 Change GI reporting source from static capability to rate-tuning module.
 
@@ -9,15 +9,15 @@
 ---
  mt76.h          |   4 ++
  mt7915/init.c   |   4 ++
- mt7915/mac.c    |  54 ++++++++++++++---------
- mt7915/main.c   |   7 +++
- mt7915/mcu.c    | 114 ++++++++++++++++++++++++++++++++++++++++++++++++
- mt7915/mcu.h    |  39 +++++++++++++++++
- mt7915/mt7915.h |   6 +++
- 7 files changed, 208 insertions(+), 20 deletions(-)
+ mt7915/mac.c    |  60 ++++++++++------
+ mt7915/main.c   |   7 ++
+ mt7915/mcu.c    | 183 ++++++++++++++++++++++++++++++++++++++++++++++++
+ mt7915/mcu.h    |  58 +++++++++++++++
+ mt7915/mt7915.h |   6 ++
+ 7 files changed, 302 insertions(+), 20 deletions(-)
 
 diff --git a/mt76.h b/mt76.h
-index 183b0fc..11d4936 100644
+index 183b0fc5..11d49363 100644
 --- a/mt76.h
 +++ b/mt76.h
 @@ -254,12 +254,16 @@ struct mt76_queue_ops {
@@ -38,7 +38,7 @@
  	MT_PHY_TYPE_HE_EXT_SU,
  	MT_PHY_TYPE_HE_TB,
 diff --git a/mt7915/init.c b/mt7915/init.c
-index b88c382..611a82b 100644
+index b88c3827..611a82b6 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
 @@ -644,6 +644,8 @@ mt7915_register_ext_phy(struct mt7915_dev *dev, struct mt7915_phy *phy)
@@ -60,7 +60,7 @@
  	INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7915_mac_work);
  	INIT_LIST_HEAD(&dev->sta_rc_list);
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index f1fdcfd..d052036 100644
+index f1fdcfde..8e30070b 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
 @@ -177,15 +177,7 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev)
@@ -124,7 +124,27 @@
  			continue;
  		}
  
-@@ -2016,6 +2004,27 @@ static void mt7915_mac_severe_check(struct mt7915_phy *phy)
+@@ -1055,6 +1043,7 @@ mt7915_mac_tx_free_v0(struct mt7915_dev *dev, void *data, int len)
+ static void mt7915_mac_add_txs(struct mt7915_dev *dev, void *data)
+ {
+ 	struct mt7915_sta *msta = NULL;
++	struct mt7915_phy *phy;
+ 	struct mt76_wcid *wcid;
+ 	__le32 *txs_data = data;
+ 	u16 wcidx;
+@@ -1090,6 +1079,11 @@ static void mt7915_mac_add_txs(struct mt7915_dev *dev, void *data)
+ 		list_add_tail(&msta->poll_list, &dev->sta_poll_list);
+ 	spin_unlock_bh(&dev->sta_poll_lock);
+ 
++	phy = msta->vif->phy;
++	spin_lock_bh(&phy->stats_lock);
++	if (list_empty(&msta->stats_list))
++		list_add_tail(&msta->stats_list, &phy->stats_list);
++	spin_unlock_bh(&phy->stats_lock);
+ out:
+ 	rcu_read_unlock();
+ }
+@@ -2016,6 +2010,27 @@ static void mt7915_mac_severe_check(struct mt7915_phy *phy)
  	phy->trb_ts = trb;
  }
  
@@ -152,7 +172,7 @@
  void mt7915_mac_sta_rc_work(struct work_struct *work)
  {
  	struct mt7915_dev *dev = container_of(work, struct mt7915_dev, rc_work);
-@@ -2071,6 +2080,11 @@ void mt7915_mac_work(struct work_struct *work)
+@@ -2071,6 +2086,11 @@ void mt7915_mac_work(struct work_struct *work)
  		mt7915_mac_severe_check(phy);
  	}
  
@@ -165,7 +185,7 @@
  
  	mt76_tx_status_check(mphy->dev, false);
 diff --git a/mt7915/main.c b/mt7915/main.c
-index ea1d4e6..870b7b2 100644
+index ea1d4e6a..870b7b23 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
 @@ -684,6 +684,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
@@ -197,20 +217,17 @@
  
  static void mt7915_tx(struct ieee80211_hw *hw,
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 2a5ad03..a9f8a88 100644
+index 2a5ad033..512a9d5f 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -3752,6 +3752,120 @@ out:
+@@ -3752,6 +3752,189 @@ out:
  	return ret;
  }
  
 +static int
-+mt7915_mcu_parse_tx_gi(struct mt7915_mcu_ra_info *mcu_rate,
-+			 struct rate_info *rate)
++mt7915_mcu_parse_tx_gi(struct mt76_dev *dev, u8 mode, u8 gi, u8 bw,
++                       struct rate_info *rate)
 +{
-+	u8 mode = mcu_rate->mode;
-+	u8 gi = mcu_rate->gi;
-+
 +	/* Legacy drivers only use 3 bits for PHY mode. For backward
 +	 * compatibility, HE and newer PHY mode indices are remapped
 +	 * to the extended bits.
@@ -232,21 +249,23 @@
 +	case MT_PHY_TYPE_HE_EXT_SU:
 +	case MT_PHY_TYPE_HE_TB:
 +	case MT_PHY_TYPE_HE_MU:
-+		switch (mcu_rate->bw) {
-+		case MCU_PHY_BW_20:
-+			gi = u8_get_bits(gi, HE_GI_BW_20);
-+			break;
-+		case MCU_PHY_BW_40:
-+			gi = u8_get_bits(gi, HE_GI_BW_40);
-+			break;
-+		case MCU_PHY_BW_80:
-+			gi = u8_get_bits(gi, HE_GI_BW_80);
-+			break;
-+		case MCU_PHY_BW_160:
-+			gi = u8_get_bits(gi, HE_GI_BW_160);
-+			break;
-+		default:
-+			return -EINVAL;
++		if (!is_mt7915(dev)) {
++			switch (bw) {
++			case MCU_PHY_BW_20:
++				gi = u8_get_bits(gi, HE_GI_BW_20);
++				break;
++			case MCU_PHY_BW_40:
++				gi = u8_get_bits(gi, HE_GI_BW_40);
++				break;
++			case MCU_PHY_BW_80:
++				gi = u8_get_bits(gi, HE_GI_BW_80);
++				break;
++			case MCU_PHY_BW_160:
++				gi = u8_get_bits(gi, HE_GI_BW_160);
++				break;
++			default:
++				return -EINVAL;
++			}
 +		}
 +
 +		if (gi > NL80211_RATE_INFO_HE_GI_3_2)
@@ -261,17 +280,78 @@
 +	return 0;
 +}
 +
-+int mt7915_mcu_get_tx_rate(struct mt7915_phy *phy, u16 wcidx)
++int mt7915_mcu_get_tx_rate_v1(struct mt7915_phy *phy, u16 wcidx)
 +{
 +	struct ieee80211_tx_status status = {};
++	struct mt7915_mcu_ra_info_v1 *rate;
 +	struct mt7915_dev *dev = phy->dev;
 +	struct mt76_phy *mphy = phy->mt76;
-+	struct mt7915_mcu_ra_info *rate;
 +	struct mt76_wcid *wcid;
 +	struct sk_buff *skb;
 +	int ret;
 +
 +	struct {
++		__le32 category;
++		u8 wcidx_lo;
++		u8 band;
++		u8 wcidx_hi;
++		u8 rsv[5];
++	} req = {
++		.category = cpu_to_le32(MCU_GET_TX_RATE),
++		.wcidx_lo = to_wcid_lo(wcidx),
++		.band = mphy->band_idx,
++		.wcidx_hi = to_wcid_hi(wcidx)
++	};
++
++	ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_QUERY(GET_TX_STAT),
++                                        &req, sizeof(req), true, &skb);
++	if (ret)
++		return ret;
++
++	rate = (struct mt7915_mcu_ra_info_v1 *)skb->data;
++	if ((rate->wcidx_hi << 8 | rate->wcidx_lo) != wcidx) {
++		ret = -EINVAL;
++		goto out;
++	}
++
++	rcu_read_lock();
++	wcid = rcu_dereference(dev->mt76.wcid[wcidx]);
++	if (!wcid) {
++		ret = -EINVAL;
++		goto unlock;
++	}
++
++	ret = mt7915_mcu_parse_tx_gi(mphy->dev, rate->mode, rate->gi,
++                                     rate->bw, &wcid->rate);
++	if (ret)
++		goto unlock;
++
++	status.sta = wcid_to_sta(wcid);
++	if (!status.sta) {
++		ret = -EINVAL;
++		goto unlock;
++	}
++	status.rate = &wcid->rate;
++	ieee80211_tx_status_ext(mphy->hw, &status);
++unlock:
++	rcu_read_unlock();
++out:
++	dev_kfree_skb(skb);
++
++	return ret;
++}
++
++int mt7915_mcu_get_tx_rate_v2(struct mt7915_phy *phy, u16 wcidx)
++{
++	struct ieee80211_tx_status status = {};
++	struct mt7915_mcu_ra_info_v2 *rate;
++	struct mt7915_dev *dev = phy->dev;
++	struct mt76_phy *mphy = phy->mt76;
++	struct mt76_wcid *wcid;
++	struct sk_buff *skb;
++	int ret;
++
++	struct {
 +		u8 category;
 +		u8 band;
 +		__le16 wcidx;
@@ -286,7 +366,7 @@
 +	if (ret)
 +		return ret;
 +
-+	rate = (struct mt7915_mcu_ra_info *)skb->data;
++	rate = (struct mt7915_mcu_ra_info_v2 *)skb->data;
 +	if (le16_to_cpu(rate->wcidx) != wcidx) {
 +		ret = -EINVAL;
 +		goto out;
@@ -299,7 +379,8 @@
 +		goto unlock;
 +	}
 +
-+	ret = mt7915_mcu_parse_tx_gi(rate, &wcid->rate);
++	ret = mt7915_mcu_parse_tx_gi(mphy->dev, rate->mode, rate->gi,
++                                     rate->bw, &wcid->rate);
 +	if (ret)
 +		goto unlock;
 +
@@ -318,14 +399,22 @@
 +	return ret;
 +}
 +
++int mt7915_mcu_get_tx_rate(struct mt7915_phy *phy, u16 wcidx)
++{
++	if (is_mt7915(&phy->dev->mt76))
++		return mt7915_mcu_get_tx_rate_v1(phy, wcidx);
++	else
++		return mt7915_mcu_get_tx_rate_v2(phy, wcidx);
++}
++
  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 1592b5d..3429e24 100644
+index 1592b5d6..aebacc7d 100644
 --- a/mt7915/mcu.h
 +++ b/mt7915/mcu.h
-@@ -152,6 +152,42 @@ struct mt7915_mcu_eeprom_info {
+@@ -152,6 +152,61 @@ struct mt7915_mcu_eeprom_info {
  	u8 data[16];
  } __packed;
  
@@ -346,7 +435,26 @@
 +#define HE_GI_BW_80	GENMASK(5, 4)
 +#define HE_GI_BW_160	GENMASK(7, 6)
 +
++struct mt7915_mcu_ra_info_v1 {
++	u8 wcidx_lo;
++	u8 band;
++	u8 wcidx_hi;
++	u8 rsv1[46];
++
++	u8 mode;
++	u8 flags;
++	u8 stbc;
++	u8 gi;
++	u8 bw;
++	u8 ldpc;
++	u8 mcs;
++	u8 nss;
++	u8 ltf;
++
++	u8 rsv2[8];
++};
++
-+struct mt7915_mcu_ra_info {
++struct mt7915_mcu_ra_info_v2 {
 +	u8 category;
 +	u8 rsv1;
 +	__le16 num;
@@ -368,7 +476,7 @@
  struct mt7915_mcu_phy_rx_info {
  	u8 category;
  	u8 rate;
-@@ -527,4 +563,7 @@ mt7915_get_power_bound(struct mt7915_phy *phy, s8 txpower)
+@@ -527,4 +582,7 @@ mt7915_get_power_bound(struct mt7915_phy *phy, s8 txpower)
  	return txpower;
  }
  
@@ -377,7 +485,7 @@
 +};
  #endif
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 376256d..81246f3 100644
+index 6c401080..891d21ea 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -131,6 +131,7 @@ struct mt7915_sta {