Skip to content

Commit 474a9f2

Browse files
moore-brosnbd168
authored andcommitted
mt76: mt7921: add debugfs support
Add debugfs support to dump driver statistics and hardware details. Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> Co-developed-by: Soul Huang <Soul.Huang@mediatek.com> Signed-off-by: Soul Huang <Soul.Huang@mediatek.com> Signed-off-by: Sean Wang <sean.wang@mediatek.com> Signed-off-by: Felix Fietkau <nbd@nbd.name>
1 parent 5c14a5f commit 474a9f2

File tree

2 files changed

+179
-1
lines changed

2 files changed

+179
-1
lines changed
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
// SPDX-License-Identifier: ISC
2+
/* Copyright (C) 2020 MediaTek Inc. */
3+
4+
#include "mt7921.h"
5+
#include "eeprom.h"
6+
7+
static int
8+
mt7921_fw_debug_set(void *data, u64 val)
9+
{
10+
struct mt7921_dev *dev = data;
11+
12+
dev->fw_debug = (u8)val;
13+
14+
mt7921_mcu_fw_log_2_host(dev, dev->fw_debug);
15+
16+
return 0;
17+
}
18+
19+
static int
20+
mt7921_fw_debug_get(void *data, u64 *val)
21+
{
22+
struct mt7921_dev *dev = data;
23+
24+
*val = dev->fw_debug;
25+
26+
return 0;
27+
}
28+
29+
DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug, mt7921_fw_debug_get,
30+
mt7921_fw_debug_set, "%lld\n");
31+
32+
static void
33+
mt7921_ampdu_stat_read_phy(struct mt7921_phy *phy,
34+
struct seq_file *file)
35+
{
36+
struct mt7921_dev *dev = file->private;
37+
int bound[15], range[4], i;
38+
39+
if (!phy)
40+
return;
41+
42+
/* Tx ampdu stat */
43+
for (i = 0; i < ARRAY_SIZE(range); i++)
44+
range[i] = mt76_rr(dev, MT_MIB_ARNG(0, i));
45+
46+
for (i = 0; i < ARRAY_SIZE(bound); i++)
47+
bound[i] = MT_MIB_ARNCR_RANGE(range[i / 4], i) + 1;
48+
49+
seq_printf(file, "\nPhy0\n");
50+
51+
seq_printf(file, "Length: %8d | ", bound[0]);
52+
for (i = 0; i < ARRAY_SIZE(bound) - 1; i++)
53+
seq_printf(file, "%3d -%3d | ",
54+
bound[i] + 1, bound[i + 1]);
55+
56+
seq_puts(file, "\nCount: ");
57+
for (i = 0; i < ARRAY_SIZE(bound); i++)
58+
seq_printf(file, "%8d | ", dev->mt76.aggr_stats[i]);
59+
seq_puts(file, "\n");
60+
61+
seq_printf(file, "BA miss count: %d\n", phy->mib.ba_miss_cnt);
62+
}
63+
64+
static int
65+
mt7921_tx_stats_read(struct seq_file *file, void *data)
66+
{
67+
struct mt7921_dev *dev = file->private;
68+
int stat[8], i, n;
69+
70+
mt7921_ampdu_stat_read_phy(&dev->phy, file);
71+
72+
/* Tx amsdu info */
73+
seq_puts(file, "Tx MSDU stat:\n");
74+
for (i = 0, n = 0; i < ARRAY_SIZE(stat); i++) {
75+
stat[i] = mt76_rr(dev, MT_PLE_AMSDU_PACK_MSDU_CNT(i));
76+
n += stat[i];
77+
}
78+
79+
for (i = 0; i < ARRAY_SIZE(stat); i++) {
80+
seq_printf(file, "AMSDU pack count of %d MSDU in TXD: 0x%x ",
81+
i + 1, stat[i]);
82+
if (n != 0)
83+
seq_printf(file, "(%d%%)\n", stat[i] * 100 / n);
84+
else
85+
seq_puts(file, "\n");
86+
}
87+
88+
return 0;
89+
}
90+
91+
static int
92+
mt7921_tx_stats_open(struct inode *inode, struct file *f)
93+
{
94+
return single_open(f, mt7921_tx_stats_read, inode->i_private);
95+
}
96+
97+
static const struct file_operations fops_tx_stats = {
98+
.open = mt7921_tx_stats_open,
99+
.read = seq_read,
100+
.llseek = seq_lseek,
101+
.release = single_release,
102+
.owner = THIS_MODULE,
103+
};
104+
105+
static int
106+
mt7921_queues_acq(struct seq_file *s, void *data)
107+
{
108+
struct mt7921_dev *dev = dev_get_drvdata(s->private);
109+
int i;
110+
111+
for (i = 0; i < 16; i++) {
112+
int j, acs = i / 4, index = i % 4;
113+
u32 ctrl, val, qlen = 0;
114+
115+
val = mt76_rr(dev, MT_PLE_AC_QEMPTY(acs, index));
116+
ctrl = BIT(31) | BIT(15) | (acs << 8);
117+
118+
for (j = 0; j < 32; j++) {
119+
if (val & BIT(j))
120+
continue;
121+
122+
mt76_wr(dev, MT_PLE_FL_Q0_CTRL,
123+
ctrl | (j + (index << 5)));
124+
qlen += mt76_get_field(dev, MT_PLE_FL_Q3_CTRL,
125+
GENMASK(11, 0));
126+
}
127+
seq_printf(s, "AC%d%d: queued=%d\n", acs, index, qlen);
128+
}
129+
130+
return 0;
131+
}
132+
133+
static int
134+
mt7921_queues_read(struct seq_file *s, void *data)
135+
{
136+
struct mt7921_dev *dev = dev_get_drvdata(s->private);
137+
struct {
138+
struct mt76_queue *q;
139+
char *queue;
140+
} queue_map[] = {
141+
{ dev->mphy.q_tx[MT_TXQ_BE], "WFDMA0" },
142+
{ dev->mt76.q_mcu[MT_MCUQ_WM], "MCUWM" },
143+
{ dev->mt76.q_mcu[MT_MCUQ_FWDL], "MCUFWQ" },
144+
};
145+
int i;
146+
147+
for (i = 0; i < ARRAY_SIZE(queue_map); i++) {
148+
struct mt76_queue *q = queue_map[i].q;
149+
150+
if (!q)
151+
continue;
152+
153+
seq_printf(s,
154+
"%s: queued=%d head=%d tail=%d\n",
155+
queue_map[i].queue, q->queued, q->head,
156+
q->tail);
157+
}
158+
159+
return 0;
160+
}
161+
162+
int mt7921_init_debugfs(struct mt7921_dev *dev)
163+
{
164+
struct dentry *dir;
165+
166+
dir = mt76_register_debugfs(&dev->mt76);
167+
if (!dir)
168+
return -ENOMEM;
169+
170+
debugfs_create_devm_seqfile(dev->mt76.dev, "queues", dir,
171+
mt7921_queues_read);
172+
debugfs_create_devm_seqfile(dev->mt76.dev, "acq", dir,
173+
mt7921_queues_acq);
174+
debugfs_create_file("tx_stats", 0400, dir, dev, &fops_tx_stats);
175+
debugfs_create_file("fw_debug", 0600, dir, dev, &fops_fw_debug);
176+
177+
return 0;
178+
}

drivers/net/wireless/mediatek/mt76/mt7921/init.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ int mt7921_register_device(struct mt7921_dev *dev)
232232

233233
ieee80211_queue_work(mt76_hw(dev), &dev->init_work);
234234

235-
return 0;
235+
return mt7921_init_debugfs(dev);
236236
}
237237

238238
void mt7921_unregister_device(struct mt7921_dev *dev)

0 commit comments

Comments
 (0)