blob: dff4e09bf55359be7caf137b9dfee7bb3a300bb3 [file] [log] [blame]
developer36fe7092023-09-27 12:24:47 +08001From 431feba8fc3c13f6181fce8da33d4df29ce626a2 Mon Sep 17 00:00:00 2001
developer27b55252022-09-05 19:09:45 +08002From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
3Date: Wed, 31 Aug 2022 20:06:52 +0800
developer36fe7092023-09-27 12:24:47 +08004Subject: [PATCH 1010/1034] wifi: mt76: testmode: add pre-cal support
developer27b55252022-09-05 19:09:45 +08005
6Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
developer27b55252022-09-05 19:09:45 +08007---
8 eeprom.c | 6 +-
9 mt76.h | 1 +
10 mt76_connac_mcu.h | 1 +
11 mt7915/eeprom.h | 34 +++-
12 mt7915/mcu.c | 27 ++-
13 mt7915/mt7915.h | 5 +
14 mt7915/testmode.c | 425 +++++++++++++++++++++++++++++++++++++++++++++-
15 mt7915/testmode.h | 36 ++++
16 testmode.c | 15 +-
17 testmode.h | 17 ++
18 tools/fields.c | 8 +
19 11 files changed, 562 insertions(+), 13 deletions(-)
20
21diff --git a/eeprom.c b/eeprom.c
developer36fe7092023-09-27 12:24:47 +080022index ff8dc939..9b637992 100644
developer27b55252022-09-05 19:09:45 +080023--- a/eeprom.c
24+++ b/eeprom.c
developer2b96a9e2023-08-09 10:28:15 +080025@@ -94,8 +94,10 @@ static int mt76_get_of_epprom_from_mtd(struct mt76_dev *dev, void *eep, int offs
developer27b55252022-09-05 19:09:45 +080026 }
27
28 #ifdef CONFIG_NL80211_TESTMODE
29- dev->test_mtd.name = devm_kstrdup(dev->dev, part, GFP_KERNEL);
30- dev->test_mtd.offset = offset;
31+ if (len == dev->eeprom.size) {
32+ dev->test_mtd.name = devm_kstrdup(dev->dev, part, GFP_KERNEL);
33+ dev->test_mtd.offset = offset;
34+ }
35 #endif
36
37 out_put_node:
38diff --git a/mt76.h b/mt76.h
developer36fe7092023-09-27 12:24:47 +080039index a5908de4..7d83d406 100644
developer27b55252022-09-05 19:09:45 +080040--- a/mt76.h
41+++ b/mt76.h
developer36fe7092023-09-27 12:24:47 +080042@@ -658,6 +658,7 @@ struct mt76_testmode_ops {
developer27b55252022-09-05 19:09:45 +080043 enum mt76_testmode_state new_state);
44 int (*dump_stats)(struct mt76_phy *phy, struct sk_buff *msg);
45 int (*set_eeprom)(struct mt76_phy *phy, u32 offset, u8 *val, u8 action);
46+ int (*dump_precal)(struct mt76_phy *phy, struct sk_buff *msg, int flag, int type);
47 };
48
49 struct mt76_testmode_entry_data {
50diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
developer36fe7092023-09-27 12:24:47 +080051index e3980c37..acbc07da 100644
developer27b55252022-09-05 19:09:45 +080052--- a/mt76_connac_mcu.h
53+++ b/mt76_connac_mcu.h
developer36fe7092023-09-27 12:24:47 +080054@@ -994,6 +994,7 @@ enum {
developer27b55252022-09-05 19:09:45 +080055
56 /* ext event table */
57 enum {
58+ MCU_EXT_EVENT_RF_TEST = 0x4,
59 MCU_EXT_EVENT_PS_SYNC = 0x5,
60 MCU_EXT_EVENT_FW_LOG_2_HOST = 0x13,
61 MCU_EXT_EVENT_THERMAL_PROTECT = 0x22,
62diff --git a/mt7915/eeprom.h b/mt7915/eeprom.h
developer36fe7092023-09-27 12:24:47 +080063index f3e56817..88aaa16a 100644
developer27b55252022-09-05 19:09:45 +080064--- a/mt7915/eeprom.h
65+++ b/mt7915/eeprom.h
66@@ -39,10 +39,18 @@ enum mt7915_eeprom_field {
67 };
68
69 #define MT_EE_WIFI_CAL_GROUP BIT(0)
70-#define MT_EE_WIFI_CAL_DPD GENMASK(2, 1)
71+#define MT_EE_WIFI_CAL_DPD_2G BIT(2)
72+#define MT_EE_WIFI_CAL_DPD_5G BIT(1)
73+#define MT_EE_WIFI_CAL_DPD_6G BIT(3)
74+#define MT_EE_WIFI_CAL_DPD GENMASK(3, 1)
75 #define MT_EE_CAL_UNIT 1024
76-#define MT_EE_CAL_GROUP_SIZE (49 * MT_EE_CAL_UNIT + 16)
77-#define MT_EE_CAL_DPD_SIZE (54 * MT_EE_CAL_UNIT)
78+#define MT_EE_CAL_GROUP_SIZE_7915 (49 * MT_EE_CAL_UNIT + 16)
79+#define MT_EE_CAL_GROUP_SIZE_7916 (54 * MT_EE_CAL_UNIT + 16)
80+#define MT_EE_CAL_GROUP_SIZE_7975 (54 * MT_EE_CAL_UNIT + 16)
81+#define MT_EE_CAL_GROUP_SIZE_7976 (94 * MT_EE_CAL_UNIT + 16)
82+#define MT_EE_CAL_GROUP_SIZE_7916_6G (94 * MT_EE_CAL_UNIT + 16)
83+#define MT_EE_CAL_DPD_SIZE_V1 (54 * MT_EE_CAL_UNIT)
84+#define MT_EE_CAL_DPD_SIZE_V2 (300 * MT_EE_CAL_UNIT)
85
86 #define MT_EE_WIFI_CONF0_TX_PATH GENMASK(2, 0)
87 #define MT_EE_WIFI_CONF0_BAND_SEL GENMASK(7, 6)
developerf1313102022-10-11 11:02:55 +080088@@ -155,6 +163,26 @@ mt7915_tssi_enabled(struct mt7915_dev *dev, enum nl80211_band band)
developer27b55252022-09-05 19:09:45 +080089 return val & MT_EE_WIFI_CONF7_TSSI0_5G;
90 }
91
92+static inline u32
93+mt7915_get_cal_group_size(struct mt7915_dev *dev)
94+{
95+ u8 *eep = dev->mt76.eeprom.data;
96+ u32 val;
97+
98+ if (is_mt7915(&dev->mt76)) {
99+ return MT_EE_CAL_GROUP_SIZE_7915;
100+ } else if (is_mt7916(&dev->mt76)) {
101+ val = eep[MT_EE_WIFI_CONF + 1];
102+ val = FIELD_GET(MT_EE_WIFI_CONF0_BAND_SEL, val);
103+ return (val == MT_EE_V2_BAND_SEL_6GHZ) ? MT_EE_CAL_GROUP_SIZE_7916_6G :
104+ MT_EE_CAL_GROUP_SIZE_7916;
105+ } else if (mt7915_check_adie(dev, false)) {
106+ return MT_EE_CAL_GROUP_SIZE_7976;
107+ } else {
108+ return MT_EE_CAL_GROUP_SIZE_7975;
109+ }
110+}
111+
112 extern const u8 mt7915_sku_group_len[MAX_SKU_RATE_GROUP_NUM];
113
114 #endif
115diff --git a/mt7915/mcu.c b/mt7915/mcu.c
developer36fe7092023-09-27 12:24:47 +0800116index 6a5f204c..b6f50daf 100644
developer27b55252022-09-05 19:09:45 +0800117--- a/mt7915/mcu.c
118+++ b/mt7915/mcu.c
developer36fe7092023-09-27 12:24:47 +0800119@@ -393,6 +393,9 @@ mt7915_mcu_rx_ext_event(struct mt7915_dev *dev, struct sk_buff *skb)
developer27b55252022-09-05 19:09:45 +0800120 case MCU_EXT_EVENT_BF_STATUS_READ:
121 mt7915_tm_txbf_status_read(dev, skb);
122 break;
123+ case MCU_EXT_EVENT_RF_TEST:
124+ mt7915_tm_rf_test_event(dev, skb);
125+ break;
126 #endif
127 default:
128 break;
developer36fe7092023-09-27 12:24:47 +0800129@@ -2930,7 +2933,7 @@ int mt7915_mcu_apply_group_cal(struct mt7915_dev *dev)
developer27b55252022-09-05 19:09:45 +0800130 u8 idx = 0, *cal = dev->cal, *eep = dev->mt76.eeprom.data;
131 u32 total = MT_EE_CAL_GROUP_SIZE;
132
133- if (1 || !(eep[MT_EE_DO_PRE_CAL] & MT_EE_WIFI_CAL_GROUP))
134+ if (!(eep[offs] & MT_EE_WIFI_CAL_GROUP))
135 return 0;
136
137 /*
developer36fe7092023-09-27 12:24:47 +0800138@@ -3010,11 +3013,29 @@ int mt7915_mcu_apply_tx_dpd(struct mt7915_phy *phy)
developer27b55252022-09-05 19:09:45 +0800139 {
140 struct mt7915_dev *dev = phy->dev;
141 struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
142- u16 total = 2, center_freq = chandef->center_freq1;
143+ enum nl80211_band band = chandef->chan->band;
144+ u32 offs = is_mt7915(&dev->mt76) ? MT_EE_DO_PRE_CAL : MT_EE_DO_PRE_CAL_V2;
145+ u16 center_freq = chandef->center_freq1;
146 u8 *cal = dev->cal, *eep = dev->mt76.eeprom.data;
147+ u8 dpd_mask, cal_num = is_mt7915(&dev->mt76) ? 2 : 3;
148 int idx;
149
150- if (1 || !(eep[MT_EE_DO_PRE_CAL] & MT_EE_WIFI_CAL_DPD))
151+ switch (band) {
152+ case NL80211_BAND_2GHZ:
153+ dpd_mask = MT_EE_WIFI_CAL_DPD_2G;
154+ break;
155+ case NL80211_BAND_5GHZ:
156+ dpd_mask = MT_EE_WIFI_CAL_DPD_5G;
157+ break;
158+ case NL80211_BAND_6GHZ:
159+ dpd_mask = MT_EE_WIFI_CAL_DPD_6G;
160+ break;
161+ default:
162+ dpd_mask = 0;
163+ break;
164+ }
165+
166+ if (!(eep[offs] & dpd_mask))
167 return 0;
168
169 idx = mt7915_dpd_freq_idx(center_freq, chandef->width);
170diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
developer36fe7092023-09-27 12:24:47 +0800171index c91415f7..863624f4 100644
developer27b55252022-09-05 19:09:45 +0800172--- a/mt7915/mt7915.h
173+++ b/mt7915/mt7915.h
developer36fe7092023-09-27 12:24:47 +0800174@@ -355,6 +355,10 @@ struct mt7915_dev {
developer27b55252022-09-05 19:09:45 +0800175 struct rchan *relay_fwlog;
176
177 void *cal;
178+ u32 cur_prek_offset;
179+ u8 dpd_chan_num_2g;
180+ u8 dpd_chan_num_5g;
181+ u8 dpd_chan_num_6g;
182
183 struct {
184 u8 debug_wm;
developer36fe7092023-09-27 12:24:47 +0800185@@ -591,6 +595,7 @@ int mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level);
developer27b55252022-09-05 19:09:45 +0800186 void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb);
187 void mt7915_mcu_exit(struct mt7915_dev *dev);
188 int mt7915_tm_txbf_status_read(struct mt7915_dev *dev, struct sk_buff *skb);
189+void mt7915_tm_rf_test_event(struct mt7915_dev *dev, struct sk_buff *skb);
190
191 static inline u16 mt7915_wtbl_size(struct mt7915_dev *dev)
192 {
193diff --git a/mt7915/testmode.c b/mt7915/testmode.c
developer36fe7092023-09-27 12:24:47 +0800194index 1e72bf2a..7d285ebc 100644
developer27b55252022-09-05 19:09:45 +0800195--- a/mt7915/testmode.c
196+++ b/mt7915/testmode.c
197@@ -5,6 +5,7 @@
198 #include "mac.h"
199 #include "mcu.h"
200 #include "testmode.h"
201+#include "eeprom.h"
202
203 enum {
204 TM_CHANGED_TXPOWER,
developer36fe7092023-09-27 12:24:47 +0800205@@ -1599,18 +1600,16 @@ mt7915_tm_rf_switch_mode(struct mt7915_dev *dev, u32 oper)
developer27b55252022-09-05 19:09:45 +0800206 static int
207 mt7915_tm_set_tx_cont(struct mt7915_phy *phy, bool en)
208 {
209-#define TX_CONT_START 0x05
210-#define TX_CONT_STOP 0x06
211 struct mt7915_dev *dev = phy->dev;
212 struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
213 int freq1 = ieee80211_frequency_to_channel(chandef->center_freq1);
214 struct mt76_testmode_data *td = &phy->mt76->test;
215- u32 func_idx = en ? TX_CONT_START : TX_CONT_STOP;
216+ u32 func_idx = en ? RF_TEST_TX_CONT_START : RF_TEST_TX_CONT_STOP;
217 u8 rate_idx = td->tx_rate_idx, mode;
developer2458e702022-12-13 15:52:04 +0800218 u8 band = phy->mt76->band_idx;
developer27b55252022-09-05 19:09:45 +0800219 u16 rateval;
220 struct mt7915_tm_rf_test req = {
221- .action = 1,
222+ .action = RF_ACT_IN_RFTEST,
223 .icap_len = 120,
224 .op.rf.func_idx = cpu_to_le32(func_idx),
225 };
developer36fe7092023-09-27 12:24:47 +0800226@@ -1695,6 +1694,316 @@ out:
developer27b55252022-09-05 19:09:45 +0800227 sizeof(req), true);
228 }
229
230+static int
231+mt7915_tm_group_prek(struct mt7915_phy *phy, enum mt76_testmode_state state)
232+{
233+ u8 *eeprom;
234+ u32 i, group_size, dpd_size, size, offs, *pre_cal;
235+ int ret = 0;
236+ struct mt7915_dev *dev = phy->dev;
237+ struct mt76_dev *mdev = &dev->mt76;
238+ struct mt7915_tm_rf_test req = {
239+ .action = RF_ACT_IN_RFTEST,
240+ .icap_len = 8,
241+ .op.rf.func_idx = cpu_to_le32(RF_TEST_RE_CAL),
242+ };
243+
244+ if (!dev->flash_mode && !dev->bin_file_mode) {
245+ dev_err(dev->mt76.dev, "Currently not in FLASH or BIN MODE,return!\n");
246+ return 1;
247+ }
248+
249+ eeprom = mdev->eeprom.data;
250+ dev->cur_prek_offset = 0;
251+ group_size = mt7915_get_cal_group_size(dev);
252+ dpd_size = is_mt7915(&dev->mt76) ? MT_EE_CAL_DPD_SIZE_V1 : MT_EE_CAL_DPD_SIZE_V2;
253+ size = group_size + dpd_size;
254+ offs = is_mt7915(&dev->mt76) ? MT_EE_DO_PRE_CAL : MT_EE_DO_PRE_CAL_V2;
255+
256+ switch (state) {
257+ case MT76_TM_STATE_GROUP_PREK:
258+ req.op.rf.param.cal_param.func_data = cpu_to_le32(RF_PRE_CAL);
259+
260+ if (!dev->cal) {
261+ dev->cal = devm_kzalloc(mdev->dev, size, GFP_KERNEL);
262+ if (!dev->cal)
263+ return -ENOMEM;
264+ }
265+
266+ ret = mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(RF_TEST), &req,
267+ sizeof(req), true);
268+
269+ if (!ret)
270+ eeprom[offs] |= MT_EE_WIFI_CAL_GROUP;
271+ break;
272+ case MT76_TM_STATE_GROUP_PREK_DUMP:
273+ pre_cal = (u32 *)dev->cal;
274+ if (!pre_cal) {
275+ dev_info(dev->mt76.dev, "Not group pre-cal yet!\n");
276+ return ret;
277+ }
278+ dev_info(dev->mt76.dev, "Group Pre-Cal:\n");
279+ for (i = 0; i < (group_size / sizeof(u32)); i += 4) {
developer2458e702022-12-13 15:52:04 +0800280+ dev_info(dev->mt76.dev, "[0x%08lx] 0x%8x 0x%8x 0x%8x 0x%8x\n",
developer27b55252022-09-05 19:09:45 +0800281+ i * sizeof(u32), pre_cal[i], pre_cal[i + 1],
282+ pre_cal[i + 2], pre_cal[i + 3]);
283+ }
284+ break;
285+ case MT76_TM_STATE_GROUP_PREK_CLEAN:
286+ pre_cal = (u32 *)dev->cal;
287+ if (!pre_cal)
288+ return ret;
289+ memset(pre_cal, 0, group_size);
290+ eeprom[offs] &= ~MT_EE_WIFI_CAL_GROUP;
291+ break;
292+ default:
293+ return -EINVAL;
294+ }
295+ return ret;
296+}
297+
298+static int
299+mt7915_tm_dpd_prek(struct mt7915_phy *phy, enum mt76_testmode_state state)
300+{
301+#define DPD_2G_CH_BW20_BITMAP_0 0x444
302+#define DPD_5G_CH_BW20_BITMAP_0 0xffffc0ff
303+#define DPD_5G_CH_BW20_BITMAP_1 0x3
304+#define DPD_5G_CH_BW20_BITMAP_7915_0 0x7dffc0ff
305+#define DPD_6G_CH_BW20_BITMAP_0 0xffffffff
306+#define DPD_6G_CH_BW20_BITMAP_1 0x07ffffff
307+ bool is_set = false;
308+ u8 band, do_precal, *eeprom;
309+ u16 bw20_size, bw160_size;
310+ u32 i, j, *bw160_freq, bw160_5g_freq[] = {5250, 5570, 5815};
311+ u32 bw160_6g_freq[] = {6025, 6185, 6345, 6505, 6665, 6825, 6985};
312+ u32 shift, freq, group_size, dpd_size, size, offs, *pre_cal, dpd_ch_bw20_bitmap[2] = {0};
313+ __le32 func_data = 0;
314+ int ret = 0;
315+ struct mt7915_dev *dev = phy->dev;
316+ struct mt76_dev *mdev = &dev->mt76;
317+ struct mt76_phy *mphy = phy->mt76;
318+ struct cfg80211_chan_def chandef_backup, *chandef = &mphy->chandef;
319+ struct ieee80211_channel chan_backup, chan, *bw20_ch;
320+ struct mt7915_tm_rf_test req = {
321+ .action = RF_ACT_IN_RFTEST,
322+ .icap_len = 8,
323+ .op.rf.func_idx = cpu_to_le32(RF_TEST_RE_CAL),
324+ };
325+
326+ if (!dev->flash_mode && !dev->bin_file_mode) {
327+ dev_err(dev->mt76.dev, "Currently not in FLASH or BIN MODE,return!\n");
328+ return -EOPNOTSUPP;
329+ }
330+
331+ eeprom = mdev->eeprom.data;
332+ dev->cur_prek_offset = 0;
333+ group_size = mt7915_get_cal_group_size(dev);
334+ dev->dpd_chan_num_2g = hweight32(DPD_2G_CH_BW20_BITMAP_0);
335+ if (is_mt7915(&dev->mt76)) {
336+ dev->dpd_chan_num_5g = hweight32(DPD_5G_CH_BW20_BITMAP_7915_0);
337+ dev->dpd_chan_num_6g = 0;
338+ dpd_size = MT_EE_CAL_DPD_SIZE_V1;
339+ offs = MT_EE_DO_PRE_CAL;
340+ } else {
341+ dev->dpd_chan_num_5g = hweight32(DPD_5G_CH_BW20_BITMAP_0) +
342+ hweight32(DPD_5G_CH_BW20_BITMAP_1) +
343+ ARRAY_SIZE(bw160_5g_freq);
344+ dev->dpd_chan_num_6g = hweight32(DPD_6G_CH_BW20_BITMAP_0) +
345+ hweight32(DPD_6G_CH_BW20_BITMAP_1) +
346+ ARRAY_SIZE(bw160_6g_freq);
347+ dpd_size = MT_EE_CAL_DPD_SIZE_V2;
348+ offs = MT_EE_DO_PRE_CAL_V2;
349+ }
350+ size = group_size + dpd_size;
351+
352+ switch (state) {
353+ case MT76_TM_STATE_DPD_2G:
354+ if (!is_set) {
355+ func_data = cpu_to_le32(RF_DPD_FLAT_CAL);
356+ dpd_ch_bw20_bitmap[0] = DPD_2G_CH_BW20_BITMAP_0;
357+ bw20_ch = mphy->sband_2g.sband.channels;
358+ bw160_freq = NULL;
359+ bw160_size = 0;
360+ band = NL80211_BAND_2GHZ;
361+ do_precal = MT_EE_WIFI_CAL_DPD_2G;
362+ is_set = true;
363+ }
364+ fallthrough;
365+ case MT76_TM_STATE_DPD_5G:
366+ if (!is_set) {
367+ if (is_mt7915(&dev->mt76)) {
368+ func_data = cpu_to_le32(RF_DPD_FLAT_CAL);
369+ dpd_ch_bw20_bitmap[0] = DPD_5G_CH_BW20_BITMAP_7915_0;
370+ bw160_size = 0;
371+ dev->cur_prek_offset -= dev->dpd_chan_num_5g * MT_EE_CAL_UNIT * 2;
372+ } else {
373+ func_data = cpu_to_le32(RF_DPD_FLAT_5G_CAL);
374+ dpd_ch_bw20_bitmap[0] = DPD_5G_CH_BW20_BITMAP_0;
375+ dpd_ch_bw20_bitmap[1] = DPD_5G_CH_BW20_BITMAP_1;
376+ bw160_size = ARRAY_SIZE(bw160_5g_freq);
377+ }
378+ bw20_ch = mphy->sband_5g.sband.channels;
379+ bw160_freq = bw160_5g_freq;
380+ band = NL80211_BAND_5GHZ;
381+ do_precal = MT_EE_WIFI_CAL_DPD_5G;
382+ is_set = true;
383+ }
384+ fallthrough;
385+ case MT76_TM_STATE_DPD_6G:
386+ if (!is_set) {
387+ func_data = cpu_to_le32(RF_DPD_FLAT_6G_CAL);
388+ dpd_ch_bw20_bitmap[0] = DPD_6G_CH_BW20_BITMAP_0;
389+ dpd_ch_bw20_bitmap[1] = DPD_6G_CH_BW20_BITMAP_1;
390+ bw20_ch = mphy->sband_6g.sband.channels;
391+ bw160_freq = bw160_6g_freq;
392+ bw160_size = ARRAY_SIZE(bw160_6g_freq);
393+ band = NL80211_BAND_6GHZ;
394+ do_precal = MT_EE_WIFI_CAL_DPD_6G;
395+ is_set = true;
396+ }
397+
398+ if (!bw20_ch)
399+ return -EOPNOTSUPP;
400+ if (!dev->cal) {
401+ dev->cal = devm_kzalloc(mdev->dev, size, GFP_KERNEL);
402+ if (!dev->cal)
403+ return -ENOMEM;
404+ }
405+
406+ req.op.rf.param.cal_param.func_data = func_data;
developer2458e702022-12-13 15:52:04 +0800407+ req.op.rf.param.cal_param.band_idx = phy->mt76->band_idx;
developer27b55252022-09-05 19:09:45 +0800408+
409+ memcpy(&chan_backup, chandef->chan, sizeof(struct ieee80211_channel));
410+ memcpy(&chandef_backup, chandef, sizeof(struct cfg80211_chan_def));
411+
412+ bw20_size = hweight32(dpd_ch_bw20_bitmap[0]) + hweight32(dpd_ch_bw20_bitmap[1]);
413+ for (i = 0, j = 0; i < bw20_size + bw160_size; i++) {
414+ if (i < bw20_size) {
415+ freq = dpd_ch_bw20_bitmap[0] ? 0 : 1;
416+ shift = ffs(dpd_ch_bw20_bitmap[freq]);
417+ j += shift;
418+ memcpy(&chan, &bw20_ch[j - 1], sizeof(struct ieee80211_channel));
419+ chandef->width = NL80211_CHAN_WIDTH_20;
420+ dpd_ch_bw20_bitmap[0] >>= shift;
421+ } else {
422+ freq = bw160_freq[i - bw20_size];
423+ chan.center_freq = freq;
424+ chan.hw_value = ieee80211_frequency_to_channel(freq);
425+ chan.band = band;
426+ chandef->width = NL80211_CHAN_WIDTH_160;
427+ }
428+
429+ memcpy(chandef->chan, &chan, sizeof(struct ieee80211_channel));
430+ if (is_mt7915(&dev->mt76))
431+ mphy->hw->conf.flags &= ~IEEE80211_CONF_OFFCHANNEL;
432+ else
433+ mphy->hw->conf.flags |= IEEE80211_CONF_OFFCHANNEL;
434+
435+ mt7915_mcu_set_chan_info(phy, MCU_EXT_CMD(CHANNEL_SWITCH));
436+
437+ ret = mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(RF_TEST), &req,
438+ sizeof(req), true);
439+ if (ret) {
440+ dev_err(dev->mt76.dev, "DPD Pre-cal: mcu send msg failed!\n");
441+ break;
442+ }
443+ }
444+ memcpy(chandef, &chandef_backup, sizeof(struct cfg80211_chan_def));
445+ memcpy(chandef->chan, &chan_backup, sizeof(struct ieee80211_channel));
446+ mt7915_mcu_set_chan_info(phy, MCU_EXT_CMD(CHANNEL_SWITCH));
447+
448+ if (!ret)
449+ eeprom[offs] |= do_precal;
450+
451+ break;
452+ case MT76_TM_STATE_DPD_DUMP:
453+ pre_cal = (u32 *)dev->cal;
454+ if (!dev->cal) {
455+ dev_info(dev->mt76.dev, "Not DPD pre-cal yet!\n");
456+ return ret;
457+ }
458+ dev_info(dev->mt76.dev, "DPD Pre-Cal:\n");
459+ for (i = 0; i < dpd_size / sizeof(u32); i += 4) {
460+ j = i + (group_size / sizeof(u32));
developer2458e702022-12-13 15:52:04 +0800461+ dev_info(dev->mt76.dev, "[0x%08lx] 0x%8x 0x%8x 0x%8x 0x%8x\n",
developer27b55252022-09-05 19:09:45 +0800462+ j * sizeof(u32), pre_cal[j], pre_cal[j + 1],
463+ pre_cal[j + 2], pre_cal[j + 3]);
464+ }
465+ break;
466+ case MT76_TM_STATE_DPD_CLEAN:
467+ pre_cal = (u32 *)dev->cal;
468+ if (!pre_cal)
469+ return ret;
470+ memset(pre_cal + (group_size / sizeof(u32)), 0, dpd_size);
471+ do_precal = MT_EE_WIFI_CAL_DPD;
472+ eeprom[offs] &= ~do_precal;
473+ break;
474+ default:
475+ return -EINVAL;
476+ }
477+ return ret;
478+}
479+
480+void mt7915_tm_re_cal_event(struct mt7915_dev *dev, struct mt7915_tm_rf_test_result *result,
481+ struct mt7915_tm_rf_test_data *data)
482+{
483+#define DPD_PER_CHAN_SIZE_7915 2
484+#define DPD_PER_CHAN_SIZE_7986 3
485+ u32 base, dpd_offest_2g, dpd_offest_5g, cal_idx = 0, cal_type = 0, len = 0;
486+ u8 *pre_cal;
487+
488+ pre_cal = dev->cal;
489+ dpd_offest_5g = dev->dpd_chan_num_6g * DPD_PER_CHAN_SIZE_7986 * MT_EE_CAL_UNIT;
490+ dpd_offest_2g = dpd_offest_5g + dev->dpd_chan_num_5g * MT_EE_CAL_UNIT *
491+ (is_mt7915(&dev->mt76) ? DPD_PER_CHAN_SIZE_7915 : DPD_PER_CHAN_SIZE_7986);
492+ cal_idx = le32_to_cpu(data->cal_idx);
493+ cal_type = le32_to_cpu(data->cal_type);
494+ len = le32_to_cpu(result->payload_len);
495+ len = len - sizeof(struct mt7915_tm_rf_test_data);
496+
497+ switch (cal_type) {
498+ case RF_PRE_CAL:
499+ base = 0;
500+ break;
501+ case RF_DPD_FLAT_CAL:
502+ base = mt7915_get_cal_group_size(dev) + dpd_offest_2g;
503+ break;
504+ case RF_DPD_FLAT_5G_CAL:
505+ base = mt7915_get_cal_group_size(dev) + dpd_offest_5g;
506+ break;
507+ case RF_DPD_FLAT_6G_CAL:
508+ base = mt7915_get_cal_group_size(dev);
509+ break;
510+ default:
511+ dev_info(dev->mt76.dev, "Unknown calibration type!\n");
512+ return;
513+ }
514+ pre_cal += (base + dev->cur_prek_offset);
515+
516+ memcpy(pre_cal, data->data, len);
517+ dev->cur_prek_offset += len;
518+}
519+
520+void mt7915_tm_rf_test_event(struct mt7915_dev *dev, struct sk_buff *skb)
521+{
522+ struct mt7915_tm_rf_test_result *result;
523+ struct mt7915_tm_rf_test_data *data;
524+ static u32 event_type;
525+
526+ result = (struct mt7915_tm_rf_test_result *)skb->data;
527+ data = (struct mt7915_tm_rf_test_data *)result->event;
528+
529+ event_type = le32_to_cpu(result->func_idx);
530+
531+ switch (event_type) {
532+ case RF_TEST_RE_CAL:
533+ mt7915_tm_re_cal_event(dev, result, data);
534+ break;
535+ default:
536+ break;
537+ }
538+}
539+
540 static void
541 mt7915_tm_update_params(struct mt7915_phy *phy, u32 changed)
542 {
developer36fe7092023-09-27 12:24:47 +0800543@@ -1739,6 +2048,10 @@ mt7915_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state)
developer27b55252022-09-05 19:09:45 +0800544 else if (prev_state == MT76_TM_STATE_OFF ||
545 state == MT76_TM_STATE_OFF)
546 mt7915_tm_init(phy, !(state == MT76_TM_STATE_OFF));
547+ else if (state >= MT76_TM_STATE_GROUP_PREK && state <= MT76_TM_STATE_GROUP_PREK_CLEAN)
548+ return mt7915_tm_group_prek(phy, state);
549+ else if (state >= MT76_TM_STATE_DPD_2G && state <= MT76_TM_STATE_DPD_CLEAN)
550+ return mt7915_tm_dpd_prek(phy, state);
551
552 if ((state == MT76_TM_STATE_IDLE &&
553 prev_state == MT76_TM_STATE_OFF) ||
developer36fe7092023-09-27 12:24:47 +0800554@@ -1909,9 +2222,113 @@ mt7915_tm_set_eeprom(struct mt76_phy *mphy, u32 offset, u8 *val, u8 action)
developer27b55252022-09-05 19:09:45 +0800555 return ret;
556 }
557
558+static int
559+mt7915_tm_dump_precal(struct mt76_phy *mphy, struct sk_buff *msg, int flag, int type)
560+{
developer32b0e0f2023-04-11 13:34:56 +0800561+#define DPD_PER_CHAN_SIZE_MASK GENMASK(31, 30)
562+#define DPD_CHAN_NUM_2G_MASK GENMASK(29, 20)
563+#define DPD_CHAN_NUM_5G_MASK GENMASK(19, 10)
564+#define DPD_CHAN_NUM_6G_MASK GENMASK(9, 0)
developer27b55252022-09-05 19:09:45 +0800565+ struct mt7915_phy *phy = mphy->priv;
566+ struct mt7915_dev *dev = phy->dev;
567+ u32 i, group_size, dpd_size, total_size, dpd_per_chan_size, dpd_info = 0;
568+ u32 base, size, total_chan_num, offs, transmit_size = 1000;
569+ u8 *pre_cal, *eeprom;
570+ void *precal;
571+ enum prek_ops {
572+ PREK_GET_INFO,
573+ PREK_SYNC_ALL,
574+ PREK_SYNC_GROUP,
575+ PREK_SYNC_DPD_2G,
576+ PREK_SYNC_DPD_5G,
577+ PREK_SYNC_DPD_6G,
578+ PREK_CLEAN_GROUP,
579+ PREK_CLEAN_DPD,
580+ };
581+
582+ if (!dev->cal) {
583+ dev_info(dev->mt76.dev, "Not pre-cal yet!\n");
584+ return 0;
585+ }
586+
587+ group_size = mt7915_get_cal_group_size(dev);
588+ dpd_size = is_mt7915(&dev->mt76) ? MT_EE_CAL_DPD_SIZE_V1 : MT_EE_CAL_DPD_SIZE_V2;
589+ dpd_per_chan_size = is_mt7915(&dev->mt76) ? 2 : 3;
590+ total_size = group_size + dpd_size;
591+ pre_cal = dev->cal;
592+ eeprom = dev->mt76.eeprom.data;
593+ offs = is_mt7915(&dev->mt76) ? MT_EE_DO_PRE_CAL : MT_EE_DO_PRE_CAL_V2;
594+
595+ total_chan_num = dev->dpd_chan_num_2g + dev->dpd_chan_num_5g + dev->dpd_chan_num_6g;
596+
597+ switch (type) {
598+ case PREK_SYNC_ALL:
599+ base = 0;
600+ size = total_size;
601+ break;
602+ case PREK_SYNC_GROUP:
603+ base = 0;
604+ size = group_size;
605+ break;
606+ case PREK_SYNC_DPD_6G:
607+ base = group_size;
608+ size = dpd_size * dev->dpd_chan_num_6g / total_chan_num;
609+ break;
610+ case PREK_SYNC_DPD_5G:
611+ base = group_size + dev->dpd_chan_num_6g * dpd_per_chan_size * MT_EE_CAL_UNIT;
612+ size = dpd_size * dev->dpd_chan_num_5g / total_chan_num;
613+ break;
614+ case PREK_SYNC_DPD_2G:
615+ base = group_size + (dev->dpd_chan_num_6g + dev->dpd_chan_num_5g) *
616+ dpd_per_chan_size * MT_EE_CAL_UNIT;
617+ size = dpd_size * dev->dpd_chan_num_2g / total_chan_num;
618+ break;
619+ case PREK_GET_INFO:
620+ break;
621+ default:
622+ return 0;
623+ }
624+
625+ if (!flag) {
626+ if (eeprom[offs] & MT_EE_WIFI_CAL_DPD) {
627+ dpd_info |= u32_encode_bits(dpd_per_chan_size, DPD_PER_CHAN_SIZE_MASK) |
628+ u32_encode_bits(dev->dpd_chan_num_2g, DPD_CHAN_NUM_2G_MASK) |
629+ u32_encode_bits(dev->dpd_chan_num_5g, DPD_CHAN_NUM_5G_MASK) |
630+ u32_encode_bits(dev->dpd_chan_num_6g, DPD_CHAN_NUM_6G_MASK);
631+ }
632+ dev->cur_prek_offset = 0;
633+ precal = nla_nest_start(msg, MT76_TM_ATTR_PRECAL_INFO);
634+ if (!precal)
635+ return -ENOMEM;
636+ nla_put_u32(msg, 0, group_size);
637+ nla_put_u32(msg, 1, dpd_size);
638+ nla_put_u32(msg, 2, dpd_info);
639+ nla_put_u32(msg, 3, transmit_size);
640+ nla_put_u32(msg, 4, eeprom[offs]);
641+ nla_nest_end(msg, precal);
642+ } else {
643+ precal = nla_nest_start(msg, MT76_TM_ATTR_PRECAL);
644+ if (!precal)
645+ return -ENOMEM;
646+
647+ transmit_size = (dev->cur_prek_offset + transmit_size < size) ?
648+ transmit_size : (size - dev->cur_prek_offset);
649+ for (i = 0; i < transmit_size; i++) {
650+ if (nla_put_u8(msg, i, pre_cal[base + dev->cur_prek_offset + i]))
651+ return -ENOMEM;
652+ }
653+ dev->cur_prek_offset += transmit_size;
654+
655+ nla_nest_end(msg, precal);
656+ }
657+
658+ return 0;
659+}
660+
661 const struct mt76_testmode_ops mt7915_testmode_ops = {
662 .set_state = mt7915_tm_set_state,
663 .set_params = mt7915_tm_set_params,
664 .dump_stats = mt7915_tm_dump_stats,
665 .set_eeprom = mt7915_tm_set_eeprom,
666+ .dump_precal = mt7915_tm_dump_precal,
667 };
668diff --git a/mt7915/testmode.h b/mt7915/testmode.h
developer36fe7092023-09-27 12:24:47 +0800669index eb0e0432..75698261 100644
developer27b55252022-09-05 19:09:45 +0800670--- a/mt7915/testmode.h
671+++ b/mt7915/testmode.h
672@@ -81,6 +81,11 @@ struct tm_tx_cont {
673 u8 txfd_mode;
674 };
675
676+struct tm_cal_param {
677+ __le32 func_data;
678+ u8 band_idx;
679+};
680+
681 struct mt7915_tm_rf_test {
682 u8 action;
683 u8 icap_len;
684@@ -96,6 +101,7 @@ struct mt7915_tm_rf_test {
685 __le32 cal_dump;
686
687 struct tm_tx_cont tx_cont;
688+ struct tm_cal_param cal_param;
689
690 u8 _pad[80];
691 } param;
692@@ -103,6 +109,20 @@ struct mt7915_tm_rf_test {
693 } op;
694 } __packed;
695
696+struct mt7915_tm_rf_test_result {
697+ struct mt76_connac2_mcu_rxd rxd;
698+
699+ u32 func_idx;
700+ u32 payload_len;
701+ u8 event[0];
702+} __packed;
703+
704+struct mt7915_tm_rf_test_data {
705+ u32 cal_idx;
706+ u32 cal_type;
707+ u8 data[0];
708+} __packed;
709+
710 enum {
711 RF_OPER_NORMAL,
712 RF_OPER_RF_TEST,
713@@ -111,6 +131,22 @@ enum {
714 RF_OPER_WIFI_SPECTRUM,
715 };
716
717+enum {
718+ RF_ACT_SWITCH_MODE,
719+ RF_ACT_IN_RFTEST,
720+};
721+
722+enum {
723+ RF_TEST_RE_CAL = 0x01,
724+ RF_TEST_TX_CONT_START = 0x05,
725+ RF_TEST_TX_CONT_STOP = 0x06,
726+};
727+
728+#define RF_DPD_FLAT_CAL BIT(28)
729+#define RF_PRE_CAL BIT(29)
730+#define RF_DPD_FLAT_5G_CAL GENMASK(29, 28)
731+#define RF_DPD_FLAT_6G_CAL (BIT(30) | BIT(28))
732+
733 enum {
734 TAM_ARB_OP_MODE_NORMAL = 1,
735 TAM_ARB_OP_MODE_TEST,
736diff --git a/testmode.c b/testmode.c
developer36fe7092023-09-27 12:24:47 +0800737index d2cef5b9..b1b643c3 100644
developer27b55252022-09-05 19:09:45 +0800738--- a/testmode.c
739+++ b/testmode.c
developer2b96a9e2023-08-09 10:28:15 +0800740@@ -767,6 +767,18 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
developer27b55252022-09-05 19:09:45 +0800741
742 mutex_lock(&dev->mutex);
743
744+ if (tb[MT76_TM_ATTR_PRECAL] || tb[MT76_TM_ATTR_PRECAL_INFO]) {
745+ int flag, type;
746+
747+ err = -EINVAL;
748+ flag = tb[MT76_TM_ATTR_PRECAL] ? 1 : 0;
749+ type = flag ? nla_get_u8(tb[MT76_TM_ATTR_PRECAL_INFO]) : 0;
750+ if (dev->test_ops->dump_precal)
751+ err = dev->test_ops->dump_precal(phy, msg, flag, type);
752+
753+ goto out;
754+ }
755+
756 if (tb[MT76_TM_ATTR_STATS]) {
757 err = -EINVAL;
758
developer2b96a9e2023-08-09 10:28:15 +0800759@@ -800,7 +812,8 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
developer27b55252022-09-05 19:09:45 +0800760
761 if (dev->test_mtd.name &&
762 (nla_put_string(msg, MT76_TM_ATTR_MTD_PART, dev->test_mtd.name) ||
763- nla_put_u32(msg, MT76_TM_ATTR_MTD_OFFSET, dev->test_mtd.offset)))
764+ nla_put_u32(msg, MT76_TM_ATTR_MTD_OFFSET, dev->test_mtd.offset) ||
developerb9a96602023-01-10 19:53:25 +0800765+ nla_put_u8(msg, MT76_TM_ATTR_BAND_IDX, phy->band_idx)))
developer27b55252022-09-05 19:09:45 +0800766 goto out;
767
768 if (nla_put_u32(msg, MT76_TM_ATTR_TX_COUNT, td->tx_count) ||
769diff --git a/testmode.h b/testmode.h
developer36fe7092023-09-27 12:24:47 +0800770index 8c55fa0f..109a556a 100644
developer27b55252022-09-05 19:09:45 +0800771--- a/testmode.h
772+++ b/testmode.h
773@@ -19,6 +19,7 @@
774 *
775 * @MT76_TM_ATTR_MTD_PART: mtd partition used for eeprom data (string)
776 * @MT76_TM_ATTR_MTD_OFFSET: offset of eeprom data within the partition (u32)
developerb9a96602023-01-10 19:53:25 +0800777+ * @MT76_TM_ATTR_BAND_IDX: band idx of the chip (u8)
developer27b55252022-09-05 19:09:45 +0800778 *
779 * @MT76_TM_ATTR_TX_COUNT: configured number of frames to send when setting
780 * state to MT76_TM_STATE_TX_FRAMES (u32)
781@@ -40,6 +41,11 @@
782 *
783 * @MT76_TM_ATTR_STATS: statistics (nested, see &enum mt76_testmode_stats_attr)
784 *
785+ * @MT76_TM_ATTR_PRECAL: Pre-cal data (u8)
786+ * @MT76_TM_ATTR_PRECAL_INFO: group size, dpd size, dpd_info, transmit size,
787+ * eeprom cal indicator (u32),
788+ * dpd_info = [dpd_per_chan_size, chan_num_2g,
789+ * chan_num_5g, chan_num_6g]
790 * @MT76_TM_ATTR_TX_SPE_IDX: tx spatial extension index (u8)
791 *
792 * @MT76_TM_ATTR_TX_DUTY_CYCLE: packet tx duty cycle (u8)
793@@ -67,6 +73,7 @@ enum mt76_testmode_attr {
794
795 MT76_TM_ATTR_MTD_PART,
796 MT76_TM_ATTR_MTD_OFFSET,
developerb9a96602023-01-10 19:53:25 +0800797+ MT76_TM_ATTR_BAND_IDX,
developer27b55252022-09-05 19:09:45 +0800798
799 MT76_TM_ATTR_TX_COUNT,
800 MT76_TM_ATTR_TX_LENGTH,
801@@ -85,6 +92,8 @@ enum mt76_testmode_attr {
802 MT76_TM_ATTR_FREQ_OFFSET,
803
804 MT76_TM_ATTR_STATS,
805+ MT76_TM_ATTR_PRECAL,
806+ MT76_TM_ATTR_PRECAL_INFO,
807
808 MT76_TM_ATTR_TX_SPE_IDX,
809
810@@ -184,6 +193,14 @@ enum mt76_testmode_state {
811 MT76_TM_STATE_TX_FRAMES,
812 MT76_TM_STATE_RX_FRAMES,
813 MT76_TM_STATE_TX_CONT,
814+ MT76_TM_STATE_GROUP_PREK,
815+ MT76_TM_STATE_GROUP_PREK_DUMP,
816+ MT76_TM_STATE_GROUP_PREK_CLEAN,
817+ MT76_TM_STATE_DPD_2G,
818+ MT76_TM_STATE_DPD_5G,
819+ MT76_TM_STATE_DPD_6G,
820+ MT76_TM_STATE_DPD_DUMP,
821+ MT76_TM_STATE_DPD_CLEAN,
822 MT76_TM_STATE_ON,
823
824 /* keep last */
825diff --git a/tools/fields.c b/tools/fields.c
developer36fe7092023-09-27 12:24:47 +0800826index 7e564a3b..3ca5cd1f 100644
developer27b55252022-09-05 19:09:45 +0800827--- a/tools/fields.c
828+++ b/tools/fields.c
829@@ -11,6 +11,14 @@ static const char * const testmode_state[] = {
830 [MT76_TM_STATE_TX_FRAMES] = "tx_frames",
831 [MT76_TM_STATE_RX_FRAMES] = "rx_frames",
832 [MT76_TM_STATE_TX_CONT] = "tx_cont",
833+ [MT76_TM_STATE_GROUP_PREK] = "group_prek",
834+ [MT76_TM_STATE_GROUP_PREK_DUMP] = "group_prek_dump",
835+ [MT76_TM_STATE_GROUP_PREK_CLEAN] = "group_prek_clean",
836+ [MT76_TM_STATE_DPD_2G] = "dpd_2g",
837+ [MT76_TM_STATE_DPD_5G] = "dpd_5g",
838+ [MT76_TM_STATE_DPD_6G] = "dpd_6g",
839+ [MT76_TM_STATE_DPD_DUMP] = "dpd_dump",
840+ [MT76_TM_STATE_DPD_CLEAN] = "dpd_clean",
841 };
842
843 static const char * const testmode_tx_mode[] = {
844--
developer36fe7092023-09-27 12:24:47 +08008452.39.2
developer27b55252022-09-05 19:09:45 +0800846