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 
10 	if (!mt7615_wait_for_mcu_init(dev))
11 		return 0;
12 
13 	return mt7615_mcu_rdd_send_pattern(dev);
14 }
15 
16 DEFINE_DEBUGFS_ATTRIBUTE(fops_radar_pattern, NULL,
17 			 mt7615_radar_pattern_set, "%lld\n");
18 
19 static int
20 mt7615_scs_set(void *data, u64 val)
21 {
22 	struct mt7615_dev *dev = data;
23 	struct mt7615_phy *ext_phy;
24 
25 	if (!mt7615_wait_for_mcu_init(dev))
26 		return 0;
27 
28 	mt7615_mac_set_scs(&dev->phy, val);
29 	ext_phy = mt7615_ext_phy(dev);
30 	if (ext_phy)
31 		mt7615_mac_set_scs(ext_phy, val);
32 
33 	return 0;
34 }
35 
36 static int
37 mt7615_scs_get(void *data, u64 *val)
38 {
39 	struct mt7615_dev *dev = data;
40 
41 	*val = dev->phy.scs_en;
42 
43 	return 0;
44 }
45 
46 DEFINE_DEBUGFS_ATTRIBUTE(fops_scs, mt7615_scs_get,
47 			 mt7615_scs_set, "%lld\n");
48 
49 static int
50 mt7615_dbdc_set(void *data, u64 val)
51 {
52 	struct mt7615_dev *dev = data;
53 
54 	if (!mt7615_wait_for_mcu_init(dev))
55 		return 0;
56 
57 	if (val)
58 		mt7615_register_ext_phy(dev);
59 	else
60 		mt7615_unregister_ext_phy(dev);
61 
62 	return 0;
63 }
64 
65 static int
66 mt7615_dbdc_get(void *data, u64 *val)
67 {
68 	struct mt7615_dev *dev = data;
69 
70 	*val = !!mt7615_ext_phy(dev);
71 
72 	return 0;
73 }
74 
75 DEFINE_DEBUGFS_ATTRIBUTE(fops_dbdc, mt7615_dbdc_get,
76 			 mt7615_dbdc_set, "%lld\n");
77 
78 static int
79 mt7615_fw_debug_set(void *data, u64 val)
80 {
81 	struct mt7615_dev *dev = data;
82 
83 	if (!mt7615_wait_for_mcu_init(dev))
84 		return 0;
85 
86 	dev->fw_debug = val;
87 	mt7615_mcu_fw_log_2_host(dev, dev->fw_debug ? 2 : 0);
88 
89 	return 0;
90 }
91 
92 static int
93 mt7615_fw_debug_get(void *data, u64 *val)
94 {
95 	struct mt7615_dev *dev = data;
96 
97 	*val = dev->fw_debug;
98 
99 	return 0;
100 }
101 
102 DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug, mt7615_fw_debug_get,
103 			 mt7615_fw_debug_set, "%lld\n");
104 
105 static int
106 mt7615_reset_test_set(void *data, u64 val)
107 {
108 	struct mt7615_dev *dev = data;
109 	struct sk_buff *skb;
110 
111 	if (!mt7615_wait_for_mcu_init(dev))
112 		return 0;
113 
114 	skb = alloc_skb(1, GFP_KERNEL);
115 	if (!skb)
116 		return -ENOMEM;
117 
118 	skb_put(skb, 1);
119 	mt76_tx_queue_skb_raw(dev, 0, skb, 0);
120 
121 	return 0;
122 }
123 
124 DEFINE_DEBUGFS_ATTRIBUTE(fops_reset_test, NULL,
125 			 mt7615_reset_test_set, "%lld\n");
126 
127 static void
128 mt7615_ampdu_stat_read_phy(struct mt7615_phy *phy,
129 			   struct seq_file *file)
130 {
131 	struct mt7615_dev *dev = file->private;
132 	u32 reg = is_mt7663(&dev->mt76) ? MT_MIB_ARNG(0) : MT_AGG_ASRCR0;
133 	bool ext_phy = phy != &dev->phy;
134 	int bound[7], i, range;
135 
136 	if (!phy)
137 		return;
138 
139 	range = mt76_rr(dev, reg);
140 	for (i = 0; i < 4; i++)
141 		bound[i] = MT_AGG_ASRCR_RANGE(range, i) + 1;
142 
143 	range = mt76_rr(dev, reg + 4);
144 	for (i = 0; i < 3; i++)
145 		bound[i + 4] = MT_AGG_ASRCR_RANGE(range, i) + 1;
146 
147 	seq_printf(file, "\nPhy %d\n", ext_phy);
148 
149 	seq_printf(file, "Length: %8d | ", bound[0]);
150 	for (i = 0; i < ARRAY_SIZE(bound) - 1; i++)
151 		seq_printf(file, "%3d -%3d | ",
152 			   bound[i], bound[i + 1]);
153 	seq_puts(file, "\nCount:  ");
154 
155 	range = ext_phy ? ARRAY_SIZE(dev->mt76.aggr_stats) / 2 : 0;
156 	for (i = 0; i < ARRAY_SIZE(bound); i++)
157 		seq_printf(file, "%8d | ", dev->mt76.aggr_stats[i + range]);
158 	seq_puts(file, "\n");
159 
160 	seq_printf(file, "BA miss count: %d\n", phy->mib.ba_miss_cnt);
161 	seq_printf(file, "PER: %ld.%1ld%%\n",
162 		   phy->mib.aggr_per / 10, phy->mib.aggr_per % 10);
163 }
164 
165 static int
166 mt7615_ampdu_stat_read(struct seq_file *file, void *data)
167 {
168 	struct mt7615_dev *dev = file->private;
169 
170 	mt7615_ampdu_stat_read_phy(&dev->phy, file);
171 	mt7615_ampdu_stat_read_phy(mt7615_ext_phy(dev), file);
172 
173 	return 0;
174 }
175 
176 static int
177 mt7615_ampdu_stat_open(struct inode *inode, struct file *f)
178 {
179 	return single_open(f, mt7615_ampdu_stat_read, inode->i_private);
180 }
181 
182 static const struct file_operations fops_ampdu_stat = {
183 	.open = mt7615_ampdu_stat_open,
184 	.read = seq_read,
185 	.llseek = seq_lseek,
186 	.release = single_release,
187 };
188 
189 static void
190 mt7615_radio_read_phy(struct mt7615_phy *phy, struct seq_file *s)
191 {
192 	struct mt7615_dev *dev = dev_get_drvdata(s->private);
193 	bool ext_phy = phy != &dev->phy;
194 
195 	if (!phy)
196 		return;
197 
198 	seq_printf(s, "Radio %d sensitivity: ofdm=%d cck=%d\n", ext_phy,
199 		   phy->ofdm_sensitivity, phy->cck_sensitivity);
200 	seq_printf(s, "Radio %d false CCA: ofdm=%d cck=%d\n", ext_phy,
201 		   phy->false_cca_ofdm, phy->false_cca_cck);
202 }
203 
204 static int
205 mt7615_radio_read(struct seq_file *s, void *data)
206 {
207 	struct mt7615_dev *dev = dev_get_drvdata(s->private);
208 
209 	mt7615_radio_read_phy(&dev->phy, s);
210 	mt7615_radio_read_phy(mt7615_ext_phy(dev), s);
211 
212 	return 0;
213 }
214 
215 static int mt7615_read_temperature(struct seq_file *s, void *data)
216 {
217 	struct mt7615_dev *dev = dev_get_drvdata(s->private);
218 	int temp;
219 
220 	if (!mt7615_wait_for_mcu_init(dev))
221 		return 0;
222 
223 	/* cpu */
224 	temp = mt7615_mcu_get_temperature(dev, 0);
225 	seq_printf(s, "Temperature: %d\n", temp);
226 
227 	return 0;
228 }
229 
230 static int
231 mt7615_queues_acq(struct seq_file *s, void *data)
232 {
233 	struct mt7615_dev *dev = dev_get_drvdata(s->private);
234 	int i;
235 
236 	for (i = 0; i < 16; i++) {
237 		int j, acs = i / 4, index = i % 4;
238 		u32 ctrl, val, qlen = 0;
239 
240 		val = mt76_rr(dev, MT_PLE_AC_QEMPTY(acs, index));
241 		ctrl = BIT(31) | BIT(15) | (acs << 8);
242 
243 		for (j = 0; j < 32; j++) {
244 			if (val & BIT(j))
245 				continue;
246 
247 			mt76_wr(dev, MT_PLE_FL_Q0_CTRL,
248 				ctrl | (j + (index << 5)));
249 			qlen += mt76_get_field(dev, MT_PLE_FL_Q3_CTRL,
250 					       GENMASK(11, 0));
251 		}
252 		seq_printf(s, "AC%d%d: queued=%d\n", acs, index, qlen);
253 	}
254 
255 	return 0;
256 }
257 
258 static int
259 mt7615_queues_read(struct seq_file *s, void *data)
260 {
261 	struct mt7615_dev *dev = dev_get_drvdata(s->private);
262 	static const struct {
263 		char *queue;
264 		int id;
265 	} queue_map[] = {
266 		{ "PDMA0", MT_TXQ_BE },
267 		{ "MCUQ", MT_TXQ_MCU },
268 		{ "MCUFWQ", MT_TXQ_FWDL },
269 	};
270 	int i;
271 
272 	for (i = 0; i < ARRAY_SIZE(queue_map); i++) {
273 		struct mt76_sw_queue *q = &dev->mt76.q_tx[queue_map[i].id];
274 
275 		if (!q->q)
276 			continue;
277 
278 		seq_printf(s,
279 			   "%s:	queued=%d head=%d tail=%d\n",
280 			   queue_map[i].queue, q->q->queued, q->q->head,
281 			   q->q->tail);
282 	}
283 
284 	return 0;
285 }
286 
287 int mt7615_init_debugfs(struct mt7615_dev *dev)
288 {
289 	struct dentry *dir;
290 
291 	dir = mt76_register_debugfs(&dev->mt76);
292 	if (!dir)
293 		return -ENOMEM;
294 
295 	if (is_mt7615(&dev->mt76))
296 		debugfs_create_devm_seqfile(dev->mt76.dev, "xmit-queues", dir,
297 					    mt7615_queues_read);
298 	else
299 		debugfs_create_devm_seqfile(dev->mt76.dev, "xmit-queues", dir,
300 					    mt76_queues_read);
301 	debugfs_create_devm_seqfile(dev->mt76.dev, "acq", dir,
302 				    mt7615_queues_acq);
303 	debugfs_create_file("ampdu_stat", 0400, dir, dev, &fops_ampdu_stat);
304 	debugfs_create_file("scs", 0600, dir, dev, &fops_scs);
305 	debugfs_create_file("dbdc", 0600, dir, dev, &fops_dbdc);
306 	debugfs_create_file("fw_debug", 0600, dir, dev, &fops_fw_debug);
307 	debugfs_create_devm_seqfile(dev->mt76.dev, "radio", dir,
308 				    mt7615_radio_read);
309 	debugfs_create_u32("dfs_hw_pattern", 0400, dir, &dev->hw_pattern);
310 	/* test pattern knobs */
311 	debugfs_create_u8("pattern_len", 0600, dir,
312 			  &dev->radar_pattern.n_pulses);
313 	debugfs_create_u32("pulse_period", 0600, dir,
314 			   &dev->radar_pattern.period);
315 	debugfs_create_u16("pulse_width", 0600, dir,
316 			   &dev->radar_pattern.width);
317 	debugfs_create_u16("pulse_power", 0600, dir,
318 			   &dev->radar_pattern.power);
319 	debugfs_create_file("radar_trigger", 0200, dir, dev,
320 			    &fops_radar_pattern);
321 	debugfs_create_file("reset_test", 0200, dir, dev,
322 			    &fops_reset_test);
323 	debugfs_create_devm_seqfile(dev->mt76.dev, "temperature", dir,
324 				    mt7615_read_temperature);
325 
326 	return 0;
327 }
328 EXPORT_SYMBOL_GPL(mt7615_init_debugfs);
329