xref: /linux/drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c (revision 48dea9a700c8728cc31a1dd44588b97578de86ee)
1 // SPDX-License-Identifier: ISC
2 
3 #include "mt7615.h"
4 
5 static int
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
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
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
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
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
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
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
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
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
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
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
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 	mt7615_mutex_acquire(dev);
169 
170 	skb = alloc_skb(1, GFP_KERNEL);
171 	if (!skb)
172 		return -ENOMEM;
173 
174 	skb_put(skb, 1);
175 	mt76_tx_queue_skb_raw(dev, 0, skb, 0);
176 
177 	mt7615_mutex_release(dev);
178 
179 	return 0;
180 }
181 
182 DEFINE_DEBUGFS_ATTRIBUTE(fops_reset_test, NULL,
183 			 mt7615_reset_test_set, "%lld\n");
184 
185 static void
186 mt7615_ampdu_stat_read_phy(struct mt7615_phy *phy,
187 			   struct seq_file *file)
188 {
189 	struct mt7615_dev *dev = file->private;
190 	u32 reg = is_mt7663(&dev->mt76) ? MT_MIB_ARNG(0) : MT_AGG_ASRCR0;
191 	bool ext_phy = phy != &dev->phy;
192 	int bound[7], i, range;
193 
194 	if (!phy)
195 		return;
196 
197 	range = mt76_rr(dev, reg);
198 	for (i = 0; i < 4; i++)
199 		bound[i] = MT_AGG_ASRCR_RANGE(range, i) + 1;
200 
201 	range = mt76_rr(dev, reg + 4);
202 	for (i = 0; i < 3; i++)
203 		bound[i + 4] = MT_AGG_ASRCR_RANGE(range, i) + 1;
204 
205 	seq_printf(file, "\nPhy %d\n", ext_phy);
206 
207 	seq_printf(file, "Length: %8d | ", bound[0]);
208 	for (i = 0; i < ARRAY_SIZE(bound) - 1; i++)
209 		seq_printf(file, "%3d -%3d | ",
210 			   bound[i], bound[i + 1]);
211 	seq_puts(file, "\nCount:  ");
212 
213 	range = ext_phy ? ARRAY_SIZE(dev->mt76.aggr_stats) / 2 : 0;
214 	for (i = 0; i < ARRAY_SIZE(bound); i++)
215 		seq_printf(file, "%8d | ", dev->mt76.aggr_stats[i + range]);
216 	seq_puts(file, "\n");
217 
218 	seq_printf(file, "BA miss count: %d\n", phy->mib.ba_miss_cnt);
219 	seq_printf(file, "PER: %ld.%1ld%%\n",
220 		   phy->mib.aggr_per / 10, phy->mib.aggr_per % 10);
221 }
222 
223 static int
224 mt7615_ampdu_stat_read(struct seq_file *file, void *data)
225 {
226 	struct mt7615_dev *dev = file->private;
227 
228 	mt7615_mutex_acquire(dev);
229 
230 	mt7615_ampdu_stat_read_phy(&dev->phy, file);
231 	mt7615_ampdu_stat_read_phy(mt7615_ext_phy(dev), file);
232 
233 	mt7615_mutex_release(dev);
234 
235 	return 0;
236 }
237 
238 static int
239 mt7615_ampdu_stat_open(struct inode *inode, struct file *f)
240 {
241 	return single_open(f, mt7615_ampdu_stat_read, inode->i_private);
242 }
243 
244 static const struct file_operations fops_ampdu_stat = {
245 	.open = mt7615_ampdu_stat_open,
246 	.read = seq_read,
247 	.llseek = seq_lseek,
248 	.release = single_release,
249 };
250 
251 static void
252 mt7615_radio_read_phy(struct mt7615_phy *phy, struct seq_file *s)
253 {
254 	struct mt7615_dev *dev = dev_get_drvdata(s->private);
255 	bool ext_phy = phy != &dev->phy;
256 
257 	if (!phy)
258 		return;
259 
260 	seq_printf(s, "Radio %d sensitivity: ofdm=%d cck=%d\n", ext_phy,
261 		   phy->ofdm_sensitivity, phy->cck_sensitivity);
262 	seq_printf(s, "Radio %d false CCA: ofdm=%d cck=%d\n", ext_phy,
263 		   phy->false_cca_ofdm, phy->false_cca_cck);
264 }
265 
266 static int
267 mt7615_radio_read(struct seq_file *s, void *data)
268 {
269 	struct mt7615_dev *dev = dev_get_drvdata(s->private);
270 
271 	mt7615_radio_read_phy(&dev->phy, s);
272 	mt7615_radio_read_phy(mt7615_ext_phy(dev), s);
273 
274 	return 0;
275 }
276 
277 static int mt7615_read_temperature(struct seq_file *s, void *data)
278 {
279 	struct mt7615_dev *dev = dev_get_drvdata(s->private);
280 	int temp;
281 
282 	if (!mt7615_wait_for_mcu_init(dev))
283 		return 0;
284 
285 	/* cpu */
286 	mt7615_mutex_acquire(dev);
287 	temp = mt7615_mcu_get_temperature(dev, 0);
288 	mt7615_mutex_release(dev);
289 
290 	seq_printf(s, "Temperature: %d\n", temp);
291 
292 	return 0;
293 }
294 
295 static int
296 mt7615_queues_acq(struct seq_file *s, void *data)
297 {
298 	struct mt7615_dev *dev = dev_get_drvdata(s->private);
299 	int i;
300 
301 	mt7615_mutex_acquire(dev);
302 
303 	for (i = 0; i < 16; i++) {
304 		int j, wmm_idx = i % MT7615_MAX_WMM_SETS;
305 		int acs = i / MT7615_MAX_WMM_SETS;
306 		u32 ctrl, val, qlen = 0;
307 
308 		val = mt76_rr(dev, MT_PLE_AC_QEMPTY(acs, wmm_idx));
309 		ctrl = BIT(31) | BIT(15) | (acs << 8);
310 
311 		for (j = 0; j < 32; j++) {
312 			if (val & BIT(j))
313 				continue;
314 
315 			mt76_wr(dev, MT_PLE_FL_Q0_CTRL,
316 				ctrl | (j + (wmm_idx << 5)));
317 			qlen += mt76_get_field(dev, MT_PLE_FL_Q3_CTRL,
318 					       GENMASK(11, 0));
319 		}
320 		seq_printf(s, "AC%d%d: queued=%d\n", wmm_idx, acs, qlen);
321 	}
322 
323 	mt7615_mutex_release(dev);
324 
325 	return 0;
326 }
327 
328 static int
329 mt7615_queues_read(struct seq_file *s, void *data)
330 {
331 	struct mt7615_dev *dev = dev_get_drvdata(s->private);
332 	static const struct {
333 		char *queue;
334 		int id;
335 	} queue_map[] = {
336 		{ "PDMA0", MT_TXQ_BE },
337 		{ "MCUQ", MT_TXQ_MCU },
338 		{ "MCUFWQ", MT_TXQ_FWDL },
339 	};
340 	int i;
341 
342 	for (i = 0; i < ARRAY_SIZE(queue_map); i++) {
343 		struct mt76_sw_queue *q = &dev->mt76.q_tx[queue_map[i].id];
344 
345 		if (!q->q)
346 			continue;
347 
348 		seq_printf(s,
349 			   "%s:	queued=%d head=%d tail=%d\n",
350 			   queue_map[i].queue, q->q->queued, q->q->head,
351 			   q->q->tail);
352 	}
353 
354 	return 0;
355 }
356 
357 static int
358 mt7615_rf_reg_set(void *data, u64 val)
359 {
360 	struct mt7615_dev *dev = data;
361 
362 	mt7615_rf_wr(dev, dev->debugfs_rf_wf, dev->debugfs_rf_reg, val);
363 
364 	return 0;
365 }
366 
367 static int
368 mt7615_rf_reg_get(void *data, u64 *val)
369 {
370 	struct mt7615_dev *dev = data;
371 
372 	*val = mt7615_rf_rr(dev, dev->debugfs_rf_wf, dev->debugfs_rf_reg);
373 
374 	return 0;
375 }
376 
377 DEFINE_DEBUGFS_ATTRIBUTE(fops_rf_reg, mt7615_rf_reg_get, mt7615_rf_reg_set,
378 			 "0x%08llx\n");
379 
380 int mt7615_init_debugfs(struct mt7615_dev *dev)
381 {
382 	struct dentry *dir;
383 
384 	dir = mt76_register_debugfs(&dev->mt76);
385 	if (!dir)
386 		return -ENOMEM;
387 
388 	if (is_mt7615(&dev->mt76))
389 		debugfs_create_devm_seqfile(dev->mt76.dev, "xmit-queues", dir,
390 					    mt7615_queues_read);
391 	else
392 		debugfs_create_devm_seqfile(dev->mt76.dev, "xmit-queues", dir,
393 					    mt76_queues_read);
394 	debugfs_create_devm_seqfile(dev->mt76.dev, "acq", dir,
395 				    mt7615_queues_acq);
396 	debugfs_create_file("ampdu_stat", 0400, dir, dev, &fops_ampdu_stat);
397 	debugfs_create_file("scs", 0600, dir, dev, &fops_scs);
398 	debugfs_create_file("dbdc", 0600, dir, dev, &fops_dbdc);
399 	debugfs_create_file("fw_debug", 0600, dir, dev, &fops_fw_debug);
400 	debugfs_create_file("runtime-pm", 0600, dir, dev, &fops_pm);
401 	debugfs_create_file("idle-timeout", 0600, dir, dev,
402 			    &fops_pm_idle_timeout);
403 	debugfs_create_devm_seqfile(dev->mt76.dev, "radio", dir,
404 				    mt7615_radio_read);
405 	debugfs_create_u32("dfs_hw_pattern", 0400, dir, &dev->hw_pattern);
406 	/* test pattern knobs */
407 	debugfs_create_u8("pattern_len", 0600, dir,
408 			  &dev->radar_pattern.n_pulses);
409 	debugfs_create_u32("pulse_period", 0600, dir,
410 			   &dev->radar_pattern.period);
411 	debugfs_create_u16("pulse_width", 0600, dir,
412 			   &dev->radar_pattern.width);
413 	debugfs_create_u16("pulse_power", 0600, dir,
414 			   &dev->radar_pattern.power);
415 	debugfs_create_file("radar_trigger", 0200, dir, dev,
416 			    &fops_radar_pattern);
417 	debugfs_create_file("reset_test", 0200, dir, dev,
418 			    &fops_reset_test);
419 	debugfs_create_devm_seqfile(dev->mt76.dev, "temperature", dir,
420 				    mt7615_read_temperature);
421 
422 	debugfs_create_u32("rf_wfidx", 0600, dir, &dev->debugfs_rf_wf);
423 	debugfs_create_u32("rf_regidx", 0600, dir, &dev->debugfs_rf_reg);
424 	debugfs_create_file_unsafe("rf_regval", 0600, dir, dev,
425 				   &fops_rf_reg);
426 
427 	return 0;
428 }
429 EXPORT_SYMBOL_GPL(mt7615_init_debugfs);
430