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