blob: dcf7db6fc52589b17b43e10f39b9ae44e87db581 [file] [log] [blame]
developer5f11e9e2022-03-10 15:03:47 +08001diff --git a/package/kernel/mt76/patches/1006-mt76-mt7915-testmode-patches.patch b/package/kernel/mt76/patches/1006-mt76-mt7915-testmode-patches.patch
2new file mode 100644
3index 00000000..002d1fcb
4--- /dev/null
5+++ b/package/kernel/mt76/patches/1006-mt76-mt7915-testmode-patches.patch
6@@ -0,0 +1,2014 @@
7+From cdb7bc7976835e2b96ae5f19392a793d1895fd4f Mon Sep 17 00:00:00 2001
8+From: Shayne Chen <shayne.chen@mediatek.com>
9+Date: Wed, 19 Jan 2022 15:46:06 +0800
10+Subject: [PATCH 1006/1006] mt76: mt7915: testmode patches
11+
12+---
13+ drivers/net/wireless/mediatek/mt76/mac80211.c | 18 +-
14+ drivers/net/wireless/mediatek/mt76/mt76.h | 123 ++++-
15+ .../wireless/mediatek/mt76/mt76_connac_mcu.c | 5 +
16+ .../wireless/mediatek/mt76/mt76_connac_mcu.h | 1 +
17+ .../net/wireless/mediatek/mt76/mt7915/init.c | 2 +-
18+ .../net/wireless/mediatek/mt76/mt7915/mac.c | 26 +-
19+ .../net/wireless/mediatek/mt76/mt7915/mcu.c | 13 +-
20+ .../net/wireless/mediatek/mt76/mt7915/mcu.h | 5 +
21+ .../net/wireless/mediatek/mt76/mt7915/mmio.c | 2 +
22+ .../wireless/mediatek/mt76/mt7915/mt7915.h | 2 +-
23+ .../net/wireless/mediatek/mt76/mt7915/regs.h | 16 +-
24+ .../wireless/mediatek/mt76/mt7915/testmode.c | 513 +++++++++++++++---
25+ .../wireless/mediatek/mt76/mt7915/testmode.h | 38 ++
26+ drivers/net/wireless/mediatek/mt76/testmode.c | 276 ++++++++--
27+ drivers/net/wireless/mediatek/mt76/testmode.h | 71 +++
28+ .../net/wireless/mediatek/mt76/tools/fields.c | 76 +++
29+ drivers/net/wireless/mediatek/mt76/tx.c | 3 +-
30+ 17 files changed, 1048 insertions(+), 142 deletions(-)
31+
32+diff --git a/mac80211.c b/mac80211.c
33+index 9796419..e473227 100644
34+--- a/mac80211.c
35++++ b/mac80211.c
36+@@ -45,6 +45,9 @@ static const struct ieee80211_channel mt76_channels_2ghz[] = {
37+ };
38+
39+ static const struct ieee80211_channel mt76_channels_5ghz[] = {
40++ CHAN5G(12, 5060),
41++ CHAN5G(16, 5080),
42++
43+ CHAN5G(36, 5180),
44+ CHAN5G(40, 5200),
45+ CHAN5G(44, 5220),
46+@@ -55,6 +58,13 @@ static const struct ieee80211_channel mt76_channels_5ghz[] = {
47+ CHAN5G(60, 5300),
48+ CHAN5G(64, 5320),
49+
50++ CHAN5G(68, 5340),
51++ CHAN5G(80, 5400),
52++ CHAN5G(84, 5420),
53++ CHAN5G(88, 5440),
54++ CHAN5G(92, 5460),
55++ CHAN5G(96, 5480),
56++
57+ CHAN5G(100, 5500),
58+ CHAN5G(104, 5520),
59+ CHAN5G(108, 5540),
60+@@ -75,6 +85,11 @@ static const struct ieee80211_channel mt76_channels_5ghz[] = {
61+ CHAN5G(165, 5825),
62+ CHAN5G(169, 5845),
63+ CHAN5G(173, 5865),
64++
65++ CHAN5G(184, 4920),
66++ CHAN5G(188, 4940),
67++ CHAN5G(192, 4960),
68++ CHAN5G(196, 4980),
69+ };
70+
71+ static const struct ieee80211_channel mt76_channels_6ghz[] = {
72+@@ -737,7 +752,8 @@ void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb)
73+ }
74+
75+ #ifdef CONFIG_NL80211_TESTMODE
76+- if (phy->test.state == MT76_TM_STATE_RX_FRAMES) {
77++ if (!(phy->test.flag & MT_TM_FW_RX_COUNT) &&
78++ phy->test.state == MT76_TM_STATE_RX_FRAMES) {
79+ phy->test.rx_stats.packets[q]++;
80+ if (status->flag & RX_FLAG_FAILED_FCS_CRC)
81+ phy->test.rx_stats.fcs_error[q]++;
82+diff --git a/mt76.h b/mt76.h
83+index 5e10fe1..4b502c6 100644
84+--- a/mt76.h
85++++ b/mt76.h
86+@@ -581,6 +581,25 @@ struct mt76_testmode_ops {
87+ int (*set_params)(struct mt76_phy *phy, struct nlattr **tb,
88+ enum mt76_testmode_state new_state);
89+ int (*dump_stats)(struct mt76_phy *phy, struct sk_buff *msg);
90++ int (*set_eeprom)(struct mt76_phy *phy, u32 offset, u8 *val, u8 action);
91++};
92++
93++#define MT_TM_FW_RX_COUNT BIT(0)
94++
95++struct mt76_testmode_sta_data {
96++ u16 tx_mpdu_len;
97++ u8 tx_rate_idx;
98++ u8 tx_rate_nss;
99++ u8 tx_rate_ldpc;
100++
101++ u8 aid;
102++ u8 ru_alloc;
103++ u8 ru_idx;
104++};
105++
106++struct mt76_testmode_sta {
107++ struct sk_buff *tx_skb;
108++ struct mt76_testmode_sta_data sd;
109+ };
110+
111+ struct mt76_testmode_data {
112+@@ -590,13 +609,9 @@ struct mt76_testmode_data {
113+ struct sk_buff *tx_skb;
114+
115+ u32 tx_count;
116+- u16 tx_mpdu_len;
117+
118+ u8 tx_rate_mode;
119+- u8 tx_rate_idx;
120+- u8 tx_rate_nss;
121+ u8 tx_rate_sgi;
122+- u8 tx_rate_ldpc;
123+ u8 tx_rate_stbc;
124+ u8 tx_ltf;
125+
126+@@ -614,6 +629,35 @@ struct mt76_testmode_data {
127+
128+ u8 addr[3][ETH_ALEN];
129+
130++ u8 flag;
131++
132++ struct {
133++ u8 type;
134++ u8 enable;
135++ } cfg;
136++
137++ u8 off_ch_scan_ch;
138++ u8 off_ch_scan_center_ch;
139++ u8 off_ch_scan_bw;
140++ u8 off_ch_scan_path;
141++
142++ struct mt76_wcid *tm_wcid[MT76_TM_MAX_STA_NUM + 1];
143++ u8 cur_aid;
144++ u16 tm_sta_mask;
145++ union {
146++ struct mt76_testmode_sta_data sd;
147++ struct {
148++ u16 tx_mpdu_len;
149++ u8 tx_rate_idx;
150++ u8 tx_rate_nss;
151++ u8 tx_rate_ldpc;
152++
153++ u8 aid;
154++ u8 ru_alloc;
155++ u8 ru_idx;
156++ };
157++ };
158++
159+ u32 tx_pending;
160+ u32 tx_queued;
161+ u16 tx_queued_limit;
162+@@ -621,6 +665,7 @@ struct mt76_testmode_data {
163+ struct {
164+ u64 packets[__MT_RXQ_MAX];
165+ u64 fcs_error[__MT_RXQ_MAX];
166++ u64 len_mismatch;
167+ } rx_stats;
168+ };
169+
170+@@ -1091,22 +1136,69 @@ static inline bool mt76_testmode_enabled(struct mt76_phy *phy)
171+ #endif
172+ }
173+
174++#ifdef CONFIG_NL80211_TESTMODE
175++static inline bool
176++mt76_testmode_has_sta(struct mt76_phy *phy)
177++{
178++ return phy->test.tm_sta_mask != 0;
179++}
180++
181++static inline struct mt76_testmode_sta *
182++mt76_testmode_aid_get_sta(struct mt76_phy *phy, u8 aid)
183++{
184++ struct mt76_wcid *wcid = phy->test.tm_wcid[aid];
185++
186++ if (!wcid || !aid)
187++ return NULL;
188++
189++ return (struct mt76_testmode_sta *)((u8 *)wcid + phy->hw->sta_data_size);
190++}
191++
192++#define mt76_testmode_for_each_sta(phy, aid, tm_sta) \
193++ for (aid = 1, tm_sta = mt76_testmode_aid_get_sta(phy, 1); \
194++ aid <= hweight16(phy->test.tm_sta_mask); \
195++ aid = phy->test.tm_sta_mask >> aid ? \
196++ ffs(phy->test.tm_sta_mask >> aid) + aid : \
197++ aid + 1, \
198++ tm_sta = mt76_testmode_aid_get_sta(phy, aid))
199++
200++static inline bool
201++__mt76_testmode_check_skb(struct mt76_phy *phy, struct sk_buff *skb)
202++{
203++ struct mt76_testmode_sta *tm_sta;
204++ int i;
205++
206++ if (!mt76_testmode_has_sta(phy))
207++ return false;
208++
209++ mt76_testmode_for_each_sta(phy, i, tm_sta) {
210++ if (tm_sta->tx_skb == skb)
211++ return true;
212++ }
213++
214++ return false;
215++}
216++
217+ static inline bool mt76_is_testmode_skb(struct mt76_dev *dev,
218+ struct sk_buff *skb,
219+ struct ieee80211_hw **hw)
220+ {
221+-#ifdef CONFIG_NL80211_TESTMODE
222+- if (skb == dev->phy.test.tx_skb)
223+- *hw = dev->phy.hw;
224+- else if (dev->phy2 && skb == dev->phy2->test.tx_skb)
225+- *hw = dev->phy2->hw;
226+- else
227+- return false;
228+- return true;
229+-#else
230++ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
231++ struct mt76_phy *phy = &dev->phy;
232++
233++ if ((info->hw_queue & MT_TX_HW_QUEUE_EXT_PHY) && dev->phy2)
234++ phy = dev->phy2;
235++
236++ if (mt76_testmode_enabled(phy) &&
237++ (skb == phy->test.tx_skb ||
238++ __mt76_testmode_check_skb(phy, skb))) {
239++ *hw = phy->hw;
240++ return true;
241++ }
242++
243+ return false;
244+-#endif
245+ }
246++#endif
247+
248+ void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb);
249+ void mt76_tx(struct mt76_phy *dev, struct ieee80211_sta *sta,
250+@@ -1198,7 +1290,7 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
251+ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
252+ struct netlink_callback *cb, void *data, int len);
253+ int mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state);
254+-int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len);
255++int mt76_testmode_init_skb(struct mt76_phy *phy, u32 len, u8 aid, struct sk_buff **skb);
256+
257+ static inline void mt76_testmode_reset(struct mt76_phy *phy, bool disable)
258+ {
259+@@ -1212,7 +1304,6 @@ static inline void mt76_testmode_reset(struct mt76_phy *phy, bool disable)
260+ #endif
261+ }
262+
263+-
264+ /* internal */
265+ static inline struct ieee80211_hw *
266+ mt76_tx_status_get_hw(struct mt76_dev *dev, struct sk_buff *skb)
267+diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
268+index 0a646ae..9158329 100644
269+--- a/mt76_connac_mcu.c
270++++ b/mt76_connac_mcu.c
271+@@ -389,6 +389,7 @@ void mt76_connac_mcu_sta_basic_tlv(struct sk_buff *skb,
272+ switch (vif->type) {
273+ case NL80211_IFTYPE_MESH_POINT:
274+ case NL80211_IFTYPE_AP:
275++ case NL80211_IFTYPE_MONITOR:
276+ if (vif->p2p)
277+ conn_type = CONNECTION_P2P_GC;
278+ else
279+@@ -577,6 +578,10 @@ void mt76_connac_mcu_wtbl_generic_tlv(struct mt76_dev *dev,
280+ wtbl_tlv, sta_wtbl);
281+ spe = (struct wtbl_spe *)tlv;
282+ spe->spe_idx = 24;
283++
284++ /* check */
285++ if (vif->type == NL80211_IFTYPE_MONITOR)
286++ rx->rca1 = 0;
287+ }
288+ EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_generic_tlv);
289+
290+diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
291+index 8903e08..cb7d096 100644
292+--- a/mt76_connac_mcu.h
293++++ b/mt76_connac_mcu.h
294+@@ -987,6 +987,7 @@ enum {
295+ MCU_EXT_CMD_OFFCH_SCAN_CTRL = 0x9a,
296+ MCU_EXT_CMD_SET_RDD_TH = 0x9d,
297+ MCU_EXT_CMD_MURU_CTRL = 0x9f,
298++ MCU_EXT_CMD_RX_STAT = 0xa4,
299+ MCU_EXT_CMD_SET_SPR = 0xa8,
300+ MCU_EXT_CMD_GROUP_PRE_CAL_INFO = 0xab,
301+ MCU_EXT_CMD_DPD_PRE_CAL_INFO = 0xac,
302+diff --git a/mt7915/init.c b/mt7915/init.c
303+index aed4731..7ec48e0 100644
304+--- a/mt7915/init.c
305++++ b/mt7915/init.c
306+@@ -568,7 +568,7 @@ static void mt7915_init_work(struct work_struct *work)
307+ struct mt7915_dev *dev = container_of(work, struct mt7915_dev,
308+ init_work);
309+
310+- mt7915_mcu_set_eeprom(dev);
311++ mt7915_mcu_set_eeprom(dev, dev->flash_mode);
312+ mt7915_mac_init(dev);
313+ mt7915_init_txpower(dev, &dev->mphy.sband_2g.sband);
314+ mt7915_init_txpower(dev, &dev->mphy.sband_5g.sband);
315+diff --git a/mt7915/mac.c b/mt7915/mac.c
316+index efdc1b1..9a5bb20 100644
317+--- a/mt7915/mac.c
318++++ b/mt7915/mac.c
319+@@ -904,16 +904,28 @@ mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi,
320+ {
321+ #ifdef CONFIG_NL80211_TESTMODE
322+ struct mt76_testmode_data *td = &phy->mt76->test;
323++ struct mt76_testmode_sta_data *sd = &td->sd;
324+ const struct ieee80211_rate *r;
325+- u8 bw, mode, nss = td->tx_rate_nss;
326+- u8 rate_idx = td->tx_rate_idx;
327++ u8 bw, mode, nss, rate_idx;
328+ u16 rateval = 0;
329+ u32 val;
330+ bool cck = false;
331+ int band;
332+
333+- if (skb != phy->mt76->test.tx_skb)
334+- return;
335++ if (mt76_testmode_has_sta(phy->mt76)) {
336++ struct mt76_testmode_sta *tm_sta;
337++ int i;
338++
339++ mt76_testmode_for_each_sta(phy->mt76, i, tm_sta) {
340++ if (tm_sta->tx_skb == skb) {
341++ sd = &tm_sta->sd;
342++ break;
343++ }
344++ }
345++ }
346++
347++ nss = sd->tx_rate_nss;
348++ rate_idx = sd->tx_rate_idx;
349+
350+ switch (td->tx_rate_mode) {
351+ case MT76_TM_TX_MODE_HT:
352+@@ -1003,9 +1015,10 @@ mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi,
353+ if (mode >= MT_PHY_TYPE_HE_SU)
354+ val |= FIELD_PREP(MT_TXD6_HELTF, td->tx_ltf);
355+
356+- if (td->tx_rate_ldpc || (bw > 0 && mode >= MT_PHY_TYPE_HE_SU))
357++ if (sd->tx_rate_ldpc || (bw > 0 && mode >= MT_PHY_TYPE_HE_SU))
358+ val |= MT_TXD6_LDPC;
359+
360++ txwi[1] &= ~cpu_to_le32(MT_TXD1_VTA);
361+ txwi[3] &= ~cpu_to_le32(MT_TXD3_SN_VALID);
362+ txwi[6] |= cpu_to_le32(val);
363+ txwi[7] |= cpu_to_le32(FIELD_PREP(MT_TXD7_SPE_IDX,
364+@@ -1472,6 +1485,9 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
365+ continue;
366+
367+ msta = container_of(wcid, struct mt7915_sta, wcid);
368++ if (mt76_testmode_enabled(msta->vif->phy->mt76))
369++ continue;
370++
371+ spin_lock_bh(&dev->sta_poll_lock);
372+ if (list_empty(&msta->poll_list))
373+ list_add_tail(&msta->poll_list, &dev->sta_poll_list);
374+diff --git a/mt7915/mcu.c b/mt7915/mcu.c
375+index bb77edc..29ba3ed 100644
376+--- a/mt7915/mcu.c
377++++ b/mt7915/mcu.c
378+@@ -289,7 +289,6 @@ mt7915_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
379+ if (mcu_txd->ext_cid) {
380+ mcu_txd->ext_cid_ack = 1;
381+
382+- /* do not use Q_SET for efuse */
383+ if (cmd & __MCU_CMD_FIELD_QUERY)
384+ mcu_txd->set_query = MCU_Q_QUERY;
385+ else
386+@@ -2784,7 +2783,6 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
387+ struct mt7915_dev *dev = phy->dev;
388+ struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
389+ int freq1 = chandef->center_freq1;
390+- bool ext_phy = phy != &dev->phy;
391+ struct {
392+ u8 control_ch;
393+ u8 center_ch;
394+@@ -2814,14 +2812,9 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
395+
396+ #ifdef CONFIG_NL80211_TESTMODE
397+ if (phy->mt76->test.tx_antenna_mask &&
398+- (phy->mt76->test.state == MT76_TM_STATE_TX_FRAMES ||
399+- phy->mt76->test.state == MT76_TM_STATE_RX_FRAMES ||
400+- phy->mt76->test.state == MT76_TM_STATE_TX_CONT)) {
401++ mt76_testmode_enabled(phy->mt76)) {
402+ req.tx_streams_num = fls(phy->mt76->test.tx_antenna_mask);
403+ req.rx_streams = phy->mt76->test.tx_antenna_mask;
404+-
405+- if (ext_phy)
406+- req.rx_streams >>= dev->chainshift;
407+ }
408+ #endif
409+
410+@@ -2887,14 +2880,14 @@ static int mt7915_mcu_set_eeprom_flash(struct mt7915_dev *dev)
411+ return 0;
412+ }
413+
414+-int mt7915_mcu_set_eeprom(struct mt7915_dev *dev)
415++int mt7915_mcu_set_eeprom(struct mt7915_dev *dev, bool flash_mode)
416+ {
417+ struct mt7915_mcu_eeprom req = {
418+ .buffer_mode = EE_MODE_EFUSE,
419+ .format = EE_FORMAT_WHOLE,
420+ };
421+
422+- if (dev->flash_mode)
423++ if (flash_mode)
424+ return mt7915_mcu_set_eeprom_flash(dev);
425+
426+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(EFUSE_BUFFER_MODE),
427+diff --git a/mt7915/mcu.h b/mt7915/mcu.h
428+index 30211cb..4b78468 100644
429+--- a/mt7915/mcu.h
430++++ b/mt7915/mcu.h
431+@@ -27,7 +27,12 @@ struct mt7915_mcu_txd {
432+
433+ enum {
434+ MCU_ATE_SET_TRX = 0x1,
435++ MCU_ATE_SET_TSSI = 0x5,
436++ MCU_ATE_SET_DPD = 0x6,
437++ MCU_ATE_SET_RATE_POWER_OFFSET = 0x7,
438++ MCU_ATE_SET_THERMAL_COMP = 0x8,
439+ MCU_ATE_SET_FREQ_OFFSET = 0xa,
440++ MCU_ATE_SET_PHY_COUNT = 0x11,
441+ MCU_ATE_SET_SLOT_TIME = 0x13,
442+ MCU_ATE_CLEAN_TXQUEUE = 0x1c,
443+ };
444+diff --git a/mt7915/mmio.c b/mt7915/mmio.c
445+index 1b14bba..207941d 100644
446+--- a/mt7915/mmio.c
447++++ b/mt7915/mmio.c
448+@@ -53,6 +53,7 @@ static const u32 mt7986_reg[] = {
449+ };
450+
451+ static const u32 mt7915_offs[] = {
452++ [TMAC_TCR2] = 0x05c,
453+ [TMAC_CDTR] = 0x090,
454+ [TMAC_ODTR] = 0x094,
455+ [TMAC_ATCR] = 0x098,
456+@@ -125,6 +126,7 @@ static const u32 mt7915_offs[] = {
457+ };
458+
459+ static const u32 mt7916_offs[] = {
460++ [TMAC_TCR2] = 0x004,
461+ [TMAC_CDTR] = 0x0c8,
462+ [TMAC_ODTR] = 0x0cc,
463+ [TMAC_ATCR] = 0x00c,
464+diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
465+index b3abe77..db4c6bc 100644
466+--- a/mt7915/mt7915.h
467++++ b/mt7915/mt7915.h
468+@@ -539,7 +539,7 @@ int mt7915_mcu_set_fixed_rate_ctrl(struct mt7915_dev *dev,
469+ struct ieee80211_vif *vif,
470+ struct ieee80211_sta *sta,
471+ void *data, u32 field);
472+-int mt7915_mcu_set_eeprom(struct mt7915_dev *dev);
473++int mt7915_mcu_set_eeprom(struct mt7915_dev *dev, bool flash_mode);
474+ int mt7915_mcu_get_eeprom(struct mt7915_dev *dev, u32 offset);
475+ int mt7915_mcu_get_eeprom_free_block(struct mt7915_dev *dev, u8 *block_num);
476+ int mt7915_mcu_set_mac(struct mt7915_dev *dev, int band, bool enable,
477+diff --git a/mt7915/regs.h b/mt7915/regs.h
478+index 71f325a..dcfb3f8 100644
479+--- a/mt7915/regs.h
480++++ b/mt7915/regs.h
481+@@ -34,6 +34,7 @@ enum reg_rev {
482+ };
483+
484+ enum offs_rev {
485++ TMAC_TCR2,
486+ TMAC_CDTR,
487+ TMAC_ODTR,
488+ TMAC_ATCR,
489+@@ -171,6 +172,12 @@ enum offs_rev {
490+ #define MT_MDP_TO_HIF 0
491+ #define MT_MDP_TO_WM 1
492+
493++#define MT_MDP_TOP_DBG_WDT_CTRL MT_MDP(0x0d0)
494++#define MT_MDP_TOP_DBG_WDT_CTRL_TDP_DIS_BLK BIT(7)
495++
496++#define MT_MDP_TOP_DBG_CTRL MT_MDP(0x0dc)
497++#define MT_MDP_TOP_DBG_CTRL_ENQ_MODE BIT(30)
498++
499+ /* TMAC: band 0(0x820e4000), band 1(0x820f4000) */
500+ #define MT_WF_TMAC_BASE(_band) ((_band) ? 0x820f4000 : 0x820e4000)
501+ #define MT_WF_TMAC(_band, ofs) (MT_WF_TMAC_BASE(_band) + (ofs))
502+@@ -179,6 +186,9 @@ enum offs_rev {
503+ #define MT_TMAC_TCR0_TX_BLINK GENMASK(7, 6)
504+ #define MT_TMAC_TCR0_TBTT_STOP_CTRL BIT(25)
505+
506++#define MT_TMAC_TCR2(_band) MT_WF_TMAC(_band, __OFFS(TMAC_TCR2))
507++#define MT_TMAC_TCR2_SCH_DET_DIS BIT(19)
508++
509+ #define MT_TMAC_CDTR(_band) MT_WF_TMAC(_band, __OFFS(TMAC_CDTR))
510+ #define MT_TMAC_ODTR(_band) MT_WF_TMAC(_band, __OFFS(TMAC_ODTR))
511+ #define MT_TIMEOUT_VAL_PLCP GENMASK(15, 0)
512+@@ -437,8 +447,10 @@ enum offs_rev {
513+ #define MT_AGG_PCR0_VHT_PROT BIT(13)
514+ #define MT_AGG_PCR0_PTA_WIN_DIS BIT(15)
515+
516+-#define MT_AGG_PCR1_RTS0_NUM_THRES GENMASK(31, 23)
517+-#define MT_AGG_PCR1_RTS0_LEN_THRES GENMASK(19, 0)
518++#define MT_AGG_PCR1_RTS0_NUM_THRES GENMASK(31, 23)
519++#define MT_AGG_PCR1_RTS0_LEN_THRES GENMASK(19, 0)
520++#define MT_AGG_PCR1_RTS0_NUM_THRES_MT7916 GENMASK(29, 24)
521++#define MT_AGG_PCR1_RTS0_LEN_THRES_MT7916 GENMASK(22, 0)
522+
523+ #define MT_AGG_ACR0(_band) MT_WF_AGG(_band, __OFFS(AGG_ACR0))
524+ #define MT_AGG_ACR_CFEND_RATE GENMASK(13, 0)
525+diff --git a/mt7915/testmode.c b/mt7915/testmode.c
526+index 6605e24..9f13919 100644
527+--- a/mt7915/testmode.c
528++++ b/mt7915/testmode.c
529+@@ -9,6 +9,9 @@
530+ enum {
531+ TM_CHANGED_TXPOWER,
532+ TM_CHANGED_FREQ_OFFSET,
533++ TM_CHANGED_CFG,
534++ TM_CHANGED_OFF_CH_SCAN_CH,
535++ TM_CHANGED_AID,
536+
537+ /* must be last */
538+ NUM_TM_CHANGED
539+@@ -17,6 +20,9 @@ enum {
540+ static const u8 tm_change_map[] = {
541+ [TM_CHANGED_TXPOWER] = MT76_TM_ATTR_TX_POWER,
542+ [TM_CHANGED_FREQ_OFFSET] = MT76_TM_ATTR_FREQ_OFFSET,
543++ [TM_CHANGED_CFG] = MT76_TM_ATTR_CFG,
544++ [TM_CHANGED_OFF_CH_SCAN_CH] = MT76_TM_ATTR_OFF_CH_SCAN_CH,
545++ [TM_CHANGED_AID] = MT76_TM_ATTR_AID,
546+ };
547+
548+ struct reg_band {
549+@@ -30,10 +36,29 @@ struct reg_band {
550+ { _list.band[0] = MT_##_reg(0, _idx); \
551+ _list.band[1] = MT_##_reg(1, _idx); }
552+
553+-#define TM_REG_MAX_ID 17
554++#define TM_REG_MAX_ID 20
555+ static struct reg_band reg_backup_list[TM_REG_MAX_ID];
556+
557+
558++static u8 mt7915_tm_chan_bw(enum nl80211_chan_width width)
559++{
560++ static const u8 width_to_bw[] = {
561++ [NL80211_CHAN_WIDTH_40] = TM_CBW_40MHZ,
562++ [NL80211_CHAN_WIDTH_80] = TM_CBW_80MHZ,
563++ [NL80211_CHAN_WIDTH_80P80] = TM_CBW_8080MHZ,
564++ [NL80211_CHAN_WIDTH_160] = TM_CBW_160MHZ,
565++ [NL80211_CHAN_WIDTH_5] = TM_CBW_5MHZ,
566++ [NL80211_CHAN_WIDTH_10] = TM_CBW_10MHZ,
567++ [NL80211_CHAN_WIDTH_20] = TM_CBW_20MHZ,
568++ [NL80211_CHAN_WIDTH_20_NOHT] = TM_CBW_20MHZ,
569++ };
570++
571++ if (width >= ARRAY_SIZE(width_to_bw))
572++ return 0;
573++
574++ return width_to_bw[width];
575++}
576++
577+ static int
578+ mt7915_tm_set_tx_power(struct mt7915_phy *phy)
579+ {
580+@@ -119,15 +144,45 @@ mt7915_tm_set_trx(struct mt7915_phy *phy, int type, bool en)
581+ }
582+
583+ static int
584+-mt7915_tm_clean_hwq(struct mt7915_phy *phy, u8 wcid)
585++mt7915_tm_clean_hwq(struct mt7915_phy *phy)
586+ {
587+ struct mt7915_dev *dev = phy->dev;
588+ struct mt7915_tm_cmd req = {
589+ .testmode_en = 1,
590+ .param_idx = MCU_ATE_CLEAN_TXQUEUE,
591+- .param.clean.wcid = wcid,
592+ .param.clean.band = phy != &dev->phy,
593+ };
594++ struct mt76_testmode_sta *tm_sta;
595++ int ret, i;
596++
597++ if (!mt76_testmode_has_sta(phy->mt76)) {
598++ req.param.clean.wcid = dev->mt76.global_wcid.idx;
599++
600++ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(ATE_CTRL),
601++ &req, sizeof(req), false);
602++ }
603++
604++ mt76_testmode_for_each_sta(phy->mt76, i, tm_sta) {
605++ req.param.clean.wcid = phy->mt76->test.tm_wcid[i]->idx;
606++ ret = mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(ATE_CTRL),
607++ &req, sizeof(req), false);
608++ if (ret)
609++ return ret;
610++ }
611++
612++ return 0;
613++}
614++
615++static int
616++mt7915_tm_set_phy_count(struct mt7915_phy *phy, u8 control)
617++{
618++ struct mt7915_dev *dev = phy->dev;
619++ struct mt7915_tm_cmd req = {
620++ .testmode_en = 1,
621++ .param_idx = MCU_ATE_SET_PHY_COUNT,
622++ .param.cfg.enable = control,
623++ .param.cfg.band = phy != &dev->phy,
624++ };
625+
626+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(ATE_CTRL), &req,
627+ sizeof(req), false);
628+@@ -167,6 +222,77 @@ mt7915_tm_set_tam_arb(struct mt7915_phy *phy, bool enable, bool mu)
629+ return mt7915_mcu_set_muru_ctrl(dev, MURU_SET_ARB_OP_MODE, op_mode);
630+ }
631+
632++static int
633++mt7915_tm_set_cfg(struct mt7915_phy *phy)
634++{
635++ static const u8 cfg_cmd[] = {
636++ [MT76_TM_CFG_TSSI] = MCU_ATE_SET_TSSI,
637++ [MT76_TM_CFG_DPD] = MCU_ATE_SET_DPD,
638++ [MT76_TM_CFG_RATE_POWER_OFFSET] = MCU_ATE_SET_RATE_POWER_OFFSET,
639++ [MT76_TM_CFG_THERMAL_COMP] = MCU_ATE_SET_THERMAL_COMP,
640++ };
641++ struct mt76_testmode_data *td = &phy->mt76->test;
642++ struct mt7915_dev *dev = phy->dev;
643++ struct mt7915_tm_cmd req = {
644++ .testmode_en = !(phy->mt76->test.state == MT76_TM_STATE_OFF),
645++ .param_idx = cfg_cmd[td->cfg.type],
646++ .param.cfg.enable = td->cfg.enable,
647++ .param.cfg.band = phy != &dev->phy,
648++ };
649++
650++ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(ATE_CTRL), &req,
651++ sizeof(req), false);
652++}
653++
654++static int
655++mt7915_tm_set_off_channel_scan(struct mt7915_phy *phy)
656++{
657++#define OFF_CH_SCAN_SIMPLE_RX 2
658++ struct mt76_testmode_data *td = &phy->mt76->test;
659++ struct mt7915_dev *dev = phy->dev;
660++ struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
661++ int freq1 = chandef->center_freq1;
662++ struct {
663++ u8 cur_pri_ch;
664++ u8 cur_center_ch;
665++ u8 cur_bw;
666++ u8 cur_tx_path;
667++ u8 cur_rx_path;
668++
669++ u8 scan_pri_ch;
670++ u8 scan_center_ch;
671++ u8 scan_bw;
672++ u8 scan_tx_path;
673++ u8 scan_rx_path;
674++
675++ u8 enable;
676++ u8 band_idx;
677++ u8 type;
678++ u8 is_5g;
679++ u8 _rsv[2];
680++ } __packed req = {
681++ .cur_pri_ch = chandef->chan->hw_value,
682++ .cur_center_ch = ieee80211_frequency_to_channel(freq1),
683++ .cur_bw = mt7915_tm_chan_bw(chandef->width),
684++ .cur_tx_path = td->tx_antenna_mask,
685++ .cur_rx_path = td->tx_antenna_mask,
686++
687++ .scan_pri_ch = td->off_ch_scan_ch,
688++ .scan_center_ch = td->off_ch_scan_center_ch,
689++ .scan_bw = td->off_ch_scan_bw,
690++ .scan_tx_path = td->off_ch_scan_path,
691++ .scan_rx_path = td->off_ch_scan_path,
692++
693++ .enable = !!td->off_ch_scan_ch,
694++ .band_idx = phy != &dev->phy,
695++ .type = OFF_CH_SCAN_SIMPLE_RX,
696++ .is_5g = td->off_ch_scan_ch > 14 ? 1 : 0,
697++ };
698++
699++ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(OFFCH_SCAN_CTRL), &req,
700++ sizeof(req), false);
701++}
702++
703+ static int
704+ mt7915_tm_set_wmm_qid(struct mt7915_dev *dev, u8 qid, u8 aifs, u8 cw_min,
705+ u16 cw_max, u16 txop)
706+@@ -320,7 +446,7 @@ mt7915_tm_set_tx_len(struct mt7915_phy *phy, u32 tx_time)
707+ bitrate = cfg80211_calculate_bitrate(&rate);
708+ tx_len = bitrate * tx_time / 10 / 8;
709+
710+- ret = mt76_testmode_alloc_skb(phy->mt76, tx_len);
711++ ret = mt76_testmode_init_skb(phy->mt76, tx_len, 0, &td->tx_skb);
712+ if (ret)
713+ return ret;
714+
715+@@ -332,7 +458,7 @@ mt7915_tm_reg_backup_restore(struct mt7915_phy *phy)
716+ {
717+ int n_regs = ARRAY_SIZE(reg_backup_list);
718+ struct mt7915_dev *dev = phy->dev;
719+- u32 *b = phy->test.reg_backup;
720++ u32 *b = phy->test.reg_backup, val;
721+ int i;
722+
723+ REG_BAND_IDX(reg_backup_list[0], AGG_PCR0, 0);
724+@@ -344,18 +470,28 @@ mt7915_tm_reg_backup_restore(struct mt7915_phy *phy)
725+ REG_BAND(reg_backup_list[6], AGG_MRCR);
726+ REG_BAND(reg_backup_list[7], TMAC_TFCR0);
727+ REG_BAND(reg_backup_list[8], TMAC_TCR0);
728+- REG_BAND(reg_backup_list[9], AGG_ATCR1);
729+- REG_BAND(reg_backup_list[10], AGG_ATCR3);
730+- REG_BAND(reg_backup_list[11], TMAC_TRCR0);
731+- REG_BAND(reg_backup_list[12], TMAC_ICR0);
732+- REG_BAND_IDX(reg_backup_list[13], ARB_DRNGR0, 0);
733+- REG_BAND_IDX(reg_backup_list[14], ARB_DRNGR0, 1);
734+- REG_BAND(reg_backup_list[15], WF_RFCR);
735+- REG_BAND(reg_backup_list[16], WF_RFCR1);
736++ REG_BAND(reg_backup_list[9], TMAC_TCR2);
737++ REG_BAND(reg_backup_list[10], AGG_ATCR1);
738++ REG_BAND(reg_backup_list[11], AGG_ATCR3);
739++ REG_BAND(reg_backup_list[12], TMAC_TRCR0);
740++ REG_BAND(reg_backup_list[13], TMAC_ICR0);
741++ REG_BAND_IDX(reg_backup_list[14], ARB_DRNGR0, 0);
742++ REG_BAND_IDX(reg_backup_list[15], ARB_DRNGR0, 1);
743++ REG_BAND(reg_backup_list[16], WF_RFCR);
744++ REG_BAND(reg_backup_list[17], WF_RFCR1);
745++
746++ if (is_mt7916(&dev->mt76)) {
747++ reg_backup_list[18].band[phy->band_idx] = MT_MDP_TOP_DBG_WDT_CTRL;
748++ reg_backup_list[19].band[phy->band_idx] = MT_MDP_TOP_DBG_CTRL;
749++ }
750+
751+ if (phy->mt76->test.state == MT76_TM_STATE_OFF) {
752+- for (i = 0; i < n_regs; i++)
753+- mt76_wr(dev, reg_backup_list[i].band[phy->band_idx], b[i]);
754++ for (i = 0; i < n_regs; i++) {
755++ u8 reg = reg_backup_list[i].band[phy->band_idx];
756++
757++ if (reg)
758++ mt76_wr(dev, reg, b[i]);
759++ }
760+ return;
761+ }
762+
763+@@ -375,8 +511,13 @@ mt7915_tm_reg_backup_restore(struct mt7915_phy *phy)
764+ MT_AGG_PCR0_BW40_PROT | MT_AGG_PCR0_BW80_PROT);
765+ mt76_set(dev, MT_AGG_PCR0(phy->band_idx, 0), MT_AGG_PCR0_PTA_WIN_DIS);
766+
767+- mt76_wr(dev, MT_AGG_PCR0(phy->band_idx, 1), MT_AGG_PCR1_RTS0_NUM_THRES |
768+- MT_AGG_PCR1_RTS0_LEN_THRES);
769++ if (is_mt7915(&dev->mt76))
770++ val = MT_AGG_PCR1_RTS0_NUM_THRES | MT_AGG_PCR1_RTS0_LEN_THRES;
771++ else
772++ val = MT_AGG_PCR1_RTS0_NUM_THRES_MT7916 |
773++ MT_AGG_PCR1_RTS0_LEN_THRES_MT7916;
774++
775++ mt76_wr(dev, MT_AGG_PCR0(phy->band_idx, 1), val);
776+
777+ mt76_clear(dev, MT_AGG_MRCR(phy->band_idx), MT_AGG_MRCR_BAR_CNT_LIMIT |
778+ MT_AGG_MRCR_LAST_RTS_CTS_RN | MT_AGG_MRCR_RTS_FAIL_LIMIT |
779+@@ -389,31 +530,124 @@ mt7915_tm_reg_backup_restore(struct mt7915_phy *phy)
780+
781+ mt76_wr(dev, MT_TMAC_TFCR0(phy->band_idx), 0);
782+ mt76_clear(dev, MT_TMAC_TCR0(phy->band_idx), MT_TMAC_TCR0_TBTT_STOP_CTRL);
783++ mt76_set(dev, MT_TMAC_TCR2(phy->band_idx), MT_TMAC_TCR2_SCH_DET_DIS);
784+
785+ /* config rx filter for testmode rx */
786+ mt76_wr(dev, MT_WF_RFCR(phy->band_idx), 0xcf70a);
787+ mt76_wr(dev, MT_WF_RFCR1(phy->band_idx), 0);
788++
789++ if (is_mt7916(&dev->mt76)) {
790++ /* enable MDP Tx block mode */
791++ mt76_clear(dev, MT_MDP_TOP_DBG_WDT_CTRL,
792++ MT_MDP_TOP_DBG_WDT_CTRL_TDP_DIS_BLK);
793++ mt76_clear(dev, MT_MDP_TOP_DBG_CTRL,
794++ MT_MDP_TOP_DBG_CTRL_ENQ_MODE);
795++ }
796++}
797++
798++static int
799++mt7915_tm_sta_add(struct mt7915_phy *phy, u8 aid,
800++ struct mt76_testmode_sta_data *sd)
801++{
802++ struct mt76_testmode_data *td = &phy->mt76->test;
803++ struct mt76_testmode_sta *tm_sta;
804++
805++ if (!aid)
806++ return 0;
807++
808++ if (!td->tm_wcid[aid]) {
809++ struct ieee80211_vif *vif = phy->monitor_vif;
810++ struct ieee80211_sband_iftype_data *data;
811++ struct ieee80211_supported_band *sband;
812++ struct ieee80211_sta *sta;
813++ struct mt7915_sta *msta;
814++ int ret;
815++
816++ sta = kzalloc(sizeof(*sta) + phy->mt76->hw->sta_data_size +
817++ sizeof(*tm_sta), GFP_KERNEL);
818++ if (!sta)
819++ return -ENOMEM;
820++
821++ if (phy->mt76->chandef.chan->band == NL80211_BAND_5GHZ) {
822++ sband = &phy->mt76->sband_5g.sband;
823++ data = phy->iftype[NL80211_BAND_5GHZ];
824++ } else {
825++ sband = &phy->mt76->sband_2g.sband;
826++ data = phy->iftype[NL80211_BAND_2GHZ];
827++ }
828++
829++ ether_addr_copy(sta->addr, phy->mt76->macaddr);
830++ sta->addr[0] += aid * 4;
831++ memcpy(&sta->ht_cap, &sband->ht_cap, sizeof(sta->ht_cap));
832++ memcpy(&sta->vht_cap, &sband->vht_cap, sizeof(sta->vht_cap));
833++ memcpy(&sta->he_cap, &data[NL80211_IFTYPE_STATION].he_cap,
834++ sizeof(sta->he_cap));
835++ sta->aid = aid;
836++ sta->wme = 1;
837++
838++ ret = mt7915_mac_sta_add(&phy->dev->mt76, vif, sta);
839++ if (ret) {
840++ kfree(sta);
841++ return ret;
842++ }
843++
844++ msta = (struct mt7915_sta *)sta->drv_priv;
845++ td->tm_wcid[aid] = &msta->wcid;
846++ td->tm_sta_mask |= BIT(aid - 1);
847++ }
848++
849++ tm_sta = mt76_testmode_aid_get_sta(phy->mt76, aid);
850++ memcpy(&tm_sta->sd, sd, sizeof(tm_sta->sd));
851++
852++ return 0;
853+ }
854+
855+ static void
856+-mt7915_tm_init(struct mt7915_phy *phy, bool en)
857++mt7915_tm_sta_remove(struct mt7915_phy *phy, u8 aid)
858+ {
859++ struct mt76_testmode_data *td = &phy->mt76->test;
860++ struct mt76_wcid *wcid = td->tm_wcid[aid];
861+ struct mt7915_dev *dev = phy->dev;
862++ struct ieee80211_sta *sta = wcid_to_sta(wcid);
863+
864+- if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state))
865++ mt7915_mac_sta_remove(&dev->mt76, phy->monitor_vif, sta);
866++ mt76_wcid_mask_clear(dev->mt76.wcid_mask, wcid->idx);
867++
868++ kfree(sta);
869++ td->tm_wcid[aid] = NULL;
870++ td->tm_sta_mask &= ~BIT(aid - 1);
871++}
872++
873++static void
874++mt7915_tm_sta_remove_all(struct mt7915_phy *phy)
875++{
876++ int i;
877++
878++ if (!mt76_testmode_has_sta(phy->mt76))
879+ return;
880+
881+- mt7915_mcu_set_sku_en(phy, !en);
882++ for (i = 1; i < ARRAY_SIZE(phy->mt76->test.tm_wcid); i++) {
883++ if (phy->mt76->test.tm_wcid[i])
884++ mt7915_tm_sta_remove(phy, i);
885++ }
886++}
887+
888+- mt7915_tm_mode_ctrl(dev, en);
889+- mt7915_tm_reg_backup_restore(phy);
890+- mt7915_tm_set_trx(phy, TM_MAC_TXRX, !en);
891++static int
892++mt7915_tm_set_sta(struct mt7915_phy *phy)
893++{
894++ struct mt76_testmode_data *td = &phy->mt76->test;
895+
896+- mt7915_mcu_add_bss_info(phy, phy->monitor_vif, en);
897+- mt7915_mcu_add_sta(dev, phy->monitor_vif, NULL, en);
898++ if (!td->aid) {
899++ mt7915_tm_sta_remove_all(phy);
900++ return 0;
901++ }
902+
903+- if (!en)
904+- mt7915_tm_set_tam_arb(phy, en, 0);
905++ if (td->tx_count == 0) {
906++ mt7915_tm_sta_remove(phy, td->aid);
907++ return 0;
908++ }
909++
910++ return mt7915_tm_sta_add(phy, td->aid, &td->sd);
911+ }
912+
913+ static void
914+@@ -426,59 +660,122 @@ mt7915_tm_update_channel(struct mt7915_phy *phy)
915+ mt7915_mcu_set_chan_info(phy, MCU_EXT_CMD(SET_RX_PATH));
916+ }
917+
918++static bool
919++mt7915_tm_check_skb(struct mt7915_phy *phy)
920++{
921++ struct mt76_testmode_data *td = &phy->mt76->test;
922++ struct ieee80211_tx_info *info;
923++
924++ if (!mt76_testmode_has_sta(phy->mt76)) {
925++ if (!td->tx_skb)
926++ return false;
927++
928++ info = IEEE80211_SKB_CB(td->tx_skb);
929++ info->control.vif = phy->monitor_vif;
930++ } else {
931++ struct mt76_testmode_sta *tm_sta;
932++ int i;
933++
934++ mt76_testmode_for_each_sta(phy->mt76, i, tm_sta) {
935++ if (!tm_sta->tx_skb)
936++ return false;
937++
938++ info = IEEE80211_SKB_CB(tm_sta->tx_skb);
939++ info->control.vif = phy->monitor_vif;
940++ }
941++ }
942++
943++ return true;
944++}
945++
946+ static void
947+ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
948+ {
949+ static const u8 spe_idx_map[] = {0, 0, 1, 0, 3, 2, 4, 0,
950+ 9, 8, 6, 10, 16, 12, 18, 0};
951+ struct mt76_testmode_data *td = &phy->mt76->test;
952+- struct mt7915_dev *dev = phy->dev;
953+- struct ieee80211_tx_info *info;
954+- u8 duty_cycle = td->tx_duty_cycle;
955+- u32 tx_time = td->tx_time;
956+- u32 ipg = td->tx_ipg;
957+
958+ mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, false);
959+- mt7915_tm_clean_hwq(phy, dev->mt76.global_wcid.idx);
960++ mt7915_tm_set_trx(phy, TM_MAC_TX, false);
961+
962+ if (en) {
963++ u32 tx_time = td->tx_time, ipg = td->tx_ipg;
964++ u8 duty_cycle = td->tx_duty_cycle;
965++
966+ mt7915_tm_update_channel(phy);
967+
968+ if (td->tx_spe_idx) {
969+ phy->test.spe_idx = td->tx_spe_idx;
970+ } else {
971+- u8 tx_ant = td->tx_antenna_mask;
972++ phy->test.spe_idx = spe_idx_map[td->tx_antenna_mask];
973++ }
974+
975+- if (phy != &dev->phy)
976+- tx_ant >>= dev->chainshift;
977+- phy->test.spe_idx = spe_idx_map[tx_ant];
978++ /* if all three params are set, duty_cycle will be ignored */
979++ if (duty_cycle && tx_time && !ipg) {
980++ ipg = tx_time * 100 / duty_cycle - tx_time;
981++ } else if (duty_cycle && !tx_time && ipg) {
982++ if (duty_cycle < 100)
983++ tx_time = duty_cycle * ipg / (100 - duty_cycle);
984+ }
985++
986++ mt7915_tm_set_ipg_params(phy, ipg, td->tx_rate_mode);
987++ mt7915_tm_set_tx_len(phy, tx_time);
988++
989++ if (ipg)
990++ td->tx_queued_limit = MT76_TM_TIMEOUT * 1000000 / ipg / 2;
991++
992++ if (!mt7915_tm_check_skb(phy))
993++ return;
994++ } else {
995++ mt7915_tm_clean_hwq(phy);
996+ }
997+
998+ mt7915_tm_set_tam_arb(phy, en,
999+ td->tx_rate_mode == MT76_TM_TX_MODE_HE_MU);
1000+
1001+- /* if all three params are set, duty_cycle will be ignored */
1002+- if (duty_cycle && tx_time && !ipg) {
1003+- ipg = tx_time * 100 / duty_cycle - tx_time;
1004+- } else if (duty_cycle && !tx_time && ipg) {
1005+- if (duty_cycle < 100)
1006+- tx_time = duty_cycle * ipg / (100 - duty_cycle);
1007+- }
1008++ mt7915_tm_set_trx(phy, TM_MAC_TX, en);
1009++}
1010+
1011+- mt7915_tm_set_ipg_params(phy, ipg, td->tx_rate_mode);
1012+- mt7915_tm_set_tx_len(phy, tx_time);
1013++static int
1014++mt7915_tm_get_rx_stats(struct mt7915_phy *phy, bool clear)
1015++{
1016++#define CMD_RX_STAT_BAND 0x3
1017++ struct mt76_testmode_data *td = &phy->mt76->test;
1018++ struct mt7915_tm_rx_stat_band *rs_band;
1019++ struct mt7915_dev *dev = phy->dev;
1020++ struct sk_buff *skb;
1021++ struct {
1022++ u8 format_id;
1023++ u8 band;
1024++ u8 _rsv[2];
1025++ } __packed req = {
1026++ .format_id = CMD_RX_STAT_BAND,
1027++ .band = phy != &dev->phy,
1028++ };
1029++ int ret;
1030+
1031+- if (ipg)
1032+- td->tx_queued_limit = MT76_TM_TIMEOUT * 1000000 / ipg / 2;
1033++ ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_CMD(RX_STAT),
1034++ &req, sizeof(req), true, &skb);
1035++ if (ret)
1036++ return ret;
1037+
1038+- if (!en || !td->tx_skb)
1039+- return;
1040++ rs_band = (struct mt7915_tm_rx_stat_band *)skb->data;
1041++ /* pr_info("mdrdy_cnt = %d\n", le32_to_cpu(rs_band->mdrdy_cnt)); */
1042++ /* pr_info("fcs_err = %d\n", le16_to_cpu(rs_band->fcs_err)); */
1043++ /* pr_info("len_mismatch = %d\n", le16_to_cpu(rs_band->len_mismatch)); */
1044++ /* pr_info("fcs_ok = %d\n", le16_to_cpu(rs_band->fcs_succ)); */
1045+
1046+- info = IEEE80211_SKB_CB(td->tx_skb);
1047+- info->control.vif = phy->monitor_vif;
1048++ if (!clear) {
1049++ enum mt76_rxq_id q = req.band ? MT_RXQ_EXT : MT_RXQ_MAIN;
1050+
1051+- mt7915_tm_set_trx(phy, TM_MAC_TX, en);
1052++ td->rx_stats.packets[q] += le32_to_cpu(rs_band->mdrdy_cnt);
1053++ td->rx_stats.fcs_error[q] += le16_to_cpu(rs_band->fcs_err);
1054++ td->rx_stats.len_mismatch += le16_to_cpu(rs_band->len_mismatch);
1055++ }
1056++
1057++ dev_kfree_skb(skb);
1058++
1059++ return 0;
1060+ }
1061+
1062+ static void
1063+@@ -487,12 +784,15 @@ mt7915_tm_set_rx_frames(struct mt7915_phy *phy, bool en)
1064+ mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, false);
1065+
1066+ if (en) {
1067+- struct mt7915_dev *dev = phy->dev;
1068+-
1069+ mt7915_tm_update_channel(phy);
1070+
1071+ /* read-clear */
1072+- mt76_rr(dev, MT_MIB_SDR3(phy != &dev->phy));
1073++ mt7915_tm_get_rx_stats(phy, true);
1074++
1075++ /* clear fw count */
1076++ mt7915_tm_set_phy_count(phy, 0);
1077++ mt7915_tm_set_phy_count(phy, 1);
1078++
1079+ mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, en);
1080+ }
1081+ }
1082+@@ -631,6 +931,31 @@ out:
1083+ sizeof(req), true);
1084+ }
1085+
1086++static void
1087++mt7915_tm_init(struct mt7915_phy *phy, bool en)
1088++{
1089++ struct mt7915_dev *dev = phy->dev;
1090++
1091++ if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state))
1092++ return;
1093++
1094++ mt7915_mcu_set_sku_en(phy, !en);
1095++
1096++ mt7915_tm_mode_ctrl(dev, en);
1097++ mt7915_tm_reg_backup_restore(phy);
1098++ mt7915_tm_set_trx(phy, TM_MAC_TXRX, !en);
1099++
1100++ mt7915_mcu_add_bss_info(phy, phy->monitor_vif, en);
1101++ mt7915_mcu_add_sta(dev, phy->monitor_vif, NULL, en);
1102++
1103++ phy->mt76->test.flag |= MT_TM_FW_RX_COUNT;
1104++
1105++ if (!en) {
1106++ mt7915_tm_set_tam_arb(phy, en, 0);
1107++ mt7915_tm_sta_remove_all(phy);
1108++ }
1109++}
1110++
1111+ static void
1112+ mt7915_tm_update_params(struct mt7915_phy *phy, u32 changed)
1113+ {
1114+@@ -641,6 +966,12 @@ mt7915_tm_update_params(struct mt7915_phy *phy, u32 changed)
1115+ mt7915_tm_set_freq_offset(phy, en, en ? td->freq_offset : 0);
1116+ if (changed & BIT(TM_CHANGED_TXPOWER))
1117+ mt7915_tm_set_tx_power(phy);
1118++ if (changed & BIT(TM_CHANGED_CFG))
1119++ mt7915_tm_set_cfg(phy);
1120++ if (changed & BIT(TM_CHANGED_OFF_CH_SCAN_CH))
1121++ mt7915_tm_set_off_channel_scan(phy);
1122++ if (changed & BIT(TM_CHANGED_AID))
1123++ mt7915_tm_set_sta(phy);
1124+ }
1125+
1126+ static int
1127+@@ -700,9 +1031,6 @@ mt7915_tm_set_params(struct mt76_phy *mphy, struct nlattr **tb,
1128+ td->state == MT76_TM_STATE_OFF)
1129+ return 0;
1130+
1131+- if (td->tx_antenna_mask & ~mphy->chainmask)
1132+- return -EINVAL;
1133+-
1134+ for (i = 0; i < ARRAY_SIZE(tm_change_map); i++) {
1135+ if (tb[tm_change_map[i]])
1136+ changed |= BIT(i);
1137+@@ -717,12 +1045,8 @@ static int
1138+ mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg)
1139+ {
1140+ struct mt7915_phy *phy = mphy->priv;
1141+- struct mt7915_dev *dev = phy->dev;
1142+- enum mt76_rxq_id q;
1143+ void *rx, *rssi;
1144+- u16 fcs_err;
1145+ int i;
1146+- u32 cnt;
1147+
1148+ rx = nla_nest_start(msg, MT76_TM_STATS_ATTR_LAST_RX);
1149+ if (!rx)
1150+@@ -766,19 +1090,68 @@ mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg)
1151+
1152+ nla_nest_end(msg, rx);
1153+
1154+- cnt = mt76_rr(dev, MT_MIB_SDR3(phy->band_idx));
1155+- fcs_err = is_mt7915(&dev->mt76) ? FIELD_GET(MT_MIB_SDR3_FCS_ERR_MASK, cnt) :
1156+- FIELD_GET(MT_MIB_SDR3_FCS_ERR_MASK_MT7916, cnt);
1157++ return mt7915_tm_get_rx_stats(phy, false);
1158++}
1159++
1160++static int
1161++mt7915_tm_write_back_to_efuse(struct mt7915_dev *dev)
1162++{
1163++ struct mt7915_mcu_eeprom_info req = {};
1164++ u8 *eeprom = dev->mt76.eeprom.data;
1165++ int i, ret = -EINVAL;
1166+
1167+- q = phy->band_idx ? MT_RXQ_EXT : MT_RXQ_MAIN;
1168+- mphy->test.rx_stats.packets[q] += fcs_err;
1169+- mphy->test.rx_stats.fcs_error[q] += fcs_err;
1170++ if (is_mt7986(&dev->mt76))
1171++ goto out;
1172+
1173+- return 0;
1174++ /* prevent from damaging chip id in efuse */
1175++ if (mt76_chip(&dev->mt76) != get_unaligned_le16(eeprom))
1176++ goto out;
1177++
1178++ for (i = 0; i < MT7915_EEPROM_SIZE; i += MT76_TM_EEPROM_BLOCK_SIZE) {
1179++ req.addr = cpu_to_le32(i);
1180++ memcpy(&req.data, eeprom + i, MT76_TM_EEPROM_BLOCK_SIZE);
1181++
1182++ ret = mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(EFUSE_ACCESS),
1183++ &req, sizeof(req), true);
1184++ if (ret)
1185++ return ret;
1186++ }
1187++
1188++out:
1189++ return ret;
1190++}
1191++
1192++static int
1193++mt7915_tm_set_eeprom(struct mt76_phy *mphy, u32 offset, u8 *val, u8 action)
1194++{
1195++ struct mt7915_phy *phy = mphy->priv;
1196++ struct mt7915_dev *dev = phy->dev;
1197++ u8 *eeprom = dev->mt76.eeprom.data;
1198++ int ret = 0;
1199++
1200++ if (offset >= MT7915_EEPROM_SIZE)
1201++ return -EINVAL;
1202++
1203++ switch (action) {
1204++ case MT76_TM_EEPROM_ACTION_UPDATE_DATA:
1205++ memcpy(eeprom + offset, val, MT76_TM_EEPROM_BLOCK_SIZE);
1206++ break;
1207++ case MT76_TM_EEPROM_ACTION_UPDATE_BUFFER_MODE:
1208++ ret = mt7915_mcu_set_eeprom(dev, true);
1209++ break;
1210++ case MT76_TM_EEPROM_ACTION_WRITE_TO_EFUSE:
1211++ ret = mt7915_tm_write_back_to_efuse(dev);
1212++ break;
1213++ default:
1214++ break;
1215++ }
1216++
1217++ return ret;
1218+ }
1219+
1220+ const struct mt76_testmode_ops mt7915_testmode_ops = {
1221+ .set_state = mt7915_tm_set_state,
1222+ .set_params = mt7915_tm_set_params,
1223+ .dump_stats = mt7915_tm_dump_stats,
1224++ .set_eeprom = mt7915_tm_set_eeprom,
1225+ };
1226+diff --git a/mt7915/testmode.h b/mt7915/testmode.h
1227+index 5573ac3..d22aabe 100644
1228+--- a/mt7915/testmode.h
1229++++ b/mt7915/testmode.h
1230+@@ -33,6 +33,12 @@ struct mt7915_tm_clean_txq {
1231+ u8 rsv;
1232+ };
1233+
1234++struct mt7915_tm_cfg {
1235++ u8 enable;
1236++ u8 band;
1237++ u8 _rsv[2];
1238++};
1239++
1240+ struct mt7915_tm_cmd {
1241+ u8 testmode_en;
1242+ u8 param_idx;
1243+@@ -43,6 +49,7 @@ struct mt7915_tm_cmd {
1244+ struct mt7915_tm_freq_offset freq;
1245+ struct mt7915_tm_slot_time slot;
1246+ struct mt7915_tm_clean_txq clean;
1247++ struct mt7915_tm_cfg cfg;
1248+ u8 test[72];
1249+ } param;
1250+ } __packed;
1251+@@ -102,4 +109,35 @@ enum {
1252+ TAM_ARB_OP_MODE_FORCE_SU = 5,
1253+ };
1254+
1255++struct mt7915_tm_rx_stat_band {
1256++ u8 category;
1257++
1258++ /* mac */
1259++ __le16 fcs_err;
1260++ __le16 len_mismatch;
1261++ __le16 fcs_succ;
1262++ __le32 mdrdy_cnt;
1263++ /* phy */
1264++ __le16 fcs_err_cck;
1265++ __le16 fcs_err_ofdm;
1266++ __le16 pd_cck;
1267++ __le16 pd_ofdm;
1268++ __le16 sig_err_cck;
1269++ __le16 sfd_err_cck;
1270++ __le16 sig_err_ofdm;
1271++ __le16 tag_err_ofdm;
1272++ __le16 mdrdy_cnt_cck;
1273++ __le16 mdrdy_cnt_ofdm;
1274++};
1275++
1276++enum {
1277++ TM_CBW_20MHZ,
1278++ TM_CBW_40MHZ,
1279++ TM_CBW_80MHZ,
1280++ TM_CBW_10MHZ,
1281++ TM_CBW_5MHZ,
1282++ TM_CBW_160MHZ,
1283++ TM_CBW_8080MHZ,
1284++};
1285++
1286+ #endif
1287+diff --git a/testmode.c b/testmode.c
1288+index 382b456..9da490c 100644
1289+--- a/testmode.c
1290++++ b/testmode.c
1291+@@ -25,18 +25,18 @@ const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = {
1292+ };
1293+ EXPORT_SYMBOL_GPL(mt76_tm_policy);
1294+
1295+-void mt76_testmode_tx_pending(struct mt76_phy *phy)
1296++static u16
1297++mt76_testmode_queue_tx(struct mt76_phy *phy, struct mt76_wcid *wcid,
1298++ struct sk_buff *skb, u32 limit)
1299+ {
1300+ struct mt76_testmode_data *td = &phy->test;
1301+ struct mt76_dev *dev = phy->dev;
1302+- struct mt76_wcid *wcid = &dev->global_wcid;
1303+- struct sk_buff *skb = td->tx_skb;
1304+ struct mt76_queue *q;
1305+- u16 tx_queued_limit;
1306++ u16 tx_queued_limit, count = 0;
1307+ int qid;
1308+
1309+- if (!skb || !td->tx_pending)
1310+- return;
1311++ if (!skb)
1312++ return 0;
1313+
1314+ qid = skb_get_queue_mapping(skb);
1315+ q = phy->q_tx[qid];
1316+@@ -45,7 +45,7 @@ void mt76_testmode_tx_pending(struct mt76_phy *phy)
1317+
1318+ spin_lock_bh(&q->lock);
1319+
1320+- while (td->tx_pending > 0 &&
1321++ while (count < limit &&
1322+ td->tx_queued - td->tx_done < tx_queued_limit &&
1323+ q->queued < q->ndesc / 2) {
1324+ int ret;
1325+@@ -55,13 +55,56 @@ void mt76_testmode_tx_pending(struct mt76_phy *phy)
1326+ if (ret < 0)
1327+ break;
1328+
1329+- td->tx_pending--;
1330+ td->tx_queued++;
1331++ count++;
1332+ }
1333+
1334+ dev->queue_ops->kick(dev, q);
1335+
1336+ spin_unlock_bh(&q->lock);
1337++
1338++ return count;
1339++}
1340++
1341++void mt76_testmode_tx_pending(struct mt76_phy *phy)
1342++{
1343++ struct mt76_testmode_data *td = &phy->test;
1344++ u16 count;
1345++
1346++ if (!td->tx_pending)
1347++ return;
1348++
1349++ if (!mt76_testmode_has_sta(phy)) {
1350++ count = mt76_testmode_queue_tx(phy, &phy->dev->global_wcid,
1351++ td->tx_skb, td->tx_pending);
1352++ td->tx_pending -= count;
1353++
1354++ return;
1355++ }
1356++
1357++ while (true) {
1358++ struct mt76_testmode_sta *tm_sta;
1359++ struct mt76_wcid *wcid;
1360++ u32 limit, per_sta_cnt = 1;
1361++
1362++ if (td->tx_rate_mode != MT76_TM_TX_MODE_HE_MU)
1363++ per_sta_cnt = td->tx_count / hweight16(phy->test.tm_sta_mask);
1364++
1365++ limit = td->tx_pending % per_sta_cnt;
1366++ if (limit == 0)
1367++ limit = per_sta_cnt;
1368++
1369++ tm_sta = mt76_testmode_aid_get_sta(phy, td->cur_aid);
1370++ wcid = td->tm_wcid[td->cur_aid];
1371++ count = mt76_testmode_queue_tx(phy, wcid, tm_sta->tx_skb, limit);
1372++
1373++ td->tx_pending -= count;
1374++
1375++ if (td->tx_pending && (td->tx_pending % per_sta_cnt == 0))
1376++ td->cur_aid = ffs(td->tm_sta_mask >> td->cur_aid) + td->cur_aid;
1377++ else
1378++ break;
1379++ }
1380+ }
1381+
1382+ static u32
1383+@@ -87,15 +130,34 @@ mt76_testmode_max_mpdu_len(struct mt76_phy *phy, u8 tx_rate_mode)
1384+ }
1385+
1386+ static void
1387+-mt76_testmode_free_skb(struct mt76_phy *phy)
1388++mt76_testmode_free_skb(struct sk_buff **tx_skb)
1389++{
1390++ dev_kfree_skb(*tx_skb);
1391++ *tx_skb = NULL;
1392++}
1393++
1394++static void
1395++mt76_testmode_free_skb_all(struct mt76_phy *phy)
1396+ {
1397+ struct mt76_testmode_data *td = &phy->test;
1398+
1399+- dev_kfree_skb(td->tx_skb);
1400+- td->tx_skb = NULL;
1401++ if (mt76_testmode_has_sta(phy)) {
1402++ struct mt76_testmode_sta *tm_sta;
1403++ int i;
1404++
1405++ mt76_testmode_for_each_sta(phy, i, tm_sta) {
1406++ mt76_testmode_free_skb(&tm_sta->tx_skb);
1407++ }
1408++
1409++ return;
1410++ }
1411++
1412++ mt76_testmode_free_skb(&td->tx_skb);
1413+ }
1414+
1415+-int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len)
1416++static int
1417++mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len,
1418++ struct sk_buff **tx_skb, u8 *da)
1419+ {
1420+ #define MT_TXP_MAX_LEN 4095
1421+ u16 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
1422+@@ -128,7 +190,9 @@ int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len)
1423+ hdr->frame_control = cpu_to_le16(fc);
1424+ memcpy(hdr->addr1, td->addr[0], ETH_ALEN);
1425+ memcpy(hdr->addr2, td->addr[1], ETH_ALEN);
1426+- memcpy(hdr->addr3, td->addr[2], ETH_ALEN);
1427++ /* memcpy(hdr->addr3, td->addr[2], ETH_ALEN); */
1428++ memcpy(hdr->addr3, da, ETH_ALEN);
1429++
1430+ skb_set_queue_mapping(head, IEEE80211_AC_BE);
1431+
1432+ info = IEEE80211_SKB_CB(head);
1433+@@ -152,7 +216,7 @@ int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len)
1434+
1435+ frag = alloc_skb(frag_len, GFP_KERNEL);
1436+ if (!frag) {
1437+- mt76_testmode_free_skb(phy);
1438++ mt76_testmode_free_skb(tx_skb);
1439+ dev_kfree_skb(head);
1440+ return -ENOMEM;
1441+ }
1442+@@ -165,23 +229,25 @@ int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len)
1443+ frag_tail = &(*frag_tail)->next;
1444+ }
1445+
1446+- mt76_testmode_free_skb(phy);
1447+- td->tx_skb = head;
1448++ mt76_testmode_free_skb(tx_skb);
1449++ *tx_skb = head;
1450+
1451+ return 0;
1452+ }
1453+-EXPORT_SYMBOL(mt76_testmode_alloc_skb);
1454+
1455+-static int
1456+-mt76_testmode_tx_init(struct mt76_phy *phy)
1457++int mt76_testmode_init_skb(struct mt76_phy *phy, u32 len, u8 aid,
1458++ struct sk_buff **tx_skb)
1459+ {
1460+ struct mt76_testmode_data *td = &phy->test;
1461+ struct ieee80211_tx_info *info;
1462+ struct ieee80211_tx_rate *rate;
1463+ u8 max_nss = hweight8(phy->antenna_mask);
1464++ u8 da[ETH_ALEN];
1465+ int ret;
1466+
1467+- ret = mt76_testmode_alloc_skb(phy, td->tx_mpdu_len);
1468++ ether_addr_copy(da, phy->macaddr);
1469++ da[0] += aid * 4;
1470++ ret = mt76_testmode_alloc_skb(phy, len, tx_skb, da);
1471+ if (ret)
1472+ return ret;
1473+
1474+@@ -191,7 +257,7 @@ mt76_testmode_tx_init(struct mt76_phy *phy)
1475+ if (td->tx_antenna_mask)
1476+ max_nss = min_t(u8, max_nss, hweight8(td->tx_antenna_mask));
1477+
1478+- info = IEEE80211_SKB_CB(td->tx_skb);
1479++ info = IEEE80211_SKB_CB(*tx_skb);
1480+ rate = &info->control.rates[0];
1481+ rate->count = 1;
1482+ rate->idx = td->tx_rate_idx;
1483+@@ -263,6 +329,28 @@ mt76_testmode_tx_init(struct mt76_phy *phy)
1484+ out:
1485+ return 0;
1486+ }
1487++EXPORT_SYMBOL(mt76_testmode_init_skb);
1488++
1489++static int
1490++mt76_testmode_tx_init(struct mt76_phy *phy)
1491++{
1492++ struct mt76_testmode_data *td = &phy->test;
1493++ struct mt76_testmode_sta *tm_sta;
1494++ int ret, i;
1495++
1496++ if (!mt76_testmode_has_sta(phy))
1497++ return mt76_testmode_init_skb(phy, td->tx_mpdu_len,
1498++ 0, &td->tx_skb);
1499++
1500++ mt76_testmode_for_each_sta(phy, i, tm_sta) {
1501++ ret = mt76_testmode_init_skb(phy, tm_sta->sd.tx_mpdu_len,
1502++ tm_sta->sd.aid, &tm_sta->tx_skb);
1503++ if (ret)
1504++ return ret;
1505++ }
1506++
1507++ return 0;
1508++}
1509+
1510+ static void
1511+ mt76_testmode_tx_start(struct mt76_phy *phy)
1512+@@ -273,6 +361,17 @@ mt76_testmode_tx_start(struct mt76_phy *phy)
1513+ td->tx_queued = 0;
1514+ td->tx_done = 0;
1515+ td->tx_pending = td->tx_count;
1516++
1517++ if (mt76_testmode_has_sta(phy)) {
1518++ td->cur_aid = ffs(td->tm_sta_mask);
1519++
1520++ /* The actual tx count of MU packets will be pass to FW
1521++ * by a mcu command in testmode.
1522++ */
1523++ if (td->tx_rate_mode == MT76_TM_TX_MODE_HE_MU)
1524++ td->tx_pending = hweight16(phy->test.tm_sta_mask);
1525++ }
1526++
1527+ mt76_worker_schedule(&dev->tx_worker);
1528+ }
1529+
1530+@@ -291,7 +390,7 @@ mt76_testmode_tx_stop(struct mt76_phy *phy)
1531+ wait_event_timeout(dev->tx_wait, td->tx_done == td->tx_queued,
1532+ MT76_TM_TIMEOUT * HZ);
1533+
1534+- mt76_testmode_free_skb(phy);
1535++ mt76_testmode_free_skb_all(phy);
1536+ }
1537+
1538+ static inline void
1539+@@ -331,8 +430,11 @@ __mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state)
1540+ struct mt76_dev *dev = phy->dev;
1541+ int err;
1542+
1543+- if (prev_state == MT76_TM_STATE_TX_FRAMES)
1544++ if (prev_state == MT76_TM_STATE_TX_FRAMES) {
1545++ if (phy->test.tx_rate_mode == MT76_TM_TX_MODE_HE_MU)
1546++ dev->test_ops->set_state(phy, MT76_TM_STATE_IDLE);
1547+ mt76_testmode_tx_stop(phy);
1548++ }
1549+
1550+ if (state == MT76_TM_STATE_TX_FRAMES) {
1551+ err = mt76_testmode_tx_init(phy);
1552+@@ -382,7 +484,6 @@ int mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state
1553+ }
1554+
1555+ return __mt76_testmode_set_state(phy, state);
1556+-
1557+ }
1558+ EXPORT_SYMBOL(mt76_testmode_set_state);
1559+
1560+@@ -402,6 +503,44 @@ mt76_tm_get_u8(struct nlattr *attr, u8 *dest, u8 min, u8 max)
1561+ return 0;
1562+ }
1563+
1564++static int
1565++mt76_testmode_set_eeprom(struct mt76_phy *phy, struct nlattr **tb)
1566++{
1567++ struct mt76_dev *dev = phy->dev;
1568++ u8 action, val[MT76_TM_EEPROM_BLOCK_SIZE];
1569++ u32 offset = 0;
1570++ int err = -EINVAL;
1571++
1572++ if (!dev->test_ops->set_eeprom)
1573++ return -EOPNOTSUPP;
1574++
1575++ if (mt76_tm_get_u8(tb[MT76_TM_ATTR_EEPROM_ACTION], &action,
1576++ 0, MT76_TM_EEPROM_ACTION_MAX))
1577++ goto out;
1578++
1579++ if (tb[MT76_TM_ATTR_EEPROM_OFFSET]) {
1580++ struct nlattr *cur;
1581++ int rem, idx = 0;
1582++
1583++ offset = nla_get_u32(tb[MT76_TM_ATTR_EEPROM_OFFSET]);
1584++ if (!!(offset % MT76_TM_EEPROM_BLOCK_SIZE) ||
1585++ !tb[MT76_TM_ATTR_EEPROM_VAL])
1586++ goto out;
1587++
1588++ nla_for_each_nested(cur, tb[MT76_TM_ATTR_EEPROM_VAL], rem) {
1589++ if (nla_len(cur) != 1 || idx >= ARRAY_SIZE(val))
1590++ goto out;
1591++
1592++ val[idx++] = nla_get_u8(cur);
1593++ }
1594++ }
1595++
1596++ err = dev->test_ops->set_eeprom(phy, offset, val, action);
1597++
1598++out:
1599++ return err;
1600++}
1601++
1602+ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1603+ void *data, int len)
1604+ {
1605+@@ -425,6 +564,11 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1606+
1607+ mutex_lock(&dev->mutex);
1608+
1609++ if (tb[MT76_TM_ATTR_EEPROM_ACTION]) {
1610++ err = mt76_testmode_set_eeprom(phy, tb);
1611++ goto out;
1612++ }
1613++
1614+ if (tb[MT76_TM_ATTR_RESET]) {
1615+ mt76_testmode_set_state(phy, MT76_TM_STATE_OFF);
1616+ memset(td, 0, sizeof(*td));
1617+@@ -446,13 +590,16 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1618+ mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_RATE_LDPC], &td->tx_rate_ldpc, 0, 1) ||
1619+ mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_RATE_STBC], &td->tx_rate_stbc, 0, 1) ||
1620+ mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_LTF], &td->tx_ltf, 0, 2) ||
1621+- mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_ANTENNA],
1622+- &td->tx_antenna_mask, 0, 0xff) ||
1623++ mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_ANTENNA], &td->tx_antenna_mask,
1624++ 1, phy->antenna_mask) ||
1625+ mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_SPE_IDX], &td->tx_spe_idx, 0, 27) ||
1626+ mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_DUTY_CYCLE],
1627+ &td->tx_duty_cycle, 0, 99) ||
1628+ mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_POWER_CONTROL],
1629+- &td->tx_power_control, 0, 1))
1630++ &td->tx_power_control, 0, 1) ||
1631++ mt76_tm_get_u8(tb[MT76_TM_ATTR_AID], &td->aid, 0, 16) ||
1632++ mt76_tm_get_u8(tb[MT76_TM_ATTR_RU_ALLOC], &td->ru_alloc, 0, 0xff) ||
1633++ mt76_tm_get_u8(tb[MT76_TM_ATTR_RU_IDX], &td->ru_idx, 0, 68))
1634+ goto out;
1635+
1636+ if (tb[MT76_TM_ATTR_TX_LENGTH]) {
1637+@@ -484,8 +631,7 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1638+
1639+ if (tb[MT76_TM_ATTR_TX_POWER]) {
1640+ struct nlattr *cur;
1641+- int idx = 0;
1642+- int rem;
1643++ int rem, idx = 0;
1644+
1645+ nla_for_each_nested(cur, tb[MT76_TM_ATTR_TX_POWER], rem) {
1646+ if (nla_len(cur) != 1 ||
1647+@@ -505,11 +651,47 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1648+ if (nla_len(cur) != ETH_ALEN || idx >= 3)
1649+ goto out;
1650+
1651+- memcpy(td->addr[idx], nla_data(cur), ETH_ALEN);
1652++ memcpy(td->addr[idx++], nla_data(cur), ETH_ALEN);
1653++ }
1654++ }
1655++
1656++ if (tb[MT76_TM_ATTR_CFG]) {
1657++ struct nlattr *cur;
1658++ int rem, idx = 0;
1659++
1660++ nla_for_each_nested(cur, tb[MT76_TM_ATTR_CFG], rem) {
1661++ if (nla_len(cur) != 1 || idx >= 2)
1662++ goto out;
1663++
1664++ if (idx == 0)
1665++ td->cfg.type = nla_get_u8(cur);
1666++ else
1667++ td->cfg.enable = nla_get_u8(cur);
1668+ idx++;
1669+ }
1670+ }
1671+
1672++ if (tb[MT76_TM_ATTR_OFF_CH_SCAN_CH]) {
1673++ u8 ch = nla_get_u8(tb[MT76_TM_ATTR_OFF_CH_SCAN_CH]);
1674++ struct ieee80211_supported_band *sband;
1675++
1676++ sband = ch > 14 ? &phy->sband_5g.sband :
1677++ &phy->sband_2g.sband;
1678++ if (ch && (ch < sband->channels[0].hw_value ||
1679++ ch > sband->channels[sband->n_channels - 1].hw_value))
1680++ goto out;
1681++
1682++ td->off_ch_scan_ch = ch;
1683++
1684++ if (mt76_tm_get_u8(tb[MT76_TM_ATTR_OFF_CH_SCAN_CENTER_CH],
1685++ &td->off_ch_scan_center_ch, ch - 6, ch + 6) ||
1686++ mt76_tm_get_u8(tb[MT76_TM_ATTR_OFF_CH_SCAN_BW],
1687++ &td->off_ch_scan_bw, 0, 6) ||
1688++ mt76_tm_get_u8(tb[MT76_TM_ATTR_OFF_CH_SCAN_PATH],
1689++ &td->off_ch_scan_path, 1, 0xff))
1690++ goto out;
1691++ }
1692++
1693+ if (dev->test_ops->set_params) {
1694+ err = dev->test_ops->set_params(phy, tb, state);
1695+ if (err)
1696+@@ -559,6 +741,9 @@ mt76_testmode_dump_stats(struct mt76_phy *phy, struct sk_buff *msg)
1697+ nla_put_u64_64bit(msg, MT76_TM_STATS_ATTR_RX_PACKETS, rx_packets,
1698+ MT76_TM_STATS_ATTR_PAD) ||
1699+ nla_put_u64_64bit(msg, MT76_TM_STATS_ATTR_RX_FCS_ERROR, rx_fcs_error,
1700++ MT76_TM_STATS_ATTR_PAD) ||
1701++ nla_put_u64_64bit(msg, MT76_TM_STATS_ATTR_RX_LEN_MISMATCH,
1702++ td->rx_stats.len_mismatch,
1703+ MT76_TM_STATS_ATTR_PAD))
1704+ return -EMSGSIZE;
1705+
1706+@@ -571,6 +756,7 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
1707+ struct mt76_phy *phy = hw->priv;
1708+ struct mt76_dev *dev = phy->dev;
1709+ struct mt76_testmode_data *td = &phy->test;
1710++ struct mt76_testmode_sta_data *sd = &td->sd;
1711+ struct nlattr *tb[NUM_MT76_TM_ATTRS] = {};
1712+ int err = 0;
1713+ void *a;
1714+@@ -603,6 +789,23 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
1715+ goto out;
1716+ }
1717+
1718++ if (tb[MT76_TM_ATTR_AID]) {
1719++ struct mt76_testmode_sta *tm_sta;
1720++ u8 aid;
1721++
1722++ err = mt76_tm_get_u8(tb[MT76_TM_ATTR_AID], &aid, 1, 16);
1723++ if (err)
1724++ goto out;
1725++
1726++ tm_sta = mt76_testmode_aid_get_sta(phy, aid);
1727++ if (!tm_sta) {
1728++ err = -EINVAL;
1729++ goto out;
1730++ }
1731++
1732++ sd = &tm_sta->sd;
1733++ }
1734++
1735+ mt76_testmode_init_defaults(phy);
1736+
1737+ err = -EMSGSIZE;
1738+@@ -615,12 +818,8 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
1739+ goto out;
1740+
1741+ if (nla_put_u32(msg, MT76_TM_ATTR_TX_COUNT, td->tx_count) ||
1742+- nla_put_u32(msg, MT76_TM_ATTR_TX_LENGTH, td->tx_mpdu_len) ||
1743+ nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_MODE, td->tx_rate_mode) ||
1744+- nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_NSS, td->tx_rate_nss) ||
1745+- nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_IDX, td->tx_rate_idx) ||
1746+ nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_SGI, td->tx_rate_sgi) ||
1747+- nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_LDPC, td->tx_rate_ldpc) ||
1748+ nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_STBC, td->tx_rate_stbc) ||
1749+ (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_LTF) &&
1750+ nla_put_u8(msg, MT76_TM_ATTR_TX_LTF, td->tx_ltf)) ||
1751+@@ -640,6 +839,15 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
1752+ nla_put_u8(msg, MT76_TM_ATTR_FREQ_OFFSET, td->freq_offset)))
1753+ goto out;
1754+
1755++ if (nla_put_u8(msg, MT76_TM_ATTR_AID, sd->aid) ||
1756++ nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_NSS, sd->tx_rate_nss) ||
1757++ nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_IDX, sd->tx_rate_idx) ||
1758++ nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_LDPC, sd->tx_rate_ldpc) ||
1759++ nla_put_u8(msg, MT76_TM_ATTR_RU_ALLOC, sd->ru_alloc) ||
1760++ nla_put_u8(msg, MT76_TM_ATTR_RU_IDX, sd->ru_idx) ||
1761++ nla_put_u32(msg, MT76_TM_ATTR_TX_LENGTH, sd->tx_mpdu_len))
1762++ goto out;
1763++
1764+ if (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_POWER)) {
1765+ a = nla_nest_start(msg, MT76_TM_ATTR_TX_POWER);
1766+ if (!a)
1767+diff --git a/testmode.h b/testmode.h
1768+index 5e2792d..b360d7a 100644
1769+--- a/testmode.h
1770++++ b/testmode.h
1771+@@ -6,6 +6,8 @@
1772+ #define __MT76_TESTMODE_H
1773+
1774+ #define MT76_TM_TIMEOUT 10
1775++#define MT76_TM_EEPROM_BLOCK_SIZE 16
1776++#define MT76_TM_MAX_STA_NUM 16
1777+
1778+ /**
1779+ * enum mt76_testmode_attr - testmode attributes inside NL80211_ATTR_TESTDATA
1780+@@ -47,6 +49,20 @@
1781+ * @MT76_TM_ATTR_DRV_DATA: driver specific netlink attrs (nested)
1782+ *
1783+ * @MT76_TM_ATTR_MAC_ADDRS: array of nested MAC addresses (nested)
1784++ *
1785++ * @MT76_TM_ATTR_EEPROM_ACTION: eeprom setting actions
1786++ * (u8, see &enum mt76_testmode_eeprom_action)
1787++ * @MT76_TM_ATTR_EEPROM_OFFSET: offset of eeprom data block for writing (u32)
1788++ * @MT76_TM_ATTR_EEPROM_VAL: values for writing into a 16-byte data block
1789++ * (nested, u8 attrs)
1790++ *
1791++ * @MT76_TM_ATTR_CFG: config testmode rf feature (nested, see &mt76_testmode_cfg)
1792++ *
1793++ * @MT76_TM_ATTR_OFF_CH_SCAN_CH: monitored channel for off channel scan (u8)
1794++ * @MT76_TM_ATTR_OFF_CH_SCAN_CENTER_CH: monitored channel for off channel scan (u8)
1795++ * @MT76_TM_ATTR_OFF_CH_SCAN_BW: monitored bw for off channel scan (u8)
1796++ * @MT76_TM_ATTR_OFF_CH_SCAN_PATH: monitored rx path for off channel scan (u8)
1797++ *
1798+ */
1799+ enum mt76_testmode_attr {
1800+ MT76_TM_ATTR_UNSPEC,
1801+@@ -85,6 +101,21 @@ enum mt76_testmode_attr {
1802+
1803+ MT76_TM_ATTR_MAC_ADDRS,
1804+
1805++ MT76_TM_ATTR_EEPROM_ACTION,
1806++ MT76_TM_ATTR_EEPROM_OFFSET,
1807++ MT76_TM_ATTR_EEPROM_VAL,
1808++
1809++ MT76_TM_ATTR_CFG,
1810++
1811++ MT76_TM_ATTR_OFF_CH_SCAN_CH,
1812++ MT76_TM_ATTR_OFF_CH_SCAN_CENTER_CH,
1813++ MT76_TM_ATTR_OFF_CH_SCAN_BW,
1814++ MT76_TM_ATTR_OFF_CH_SCAN_PATH,
1815++
1816++ MT76_TM_ATTR_AID,
1817++ MT76_TM_ATTR_RU_ALLOC,
1818++ MT76_TM_ATTR_RU_IDX,
1819++
1820+ /* keep last */
1821+ NUM_MT76_TM_ATTRS,
1822+ MT76_TM_ATTR_MAX = NUM_MT76_TM_ATTRS - 1,
1823+@@ -101,6 +132,8 @@ enum mt76_testmode_attr {
1824+ * @MT76_TM_STATS_ATTR_RX_FCS_ERROR: number of rx packets with FCS error (u64)
1825+ * @MT76_TM_STATS_ATTR_LAST_RX: information about the last received packet
1826+ * see &enum mt76_testmode_rx_attr
1827++ * @MT76_TM_STATS_ATTR_RX_LEN_MISMATCH: number of rx packets with length
1828++ * mismatch error (u64)
1829+ */
1830+ enum mt76_testmode_stats_attr {
1831+ MT76_TM_STATS_ATTR_UNSPEC,
1832+@@ -113,6 +146,7 @@ enum mt76_testmode_stats_attr {
1833+ MT76_TM_STATS_ATTR_RX_PACKETS,
1834+ MT76_TM_STATS_ATTR_RX_FCS_ERROR,
1835+ MT76_TM_STATS_ATTR_LAST_RX,
1836++ MT76_TM_STATS_ATTR_RX_LEN_MISMATCH,
1837+
1838+ /* keep last */
1839+ NUM_MT76_TM_STATS_ATTRS,
1840+@@ -195,4 +229,41 @@ enum mt76_testmode_tx_mode {
1841+
1842+ extern const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS];
1843+
1844++/**
1845++ * enum mt76_testmode_eeprom_action - eeprom setting actions
1846++ *
1847++ * @MT76_TM_EEPROM_ACTION_UPDATE_DATA: update rf values to specific
1848++ * eeprom data block
1849++ * @MT76_TM_EEPROM_ACTION_UPDATE_BUFFER_MODE: send updated eeprom data to fw
1850++ * @MT76_TM_EEPROM_ACTION_WRITE_TO_EFUSE: write eeprom data back to efuse
1851++ */
1852++enum mt76_testmode_eeprom_action {
1853++ MT76_TM_EEPROM_ACTION_UPDATE_DATA,
1854++ MT76_TM_EEPROM_ACTION_UPDATE_BUFFER_MODE,
1855++ MT76_TM_EEPROM_ACTION_WRITE_TO_EFUSE,
1856++
1857++ /* keep last */
1858++ NUM_MT76_TM_EEPROM_ACTION,
1859++ MT76_TM_EEPROM_ACTION_MAX = NUM_MT76_TM_EEPROM_ACTION - 1,
1860++};
1861++
1862++/**
1863++ * enum mt76_testmode_cfg - packet tx phy mode
1864++ *
1865++ * @MT76_TM_EEPROM_ACTION_UPDATE_DATA: update rf values to specific
1866++ * eeprom data block
1867++ * @MT76_TM_EEPROM_ACTION_UPDATE_BUFFER_MODE: send updated eeprom data to fw
1868++ * @MT76_TM_EEPROM_ACTION_WRITE_TO_EFUSE: write eeprom data back to efuse
1869++ */
1870++enum mt76_testmode_cfg {
1871++ MT76_TM_CFG_TSSI,
1872++ MT76_TM_CFG_DPD,
1873++ MT76_TM_CFG_RATE_POWER_OFFSET,
1874++ MT76_TM_CFG_THERMAL_COMP,
1875++
1876++ /* keep last */
1877++ NUM_MT76_TM_CFG,
1878++ MT76_TM_CFG_MAX = NUM_MT76_TM_CFG - 1,
1879++};
1880++
1881+ #endif
1882+diff --git a/tools/fields.c b/tools/fields.c
1883+index e3f6908..036406c 100644
1884+--- a/tools/fields.c
1885++++ b/tools/fields.c
1886+@@ -10,6 +10,7 @@ static const char * const testmode_state[] = {
1887+ [MT76_TM_STATE_IDLE] = "idle",
1888+ [MT76_TM_STATE_TX_FRAMES] = "tx_frames",
1889+ [MT76_TM_STATE_RX_FRAMES] = "rx_frames",
1890++ [MT76_TM_STATE_TX_CONT] = "tx_cont",
1891+ };
1892+
1893+ static const char * const testmode_tx_mode[] = {
1894+@@ -201,6 +202,63 @@ static void print_extra_stats(const struct tm_field *field, struct nlattr **tb)
1895+ printf("%srx_per=%.02f%%\n", prefix, 100 * failed / total);
1896+ }
1897+
1898++static bool parse_mac(const struct tm_field *field, int idx,
1899++ struct nl_msg *msg, const char *val)
1900++{
1901++#define ETH_ALEN 6
1902++ bool ret = true;
1903++ char *str, *cur, *ap;
1904++ void *a;
1905++
1906++ ap = str = strdup(val);
1907++
1908++ a = nla_nest_start(msg, idx);
1909++
1910++ idx = 0;
1911++ while ((cur = strsep(&ap, ",")) != NULL) {
1912++ unsigned char addr[ETH_ALEN];
1913++ char *val, *tmp = cur;
1914++ int i = 0;
1915++
1916++ while ((val = strsep(&tmp, ":")) != NULL) {
1917++ if (i >= ETH_ALEN)
1918++ break;
1919++
1920++ addr[i++] = strtoul(val, NULL, 16);
1921++ }
1922++
1923++ nla_put(msg, idx, ETH_ALEN, addr);
1924++
1925++ idx++;
1926++ }
1927++
1928++ nla_nest_end(msg, a);
1929++
1930++ free(str);
1931++
1932++ return ret;
1933++}
1934++
1935++static void print_mac(const struct tm_field *field, struct nlattr *attr)
1936++{
1937++#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
1938++#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
1939++ unsigned char addr[3][6];
1940++ struct nlattr *cur;
1941++ int idx = 0;
1942++ int rem;
1943++
1944++ nla_for_each_nested(cur, attr, rem) {
1945++ if (nla_len(cur) != 6)
1946++ continue;
1947++ memcpy(addr[idx++], nla_data(cur), 6);
1948++ }
1949++
1950++ printf("" MACSTR "," MACSTR "," MACSTR "",
1951++ MAC2STR(addr[0]), MAC2STR(addr[1]), MAC2STR(addr[2]));
1952++
1953++ return;
1954++}
1955+
1956+ #define FIELD_GENERIC(_field, _name, ...) \
1957+ [FIELD_NAME(_field)] = { \
1958+@@ -250,6 +308,13 @@ static void print_extra_stats(const struct tm_field *field, struct nlattr **tb)
1959+ ##__VA_ARGS__ \
1960+ )
1961+
1962++#define FIELD_MAC(_field, _name) \
1963++ [FIELD_NAME(_field)] = { \
1964++ .name = _name, \
1965++ .parse = parse_mac, \
1966++ .print = print_mac \
1967++ }
1968++
1969+ #define FIELD_NAME(_field) MT76_TM_RX_ATTR_##_field
1970+ static const struct tm_field rx_fields[NUM_MT76_TM_RX_ATTRS] = {
1971+ FIELD_RO(s32, FREQ_OFFSET, "freq_offset"),
1972+@@ -300,10 +365,16 @@ static const struct tm_field testdata_fields[NUM_MT76_TM_ATTRS] = {
1973+ FIELD(u8, TX_RATE_LDPC, "tx_rate_ldpc"),
1974+ FIELD(u8, TX_RATE_STBC, "tx_rate_stbc"),
1975+ FIELD(u8, TX_LTF, "tx_ltf"),
1976++ FIELD(u8, TX_DUTY_CYCLE, "tx_duty_cycle"),
1977++ FIELD(u32, TX_IPG, "tx_ipg"),
1978++ FIELD(u32, TX_TIME, "tx_time"),
1979+ FIELD(u8, TX_POWER_CONTROL, "tx_power_control"),
1980+ FIELD_ARRAY(u8, TX_POWER, "tx_power"),
1981+ FIELD(u8, TX_ANTENNA, "tx_antenna"),
1982++ FIELD(u8, TX_SPE_IDX, "tx_spe_idx"),
1983+ FIELD(u32, FREQ_OFFSET, "freq_offset"),
1984++ FIELD(u8, AID, "aid"),
1985++ FIELD_MAC(MAC_ADDRS, "mac_addrs"),
1986+ FIELD_NESTED_RO(STATS, stats, "",
1987+ .print_extra = print_extra_stats),
1988+ };
1989+@@ -322,9 +393,14 @@ static struct nla_policy testdata_policy[NUM_MT76_TM_ATTRS] = {
1990+ [MT76_TM_ATTR_TX_RATE_LDPC] = { .type = NLA_U8 },
1991+ [MT76_TM_ATTR_TX_RATE_STBC] = { .type = NLA_U8 },
1992+ [MT76_TM_ATTR_TX_LTF] = { .type = NLA_U8 },
1993++ [MT76_TM_ATTR_TX_DUTY_CYCLE] = { .type = NLA_U8 },
1994++ [MT76_TM_ATTR_TX_IPG] = { .type = NLA_U32 },
1995++ [MT76_TM_ATTR_TX_TIME] = { .type = NLA_U32 },
1996+ [MT76_TM_ATTR_TX_POWER_CONTROL] = { .type = NLA_U8 },
1997+ [MT76_TM_ATTR_TX_ANTENNA] = { .type = NLA_U8 },
1998++ [MT76_TM_ATTR_TX_SPE_IDX] = { .type = NLA_U8 },
1999+ [MT76_TM_ATTR_FREQ_OFFSET] = { .type = NLA_U32 },
2000++ [MT76_TM_ATTR_AID] = { .type = NLA_U8 },
2001+ [MT76_TM_ATTR_STATS] = { .type = NLA_NESTED },
2002+ };
2003+
2004+diff --git a/tx.c b/tx.c
2005+index 6b8c9dc..ca5e6d9 100644
2006+--- a/tx.c
2007++++ b/tx.c
2008+@@ -245,8 +245,7 @@ void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid_idx, struct sk_buff *
2009+ if (mt76_is_testmode_skb(dev, skb, &hw)) {
2010+ struct mt76_phy *phy = hw->priv;
2011+
2012+- if (skb == phy->test.tx_skb)
2013+- phy->test.tx_done++;
2014++ phy->test.tx_done++;
2015+ if (phy->test.tx_queued == phy->test.tx_done)
2016+ wake_up(&dev->tx_wait);
2017+
2018+--
2019+2.25.1
2020+