xref: /openbmc/linux/drivers/net/wireless/ti/wl1251/debugfs.c (revision 90921014608d91a03766d0025fa32662dc7c5062)
1*90921014SLuciano Coelho /*
2*90921014SLuciano Coelho  * This file is part of wl1251
3*90921014SLuciano Coelho  *
4*90921014SLuciano Coelho  * Copyright (C) 2009 Nokia Corporation
5*90921014SLuciano Coelho  *
6*90921014SLuciano Coelho  * This program is free software; you can redistribute it and/or
7*90921014SLuciano Coelho  * modify it under the terms of the GNU General Public License
8*90921014SLuciano Coelho  * version 2 as published by the Free Software Foundation.
9*90921014SLuciano Coelho  *
10*90921014SLuciano Coelho  * This program is distributed in the hope that it will be useful, but
11*90921014SLuciano Coelho  * WITHOUT ANY WARRANTY; without even the implied warranty of
12*90921014SLuciano Coelho  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13*90921014SLuciano Coelho  * General Public License for more details.
14*90921014SLuciano Coelho  *
15*90921014SLuciano Coelho  * You should have received a copy of the GNU General Public License
16*90921014SLuciano Coelho  * along with this program; if not, write to the Free Software
17*90921014SLuciano Coelho  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18*90921014SLuciano Coelho  * 02110-1301 USA
19*90921014SLuciano Coelho  *
20*90921014SLuciano Coelho  */
21*90921014SLuciano Coelho 
22*90921014SLuciano Coelho #include "debugfs.h"
23*90921014SLuciano Coelho 
24*90921014SLuciano Coelho #include <linux/skbuff.h>
25*90921014SLuciano Coelho #include <linux/slab.h>
26*90921014SLuciano Coelho 
27*90921014SLuciano Coelho #include "wl1251.h"
28*90921014SLuciano Coelho #include "acx.h"
29*90921014SLuciano Coelho #include "ps.h"
30*90921014SLuciano Coelho 
31*90921014SLuciano Coelho /* ms */
32*90921014SLuciano Coelho #define WL1251_DEBUGFS_STATS_LIFETIME 1000
33*90921014SLuciano Coelho 
34*90921014SLuciano Coelho /* debugfs macros idea from mac80211 */
35*90921014SLuciano Coelho 
36*90921014SLuciano Coelho #define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...)		\
37*90921014SLuciano Coelho static ssize_t name## _read(struct file *file, char __user *userbuf,	\
38*90921014SLuciano Coelho 			    size_t count, loff_t *ppos)			\
39*90921014SLuciano Coelho {									\
40*90921014SLuciano Coelho 	struct wl1251 *wl = file->private_data;				\
41*90921014SLuciano Coelho 	char buf[buflen];						\
42*90921014SLuciano Coelho 	int res;							\
43*90921014SLuciano Coelho 									\
44*90921014SLuciano Coelho 	res = scnprintf(buf, buflen, fmt "\n", ##value);		\
45*90921014SLuciano Coelho 	return simple_read_from_buffer(userbuf, count, ppos, buf, res);	\
46*90921014SLuciano Coelho }									\
47*90921014SLuciano Coelho 									\
48*90921014SLuciano Coelho static const struct file_operations name## _ops = {			\
49*90921014SLuciano Coelho 	.read = name## _read,						\
50*90921014SLuciano Coelho 	.open = wl1251_open_file_generic,				\
51*90921014SLuciano Coelho 	.llseek	= generic_file_llseek,					\
52*90921014SLuciano Coelho };
53*90921014SLuciano Coelho 
54*90921014SLuciano Coelho #define DEBUGFS_ADD(name, parent)					\
55*90921014SLuciano Coelho 	wl->debugfs.name = debugfs_create_file(#name, 0400, parent,	\
56*90921014SLuciano Coelho 					       wl, &name## _ops);	\
57*90921014SLuciano Coelho 	if (IS_ERR(wl->debugfs.name)) {					\
58*90921014SLuciano Coelho 		ret = PTR_ERR(wl->debugfs.name);			\
59*90921014SLuciano Coelho 		wl->debugfs.name = NULL;				\
60*90921014SLuciano Coelho 		goto out;						\
61*90921014SLuciano Coelho 	}
62*90921014SLuciano Coelho 
63*90921014SLuciano Coelho #define DEBUGFS_DEL(name)						\
64*90921014SLuciano Coelho 	do {								\
65*90921014SLuciano Coelho 		debugfs_remove(wl->debugfs.name);			\
66*90921014SLuciano Coelho 		wl->debugfs.name = NULL;				\
67*90921014SLuciano Coelho 	} while (0)
68*90921014SLuciano Coelho 
69*90921014SLuciano Coelho #define DEBUGFS_FWSTATS_FILE(sub, name, buflen, fmt)			\
70*90921014SLuciano Coelho static ssize_t sub## _ ##name## _read(struct file *file,		\
71*90921014SLuciano Coelho 				      char __user *userbuf,		\
72*90921014SLuciano Coelho 				      size_t count, loff_t *ppos)	\
73*90921014SLuciano Coelho {									\
74*90921014SLuciano Coelho 	struct wl1251 *wl = file->private_data;				\
75*90921014SLuciano Coelho 	char buf[buflen];						\
76*90921014SLuciano Coelho 	int res;							\
77*90921014SLuciano Coelho 									\
78*90921014SLuciano Coelho 	wl1251_debugfs_update_stats(wl);				\
79*90921014SLuciano Coelho 									\
80*90921014SLuciano Coelho 	res = scnprintf(buf, buflen, fmt "\n",				\
81*90921014SLuciano Coelho 			wl->stats.fw_stats->sub.name);			\
82*90921014SLuciano Coelho 	return simple_read_from_buffer(userbuf, count, ppos, buf, res);	\
83*90921014SLuciano Coelho }									\
84*90921014SLuciano Coelho 									\
85*90921014SLuciano Coelho static const struct file_operations sub## _ ##name## _ops = {		\
86*90921014SLuciano Coelho 	.read = sub## _ ##name## _read,					\
87*90921014SLuciano Coelho 	.open = wl1251_open_file_generic,				\
88*90921014SLuciano Coelho 	.llseek	= generic_file_llseek,					\
89*90921014SLuciano Coelho };
90*90921014SLuciano Coelho 
91*90921014SLuciano Coelho #define DEBUGFS_FWSTATS_ADD(sub, name)				\
92*90921014SLuciano Coelho 	DEBUGFS_ADD(sub## _ ##name, wl->debugfs.fw_statistics)
93*90921014SLuciano Coelho 
94*90921014SLuciano Coelho #define DEBUGFS_FWSTATS_DEL(sub, name)				\
95*90921014SLuciano Coelho 	DEBUGFS_DEL(sub## _ ##name)
96*90921014SLuciano Coelho 
97*90921014SLuciano Coelho static void wl1251_debugfs_update_stats(struct wl1251 *wl)
98*90921014SLuciano Coelho {
99*90921014SLuciano Coelho 	int ret;
100*90921014SLuciano Coelho 
101*90921014SLuciano Coelho 	mutex_lock(&wl->mutex);
102*90921014SLuciano Coelho 
103*90921014SLuciano Coelho 	ret = wl1251_ps_elp_wakeup(wl);
104*90921014SLuciano Coelho 	if (ret < 0)
105*90921014SLuciano Coelho 		goto out;
106*90921014SLuciano Coelho 
107*90921014SLuciano Coelho 	if (wl->state == WL1251_STATE_ON &&
108*90921014SLuciano Coelho 	    time_after(jiffies, wl->stats.fw_stats_update +
109*90921014SLuciano Coelho 		       msecs_to_jiffies(WL1251_DEBUGFS_STATS_LIFETIME))) {
110*90921014SLuciano Coelho 		wl1251_acx_statistics(wl, wl->stats.fw_stats);
111*90921014SLuciano Coelho 		wl->stats.fw_stats_update = jiffies;
112*90921014SLuciano Coelho 	}
113*90921014SLuciano Coelho 
114*90921014SLuciano Coelho 	wl1251_ps_elp_sleep(wl);
115*90921014SLuciano Coelho 
116*90921014SLuciano Coelho out:
117*90921014SLuciano Coelho 	mutex_unlock(&wl->mutex);
118*90921014SLuciano Coelho }
119*90921014SLuciano Coelho 
120*90921014SLuciano Coelho static int wl1251_open_file_generic(struct inode *inode, struct file *file)
121*90921014SLuciano Coelho {
122*90921014SLuciano Coelho 	file->private_data = inode->i_private;
123*90921014SLuciano Coelho 	return 0;
124*90921014SLuciano Coelho }
125*90921014SLuciano Coelho 
126*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, 20, "%u");
127*90921014SLuciano Coelho 
128*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(rx, out_of_mem, 20, "%u");
129*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, 20, "%u");
130*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(rx, hw_stuck, 20, "%u");
131*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(rx, dropped, 20, "%u");
132*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(rx, fcs_err, 20, "%u");
133*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, 20, "%u");
134*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(rx, path_reset, 20, "%u");
135*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(rx, reset_counter, 20, "%u");
136*90921014SLuciano Coelho 
137*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(dma, rx_requested, 20, "%u");
138*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(dma, rx_errors, 20, "%u");
139*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(dma, tx_requested, 20, "%u");
140*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(dma, tx_errors, 20, "%u");
141*90921014SLuciano Coelho 
142*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, 20, "%u");
143*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, fiqs, 20, "%u");
144*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, rx_headers, 20, "%u");
145*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, 20, "%u");
146*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, rx_rdys, 20, "%u");
147*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, irqs, 20, "%u");
148*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, tx_procs, 20, "%u");
149*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, decrypt_done, 20, "%u");
150*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, dma0_done, 20, "%u");
151*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, dma1_done, 20, "%u");
152*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, 20, "%u");
153*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, commands, 20, "%u");
154*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, rx_procs, 20, "%u");
155*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, 20, "%u");
156*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, 20, "%u");
157*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, pci_pm, 20, "%u");
158*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, wakeups, 20, "%u");
159*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, low_rssi, 20, "%u");
160*90921014SLuciano Coelho 
161*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(wep, addr_key_count, 20, "%u");
162*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(wep, default_key_count, 20, "%u");
163*90921014SLuciano Coelho /* skipping wep.reserved */
164*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(wep, key_not_found, 20, "%u");
165*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, 20, "%u");
166*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(wep, packets, 20, "%u");
167*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(wep, interrupt, 20, "%u");
168*90921014SLuciano Coelho 
169*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(pwr, ps_enter, 20, "%u");
170*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(pwr, elp_enter, 20, "%u");
171*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, 20, "%u");
172*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, 20, "%u");
173*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, 20, "%u");
174*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, 20, "%u");
175*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, 20, "%u");
176*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, 20, "%u");
177*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(pwr, power_save_off, 20, "%u");
178*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(pwr, enable_ps, 20, "%u");
179*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(pwr, disable_ps, 20, "%u");
180*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, 20, "%u");
181*90921014SLuciano Coelho /* skipping cont_miss_bcns_spread for now */
182*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, 20, "%u");
183*90921014SLuciano Coelho 
184*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(mic, rx_pkts, 20, "%u");
185*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(mic, calc_failure, 20, "%u");
186*90921014SLuciano Coelho 
187*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, 20, "%u");
188*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, 20, "%u");
189*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, 20, "%u");
190*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, 20, "%u");
191*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, 20, "%u");
192*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, 20, "%u");
193*90921014SLuciano Coelho 
194*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(event, heart_beat, 20, "%u");
195*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(event, calibration, 20, "%u");
196*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(event, rx_mismatch, 20, "%u");
197*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, 20, "%u");
198*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(event, rx_pool, 20, "%u");
199*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(event, oom_late, 20, "%u");
200*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, 20, "%u");
201*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(event, tx_stuck, 20, "%u");
202*90921014SLuciano Coelho 
203*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, 20, "%u");
204*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, 20, "%u");
205*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, 20, "%u");
206*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, 20, "%u");
207*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, 20, "%u");
208*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, 20, "%u");
209*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, 20, "%u");
210*90921014SLuciano Coelho 
211*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, 20, "%u");
212*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, 20, "%u");
213*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data,
214*90921014SLuciano Coelho 		     20, "%u");
215*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, 20, "%u");
216*90921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, 20, "%u");
217*90921014SLuciano Coelho 
218*90921014SLuciano Coelho DEBUGFS_READONLY_FILE(retry_count, 20, "%u", wl->stats.retry_count);
219*90921014SLuciano Coelho DEBUGFS_READONLY_FILE(excessive_retries, 20, "%u",
220*90921014SLuciano Coelho 		      wl->stats.excessive_retries);
221*90921014SLuciano Coelho 
222*90921014SLuciano Coelho static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf,
223*90921014SLuciano Coelho 				 size_t count, loff_t *ppos)
224*90921014SLuciano Coelho {
225*90921014SLuciano Coelho 	struct wl1251 *wl = file->private_data;
226*90921014SLuciano Coelho 	u32 queue_len;
227*90921014SLuciano Coelho 	char buf[20];
228*90921014SLuciano Coelho 	int res;
229*90921014SLuciano Coelho 
230*90921014SLuciano Coelho 	queue_len = skb_queue_len(&wl->tx_queue);
231*90921014SLuciano Coelho 
232*90921014SLuciano Coelho 	res = scnprintf(buf, sizeof(buf), "%u\n", queue_len);
233*90921014SLuciano Coelho 	return simple_read_from_buffer(userbuf, count, ppos, buf, res);
234*90921014SLuciano Coelho }
235*90921014SLuciano Coelho 
236*90921014SLuciano Coelho static const struct file_operations tx_queue_len_ops = {
237*90921014SLuciano Coelho 	.read = tx_queue_len_read,
238*90921014SLuciano Coelho 	.open = wl1251_open_file_generic,
239*90921014SLuciano Coelho 	.llseek = generic_file_llseek,
240*90921014SLuciano Coelho };
241*90921014SLuciano Coelho 
242*90921014SLuciano Coelho static ssize_t tx_queue_status_read(struct file *file, char __user *userbuf,
243*90921014SLuciano Coelho 				    size_t count, loff_t *ppos)
244*90921014SLuciano Coelho {
245*90921014SLuciano Coelho 	struct wl1251 *wl = file->private_data;
246*90921014SLuciano Coelho 	char buf[3], status;
247*90921014SLuciano Coelho 	int len;
248*90921014SLuciano Coelho 
249*90921014SLuciano Coelho 	if (wl->tx_queue_stopped)
250*90921014SLuciano Coelho 		status = 's';
251*90921014SLuciano Coelho 	else
252*90921014SLuciano Coelho 		status = 'r';
253*90921014SLuciano Coelho 
254*90921014SLuciano Coelho 	len = scnprintf(buf, sizeof(buf), "%c\n", status);
255*90921014SLuciano Coelho 	return simple_read_from_buffer(userbuf, count, ppos, buf, len);
256*90921014SLuciano Coelho }
257*90921014SLuciano Coelho 
258*90921014SLuciano Coelho static const struct file_operations tx_queue_status_ops = {
259*90921014SLuciano Coelho 	.read = tx_queue_status_read,
260*90921014SLuciano Coelho 	.open = wl1251_open_file_generic,
261*90921014SLuciano Coelho 	.llseek = generic_file_llseek,
262*90921014SLuciano Coelho };
263*90921014SLuciano Coelho 
264*90921014SLuciano Coelho static void wl1251_debugfs_delete_files(struct wl1251 *wl)
265*90921014SLuciano Coelho {
266*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow);
267*90921014SLuciano Coelho 
268*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(rx, out_of_mem);
269*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(rx, hdr_overflow);
270*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(rx, hw_stuck);
271*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(rx, dropped);
272*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(rx, fcs_err);
273*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(rx, xfr_hint_trig);
274*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(rx, path_reset);
275*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(rx, reset_counter);
276*90921014SLuciano Coelho 
277*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(dma, rx_requested);
278*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(dma, rx_errors);
279*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(dma, tx_requested);
280*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(dma, tx_errors);
281*90921014SLuciano Coelho 
282*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(isr, cmd_cmplt);
283*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(isr, fiqs);
284*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(isr, rx_headers);
285*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(isr, rx_mem_overflow);
286*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(isr, rx_rdys);
287*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(isr, irqs);
288*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(isr, tx_procs);
289*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(isr, decrypt_done);
290*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(isr, dma0_done);
291*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(isr, dma1_done);
292*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(isr, tx_exch_complete);
293*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(isr, commands);
294*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(isr, rx_procs);
295*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(isr, hw_pm_mode_changes);
296*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(isr, host_acknowledges);
297*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(isr, pci_pm);
298*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(isr, wakeups);
299*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(isr, low_rssi);
300*90921014SLuciano Coelho 
301*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(wep, addr_key_count);
302*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(wep, default_key_count);
303*90921014SLuciano Coelho 	/* skipping wep.reserved */
304*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(wep, key_not_found);
305*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(wep, decrypt_fail);
306*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(wep, packets);
307*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(wep, interrupt);
308*90921014SLuciano Coelho 
309*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(pwr, ps_enter);
310*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(pwr, elp_enter);
311*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(pwr, missing_bcns);
312*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(pwr, wake_on_host);
313*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(pwr, wake_on_timer_exp);
314*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(pwr, tx_with_ps);
315*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(pwr, tx_without_ps);
316*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(pwr, rcvd_beacons);
317*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(pwr, power_save_off);
318*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(pwr, enable_ps);
319*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(pwr, disable_ps);
320*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(pwr, fix_tsf_ps);
321*90921014SLuciano Coelho 	/* skipping cont_miss_bcns_spread for now */
322*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(pwr, rcvd_awake_beacons);
323*90921014SLuciano Coelho 
324*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(mic, rx_pkts);
325*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(mic, calc_failure);
326*90921014SLuciano Coelho 
327*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(aes, encrypt_fail);
328*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(aes, decrypt_fail);
329*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(aes, encrypt_packets);
330*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(aes, decrypt_packets);
331*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(aes, encrypt_interrupt);
332*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(aes, decrypt_interrupt);
333*90921014SLuciano Coelho 
334*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(event, heart_beat);
335*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(event, calibration);
336*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(event, rx_mismatch);
337*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(event, rx_mem_empty);
338*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(event, rx_pool);
339*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(event, oom_late);
340*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(event, phy_transmit_error);
341*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(event, tx_stuck);
342*90921014SLuciano Coelho 
343*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(ps, pspoll_timeouts);
344*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(ps, upsd_timeouts);
345*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(ps, upsd_max_sptime);
346*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(ps, upsd_max_apturn);
347*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(ps, pspoll_max_apturn);
348*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(ps, pspoll_utilization);
349*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(ps, upsd_utilization);
350*90921014SLuciano Coelho 
351*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(rxpipe, rx_prep_beacon_drop);
352*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(rxpipe, descr_host_int_trig_rx_data);
353*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
354*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(rxpipe, missed_beacon_host_int_trig_rx_data);
355*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_DEL(rxpipe, tx_xfr_host_int_trig_rx_data);
356*90921014SLuciano Coelho 
357*90921014SLuciano Coelho 	DEBUGFS_DEL(tx_queue_len);
358*90921014SLuciano Coelho 	DEBUGFS_DEL(tx_queue_status);
359*90921014SLuciano Coelho 	DEBUGFS_DEL(retry_count);
360*90921014SLuciano Coelho 	DEBUGFS_DEL(excessive_retries);
361*90921014SLuciano Coelho }
362*90921014SLuciano Coelho 
363*90921014SLuciano Coelho static int wl1251_debugfs_add_files(struct wl1251 *wl)
364*90921014SLuciano Coelho {
365*90921014SLuciano Coelho 	int ret = 0;
366*90921014SLuciano Coelho 
367*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(tx, internal_desc_overflow);
368*90921014SLuciano Coelho 
369*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(rx, out_of_mem);
370*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(rx, hdr_overflow);
371*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(rx, hw_stuck);
372*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(rx, dropped);
373*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(rx, fcs_err);
374*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(rx, xfr_hint_trig);
375*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(rx, path_reset);
376*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(rx, reset_counter);
377*90921014SLuciano Coelho 
378*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(dma, rx_requested);
379*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(dma, rx_errors);
380*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(dma, tx_requested);
381*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(dma, tx_errors);
382*90921014SLuciano Coelho 
383*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(isr, cmd_cmplt);
384*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(isr, fiqs);
385*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(isr, rx_headers);
386*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(isr, rx_mem_overflow);
387*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(isr, rx_rdys);
388*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(isr, irqs);
389*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(isr, tx_procs);
390*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(isr, decrypt_done);
391*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(isr, dma0_done);
392*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(isr, dma1_done);
393*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(isr, tx_exch_complete);
394*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(isr, commands);
395*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(isr, rx_procs);
396*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(isr, hw_pm_mode_changes);
397*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(isr, host_acknowledges);
398*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(isr, pci_pm);
399*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(isr, wakeups);
400*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(isr, low_rssi);
401*90921014SLuciano Coelho 
402*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(wep, addr_key_count);
403*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(wep, default_key_count);
404*90921014SLuciano Coelho 	/* skipping wep.reserved */
405*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(wep, key_not_found);
406*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(wep, decrypt_fail);
407*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(wep, packets);
408*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(wep, interrupt);
409*90921014SLuciano Coelho 
410*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(pwr, ps_enter);
411*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(pwr, elp_enter);
412*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(pwr, missing_bcns);
413*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(pwr, wake_on_host);
414*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(pwr, wake_on_timer_exp);
415*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(pwr, tx_with_ps);
416*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(pwr, tx_without_ps);
417*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(pwr, rcvd_beacons);
418*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(pwr, power_save_off);
419*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(pwr, enable_ps);
420*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(pwr, disable_ps);
421*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(pwr, fix_tsf_ps);
422*90921014SLuciano Coelho 	/* skipping cont_miss_bcns_spread for now */
423*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_beacons);
424*90921014SLuciano Coelho 
425*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(mic, rx_pkts);
426*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(mic, calc_failure);
427*90921014SLuciano Coelho 
428*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(aes, encrypt_fail);
429*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(aes, decrypt_fail);
430*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(aes, encrypt_packets);
431*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(aes, decrypt_packets);
432*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(aes, encrypt_interrupt);
433*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(aes, decrypt_interrupt);
434*90921014SLuciano Coelho 
435*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(event, heart_beat);
436*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(event, calibration);
437*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(event, rx_mismatch);
438*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(event, rx_mem_empty);
439*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(event, rx_pool);
440*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(event, oom_late);
441*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(event, phy_transmit_error);
442*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(event, tx_stuck);
443*90921014SLuciano Coelho 
444*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(ps, pspoll_timeouts);
445*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(ps, upsd_timeouts);
446*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(ps, upsd_max_sptime);
447*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(ps, upsd_max_apturn);
448*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(ps, pspoll_max_apturn);
449*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(ps, pspoll_utilization);
450*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(ps, upsd_utilization);
451*90921014SLuciano Coelho 
452*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(rxpipe, rx_prep_beacon_drop);
453*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(rxpipe, descr_host_int_trig_rx_data);
454*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
455*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data);
456*90921014SLuciano Coelho 	DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data);
457*90921014SLuciano Coelho 
458*90921014SLuciano Coelho 	DEBUGFS_ADD(tx_queue_len, wl->debugfs.rootdir);
459*90921014SLuciano Coelho 	DEBUGFS_ADD(tx_queue_status, wl->debugfs.rootdir);
460*90921014SLuciano Coelho 	DEBUGFS_ADD(retry_count, wl->debugfs.rootdir);
461*90921014SLuciano Coelho 	DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir);
462*90921014SLuciano Coelho 
463*90921014SLuciano Coelho out:
464*90921014SLuciano Coelho 	if (ret < 0)
465*90921014SLuciano Coelho 		wl1251_debugfs_delete_files(wl);
466*90921014SLuciano Coelho 
467*90921014SLuciano Coelho 	return ret;
468*90921014SLuciano Coelho }
469*90921014SLuciano Coelho 
470*90921014SLuciano Coelho void wl1251_debugfs_reset(struct wl1251 *wl)
471*90921014SLuciano Coelho {
472*90921014SLuciano Coelho 	if (wl->stats.fw_stats != NULL)
473*90921014SLuciano Coelho 		memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats));
474*90921014SLuciano Coelho 	wl->stats.retry_count = 0;
475*90921014SLuciano Coelho 	wl->stats.excessive_retries = 0;
476*90921014SLuciano Coelho }
477*90921014SLuciano Coelho 
478*90921014SLuciano Coelho int wl1251_debugfs_init(struct wl1251 *wl)
479*90921014SLuciano Coelho {
480*90921014SLuciano Coelho 	int ret;
481*90921014SLuciano Coelho 
482*90921014SLuciano Coelho 	wl->debugfs.rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL);
483*90921014SLuciano Coelho 
484*90921014SLuciano Coelho 	if (IS_ERR(wl->debugfs.rootdir)) {
485*90921014SLuciano Coelho 		ret = PTR_ERR(wl->debugfs.rootdir);
486*90921014SLuciano Coelho 		wl->debugfs.rootdir = NULL;
487*90921014SLuciano Coelho 		goto err;
488*90921014SLuciano Coelho 	}
489*90921014SLuciano Coelho 
490*90921014SLuciano Coelho 	wl->debugfs.fw_statistics = debugfs_create_dir("fw-statistics",
491*90921014SLuciano Coelho 						       wl->debugfs.rootdir);
492*90921014SLuciano Coelho 
493*90921014SLuciano Coelho 	if (IS_ERR(wl->debugfs.fw_statistics)) {
494*90921014SLuciano Coelho 		ret = PTR_ERR(wl->debugfs.fw_statistics);
495*90921014SLuciano Coelho 		wl->debugfs.fw_statistics = NULL;
496*90921014SLuciano Coelho 		goto err_root;
497*90921014SLuciano Coelho 	}
498*90921014SLuciano Coelho 
499*90921014SLuciano Coelho 	wl->stats.fw_stats = kzalloc(sizeof(*wl->stats.fw_stats),
500*90921014SLuciano Coelho 				      GFP_KERNEL);
501*90921014SLuciano Coelho 
502*90921014SLuciano Coelho 	if (!wl->stats.fw_stats) {
503*90921014SLuciano Coelho 		ret = -ENOMEM;
504*90921014SLuciano Coelho 		goto err_fw;
505*90921014SLuciano Coelho 	}
506*90921014SLuciano Coelho 
507*90921014SLuciano Coelho 	wl->stats.fw_stats_update = jiffies;
508*90921014SLuciano Coelho 
509*90921014SLuciano Coelho 	ret = wl1251_debugfs_add_files(wl);
510*90921014SLuciano Coelho 
511*90921014SLuciano Coelho 	if (ret < 0)
512*90921014SLuciano Coelho 		goto err_file;
513*90921014SLuciano Coelho 
514*90921014SLuciano Coelho 	return 0;
515*90921014SLuciano Coelho 
516*90921014SLuciano Coelho err_file:
517*90921014SLuciano Coelho 	kfree(wl->stats.fw_stats);
518*90921014SLuciano Coelho 	wl->stats.fw_stats = NULL;
519*90921014SLuciano Coelho 
520*90921014SLuciano Coelho err_fw:
521*90921014SLuciano Coelho 	debugfs_remove(wl->debugfs.fw_statistics);
522*90921014SLuciano Coelho 	wl->debugfs.fw_statistics = NULL;
523*90921014SLuciano Coelho 
524*90921014SLuciano Coelho err_root:
525*90921014SLuciano Coelho 	debugfs_remove(wl->debugfs.rootdir);
526*90921014SLuciano Coelho 	wl->debugfs.rootdir = NULL;
527*90921014SLuciano Coelho 
528*90921014SLuciano Coelho err:
529*90921014SLuciano Coelho 	return ret;
530*90921014SLuciano Coelho }
531*90921014SLuciano Coelho 
532*90921014SLuciano Coelho void wl1251_debugfs_exit(struct wl1251 *wl)
533*90921014SLuciano Coelho {
534*90921014SLuciano Coelho 	wl1251_debugfs_delete_files(wl);
535*90921014SLuciano Coelho 
536*90921014SLuciano Coelho 	kfree(wl->stats.fw_stats);
537*90921014SLuciano Coelho 	wl->stats.fw_stats = NULL;
538*90921014SLuciano Coelho 
539*90921014SLuciano Coelho 	debugfs_remove(wl->debugfs.fw_statistics);
540*90921014SLuciano Coelho 	wl->debugfs.fw_statistics = NULL;
541*90921014SLuciano Coelho 
542*90921014SLuciano Coelho 	debugfs_remove(wl->debugfs.rootdir);
543*90921014SLuciano Coelho 	wl->debugfs.rootdir = NULL;
544*90921014SLuciano Coelho 
545*90921014SLuciano Coelho }
546