1 | // SPDX-License-Identifier: ISC |
2 | /* |
3 | * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> |
4 | */ |
5 | |
6 | #include <linux/debugfs.h> |
7 | #include "mt76x02.h" |
8 | |
9 | static int |
10 | mt76x02_ampdu_stat_show(struct seq_file *file, void *data) |
11 | { |
12 | struct mt76x02_dev *dev = file->private; |
13 | int i, j; |
14 | |
15 | for (i = 0; i < 4; i++) { |
16 | seq_puts(m: file, s: "Length: " ); |
17 | for (j = 0; j < 8; j++) |
18 | seq_printf(m: file, fmt: "%8d | " , i * 8 + j + 1); |
19 | seq_puts(m: file, s: "\n" ); |
20 | seq_puts(m: file, s: "Count: " ); |
21 | for (j = 0; j < 8; j++) |
22 | seq_printf(m: file, fmt: "%8d | " , |
23 | dev->mphy.aggr_stats[i * 8 + j]); |
24 | seq_puts(m: file, s: "\n" ); |
25 | seq_puts(m: file, s: "--------" ); |
26 | for (j = 0; j < 8; j++) |
27 | seq_puts(m: file, s: "-----------" ); |
28 | seq_puts(m: file, s: "\n" ); |
29 | } |
30 | |
31 | return 0; |
32 | } |
33 | |
34 | DEFINE_SHOW_ATTRIBUTE(mt76x02_ampdu_stat); |
35 | |
36 | static int read_txpower(struct seq_file *file, void *data) |
37 | { |
38 | struct mt76x02_dev *dev = dev_get_drvdata(dev: file->private); |
39 | |
40 | seq_printf(m: file, fmt: "Target power: %d\n" , dev->target_power); |
41 | |
42 | mt76_seq_puts_array(file, str: "Delta" , val: dev->target_power_delta, |
43 | ARRAY_SIZE(dev->target_power_delta)); |
44 | return 0; |
45 | } |
46 | |
47 | static int |
48 | mt76x02_dfs_stat_show(struct seq_file *file, void *data) |
49 | { |
50 | struct mt76x02_dev *dev = file->private; |
51 | struct mt76x02_dfs_pattern_detector *dfs_pd = &dev->dfs_pd; |
52 | int i; |
53 | |
54 | seq_printf(m: file, fmt: "allocated sequences:\t%d\n" , |
55 | dfs_pd->seq_stats.seq_pool_len); |
56 | seq_printf(m: file, fmt: "used sequences:\t\t%d\n" , |
57 | dfs_pd->seq_stats.seq_len); |
58 | seq_puts(m: file, s: "\n" ); |
59 | |
60 | for (i = 0; i < MT_DFS_NUM_ENGINES; i++) { |
61 | seq_printf(m: file, fmt: "engine: %d\n" , i); |
62 | seq_printf(m: file, fmt: " hw pattern detected:\t%d\n" , |
63 | dfs_pd->stats[i].hw_pattern); |
64 | seq_printf(m: file, fmt: " hw pulse discarded:\t%d\n" , |
65 | dfs_pd->stats[i].hw_pulse_discarded); |
66 | seq_printf(m: file, fmt: " sw pattern detected:\t%d\n" , |
67 | dfs_pd->stats[i].sw_pattern); |
68 | } |
69 | |
70 | return 0; |
71 | } |
72 | |
73 | DEFINE_SHOW_ATTRIBUTE(mt76x02_dfs_stat); |
74 | |
75 | static int read_agc(struct seq_file *file, void *data) |
76 | { |
77 | struct mt76x02_dev *dev = dev_get_drvdata(dev: file->private); |
78 | |
79 | seq_printf(m: file, fmt: "avg_rssi: %d\n" , dev->cal.avg_rssi_all); |
80 | seq_printf(m: file, fmt: "low_gain: %d\n" , dev->cal.low_gain); |
81 | seq_printf(m: file, fmt: "false_cca: %d\n" , dev->cal.false_cca); |
82 | seq_printf(m: file, fmt: "agc_gain_adjust: %d\n" , dev->cal.agc_gain_adjust); |
83 | |
84 | return 0; |
85 | } |
86 | |
87 | static int |
88 | mt76_edcca_set(void *data, u64 val) |
89 | { |
90 | struct mt76x02_dev *dev = data; |
91 | enum nl80211_dfs_regions region = dev->mt76.region; |
92 | |
93 | mutex_lock(&dev->mt76.mutex); |
94 | |
95 | dev->ed_monitor_enabled = !!val; |
96 | dev->ed_monitor = dev->ed_monitor_enabled && |
97 | region == NL80211_DFS_ETSI; |
98 | mt76x02_edcca_init(dev); |
99 | |
100 | mutex_unlock(lock: &dev->mt76.mutex); |
101 | |
102 | return 0; |
103 | } |
104 | |
105 | static int |
106 | mt76_edcca_get(void *data, u64 *val) |
107 | { |
108 | struct mt76x02_dev *dev = data; |
109 | |
110 | *val = dev->ed_monitor_enabled; |
111 | return 0; |
112 | } |
113 | |
114 | DEFINE_DEBUGFS_ATTRIBUTE(fops_edcca, mt76_edcca_get, mt76_edcca_set, |
115 | "%lld\n" ); |
116 | |
117 | static int mt76x02_read_rate_txpower(struct seq_file *s, void *data) |
118 | { |
119 | struct mt76x02_dev *dev = dev_get_drvdata(dev: s->private); |
120 | |
121 | mt76_seq_puts_array(file: s, str: "CCK" , val: dev->rate_power.cck, |
122 | ARRAY_SIZE(dev->rate_power.cck)); |
123 | mt76_seq_puts_array(file: s, str: "OFDM" , val: dev->rate_power.ofdm, |
124 | ARRAY_SIZE(dev->rate_power.ofdm)); |
125 | mt76_seq_puts_array(file: s, str: "HT" , val: dev->rate_power.ht, |
126 | ARRAY_SIZE(dev->rate_power.ht)); |
127 | mt76_seq_puts_array(file: s, str: "VHT" , val: dev->rate_power.vht, |
128 | ARRAY_SIZE(dev->rate_power.vht)); |
129 | return 0; |
130 | } |
131 | |
132 | void mt76x02_init_debugfs(struct mt76x02_dev *dev) |
133 | { |
134 | struct dentry *dir; |
135 | |
136 | dir = mt76_register_debugfs(dev: &dev->mt76); |
137 | if (!dir) |
138 | return; |
139 | |
140 | debugfs_create_devm_seqfile(dev: dev->mt76.dev, name: "xmit-queues" , parent: dir, |
141 | read_fn: mt76_queues_read); |
142 | debugfs_create_u8(name: "temperature" , mode: 0400, parent: dir, value: &dev->cal.temp); |
143 | debugfs_create_bool(name: "tpc" , mode: 0600, parent: dir, value: &dev->enable_tpc); |
144 | |
145 | debugfs_create_file(name: "edcca" , mode: 0600, parent: dir, data: dev, fops: &fops_edcca); |
146 | debugfs_create_file(name: "ampdu_stat" , mode: 0400, parent: dir, data: dev, fops: &mt76x02_ampdu_stat_fops); |
147 | debugfs_create_file(name: "dfs_stats" , mode: 0400, parent: dir, data: dev, fops: &mt76x02_dfs_stat_fops); |
148 | debugfs_create_devm_seqfile(dev: dev->mt76.dev, name: "txpower" , parent: dir, |
149 | read_fn: read_txpower); |
150 | |
151 | debugfs_create_devm_seqfile(dev: dev->mt76.dev, name: "rate_txpower" , parent: dir, |
152 | read_fn: mt76x02_read_rate_txpower); |
153 | debugfs_create_devm_seqfile(dev: dev->mt76.dev, name: "agc" , parent: dir, read_fn: read_agc); |
154 | |
155 | debugfs_create_u32(name: "tx_hang_reset" , mode: 0400, parent: dir, value: &dev->tx_hang_reset); |
156 | } |
157 | EXPORT_SYMBOL_GPL(mt76x02_init_debugfs); |
158 | |