176055413SLorenzo Bianconi /*
276055413SLorenzo Bianconi  * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
376055413SLorenzo Bianconi  *
476055413SLorenzo Bianconi  * Permission to use, copy, modify, and/or distribute this software for any
576055413SLorenzo Bianconi  * purpose with or without fee is hereby granted, provided that the above
676055413SLorenzo Bianconi  * copyright notice and this permission notice appear in all copies.
776055413SLorenzo Bianconi  *
876055413SLorenzo Bianconi  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
976055413SLorenzo Bianconi  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1076055413SLorenzo Bianconi  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1176055413SLorenzo Bianconi  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1276055413SLorenzo Bianconi  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1376055413SLorenzo Bianconi  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1476055413SLorenzo Bianconi  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1576055413SLorenzo Bianconi  */
1676055413SLorenzo Bianconi 
1776055413SLorenzo Bianconi #include <linux/debugfs.h>
1876055413SLorenzo Bianconi #include "mt76x02.h"
1976055413SLorenzo Bianconi 
2076055413SLorenzo Bianconi static int
2176055413SLorenzo Bianconi mt76x02_ampdu_stat_read(struct seq_file *file, void *data)
2276055413SLorenzo Bianconi {
2376055413SLorenzo Bianconi 	struct mt76x02_dev *dev = file->private;
2476055413SLorenzo Bianconi 	int i, j;
2576055413SLorenzo Bianconi 
2676055413SLorenzo Bianconi 	for (i = 0; i < 4; i++) {
2776055413SLorenzo Bianconi 		seq_puts(file, "Length: ");
2876055413SLorenzo Bianconi 		for (j = 0; j < 8; j++)
2976055413SLorenzo Bianconi 			seq_printf(file, "%8d | ", i * 8 + j + 1);
3076055413SLorenzo Bianconi 		seq_puts(file, "\n");
3176055413SLorenzo Bianconi 		seq_puts(file, "Count:  ");
3276055413SLorenzo Bianconi 		for (j = 0; j < 8; j++)
3376055413SLorenzo Bianconi 			seq_printf(file, "%8d | ", dev->aggr_stats[i * 8 + j]);
3476055413SLorenzo Bianconi 		seq_puts(file, "\n");
3576055413SLorenzo Bianconi 		seq_puts(file, "--------");
3676055413SLorenzo Bianconi 		for (j = 0; j < 8; j++)
3776055413SLorenzo Bianconi 			seq_puts(file, "-----------");
3876055413SLorenzo Bianconi 		seq_puts(file, "\n");
3976055413SLorenzo Bianconi 	}
4076055413SLorenzo Bianconi 
4176055413SLorenzo Bianconi 	return 0;
4276055413SLorenzo Bianconi }
4376055413SLorenzo Bianconi 
4476055413SLorenzo Bianconi static int
4576055413SLorenzo Bianconi mt76x02_ampdu_stat_open(struct inode *inode, struct file *f)
4676055413SLorenzo Bianconi {
4776055413SLorenzo Bianconi 	return single_open(f, mt76x02_ampdu_stat_read, inode->i_private);
4876055413SLorenzo Bianconi }
4976055413SLorenzo Bianconi 
5076055413SLorenzo Bianconi static int read_txpower(struct seq_file *file, void *data)
5176055413SLorenzo Bianconi {
5276055413SLorenzo Bianconi 	struct mt76x02_dev *dev = dev_get_drvdata(file->private);
5376055413SLorenzo Bianconi 
5476055413SLorenzo Bianconi 	seq_printf(file, "Target power: %d\n", dev->target_power);
5576055413SLorenzo Bianconi 
5676055413SLorenzo Bianconi 	mt76_seq_puts_array(file, "Delta", dev->target_power_delta,
5776055413SLorenzo Bianconi 			    ARRAY_SIZE(dev->target_power_delta));
5876055413SLorenzo Bianconi 	return 0;
5976055413SLorenzo Bianconi }
6076055413SLorenzo Bianconi 
6176055413SLorenzo Bianconi static const struct file_operations fops_ampdu_stat = {
6276055413SLorenzo Bianconi 	.open = mt76x02_ampdu_stat_open,
6376055413SLorenzo Bianconi 	.read = seq_read,
6476055413SLorenzo Bianconi 	.llseek = seq_lseek,
6576055413SLorenzo Bianconi 	.release = single_release,
6676055413SLorenzo Bianconi };
6776055413SLorenzo Bianconi 
6876055413SLorenzo Bianconi static int
6976055413SLorenzo Bianconi mt76x02_dfs_stat_read(struct seq_file *file, void *data)
7076055413SLorenzo Bianconi {
7176055413SLorenzo Bianconi 	struct mt76x02_dev *dev = file->private;
7276055413SLorenzo Bianconi 	struct mt76x02_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
7376055413SLorenzo Bianconi 	int i;
7476055413SLorenzo Bianconi 
7576055413SLorenzo Bianconi 	seq_printf(file, "allocated sequences:\t%d\n",
7676055413SLorenzo Bianconi 		   dfs_pd->seq_stats.seq_pool_len);
7776055413SLorenzo Bianconi 	seq_printf(file, "used sequences:\t\t%d\n",
7876055413SLorenzo Bianconi 		   dfs_pd->seq_stats.seq_len);
7976055413SLorenzo Bianconi 	seq_puts(file, "\n");
8076055413SLorenzo Bianconi 
8176055413SLorenzo Bianconi 	for (i = 0; i < MT_DFS_NUM_ENGINES; i++) {
8276055413SLorenzo Bianconi 		seq_printf(file, "engine: %d\n", i);
8376055413SLorenzo Bianconi 		seq_printf(file, "  hw pattern detected:\t%d\n",
8476055413SLorenzo Bianconi 			   dfs_pd->stats[i].hw_pattern);
8576055413SLorenzo Bianconi 		seq_printf(file, "  hw pulse discarded:\t%d\n",
8676055413SLorenzo Bianconi 			   dfs_pd->stats[i].hw_pulse_discarded);
8776055413SLorenzo Bianconi 		seq_printf(file, "  sw pattern detected:\t%d\n",
8876055413SLorenzo Bianconi 			   dfs_pd->stats[i].sw_pattern);
8976055413SLorenzo Bianconi 	}
9076055413SLorenzo Bianconi 
9176055413SLorenzo Bianconi 	return 0;
9276055413SLorenzo Bianconi }
9376055413SLorenzo Bianconi 
9476055413SLorenzo Bianconi static int
9576055413SLorenzo Bianconi mt76x02_dfs_stat_open(struct inode *inode, struct file *f)
9676055413SLorenzo Bianconi {
9776055413SLorenzo Bianconi 	return single_open(f, mt76x02_dfs_stat_read, inode->i_private);
9876055413SLorenzo Bianconi }
9976055413SLorenzo Bianconi 
10076055413SLorenzo Bianconi static const struct file_operations fops_dfs_stat = {
10176055413SLorenzo Bianconi 	.open = mt76x02_dfs_stat_open,
10276055413SLorenzo Bianconi 	.read = seq_read,
10376055413SLorenzo Bianconi 	.llseek = seq_lseek,
10476055413SLorenzo Bianconi 	.release = single_release,
10576055413SLorenzo Bianconi };
10676055413SLorenzo Bianconi 
10776055413SLorenzo Bianconi static int read_agc(struct seq_file *file, void *data)
10876055413SLorenzo Bianconi {
10976055413SLorenzo Bianconi 	struct mt76x02_dev *dev = dev_get_drvdata(file->private);
11076055413SLorenzo Bianconi 
11176055413SLorenzo Bianconi 	seq_printf(file, "avg_rssi: %d\n", dev->cal.avg_rssi_all);
11276055413SLorenzo Bianconi 	seq_printf(file, "low_gain: %d\n", dev->cal.low_gain);
11376055413SLorenzo Bianconi 	seq_printf(file, "false_cca: %d\n", dev->cal.false_cca);
11476055413SLorenzo Bianconi 	seq_printf(file, "agc_gain_adjust: %d\n", dev->cal.agc_gain_adjust);
11576055413SLorenzo Bianconi 
11676055413SLorenzo Bianconi 	return 0;
11776055413SLorenzo Bianconi }
11876055413SLorenzo Bianconi 
11976055413SLorenzo Bianconi void mt76x02_init_debugfs(struct mt76x02_dev *dev)
12076055413SLorenzo Bianconi {
12176055413SLorenzo Bianconi 	struct dentry *dir;
12276055413SLorenzo Bianconi 
12376055413SLorenzo Bianconi 	dir = mt76_register_debugfs(&dev->mt76);
12476055413SLorenzo Bianconi 	if (!dir)
12576055413SLorenzo Bianconi 		return;
12676055413SLorenzo Bianconi 
12776055413SLorenzo Bianconi 	debugfs_create_u8("temperature", 0400, dir, &dev->cal.temp);
12876055413SLorenzo Bianconi 	debugfs_create_bool("tpc", 0600, dir, &dev->enable_tpc);
12976055413SLorenzo Bianconi 
13076055413SLorenzo Bianconi 	debugfs_create_file("ampdu_stat", 0400, dir, dev, &fops_ampdu_stat);
13176055413SLorenzo Bianconi 	debugfs_create_file("dfs_stats", 0400, dir, dev, &fops_dfs_stat);
13276055413SLorenzo Bianconi 	debugfs_create_devm_seqfile(dev->mt76.dev, "txpower", dir,
13376055413SLorenzo Bianconi 				    read_txpower);
13476055413SLorenzo Bianconi 
13576055413SLorenzo Bianconi 	debugfs_create_devm_seqfile(dev->mt76.dev, "agc", dir, read_agc);
136c1e0d2beSLorenzo Bianconi 
137c1e0d2beSLorenzo Bianconi 	debugfs_create_u32("tx_hang_reset", 0400, dir, &dev->tx_hang_reset);
13876055413SLorenzo Bianconi }
13976055413SLorenzo Bianconi EXPORT_SYMBOL_GPL(mt76x02_init_debugfs);
140