[][MAC80211][mt76][add spatial extension index support]

[Description]
Add spatial extension index support.

[Release-log]
N/A

Change-Id: I6d83c6ed6ebd64bb31be308d69364183e840ffb0
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/6241524
diff --git a/autobuild_mac80211_release/package/kernel/mt76/patches/0012-mt76-mt7915-add-spatial-extension-index-support.patch b/autobuild_mac80211_release/package/kernel/mt76/patches/0012-mt76-mt7915-add-spatial-extension-index-support.patch
new file mode 100644
index 0000000..45bdef4
--- /dev/null
+++ b/autobuild_mac80211_release/package/kernel/mt76/patches/0012-mt76-mt7915-add-spatial-extension-index-support.patch
@@ -0,0 +1,202 @@
+From ab47a5638c81b4e79bce84ea0c67cf5e89820e3b Mon Sep 17 00:00:00 2001
+From: Shayne Chen <shayne.chen@mediatek.com>
+Date: Wed, 13 Jul 2022 10:43:16 +0800
+Subject: [PATCH] mt76: mt7915: add spatial extension index support
+
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+---
+ .../net/wireless/mediatek/mt76/mt76_connac.h  | 11 ++++++++
+ .../wireless/mediatek/mt76/mt76_connac_mac.c  | 11 +++++---
+ .../wireless/mediatek/mt76/mt76_connac_mcu.h  |  2 +-
+ .../net/wireless/mediatek/mt76/mt7915/main.c  |  3 ---
+ .../net/wireless/mediatek/mt76/mt7915/mcu.c   | 26 +++++++++++++++++--
+ .../net/wireless/mediatek/mt76/mt7915/mcu.h   |  1 +
+ .../wireless/mediatek/mt76/mt7915/testmode.c  |  9 +++----
+ 7 files changed, 48 insertions(+), 15 deletions(-)
+
+diff --git a/mt76_connac.h b/mt76_connac.h
+index 9070162c..5a9c1c97 100644
+--- a/mt76_connac.h
++++ b/mt76_connac.h
+@@ -255,6 +255,17 @@ mt76_connac_txwi_to_txp(struct mt76_dev *dev, struct mt76_txwi_cache *t)
+ 	return (void *)(txwi + MT_TXD_SIZE);
+ }
+ 
++static inline u8 mt76_connac_spe_idx(u8 antenna_mask)
++{
++	static const u8 ant_to_spe[] = {0, 0, 1, 0, 3, 2, 4, 0,
++					9, 8, 6, 10, 16, 12, 18, 0};
++
++	if (antenna_mask >= sizeof(ant_to_spe))
++		return 0;
++
++	return ant_to_spe[antenna_mask];
++}
++
+ int mt76_connac_pm_wake(struct mt76_phy *phy, struct mt76_connac_pm *pm);
+ void mt76_connac_power_save_sched(struct mt76_phy *phy,
+ 				  struct mt76_connac_pm *pm);
+diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c
+index d83ed593..33abe5d6 100644
+--- a/mt76_connac_mac.c
++++ b/mt76_connac_mac.c
+@@ -402,9 +402,6 @@ mt76_connac2_mac_write_txwi_80211(struct mt76_dev *dev, __le32 *txwi,
+ 	if (ieee80211_is_beacon(fc)) {
+ 		txwi[3] &= ~cpu_to_le32(MT_TXD3_SW_POWER_MGMT);
+ 		txwi[3] |= cpu_to_le32(MT_TXD3_REM_TX_COUNT);
+-		if (!is_mt7921(dev))
+-			txwi[7] |= cpu_to_le32(FIELD_PREP(MT_TXD7_SPE_IDX,
+-							  0x18));
+ 	}
+ 
+ 	if (info->flags & IEEE80211_TX_CTL_INJECTED) {
+@@ -531,6 +528,14 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
+ 		val |= FIELD_PREP(MT_TXD6_TX_RATE, rate);
+ 		txwi[6] |= cpu_to_le32(val);
+ 		txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE);
++
++		if (!is_mt7921(dev)) {
++			u8 spe_idx = mt76_connac_spe_idx(mphy->antenna_mask);
++
++			if (!spe_idx)
++				spe_idx = 24 + ext_phy;
++			txwi[7] |= cpu_to_le32(FIELD_PREP(MT_TXD7_SPE_IDX, spe_idx));
++		}
+ 	}
+ }
+ EXPORT_SYMBOL_GPL(mt76_connac2_mac_write_txwi);
+diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
+index e94d6706..17e5213c 100644
+--- a/mt76_connac_mcu.h
++++ b/mt76_connac_mcu.h
+@@ -572,7 +572,7 @@ struct sta_rec_ra_fixed {
+ 
+ 	struct sta_phy phy;
+ 
+-	u8 spe_en;
++	u8 spe_idx;
+ 	u8 short_preamble;
+ 	u8 is_5g;
+ 	u8 mmps_mode;
+diff --git a/mt7915/main.c b/mt7915/main.c
+index 39587992..080e935c 100644
+--- a/mt7915/main.c
++++ b/mt7915/main.c
+@@ -957,9 +957,6 @@ mt7915_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
+ 	if (!tx_ant || tx_ant != rx_ant || ffs(tx_ant) > max_nss)
+ 		return -EINVAL;
+ 
+-	if ((BIT(hweight8(tx_ant)) - 1) != tx_ant)
+-		tx_ant = BIT(ffs(tx_ant) - 1) - 1;
+-
+ 	mutex_lock(&dev->mt76.mutex);
+ 
+ 	phy->mt76->antenna_mask = tx_ant;
+diff --git a/mt7915/mcu.c b/mt7915/mcu.c
+index 6587be2f..03a3c252 100644
+--- a/mt7915/mcu.c
++++ b/mt7915/mcu.c
+@@ -1306,6 +1306,9 @@ int mt7915_mcu_set_fixed_rate_ctrl(struct mt7915_dev *dev,
+ 	case RATE_PARAM_MMPS_UPDATE:
+ 		ra->mmps_mode = mt7915_mcu_get_mmps_mode(sta->smps_mode);
+ 		break;
++	case RATE_PARAM_SPE_UPDATE:
++		ra->spe_idx = *(u8 *)data;
++		break;
+ 	default:
+ 		break;
+ 	}
+@@ -1348,6 +1351,22 @@ int mt7915_mcu_add_smps(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+ 					      RATE_PARAM_MMPS_UPDATE);
+ }
+ 
++static int
++mt7915_mcu_set_spe_idx(struct mt7915_dev *dev, struct ieee80211_vif *vif,
++		       struct ieee80211_sta *sta, bool fixed_rate)
++{
++	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
++	struct mt76_phy *mphy = mvif->phy->mt76;
++	u8 spe_idx = mt76_connac_spe_idx(mphy->antenna_mask);
++
++	if (!spe_idx && !fixed_rate &&
++	    mphy->antenna_mask == mphy->hw->wiphy->available_antennas_tx)
++		spe_idx = 24 + mvif->mt76.band_idx;
++
++	return mt7915_mcu_set_fixed_rate_ctrl(dev, vif, sta, &spe_idx,
++					      RATE_PARAM_SPE_UPDATE);
++}
++
+ static int
+ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev,
+ 			       struct ieee80211_vif *vif,
+@@ -1393,7 +1412,7 @@ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev,
+ 	    mask->control[band].he_gi == GENMASK(7, 0) &&
+ 	    mask->control[band].he_ltf == GENMASK(7, 0) &&
+ 	    nrates != 1)
+-		return 0;
++		return mt7915_mcu_set_spe_idx(dev, vif, sta, false);
+ 
+ 	/* fixed single rate */
+ 	if (nrates == 1) {
+@@ -1433,7 +1452,7 @@ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev,
+ 			return ret;
+ 	}
+ 
+-	return 0;
++	return mt7915_mcu_set_spe_idx(dev, vif, sta, true);
+ }
+ 
+ static void
+@@ -2649,6 +2668,9 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
+ 	}
+ #endif
+ 
++	if (mt76_connac_spe_idx(phy->mt76->antenna_mask))
++		req.tx_streams_num = fls(phy->mt76->antenna_mask);
++
+ 	if (cmd == MCU_EXT_CMD(SET_RX_PATH) ||
+ 	    dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR)
+ 		req.switch_reason = CH_SWITCH_NORMAL;
+diff --git a/mt7915/mcu.h b/mt7915/mcu.h
+index 110e4f36..ed949802 100644
+--- a/mt7915/mcu.h
++++ b/mt7915/mcu.h
+@@ -395,6 +395,7 @@ enum {
+ 	RATE_PARAM_FIXED_MCS,
+ 	RATE_PARAM_FIXED_GI = 11,
+ 	RATE_PARAM_AUTO = 20,
++	RATE_PARAM_SPE_UPDATE = 22,
+ };
+ 
+ #define RATE_CFG_MCS			GENMASK(3, 0)
+diff --git a/mt7915/testmode.c b/mt7915/testmode.c
+index 123ceaf9..b2eee3f2 100644
+--- a/mt7915/testmode.c
++++ b/mt7915/testmode.c
+@@ -473,8 +473,6 @@ mt7915_tm_update_channel(struct mt7915_phy *phy)
+ static void
+ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
+ {
+-	static const u8 spe_idx_map[] = {0, 0, 1, 0, 3, 2, 4, 0,
+-					 9, 8, 6, 10, 16, 12, 18, 0};
+ 	struct mt76_testmode_data *td = &phy->mt76->test;
+ 	struct mt7915_dev *dev = phy->dev;
+ 	struct ieee80211_tx_info *info;
+@@ -488,11 +486,10 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
+ 	if (en) {
+ 		mt7915_tm_update_channel(phy);
+ 
+-		if (td->tx_spe_idx) {
++		if (td->tx_spe_idx)
+ 			phy->test.spe_idx = td->tx_spe_idx;
+-		} else {
+-			phy->test.spe_idx = spe_idx_map[td->tx_antenna_mask];
+-		}
++		else
++			phy->test.spe_idx = mt76_connac_spe_idx(td->tx_antenna_mask);
+ 	}
+ 
+ 	mt7915_tm_set_tam_arb(phy, en,
+-- 
+2.25.1
+