OSDN Git Service

mt76: mt7663: add awake and doze time accounting
[uclinux-h8/linux.git] / drivers / net / wireless / mediatek / mt76 / mt7615 / debugfs.c
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 mt7615_config(void *data, u64 val)
25 {
26         struct mt7615_dev *dev = data;
27         int ret;
28
29         mt7615_mutex_acquire(dev);
30         ret = mt76_connac_mcu_chip_config(&dev->mt76);
31         mt7615_mutex_release(dev);
32
33         return ret;
34 }
35
36 DEFINE_DEBUGFS_ATTRIBUTE(fops_config, NULL, mt7615_config, "%lld\n");
37
38 static int
39 mt7615_scs_set(void *data, u64 val)
40 {
41         struct mt7615_dev *dev = data;
42         struct mt7615_phy *ext_phy;
43
44         if (!mt7615_wait_for_mcu_init(dev))
45                 return 0;
46
47         mt7615_mac_set_scs(&dev->phy, val);
48         ext_phy = mt7615_ext_phy(dev);
49         if (ext_phy)
50                 mt7615_mac_set_scs(ext_phy, val);
51
52         return 0;
53 }
54
55 static int
56 mt7615_scs_get(void *data, u64 *val)
57 {
58         struct mt7615_dev *dev = data;
59
60         *val = dev->phy.scs_en;
61
62         return 0;
63 }
64
65 DEFINE_DEBUGFS_ATTRIBUTE(fops_scs, mt7615_scs_get,
66                          mt7615_scs_set, "%lld\n");
67
68 static int
69 mt7615_pm_set(void *data, u64 val)
70 {
71         struct mt7615_dev *dev = data;
72         struct mt76_connac_pm *pm = &dev->pm;
73         int ret = 0;
74
75         if (!mt7615_wait_for_mcu_init(dev))
76                 return 0;
77
78         if (!mt7615_firmware_offload(dev) || !mt76_is_mmio(&dev->mt76))
79                 return -EOPNOTSUPP;
80
81         if (val == pm->enable)
82                 return 0;
83
84         mt7615_mutex_acquire(dev);
85
86         if (dev->phy.n_beacon_vif) {
87                 ret = -EBUSY;
88                 goto out;
89         }
90
91         if (!pm->enable) {
92                 pm->stats.last_wake_event = jiffies;
93                 pm->stats.last_doze_event = jiffies;
94         }
95         pm->enable = val;
96 out:
97         mt7615_mutex_release(dev);
98
99         return ret;
100 }
101
102 static int
103 mt7615_pm_get(void *data, u64 *val)
104 {
105         struct mt7615_dev *dev = data;
106
107         *val = dev->pm.enable;
108
109         return 0;
110 }
111
112 DEFINE_DEBUGFS_ATTRIBUTE(fops_pm, mt7615_pm_get, mt7615_pm_set, "%lld\n");
113
114 static int
115 mt7615_pm_stats(struct seq_file *s, void *data)
116 {
117         struct mt7615_dev *dev = dev_get_drvdata(s->private);
118         struct mt76_connac_pm *pm = &dev->pm;
119         unsigned long awake_time = pm->stats.awake_time;
120         unsigned long doze_time = pm->stats.doze_time;
121
122         if (!test_bit(MT76_STATE_PM, &dev->mphy.state))
123                 awake_time += jiffies - pm->stats.last_wake_event;
124         else
125                 doze_time += jiffies - pm->stats.last_doze_event;
126
127         seq_printf(s, "awake time: %14u\ndoze time: %15u\n",
128                    jiffies_to_msecs(awake_time),
129                    jiffies_to_msecs(doze_time));
130
131         return 0;
132 }
133
134 static int
135 mt7615_pm_idle_timeout_set(void *data, u64 val)
136 {
137         struct mt7615_dev *dev = data;
138
139         dev->pm.idle_timeout = msecs_to_jiffies(val);
140
141         return 0;
142 }
143
144 static int
145 mt7615_pm_idle_timeout_get(void *data, u64 *val)
146 {
147         struct mt7615_dev *dev = data;
148
149         *val = jiffies_to_msecs(dev->pm.idle_timeout);
150
151         return 0;
152 }
153
154 DEFINE_DEBUGFS_ATTRIBUTE(fops_pm_idle_timeout, mt7615_pm_idle_timeout_get,
155                          mt7615_pm_idle_timeout_set, "%lld\n");
156
157 static int
158 mt7615_dbdc_set(void *data, u64 val)
159 {
160         struct mt7615_dev *dev = data;
161
162         if (!mt7615_wait_for_mcu_init(dev))
163                 return 0;
164
165         if (val)
166                 mt7615_register_ext_phy(dev);
167         else
168                 mt7615_unregister_ext_phy(dev);
169
170         return 0;
171 }
172
173 static int
174 mt7615_dbdc_get(void *data, u64 *val)
175 {
176         struct mt7615_dev *dev = data;
177
178         *val = !!mt7615_ext_phy(dev);
179
180         return 0;
181 }
182
183 DEFINE_DEBUGFS_ATTRIBUTE(fops_dbdc, mt7615_dbdc_get,
184                          mt7615_dbdc_set, "%lld\n");
185
186 static int
187 mt7615_fw_debug_set(void *data, u64 val)
188 {
189         struct mt7615_dev *dev = data;
190
191         if (!mt7615_wait_for_mcu_init(dev))
192                 return 0;
193
194         dev->fw_debug = val;
195
196         mt7615_mutex_acquire(dev);
197         mt7615_mcu_fw_log_2_host(dev, dev->fw_debug ? 2 : 0);
198         mt7615_mutex_release(dev);
199
200         return 0;
201 }
202
203 static int
204 mt7615_fw_debug_get(void *data, u64 *val)
205 {
206         struct mt7615_dev *dev = data;
207
208         *val = dev->fw_debug;
209
210         return 0;
211 }
212
213 DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug, mt7615_fw_debug_get,
214                          mt7615_fw_debug_set, "%lld\n");
215
216 static int
217 mt7615_reset_test_set(void *data, u64 val)
218 {
219         struct mt7615_dev *dev = data;
220         struct sk_buff *skb;
221
222         if (!mt7615_wait_for_mcu_init(dev))
223                 return 0;
224
225         skb = alloc_skb(1, GFP_KERNEL);
226         if (!skb)
227                 return -ENOMEM;
228
229         skb_put(skb, 1);
230
231         mt7615_mutex_acquire(dev);
232         mt76_tx_queue_skb_raw(dev, dev->mphy.q_tx[0], skb, 0);
233         mt7615_mutex_release(dev);
234
235         return 0;
236 }
237
238 DEFINE_DEBUGFS_ATTRIBUTE(fops_reset_test, NULL,
239                          mt7615_reset_test_set, "%lld\n");
240
241 static void
242 mt7615_ampdu_stat_read_phy(struct mt7615_phy *phy,
243                            struct seq_file *file)
244 {
245         struct mt7615_dev *dev = file->private;
246         u32 reg = is_mt7663(&dev->mt76) ? MT_MIB_ARNG(0) : MT_AGG_ASRCR0;
247         bool ext_phy = phy != &dev->phy;
248         int bound[7], i, range;
249
250         if (!phy)
251                 return;
252
253         range = mt76_rr(dev, reg);
254         for (i = 0; i < 4; i++)
255                 bound[i] = MT_AGG_ASRCR_RANGE(range, i) + 1;
256
257         range = mt76_rr(dev, reg + 4);
258         for (i = 0; i < 3; i++)
259                 bound[i + 4] = MT_AGG_ASRCR_RANGE(range, i) + 1;
260
261         seq_printf(file, "\nPhy %d\n", ext_phy);
262
263         seq_printf(file, "Length: %8d | ", bound[0]);
264         for (i = 0; i < ARRAY_SIZE(bound) - 1; i++)
265                 seq_printf(file, "%3d -%3d | ",
266                            bound[i], bound[i + 1]);
267         seq_puts(file, "\nCount:  ");
268
269         range = ext_phy ? ARRAY_SIZE(dev->mt76.aggr_stats) / 2 : 0;
270         for (i = 0; i < ARRAY_SIZE(bound); i++)
271                 seq_printf(file, "%8d | ", dev->mt76.aggr_stats[i + range]);
272         seq_puts(file, "\n");
273
274         seq_printf(file, "BA miss count: %d\n", phy->mib.ba_miss_cnt);
275         seq_printf(file, "PER: %ld.%1ld%%\n",
276                    phy->mib.aggr_per / 10, phy->mib.aggr_per % 10);
277 }
278
279 static int
280 mt7615_ampdu_stat_show(struct seq_file *file, void *data)
281 {
282         struct mt7615_dev *dev = file->private;
283
284         mt7615_mutex_acquire(dev);
285
286         mt7615_ampdu_stat_read_phy(&dev->phy, file);
287         mt7615_ampdu_stat_read_phy(mt7615_ext_phy(dev), file);
288
289         mt7615_mutex_release(dev);
290
291         return 0;
292 }
293
294 DEFINE_SHOW_ATTRIBUTE(mt7615_ampdu_stat);
295
296 static void
297 mt7615_radio_read_phy(struct mt7615_phy *phy, struct seq_file *s)
298 {
299         struct mt7615_dev *dev = dev_get_drvdata(s->private);
300         bool ext_phy = phy != &dev->phy;
301
302         if (!phy)
303                 return;
304
305         seq_printf(s, "Radio %d sensitivity: ofdm=%d cck=%d\n", ext_phy,
306                    phy->ofdm_sensitivity, phy->cck_sensitivity);
307         seq_printf(s, "Radio %d false CCA: ofdm=%d cck=%d\n", ext_phy,
308                    phy->false_cca_ofdm, phy->false_cca_cck);
309 }
310
311 static int
312 mt7615_radio_read(struct seq_file *s, void *data)
313 {
314         struct mt7615_dev *dev = dev_get_drvdata(s->private);
315
316         mt7615_radio_read_phy(&dev->phy, s);
317         mt7615_radio_read_phy(mt7615_ext_phy(dev), s);
318
319         return 0;
320 }
321
322 static int mt7615_read_temperature(struct seq_file *s, void *data)
323 {
324         struct mt7615_dev *dev = dev_get_drvdata(s->private);
325         int temp;
326
327         if (!mt7615_wait_for_mcu_init(dev))
328                 return 0;
329
330         /* cpu */
331         mt7615_mutex_acquire(dev);
332         temp = mt7615_mcu_get_temperature(dev, 0);
333         mt7615_mutex_release(dev);
334
335         seq_printf(s, "Temperature: %d\n", temp);
336
337         return 0;
338 }
339
340 static int
341 mt7615_queues_acq(struct seq_file *s, void *data)
342 {
343         struct mt7615_dev *dev = dev_get_drvdata(s->private);
344         int i;
345
346         mt7615_mutex_acquire(dev);
347
348         for (i = 0; i < 16; i++) {
349                 int j, wmm_idx = i % MT7615_MAX_WMM_SETS;
350                 int acs = i / MT7615_MAX_WMM_SETS;
351                 u32 ctrl, val, qlen = 0;
352
353                 val = mt76_rr(dev, MT_PLE_AC_QEMPTY(acs, wmm_idx));
354                 ctrl = BIT(31) | BIT(15) | (acs << 8);
355
356                 for (j = 0; j < 32; j++) {
357                         if (val & BIT(j))
358                                 continue;
359
360                         mt76_wr(dev, MT_PLE_FL_Q0_CTRL,
361                                 ctrl | (j + (wmm_idx << 5)));
362                         qlen += mt76_get_field(dev, MT_PLE_FL_Q3_CTRL,
363                                                GENMASK(11, 0));
364                 }
365                 seq_printf(s, "AC%d%d: queued=%d\n", wmm_idx, acs, qlen);
366         }
367
368         mt7615_mutex_release(dev);
369
370         return 0;
371 }
372
373 static int
374 mt7615_queues_read(struct seq_file *s, void *data)
375 {
376         struct mt7615_dev *dev = dev_get_drvdata(s->private);
377         struct {
378                 struct mt76_queue *q;
379                 char *queue;
380         } queue_map[] = {
381                 { dev->mphy.q_tx[MT_TXQ_BE], "PDMA0" },
382                 { dev->mt76.q_mcu[MT_MCUQ_WM], "MCUQ" },
383                 { dev->mt76.q_mcu[MT_MCUQ_FWDL], "MCUFWQ" },
384         };
385         int i;
386
387         for (i = 0; i < ARRAY_SIZE(queue_map); i++) {
388                 struct mt76_queue *q = queue_map[i].q;
389
390                 seq_printf(s,
391                            "%s: queued=%d head=%d tail=%d\n",
392                            queue_map[i].queue, q->queued, q->head,
393                            q->tail);
394         }
395
396         return 0;
397 }
398
399 static int
400 mt7615_rf_reg_set(void *data, u64 val)
401 {
402         struct mt7615_dev *dev = data;
403
404         mt7615_rf_wr(dev, dev->debugfs_rf_wf, dev->debugfs_rf_reg, val);
405
406         return 0;
407 }
408
409 static int
410 mt7615_rf_reg_get(void *data, u64 *val)
411 {
412         struct mt7615_dev *dev = data;
413
414         *val = mt7615_rf_rr(dev, dev->debugfs_rf_wf, dev->debugfs_rf_reg);
415
416         return 0;
417 }
418
419 DEFINE_DEBUGFS_ATTRIBUTE(fops_rf_reg, mt7615_rf_reg_get, mt7615_rf_reg_set,
420                          "0x%08llx\n");
421
422 static ssize_t
423 mt7615_ext_mac_addr_read(struct file *file, char __user *userbuf,
424                          size_t count, loff_t *ppos)
425 {
426         struct mt7615_dev *dev = file->private_data;
427         char buf[32 * ((ETH_ALEN * 3) + 4) + 1];
428         u8 addr[ETH_ALEN];
429         int ofs = 0;
430         int i;
431
432         for (i = 0; i < 32; i++) {
433                 if (!(dev->muar_mask & BIT(i)))
434                         continue;
435
436                 mt76_wr(dev, MT_WF_RMAC_MAR1,
437                         FIELD_PREP(MT_WF_RMAC_MAR1_IDX, i * 2) |
438                         MT_WF_RMAC_MAR1_START);
439                 put_unaligned_le32(mt76_rr(dev, MT_WF_RMAC_MAR0), addr);
440                 put_unaligned_le16((mt76_rr(dev, MT_WF_RMAC_MAR1) &
441                                     MT_WF_RMAC_MAR1_ADDR), addr + 4);
442                 ofs += snprintf(buf + ofs, sizeof(buf) - ofs, "%d=%pM\n", i, addr);
443         }
444
445         return simple_read_from_buffer(userbuf, count, ppos, buf, ofs);
446 }
447
448 static ssize_t
449 mt7615_ext_mac_addr_write(struct file *file, const char __user *userbuf,
450                           size_t count, loff_t *ppos)
451 {
452         struct mt7615_dev *dev = file->private_data;
453         unsigned long idx = 0;
454         u8 addr[ETH_ALEN];
455         char buf[32];
456         char *p;
457
458         if (count > sizeof(buf))
459                 return -EINVAL;
460
461         if (copy_from_user(buf, userbuf, count))
462                 return -EFAULT;
463
464         buf[sizeof(buf) - 1] = '\0';
465
466         p = strchr(buf, '=');
467         if (p) {
468                 *p = 0;
469                 p++;
470
471                 if (kstrtoul(buf, 0, &idx) || idx > 31)
472                         return -EINVAL;
473         } else {
474                 idx = 0;
475                 p = buf;
476         }
477
478         if (!mac_pton(p, addr))
479                 return -EINVAL;
480
481         if (is_valid_ether_addr(addr)) {
482                 dev->muar_mask |= BIT(idx);
483         } else {
484                 memset(addr, 0, sizeof(addr));
485                 dev->muar_mask &= ~BIT(idx);
486         }
487
488         mt76_rmw_field(dev, MT_WF_RMAC_MORE(0), MT_WF_RMAC_MORE_MUAR_MODE, 1);
489         mt76_wr(dev, MT_WF_RMAC_MAR0, get_unaligned_le32(addr));
490         mt76_wr(dev, MT_WF_RMAC_MAR1,
491                 get_unaligned_le16(addr + 4) |
492                 FIELD_PREP(MT_WF_RMAC_MAR1_IDX, idx * 2) |
493                 MT_WF_RMAC_MAR1_START |
494                 MT_WF_RMAC_MAR1_WRITE);
495
496         mt76_rmw_field(dev, MT_WF_RMAC_MORE(0), MT_WF_RMAC_MORE_MUAR_MODE, !!dev->muar_mask);
497
498         return count;
499 }
500
501 static const struct file_operations fops_ext_mac_addr = {
502         .open = simple_open,
503         .llseek = generic_file_llseek,
504         .read = mt7615_ext_mac_addr_read,
505         .write = mt7615_ext_mac_addr_write,
506         .owner = THIS_MODULE,
507 };
508
509 static int
510 mt7663s_sched_quota_read(struct seq_file *s, void *data)
511 {
512         struct mt7615_dev *dev = dev_get_drvdata(s->private);
513         struct mt76_sdio *sdio = &dev->mt76.sdio;
514
515         seq_printf(s, "pse_data_quota\t%d\n", sdio->sched.pse_data_quota);
516         seq_printf(s, "ple_data_quota\t%d\n", sdio->sched.ple_data_quota);
517         seq_printf(s, "pse_mcu_quota\t%d\n", sdio->sched.pse_mcu_quota);
518         seq_printf(s, "sched_deficit\t%d\n", sdio->sched.deficit);
519
520         return 0;
521 }
522
523 int mt7615_init_debugfs(struct mt7615_dev *dev)
524 {
525         struct dentry *dir;
526
527         dir = mt76_register_debugfs(&dev->mt76);
528         if (!dir)
529                 return -ENOMEM;
530
531         if (is_mt7615(&dev->mt76))
532                 debugfs_create_devm_seqfile(dev->mt76.dev, "xmit-queues", dir,
533                                             mt7615_queues_read);
534         else
535                 debugfs_create_devm_seqfile(dev->mt76.dev, "xmit-queues", dir,
536                                             mt76_queues_read);
537         debugfs_create_devm_seqfile(dev->mt76.dev, "acq", dir,
538                                     mt7615_queues_acq);
539         debugfs_create_file("ampdu_stat", 0400, dir, dev, &mt7615_ampdu_stat_fops);
540         debugfs_create_file("scs", 0600, dir, dev, &fops_scs);
541         debugfs_create_file("dbdc", 0600, dir, dev, &fops_dbdc);
542         debugfs_create_file("fw_debug", 0600, dir, dev, &fops_fw_debug);
543         debugfs_create_file("runtime-pm", 0600, dir, dev, &fops_pm);
544         debugfs_create_file("idle-timeout", 0600, dir, dev,
545                             &fops_pm_idle_timeout);
546         debugfs_create_devm_seqfile(dev->mt76.dev, "runtime_pm_stats", dir,
547                                     mt7615_pm_stats);
548         debugfs_create_devm_seqfile(dev->mt76.dev, "radio", dir,
549                                     mt7615_radio_read);
550
551         if (is_mt7615(&dev->mt76)) {
552                 debugfs_create_u32("dfs_hw_pattern", 0400, dir,
553                                    &dev->hw_pattern);
554                 /* test pattern knobs */
555                 debugfs_create_u8("pattern_len", 0600, dir,
556                                   &dev->radar_pattern.n_pulses);
557                 debugfs_create_u32("pulse_period", 0600, dir,
558                                    &dev->radar_pattern.period);
559                 debugfs_create_u16("pulse_width", 0600, dir,
560                                    &dev->radar_pattern.width);
561                 debugfs_create_u16("pulse_power", 0600, dir,
562                                    &dev->radar_pattern.power);
563                 debugfs_create_file("radar_trigger", 0200, dir, dev,
564                                     &fops_radar_pattern);
565         }
566
567         debugfs_create_file("reset_test", 0200, dir, dev,
568                             &fops_reset_test);
569         debugfs_create_devm_seqfile(dev->mt76.dev, "temperature", dir,
570                                     mt7615_read_temperature);
571         debugfs_create_file("ext_mac_addr", 0600, dir, dev, &fops_ext_mac_addr);
572
573         debugfs_create_u32("rf_wfidx", 0600, dir, &dev->debugfs_rf_wf);
574         debugfs_create_u32("rf_regidx", 0600, dir, &dev->debugfs_rf_reg);
575         debugfs_create_file_unsafe("rf_regval", 0600, dir, dev,
576                                    &fops_rf_reg);
577         if (is_mt7663(&dev->mt76))
578                 debugfs_create_file("chip_config", 0600, dir, dev,
579                                     &fops_config);
580         if (mt76_is_sdio(&dev->mt76))
581                 debugfs_create_devm_seqfile(dev->mt76.dev, "sched-quota", dir,
582                                             mt7663s_sched_quota_read);
583
584         return 0;
585 }
586 EXPORT_SYMBOL_GPL(mt7615_init_debugfs);