[][MAC80211][External release build]

[Description]
Add external release build flow

[Release-log]
N/A

Change-Id: I9e7f99d972dec580eff7b50f18f1a0bc90487e4d
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/5687836
diff --git a/autobuild_mac80211_release/mt7986_mac80211/package/kernel/mt76/patches/1110-mt76-mt7915-implement-aid-support-in-testmode.patch b/autobuild_mac80211_release/mt7986_mac80211/package/kernel/mt76/patches/1110-mt76-mt7915-implement-aid-support-in-testmode.patch
new file mode 100755
index 0000000..90b53ea
--- /dev/null
+++ b/autobuild_mac80211_release/mt7986_mac80211/package/kernel/mt76/patches/1110-mt76-mt7915-implement-aid-support-in-testmode.patch
@@ -0,0 +1,420 @@
+From 8027e94f1564089d719a6fb0eab7d29bb2981bf0 Mon Sep 17 00:00:00 2001
+From: Shayne Chen <shayne.chen@mediatek.com>
+Date: Tue, 11 May 2021 16:24:09 +0800
+Subject: [PATCH 1110/1112] mt76: mt7915: implement aid support in testmode
+
+Add support for virtual stations in mt7915 testmode.
+
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+---
+ .../wireless/mediatek/mt76/mt76_connac_mcu.c  |   5 +
+ .../net/wireless/mediatek/mt76/mt7915/mac.c   |  25 +-
+ .../wireless/mediatek/mt76/mt7915/testmode.c  | 231 +++++++++++++++---
+ 3 files changed, 216 insertions(+), 45 deletions(-)
+
+diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
+index eac096c..a361ab6 100644
+--- a/mt76_connac_mcu.c
++++ b/mt76_connac_mcu.c
+@@ -389,6 +389,7 @@ void mt76_connac_mcu_sta_basic_tlv(struct sk_buff *skb,
+ 	switch (vif->type) {
+ 	case NL80211_IFTYPE_MESH_POINT:
+ 	case NL80211_IFTYPE_AP:
++	case NL80211_IFTYPE_MONITOR:
+ 		if (vif->p2p)
+ 			conn_type = CONNECTION_P2P_GC;
+ 		else
+@@ -577,6 +578,10 @@ void mt76_connac_mcu_wtbl_generic_tlv(struct mt76_dev *dev,
+ 					     wtbl_tlv, sta_wtbl);
+ 	spe = (struct wtbl_spe *)tlv;
+ 	spe->spe_idx = 24;
++
++	/* check */
++	if (vif->type == NL80211_IFTYPE_MONITOR)
++		rx->rca1 = 0;
+ }
+ EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_generic_tlv);
+ 
+diff --git a/mt7915/mac.c b/mt7915/mac.c
+index fb42446..2ad4cb1 100644
+--- a/mt7915/mac.c
++++ b/mt7915/mac.c
+@@ -906,16 +906,28 @@ mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi,
+ {
+ #ifdef CONFIG_NL80211_TESTMODE
+ 	struct mt76_testmode_data *td = &phy->mt76->test;
++	struct mt76_testmode_sta_data *sd = &td->sd;
+ 	const struct ieee80211_rate *r;
+-	u8 bw, mode, nss = td->tx_rate_nss;
+-	u8 rate_idx = td->tx_rate_idx;
++	u8 bw, mode, nss, rate_idx;
+ 	u16 rateval = 0;
+ 	u32 val;
+ 	bool cck = false;
+ 	int band;
+ 
+-	if (skb != phy->mt76->test.tx_skb)
+-		return;
++	if (mt76_testmode_has_sta(phy->mt76)) {
++		struct mt76_testmode_sta *tm_sta;
++		int i;
++
++		mt76_testmode_for_each_sta(phy->mt76, i, tm_sta) {
++			if (tm_sta->tx_skb == skb) {
++				sd = &tm_sta->sd;
++				break;
++			}
++		}
++	}
++
++	nss = sd->tx_rate_nss;
++	rate_idx = sd->tx_rate_idx;
+ 
+ 	switch (td->tx_rate_mode) {
+ 	case MT76_TM_TX_MODE_HT:
+@@ -1005,7 +1017,7 @@ mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi,
+ 	if (mode >= MT_PHY_TYPE_HE_SU)
+ 		val |= FIELD_PREP(MT_TXD6_HELTF, td->tx_ltf);
+ 
+-	if (td->tx_rate_ldpc || (bw > 0 && mode >= MT_PHY_TYPE_HE_SU))
++	if (sd->tx_rate_ldpc || (bw > 0 && mode >= MT_PHY_TYPE_HE_SU))
+ 		val |= MT_TXD6_LDPC;
+ 
+ 	txwi[1] &= ~cpu_to_le32(MT_TXD1_VTA);
+@@ -1474,6 +1486,9 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
+ 				continue;
+ 
+ 			msta = container_of(wcid, struct mt7915_sta, wcid);
++			if (mt76_testmode_enabled(msta->vif->phy->mt76))
++				continue;
++
+ 			spin_lock_bh(&dev->sta_poll_lock);
+ 			if (list_empty(&msta->poll_list))
+ 				list_add_tail(&msta->poll_list, &dev->sta_poll_list);
+diff --git a/mt7915/testmode.c b/mt7915/testmode.c
+index 054829e..29c173d 100644
+--- a/mt7915/testmode.c
++++ b/mt7915/testmode.c
+@@ -11,6 +11,7 @@ enum {
+ 	TM_CHANGED_FREQ_OFFSET,
+ 	TM_CHANGED_CFG,
+ 	TM_CHANGED_OFF_CH_SCAN_CH,
++	TM_CHANGED_AID,
+ 
+ 	/* must be last */
+ 	NUM_TM_CHANGED
+@@ -21,6 +22,7 @@ static const u8 tm_change_map[] = {
+ 	[TM_CHANGED_FREQ_OFFSET] = MT76_TM_ATTR_FREQ_OFFSET,
+ 	[TM_CHANGED_CFG] = MT76_TM_ATTR_CFG,
+ 	[TM_CHANGED_OFF_CH_SCAN_CH] = MT76_TM_ATTR_OFF_CH_SCAN_CH,
++	[TM_CHANGED_AID] = MT76_TM_ATTR_AID,
+ };
+ 
+ struct reg_band {
+@@ -142,18 +144,33 @@ mt7915_tm_set_trx(struct mt7915_phy *phy, int type, bool en)
+ }
+ 
+ static int
+-mt7915_tm_clean_hwq(struct mt7915_phy *phy, u8 wcid)
++mt7915_tm_clean_hwq(struct mt7915_phy *phy)
+ {
+ 	struct mt7915_dev *dev = phy->dev;
+ 	struct mt7915_tm_cmd req = {
+ 		.testmode_en = 1,
+ 		.param_idx = MCU_ATE_CLEAN_TXQUEUE,
+-		.param.clean.wcid = wcid,
+ 		.param.clean.band = phy != &dev->phy,
+ 	};
++	struct mt76_testmode_sta *tm_sta;
++	int ret, i;
+ 
+-	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(ATE_CTRL), &req,
+-				 sizeof(req), false);
++	if (!mt76_testmode_has_sta(phy->mt76)) {
++		req.param.clean.wcid = dev->mt76.global_wcid.idx;
++
++		return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(ATE_CTRL),
++					 &req, sizeof(req), false);
++	}
++
++	mt76_testmode_for_each_sta(phy->mt76, i, tm_sta) {
++		req.param.clean.wcid = phy->mt76->test.tm_wcid[i]->idx;
++		ret = mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(ATE_CTRL),
++					&req, sizeof(req), false);
++		if (ret)
++			return ret;
++	}
++
++	return 0;
+ }
+ 
+ static int
+@@ -530,27 +547,109 @@ mt7915_tm_reg_backup_restore(struct mt7915_phy *phy)
+ 	}
+ }
+ 
++static int
++mt7915_tm_sta_add(struct mt7915_phy *phy, u8 aid,
++		  struct mt76_testmode_sta_data *sd)
++{
++	struct mt76_testmode_data *td = &phy->mt76->test;
++	struct mt76_testmode_sta *tm_sta;
++
++	if (!aid)
++		return 0;
++
++	if (!td->tm_wcid[aid]) {
++		struct ieee80211_vif *vif = phy->monitor_vif;
++		struct ieee80211_sband_iftype_data *data;
++		struct ieee80211_supported_band *sband;
++		struct ieee80211_sta *sta;
++		struct mt7915_sta *msta;
++		int ret;
++
++		sta = kzalloc(sizeof(*sta) + phy->mt76->hw->sta_data_size +
++			      sizeof(*tm_sta), GFP_KERNEL);
++		if (!sta)
++			return -ENOMEM;
++
++		if (phy->mt76->chandef.chan->band == NL80211_BAND_5GHZ) {
++			sband = &phy->mt76->sband_5g.sband;
++			data = phy->iftype[NL80211_BAND_5GHZ];
++		} else {
++			sband = &phy->mt76->sband_2g.sband;
++			data = phy->iftype[NL80211_BAND_2GHZ];
++		}
++
++		ether_addr_copy(sta->addr, phy->mt76->macaddr);
++		sta->addr[0] += aid * 4;
++		memcpy(&sta->ht_cap, &sband->ht_cap, sizeof(sta->ht_cap));
++		memcpy(&sta->vht_cap, &sband->vht_cap, sizeof(sta->vht_cap));
++		memcpy(&sta->he_cap, &data[NL80211_IFTYPE_STATION].he_cap,
++		       sizeof(sta->he_cap));
++		sta->aid = aid;
++		sta->wme = 1;
++
++		ret = mt7915_mac_sta_add(&phy->dev->mt76, vif, sta);
++		if (ret) {
++			kfree(sta);
++			return ret;
++		}
++
++		msta = (struct mt7915_sta *)sta->drv_priv;
++		td->tm_wcid[aid] = &msta->wcid;
++		td->tm_sta_mask |= BIT(aid - 1);
++	}
++
++	tm_sta = mt76_testmode_aid_get_sta(phy->mt76, aid);
++	memcpy(&tm_sta->sd, sd, sizeof(tm_sta->sd));
++
++	return 0;
++}
++
+ static void
+-mt7915_tm_init(struct mt7915_phy *phy, bool en)
++mt7915_tm_sta_remove(struct mt7915_phy *phy, u8 aid)
+ {
++	struct mt76_testmode_data *td = &phy->mt76->test;
++	struct mt76_wcid *wcid = td->tm_wcid[aid];
+ 	struct mt7915_dev *dev = phy->dev;
++	struct ieee80211_sta *sta = wcid_to_sta(wcid);
+ 
+-	if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state))
++	mt7915_mac_sta_remove(&dev->mt76, phy->monitor_vif, sta);
++	mt76_wcid_mask_clear(dev->mt76.wcid_mask, wcid->idx);
++
++	kfree(sta);
++	td->tm_wcid[aid] = NULL;
++	td->tm_sta_mask &= ~BIT(aid - 1);
++}
++
++static void
++mt7915_tm_sta_remove_all(struct mt7915_phy *phy)
++{
++	int i;
++
++	if (!mt76_testmode_has_sta(phy->mt76))
+ 		return;
+ 
+-	mt7915_mcu_set_sku_en(phy, !en);
++	for (i = 1; i < ARRAY_SIZE(phy->mt76->test.tm_wcid); i++) {
++		if (phy->mt76->test.tm_wcid[i])
++			mt7915_tm_sta_remove(phy, i);
++	}
++}
+ 
+-	mt7915_tm_mode_ctrl(dev, en);
+-	mt7915_tm_reg_backup_restore(phy);
+-	mt7915_tm_set_trx(phy, TM_MAC_TXRX, !en);
++static int
++mt7915_tm_set_sta(struct mt7915_phy *phy)
++{
++	struct mt76_testmode_data *td = &phy->mt76->test;
+ 
+-	mt7915_mcu_add_bss_info(phy, phy->monitor_vif, en);
+-	mt7915_mcu_add_sta(dev, phy->monitor_vif, NULL, en);
++	if (!td->aid) {
++		mt7915_tm_sta_remove_all(phy);
++		return 0;
++	}
+ 
+-	phy->mt76->test.flag |= MT_TM_FW_RX_COUNT;
++	if (td->tx_count == 0) {
++		mt7915_tm_sta_remove(phy, td->aid);
++		return 0;
++	}
+ 
+-	if (!en)
+-		mt7915_tm_set_tam_arb(phy, en, 0);
++	return mt7915_tm_sta_add(phy, td->aid, &td->sd);
+ }
+ 
+ static void
+@@ -563,22 +662,48 @@ mt7915_tm_update_channel(struct mt7915_phy *phy)
+ 	mt7915_mcu_set_chan_info(phy, MCU_EXT_CMD(SET_RX_PATH));
+ }
+ 
++static bool
++mt7915_tm_check_skb(struct mt7915_phy *phy)
++{
++	struct mt76_testmode_data *td = &phy->mt76->test;
++	struct ieee80211_tx_info *info;
++
++	if (!mt76_testmode_has_sta(phy->mt76)) {
++		if (!td->tx_skb)
++			return false;
++
++		info = IEEE80211_SKB_CB(td->tx_skb);
++		info->control.vif = phy->monitor_vif;
++	} else {
++		struct mt76_testmode_sta *tm_sta;
++		int i;
++
++		mt76_testmode_for_each_sta(phy->mt76, i, tm_sta) {
++			if (!tm_sta->tx_skb)
++				return false;
++
++			info = IEEE80211_SKB_CB(tm_sta->tx_skb);
++			info->control.vif = phy->monitor_vif;
++		}
++	}
++
++	return true;
++}
++
+ 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;
+-	u8 duty_cycle = td->tx_duty_cycle;
+-	u32 tx_time = td->tx_time;
+-	u32 ipg = td->tx_ipg;
+ 
+ 	mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, false);
+-	mt7915_tm_clean_hwq(phy, dev->mt76.global_wcid.idx);
++	mt7915_tm_set_trx(phy, TM_MAC_TX, false);
+ 
+ 	if (en) {
++		u32 tx_time = td->tx_time, ipg = td->tx_ipg;
++		u8 duty_cycle = td->tx_duty_cycle;
++
+ 		mt7915_tm_update_channel(phy);
+ 
+ 		if (td->tx_spe_idx) {
+@@ -586,30 +711,29 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
+ 		} else {
+ 			phy->test.spe_idx = spe_idx_map[td->tx_antenna_mask];
+ 		}
+-	}
+ 
+-	mt7915_tm_set_tam_arb(phy, en,
+-			      td->tx_rate_mode == MT76_TM_TX_MODE_HE_MU);
+-
+-	/* if all three params are set, duty_cycle will be ignored */
+-	if (duty_cycle && tx_time && !ipg) {
+-		ipg = tx_time * 100 / duty_cycle - tx_time;
+-	} else if (duty_cycle && !tx_time && ipg) {
+-		if (duty_cycle < 100)
+-			tx_time = duty_cycle * ipg / (100 - duty_cycle);
+-	}
++		/* if all three params are set, duty_cycle will be ignored */
++		if (duty_cycle && tx_time && !ipg) {
++			ipg = tx_time * 100 / duty_cycle - tx_time;
++		} else if (duty_cycle && !tx_time && ipg) {
++			if (duty_cycle < 100)
++				tx_time = duty_cycle * ipg / (100 - duty_cycle);
++		}
+ 
+-	mt7915_tm_set_ipg_params(phy, ipg, td->tx_rate_mode);
+-	mt7915_tm_set_tx_len(phy, tx_time);
++		mt7915_tm_set_ipg_params(phy, ipg, td->tx_rate_mode);
++		mt7915_tm_set_tx_len(phy, tx_time);
+ 
+-	if (ipg)
+-		td->tx_queued_limit = MT76_TM_TIMEOUT * 1000000 / ipg / 2;
++		if (ipg)
++			td->tx_queued_limit = MT76_TM_TIMEOUT * 1000000 / ipg / 2;
+ 
+-	if (!en || !td->tx_skb)
+-		return;
++		if (!mt7915_tm_check_skb(phy))
++			return;
++	} else {
++		mt7915_tm_clean_hwq(phy);
++	}
+ 
+-	info = IEEE80211_SKB_CB(td->tx_skb);
+-	info->control.vif = phy->monitor_vif;
++	mt7915_tm_set_tam_arb(phy, en,
++			      td->tx_rate_mode == MT76_TM_TX_MODE_HE_MU);
+ 
+ 	mt7915_tm_set_trx(phy, TM_MAC_TX, en);
+ }
+@@ -811,6 +935,31 @@ out:
+ 				 sizeof(req), true);
+ }
+ 
++static void
++mt7915_tm_init(struct mt7915_phy *phy, bool en)
++{
++	struct mt7915_dev *dev = phy->dev;
++
++	if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state))
++		return;
++
++	mt7915_mcu_set_sku_en(phy, !en);
++
++	mt7915_tm_mode_ctrl(dev, en);
++	mt7915_tm_reg_backup_restore(phy);
++	mt7915_tm_set_trx(phy, TM_MAC_TXRX, !en);
++
++	mt7915_mcu_add_bss_info(phy, phy->monitor_vif, en);
++	mt7915_mcu_add_sta(dev, phy->monitor_vif, NULL, en);
++
++	phy->mt76->test.flag |= MT_TM_FW_RX_COUNT;
++
++	if (!en) {
++		mt7915_tm_set_tam_arb(phy, en, 0);
++		mt7915_tm_sta_remove_all(phy);
++	}
++}
++
+ static void
+ mt7915_tm_update_params(struct mt7915_phy *phy, u32 changed)
+ {
+@@ -825,6 +974,8 @@ mt7915_tm_update_params(struct mt7915_phy *phy, u32 changed)
+ 		mt7915_tm_set_cfg(phy);
+ 	if (changed & BIT(TM_CHANGED_OFF_CH_SCAN_CH))
+ 		mt7915_tm_set_off_channel_scan(phy);
++	if (changed & BIT(TM_CHANGED_AID))
++		mt7915_tm_set_sta(phy);
+ }
+ 
+ static int
+-- 
+2.25.1
+