1 // SPDX-License-Identifier: ISC
2
3 #include "mt7615.h"
4
5 static int
mt7615_radar_pattern_set(void * data,u64 val)6 mt7615_radar_pattern_set(void *data, u64 val)
7 {
8 struct mt7615_dev *dev = data;
9 int err;
10
11 if (!mt7615_wait_for_mcu_init(dev))
12 return 0;
13
14 mt7615_mutex_acquire(dev);
15 err = mt7615_mcu_rdd_send_pattern(dev);
16 mt7615_mutex_release(dev);
17
18 return err;
19 }
20
21 DEFINE_DEBUGFS_ATTRIBUTE(fops_radar_pattern, NULL,
22 mt7615_radar_pattern_set, "%lld\n");
23
24 static int
mt7615_scs_set(void * data,u64 val)25 mt7615_scs_set(void *data, u64 val)
26 {
27 struct mt7615_dev *dev = data;
28 struct mt7615_phy *ext_phy;
29
30 if (!mt7615_wait_for_mcu_init(dev))
31 return 0;
32
33 mt7615_mac_set_scs(&dev->phy, val);
34 ext_phy = mt7615_ext_phy(dev);
35 if (ext_phy)
36 mt7615_mac_set_scs(ext_phy, val);
37
38 return 0;
39 }
40
41 static int
mt7615_scs_get(void * data,u64 * val)42 mt7615_scs_get(void *data, u64 *val)
43 {
44 struct mt7615_dev *dev = data;
45
46 *val = dev->phy.scs_en;
47
48 return 0;
49 }
50
51 DEFINE_DEBUGFS_ATTRIBUTE(fops_scs, mt7615_scs_get,
52 mt7615_scs_set, "%lld\n");
53
54 static int
mt7615_pm_set(void * data,u64 val)55 mt7615_pm_set(void *data, u64 val)
56 {
57 struct mt7615_dev *dev = data;
58
59 if (!mt7615_wait_for_mcu_init(dev))
60 return 0;
61
62 return mt7615_pm_set_enable(dev, val);
63 }
64
65 static int
mt7615_pm_get(void * data,u64 * val)66 mt7615_pm_get(void *data, u64 *val)
67 {
68 struct mt7615_dev *dev = data;
69
70 *val = dev->pm.enable;
71
72 return 0;
73 }
74
75 DEFINE_DEBUGFS_ATTRIBUTE(fops_pm, mt7615_pm_get, mt7615_pm_set, "%lld\n");
76
77 static int
mt7615_pm_idle_timeout_set(void * data,u64 val)78 mt7615_pm_idle_timeout_set(void *data, u64 val)
79 {
80 struct mt7615_dev *dev = data;
81
82 dev->pm.idle_timeout = msecs_to_jiffies(val);
83
84 return 0;
85 }
86
87 static int
mt7615_pm_idle_timeout_get(void * data,u64 * val)88 mt7615_pm_idle_timeout_get(void *data, u64 *val)
89 {
90 struct mt7615_dev *dev = data;
91
92 *val = jiffies_to_msecs(dev->pm.idle_timeout);
93
94 return 0;
95 }
96
97 DEFINE_DEBUGFS_ATTRIBUTE(fops_pm_idle_timeout, mt7615_pm_idle_timeout_get,
98 mt7615_pm_idle_timeout_set, "%lld\n");
99
100 static int
mt7615_dbdc_set(void * data,u64 val)101 mt7615_dbdc_set(void *data, u64 val)
102 {
103 struct mt7615_dev *dev = data;
104
105 if (!mt7615_wait_for_mcu_init(dev))
106 return 0;
107
108 if (val)
109 mt7615_register_ext_phy(dev);
110 else
111 mt7615_unregister_ext_phy(dev);
112
113 return 0;
114 }
115
116 static int
mt7615_dbdc_get(void * data,u64 * val)117 mt7615_dbdc_get(void *data, u64 *val)
118 {
119 struct mt7615_dev *dev = data;
120
121 *val = !!mt7615_ext_phy(dev);
122
123 return 0;
124 }
125
126 DEFINE_DEBUGFS_ATTRIBUTE(fops_dbdc, mt7615_dbdc_get,
127 mt7615_dbdc_set, "%lld\n");
128
129 static int
mt7615_fw_debug_set(void * data,u64 val)130 mt7615_fw_debug_set(void *data, u64 val)
131 {
132 struct mt7615_dev *dev = data;
133
134 if (!mt7615_wait_for_mcu_init(dev))
135 return 0;
136
137 dev->fw_debug = val;
138
139 mt7615_mutex_acquire(dev);
140 mt7615_mcu_fw_log_2_host(dev, dev->fw_debug ? 2 : 0);
141 mt7615_mutex_release(dev);
142
143 return 0;
144 }
145
146 static int
mt7615_fw_debug_get(void * data,u64 * val)147 mt7615_fw_debug_get(void *data, u64 *val)
148 {
149 struct mt7615_dev *dev = data;
150
151 *val = dev->fw_debug;
152
153 return 0;
154 }
155
156 DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug, mt7615_fw_debug_get,
157 mt7615_fw_debug_set, "%lld\n");
158
159 static int
mt7615_reset_test_set(void * data,u64 val)160 mt7615_reset_test_set(void *data, u64 val)
161 {
162 struct mt7615_dev *dev = data;
163 struct sk_buff *skb;
164
165 if (!mt7615_wait_for_mcu_init(dev))
166 return 0;
167
168 skb = alloc_skb(1, GFP_KERNEL);
169 if (!skb)
170 return -ENOMEM;
171
172 skb_put(skb, 1);
173
174 mt7615_mutex_acquire(dev);
175 mt76_tx_queue_skb_raw(dev, 0, skb, 0);
176 mt7615_mutex_release(dev);
177
178 return 0;
179 }
180
181 DEFINE_DEBUGFS_ATTRIBUTE(fops_reset_test, NULL,
182 mt7615_reset_test_set, "%lld\n");
183
184 static void
mt7615_ampdu_stat_read_phy(struct mt7615_phy * phy,struct seq_file * file)185 mt7615_ampdu_stat_read_phy(struct mt7615_phy *phy,
186 struct seq_file *file)
187 {
188 struct mt7615_dev *dev = file->private;
189 u32 reg = is_mt7663(&dev->mt76) ? MT_MIB_ARNG(0) : MT_AGG_ASRCR0;
190 bool ext_phy = phy != &dev->phy;
191 int bound[7], i, range;
192
193 if (!phy)
194 return;
195
196 range = mt76_rr(dev, reg);
197 for (i = 0; i < 4; i++)
198 bound[i] = MT_AGG_ASRCR_RANGE(range, i) + 1;
199
200 range = mt76_rr(dev, reg + 4);
201 for (i = 0; i < 3; i++)
202 bound[i + 4] = MT_AGG_ASRCR_RANGE(range, i) + 1;
203
204 seq_printf(file, "\nPhy %d\n", ext_phy);
205
206 seq_printf(file, "Length: %8d | ", bound[0]);
207 for (i = 0; i < ARRAY_SIZE(bound) - 1; i++)
208 seq_printf(file, "%3d -%3d | ",
209 bound[i], bound[i + 1]);
210 seq_puts(file, "\nCount: ");
211
212 range = ext_phy ? ARRAY_SIZE(dev->mt76.aggr_stats) / 2 : 0;
213 for (i = 0; i < ARRAY_SIZE(bound); i++)
214 seq_printf(file, "%8d | ", dev->mt76.aggr_stats[i + range]);
215 seq_puts(file, "\n");
216
217 seq_printf(file, "BA miss count: %d\n", phy->mib.ba_miss_cnt);
218 seq_printf(file, "PER: %ld.%1ld%%\n",
219 phy->mib.aggr_per / 10, phy->mib.aggr_per % 10);
220 }
221
222 static int
mt7615_ampdu_stat_show(struct seq_file * file,void * data)223 mt7615_ampdu_stat_show(struct seq_file *file, void *data)
224 {
225 struct mt7615_dev *dev = file->private;
226
227 mt7615_mutex_acquire(dev);
228
229 mt7615_ampdu_stat_read_phy(&dev->phy, file);
230 mt7615_ampdu_stat_read_phy(mt7615_ext_phy(dev), file);
231
232 mt7615_mutex_release(dev);
233
234 return 0;
235 }
236
237 DEFINE_SHOW_ATTRIBUTE(mt7615_ampdu_stat);
238
239 static void
mt7615_radio_read_phy(struct mt7615_phy * phy,struct seq_file * s)240 mt7615_radio_read_phy(struct mt7615_phy *phy, struct seq_file *s)
241 {
242 struct mt7615_dev *dev = dev_get_drvdata(s->private);
243 bool ext_phy = phy != &dev->phy;
244
245 if (!phy)
246 return;
247
248 seq_printf(s, "Radio %d sensitivity: ofdm=%d cck=%d\n", ext_phy,
249 phy->ofdm_sensitivity, phy->cck_sensitivity);
250 seq_printf(s, "Radio %d false CCA: ofdm=%d cck=%d\n", ext_phy,
251 phy->false_cca_ofdm, phy->false_cca_cck);
252 }
253
254 static int
mt7615_radio_read(struct seq_file * s,void * data)255 mt7615_radio_read(struct seq_file *s, void *data)
256 {
257 struct mt7615_dev *dev = dev_get_drvdata(s->private);
258
259 mt7615_radio_read_phy(&dev->phy, s);
260 mt7615_radio_read_phy(mt7615_ext_phy(dev), s);
261
262 return 0;
263 }
264
mt7615_read_temperature(struct seq_file * s,void * data)265 static int mt7615_read_temperature(struct seq_file *s, void *data)
266 {
267 struct mt7615_dev *dev = dev_get_drvdata(s->private);
268 int temp;
269
270 if (!mt7615_wait_for_mcu_init(dev))
271 return 0;
272
273 /* cpu */
274 mt7615_mutex_acquire(dev);
275 temp = mt7615_mcu_get_temperature(dev, 0);
276 mt7615_mutex_release(dev);
277
278 seq_printf(s, "Temperature: %d\n", temp);
279
280 return 0;
281 }
282
283 static int
mt7615_queues_acq(struct seq_file * s,void * data)284 mt7615_queues_acq(struct seq_file *s, void *data)
285 {
286 struct mt7615_dev *dev = dev_get_drvdata(s->private);
287 int i;
288
289 mt7615_mutex_acquire(dev);
290
291 for (i = 0; i < 16; i++) {
292 int j, wmm_idx = i % MT7615_MAX_WMM_SETS;
293 int acs = i / MT7615_MAX_WMM_SETS;
294 u32 ctrl, val, qlen = 0;
295
296 val = mt76_rr(dev, MT_PLE_AC_QEMPTY(acs, wmm_idx));
297 ctrl = BIT(31) | BIT(15) | (acs << 8);
298
299 for (j = 0; j < 32; j++) {
300 if (val & BIT(j))
301 continue;
302
303 mt76_wr(dev, MT_PLE_FL_Q0_CTRL,
304 ctrl | (j + (wmm_idx << 5)));
305 qlen += mt76_get_field(dev, MT_PLE_FL_Q3_CTRL,
306 GENMASK(11, 0));
307 }
308 seq_printf(s, "AC%d%d: queued=%d\n", wmm_idx, acs, qlen);
309 }
310
311 mt7615_mutex_release(dev);
312
313 return 0;
314 }
315
316 static int
mt7615_queues_read(struct seq_file * s,void * data)317 mt7615_queues_read(struct seq_file *s, void *data)
318 {
319 struct mt7615_dev *dev = dev_get_drvdata(s->private);
320 static const struct {
321 char *queue;
322 int id;
323 } queue_map[] = {
324 { "PDMA0", MT_TXQ_BE },
325 { "MCUQ", MT_TXQ_MCU },
326 { "MCUFWQ", MT_TXQ_FWDL },
327 };
328 int i;
329
330 for (i = 0; i < ARRAY_SIZE(queue_map); i++) {
331 struct mt76_queue *q = dev->mt76.q_tx[queue_map[i].id];
332
333 if (!q)
334 continue;
335
336 seq_printf(s,
337 "%s: queued=%d head=%d tail=%d\n",
338 queue_map[i].queue, q->queued, q->head,
339 q->tail);
340 }
341
342 return 0;
343 }
344
345 static int
mt7615_rf_reg_set(void * data,u64 val)346 mt7615_rf_reg_set(void *data, u64 val)
347 {
348 struct mt7615_dev *dev = data;
349
350 mt7615_rf_wr(dev, dev->debugfs_rf_wf, dev->debugfs_rf_reg, val);
351
352 return 0;
353 }
354
355 static int
mt7615_rf_reg_get(void * data,u64 * val)356 mt7615_rf_reg_get(void *data, u64 *val)
357 {
358 struct mt7615_dev *dev = data;
359
360 *val = mt7615_rf_rr(dev, dev->debugfs_rf_wf, dev->debugfs_rf_reg);
361
362 return 0;
363 }
364
365 DEFINE_DEBUGFS_ATTRIBUTE(fops_rf_reg, mt7615_rf_reg_get, mt7615_rf_reg_set,
366 "0x%08llx\n");
367
mt7615_init_debugfs(struct mt7615_dev * dev)368 int mt7615_init_debugfs(struct mt7615_dev *dev)
369 {
370 struct dentry *dir;
371
372 dir = mt76_register_debugfs(&dev->mt76);
373 if (!dir)
374 return -ENOMEM;
375
376 if (is_mt7615(&dev->mt76))
377 debugfs_create_devm_seqfile(dev->mt76.dev, "xmit-queues", dir,
378 mt7615_queues_read);
379 else
380 debugfs_create_devm_seqfile(dev->mt76.dev, "xmit-queues", dir,
381 mt76_queues_read);
382 debugfs_create_devm_seqfile(dev->mt76.dev, "acq", dir,
383 mt7615_queues_acq);
384 debugfs_create_file("ampdu_stat", 0400, dir, dev, &mt7615_ampdu_stat_fops);
385 debugfs_create_file("scs", 0600, dir, dev, &fops_scs);
386 debugfs_create_file("dbdc", 0600, dir, dev, &fops_dbdc);
387 debugfs_create_file("fw_debug", 0600, dir, dev, &fops_fw_debug);
388 debugfs_create_file("runtime-pm", 0600, dir, dev, &fops_pm);
389 debugfs_create_file("idle-timeout", 0600, dir, dev,
390 &fops_pm_idle_timeout);
391 debugfs_create_devm_seqfile(dev->mt76.dev, "radio", dir,
392 mt7615_radio_read);
393 debugfs_create_u32("dfs_hw_pattern", 0400, dir, &dev->hw_pattern);
394 /* test pattern knobs */
395 debugfs_create_u8("pattern_len", 0600, dir,
396 &dev->radar_pattern.n_pulses);
397 debugfs_create_u32("pulse_period", 0600, dir,
398 &dev->radar_pattern.period);
399 debugfs_create_u16("pulse_width", 0600, dir,
400 &dev->radar_pattern.width);
401 debugfs_create_u16("pulse_power", 0600, dir,
402 &dev->radar_pattern.power);
403 debugfs_create_file("radar_trigger", 0200, dir, dev,
404 &fops_radar_pattern);
405 debugfs_create_file("reset_test", 0200, dir, dev,
406 &fops_reset_test);
407 debugfs_create_devm_seqfile(dev->mt76.dev, "temperature", dir,
408 mt7615_read_temperature);
409
410 debugfs_create_u32("rf_wfidx", 0600, dir, &dev->debugfs_rf_wf);
411 debugfs_create_u32("rf_regidx", 0600, dir, &dev->debugfs_rf_reg);
412 debugfs_create_file_unsafe("rf_regval", 0600, dir, dev,
413 &fops_rf_reg);
414
415 return 0;
416 }
417 EXPORT_SYMBOL_GPL(mt7615_init_debugfs);
418