12b27bdccSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
290921014SLuciano Coelho /*
390921014SLuciano Coelho * This file is part of wl1251
490921014SLuciano Coelho *
590921014SLuciano Coelho * Copyright (C) 2009 Nokia Corporation
690921014SLuciano Coelho */
790921014SLuciano Coelho
890921014SLuciano Coelho #include "debugfs.h"
990921014SLuciano Coelho
1090921014SLuciano Coelho #include <linux/skbuff.h>
1190921014SLuciano Coelho #include <linux/slab.h>
1290921014SLuciano Coelho
1390921014SLuciano Coelho #include "wl1251.h"
1490921014SLuciano Coelho #include "acx.h"
1590921014SLuciano Coelho #include "ps.h"
1690921014SLuciano Coelho
1790921014SLuciano Coelho /* ms */
1890921014SLuciano Coelho #define WL1251_DEBUGFS_STATS_LIFETIME 1000
1990921014SLuciano Coelho
2090921014SLuciano Coelho /* debugfs macros idea from mac80211 */
2190921014SLuciano Coelho
2290921014SLuciano Coelho #define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...) \
2390921014SLuciano Coelho static ssize_t name## _read(struct file *file, char __user *userbuf, \
2490921014SLuciano Coelho size_t count, loff_t *ppos) \
2590921014SLuciano Coelho { \
2690921014SLuciano Coelho struct wl1251 *wl = file->private_data; \
2790921014SLuciano Coelho char buf[buflen]; \
2890921014SLuciano Coelho int res; \
2990921014SLuciano Coelho \
3090921014SLuciano Coelho res = scnprintf(buf, buflen, fmt "\n", ##value); \
3190921014SLuciano Coelho return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
3290921014SLuciano Coelho } \
3390921014SLuciano Coelho \
3490921014SLuciano Coelho static const struct file_operations name## _ops = { \
3590921014SLuciano Coelho .read = name## _read, \
36f2776834SJohn W. Linville .open = simple_open, \
3790921014SLuciano Coelho .llseek = generic_file_llseek, \
3890921014SLuciano Coelho };
3990921014SLuciano Coelho
4090921014SLuciano Coelho #define DEBUGFS_ADD(name, parent) \
4190921014SLuciano Coelho wl->debugfs.name = debugfs_create_file(#name, 0400, parent, \
42*fc6877b8STom Rix wl, &name## _ops) \
4390921014SLuciano Coelho
4490921014SLuciano Coelho #define DEBUGFS_DEL(name) \
4590921014SLuciano Coelho do { \
4690921014SLuciano Coelho debugfs_remove(wl->debugfs.name); \
4790921014SLuciano Coelho wl->debugfs.name = NULL; \
4890921014SLuciano Coelho } while (0)
4990921014SLuciano Coelho
5090921014SLuciano Coelho #define DEBUGFS_FWSTATS_FILE(sub, name, buflen, fmt) \
5190921014SLuciano Coelho static ssize_t sub## _ ##name## _read(struct file *file, \
5290921014SLuciano Coelho char __user *userbuf, \
5390921014SLuciano Coelho size_t count, loff_t *ppos) \
5490921014SLuciano Coelho { \
5590921014SLuciano Coelho struct wl1251 *wl = file->private_data; \
5690921014SLuciano Coelho char buf[buflen]; \
5790921014SLuciano Coelho int res; \
5890921014SLuciano Coelho \
5990921014SLuciano Coelho wl1251_debugfs_update_stats(wl); \
6090921014SLuciano Coelho \
6190921014SLuciano Coelho res = scnprintf(buf, buflen, fmt "\n", \
6290921014SLuciano Coelho wl->stats.fw_stats->sub.name); \
6390921014SLuciano Coelho return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
6490921014SLuciano Coelho } \
6590921014SLuciano Coelho \
6690921014SLuciano Coelho static const struct file_operations sub## _ ##name## _ops = { \
6790921014SLuciano Coelho .read = sub## _ ##name## _read, \
68f2776834SJohn W. Linville .open = simple_open, \
6990921014SLuciano Coelho .llseek = generic_file_llseek, \
7090921014SLuciano Coelho };
7190921014SLuciano Coelho
7290921014SLuciano Coelho #define DEBUGFS_FWSTATS_ADD(sub, name) \
7390921014SLuciano Coelho DEBUGFS_ADD(sub## _ ##name, wl->debugfs.fw_statistics)
7490921014SLuciano Coelho
7590921014SLuciano Coelho #define DEBUGFS_FWSTATS_DEL(sub, name) \
7690921014SLuciano Coelho DEBUGFS_DEL(sub## _ ##name)
7790921014SLuciano Coelho
wl1251_debugfs_update_stats(struct wl1251 * wl)7890921014SLuciano Coelho static void wl1251_debugfs_update_stats(struct wl1251 *wl)
7990921014SLuciano Coelho {
8090921014SLuciano Coelho int ret;
8190921014SLuciano Coelho
8290921014SLuciano Coelho mutex_lock(&wl->mutex);
8390921014SLuciano Coelho
8490921014SLuciano Coelho ret = wl1251_ps_elp_wakeup(wl);
8590921014SLuciano Coelho if (ret < 0)
8690921014SLuciano Coelho goto out;
8790921014SLuciano Coelho
8890921014SLuciano Coelho if (wl->state == WL1251_STATE_ON &&
8990921014SLuciano Coelho time_after(jiffies, wl->stats.fw_stats_update +
9090921014SLuciano Coelho msecs_to_jiffies(WL1251_DEBUGFS_STATS_LIFETIME))) {
9190921014SLuciano Coelho wl1251_acx_statistics(wl, wl->stats.fw_stats);
9290921014SLuciano Coelho wl->stats.fw_stats_update = jiffies;
9390921014SLuciano Coelho }
9490921014SLuciano Coelho
9590921014SLuciano Coelho wl1251_ps_elp_sleep(wl);
9690921014SLuciano Coelho
9790921014SLuciano Coelho out:
9890921014SLuciano Coelho mutex_unlock(&wl->mutex);
9990921014SLuciano Coelho }
10090921014SLuciano Coelho
10190921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, 20, "%u");
10290921014SLuciano Coelho
10390921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(rx, out_of_mem, 20, "%u");
10490921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, 20, "%u");
10590921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(rx, hw_stuck, 20, "%u");
10690921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(rx, dropped, 20, "%u");
10790921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(rx, fcs_err, 20, "%u");
10890921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, 20, "%u");
10990921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(rx, path_reset, 20, "%u");
11090921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(rx, reset_counter, 20, "%u");
11190921014SLuciano Coelho
11290921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(dma, rx_requested, 20, "%u");
11390921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(dma, rx_errors, 20, "%u");
11490921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(dma, tx_requested, 20, "%u");
11590921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(dma, tx_errors, 20, "%u");
11690921014SLuciano Coelho
11790921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, 20, "%u");
11890921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, fiqs, 20, "%u");
11990921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, rx_headers, 20, "%u");
12090921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, 20, "%u");
12190921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, rx_rdys, 20, "%u");
12290921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, irqs, 20, "%u");
12390921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, tx_procs, 20, "%u");
12490921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, decrypt_done, 20, "%u");
12590921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, dma0_done, 20, "%u");
12690921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, dma1_done, 20, "%u");
12790921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, 20, "%u");
12890921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, commands, 20, "%u");
12990921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, rx_procs, 20, "%u");
13090921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, 20, "%u");
13190921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, 20, "%u");
13290921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, pci_pm, 20, "%u");
13390921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, wakeups, 20, "%u");
13490921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(isr, low_rssi, 20, "%u");
13590921014SLuciano Coelho
13690921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(wep, addr_key_count, 20, "%u");
13790921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(wep, default_key_count, 20, "%u");
13890921014SLuciano Coelho /* skipping wep.reserved */
13990921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(wep, key_not_found, 20, "%u");
14090921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, 20, "%u");
14190921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(wep, packets, 20, "%u");
14290921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(wep, interrupt, 20, "%u");
14390921014SLuciano Coelho
14490921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(pwr, ps_enter, 20, "%u");
14590921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(pwr, elp_enter, 20, "%u");
14690921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, 20, "%u");
14790921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, 20, "%u");
14890921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, 20, "%u");
14990921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, 20, "%u");
15090921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, 20, "%u");
15190921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, 20, "%u");
15290921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(pwr, power_save_off, 20, "%u");
15390921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(pwr, enable_ps, 20, "%u");
15490921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(pwr, disable_ps, 20, "%u");
15590921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, 20, "%u");
15690921014SLuciano Coelho /* skipping cont_miss_bcns_spread for now */
15790921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, 20, "%u");
15890921014SLuciano Coelho
15990921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(mic, rx_pkts, 20, "%u");
16090921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(mic, calc_failure, 20, "%u");
16190921014SLuciano Coelho
16290921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, 20, "%u");
16390921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, 20, "%u");
16490921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, 20, "%u");
16590921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, 20, "%u");
16690921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, 20, "%u");
16790921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, 20, "%u");
16890921014SLuciano Coelho
16990921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(event, heart_beat, 20, "%u");
17090921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(event, calibration, 20, "%u");
17190921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(event, rx_mismatch, 20, "%u");
17290921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, 20, "%u");
17390921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(event, rx_pool, 20, "%u");
17490921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(event, oom_late, 20, "%u");
17590921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, 20, "%u");
17690921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(event, tx_stuck, 20, "%u");
17790921014SLuciano Coelho
17890921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, 20, "%u");
17990921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, 20, "%u");
18090921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, 20, "%u");
18190921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, 20, "%u");
18290921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, 20, "%u");
18390921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, 20, "%u");
18490921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, 20, "%u");
18590921014SLuciano Coelho
18690921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, 20, "%u");
18790921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, 20, "%u");
18890921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data,
18990921014SLuciano Coelho 20, "%u");
19090921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, 20, "%u");
19190921014SLuciano Coelho DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, 20, "%u");
19290921014SLuciano Coelho
19390921014SLuciano Coelho DEBUGFS_READONLY_FILE(retry_count, 20, "%u", wl->stats.retry_count);
19490921014SLuciano Coelho DEBUGFS_READONLY_FILE(excessive_retries, 20, "%u",
19590921014SLuciano Coelho wl->stats.excessive_retries);
19690921014SLuciano Coelho
tx_queue_len_read(struct file * file,char __user * userbuf,size_t count,loff_t * ppos)19790921014SLuciano Coelho static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf,
19890921014SLuciano Coelho size_t count, loff_t *ppos)
19990921014SLuciano Coelho {
20090921014SLuciano Coelho struct wl1251 *wl = file->private_data;
20190921014SLuciano Coelho u32 queue_len;
20290921014SLuciano Coelho char buf[20];
20390921014SLuciano Coelho int res;
20490921014SLuciano Coelho
20590921014SLuciano Coelho queue_len = skb_queue_len(&wl->tx_queue);
20690921014SLuciano Coelho
20790921014SLuciano Coelho res = scnprintf(buf, sizeof(buf), "%u\n", queue_len);
20890921014SLuciano Coelho return simple_read_from_buffer(userbuf, count, ppos, buf, res);
20990921014SLuciano Coelho }
21090921014SLuciano Coelho
21190921014SLuciano Coelho static const struct file_operations tx_queue_len_ops = {
21290921014SLuciano Coelho .read = tx_queue_len_read,
213f2776834SJohn W. Linville .open = simple_open,
21490921014SLuciano Coelho .llseek = generic_file_llseek,
21590921014SLuciano Coelho };
21690921014SLuciano Coelho
tx_queue_status_read(struct file * file,char __user * userbuf,size_t count,loff_t * ppos)21790921014SLuciano Coelho static ssize_t tx_queue_status_read(struct file *file, char __user *userbuf,
21890921014SLuciano Coelho size_t count, loff_t *ppos)
21990921014SLuciano Coelho {
22090921014SLuciano Coelho struct wl1251 *wl = file->private_data;
22190921014SLuciano Coelho char buf[3], status;
22290921014SLuciano Coelho int len;
22390921014SLuciano Coelho
22490921014SLuciano Coelho if (wl->tx_queue_stopped)
22590921014SLuciano Coelho status = 's';
22690921014SLuciano Coelho else
22790921014SLuciano Coelho status = 'r';
22890921014SLuciano Coelho
22990921014SLuciano Coelho len = scnprintf(buf, sizeof(buf), "%c\n", status);
23090921014SLuciano Coelho return simple_read_from_buffer(userbuf, count, ppos, buf, len);
23190921014SLuciano Coelho }
23290921014SLuciano Coelho
23390921014SLuciano Coelho static const struct file_operations tx_queue_status_ops = {
23490921014SLuciano Coelho .read = tx_queue_status_read,
235f2776834SJohn W. Linville .open = simple_open,
23690921014SLuciano Coelho .llseek = generic_file_llseek,
23790921014SLuciano Coelho };
23890921014SLuciano Coelho
wl1251_debugfs_delete_files(struct wl1251 * wl)23990921014SLuciano Coelho static void wl1251_debugfs_delete_files(struct wl1251 *wl)
24090921014SLuciano Coelho {
24190921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow);
24290921014SLuciano Coelho
24390921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(rx, out_of_mem);
24490921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(rx, hdr_overflow);
24590921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(rx, hw_stuck);
24690921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(rx, dropped);
24790921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(rx, fcs_err);
24890921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(rx, xfr_hint_trig);
24990921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(rx, path_reset);
25090921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(rx, reset_counter);
25190921014SLuciano Coelho
25290921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(dma, rx_requested);
25390921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(dma, rx_errors);
25490921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(dma, tx_requested);
25590921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(dma, tx_errors);
25690921014SLuciano Coelho
25790921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(isr, cmd_cmplt);
25890921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(isr, fiqs);
25990921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(isr, rx_headers);
26090921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(isr, rx_mem_overflow);
26190921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(isr, rx_rdys);
26290921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(isr, irqs);
26390921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(isr, tx_procs);
26490921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(isr, decrypt_done);
26590921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(isr, dma0_done);
26690921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(isr, dma1_done);
26790921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(isr, tx_exch_complete);
26890921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(isr, commands);
26990921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(isr, rx_procs);
27090921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(isr, hw_pm_mode_changes);
27190921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(isr, host_acknowledges);
27290921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(isr, pci_pm);
27390921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(isr, wakeups);
27490921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(isr, low_rssi);
27590921014SLuciano Coelho
27690921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(wep, addr_key_count);
27790921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(wep, default_key_count);
27890921014SLuciano Coelho /* skipping wep.reserved */
27990921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(wep, key_not_found);
28090921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(wep, decrypt_fail);
28190921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(wep, packets);
28290921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(wep, interrupt);
28390921014SLuciano Coelho
28490921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(pwr, ps_enter);
28590921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(pwr, elp_enter);
28690921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(pwr, missing_bcns);
28790921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(pwr, wake_on_host);
28890921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(pwr, wake_on_timer_exp);
28990921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(pwr, tx_with_ps);
29090921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(pwr, tx_without_ps);
29190921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(pwr, rcvd_beacons);
29290921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(pwr, power_save_off);
29390921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(pwr, enable_ps);
29490921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(pwr, disable_ps);
29590921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(pwr, fix_tsf_ps);
29690921014SLuciano Coelho /* skipping cont_miss_bcns_spread for now */
29790921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(pwr, rcvd_awake_beacons);
29890921014SLuciano Coelho
29990921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(mic, rx_pkts);
30090921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(mic, calc_failure);
30190921014SLuciano Coelho
30290921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(aes, encrypt_fail);
30390921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(aes, decrypt_fail);
30490921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(aes, encrypt_packets);
30590921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(aes, decrypt_packets);
30690921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(aes, encrypt_interrupt);
30790921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(aes, decrypt_interrupt);
30890921014SLuciano Coelho
30990921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(event, heart_beat);
31090921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(event, calibration);
31190921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(event, rx_mismatch);
31290921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(event, rx_mem_empty);
31390921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(event, rx_pool);
31490921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(event, oom_late);
31590921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(event, phy_transmit_error);
31690921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(event, tx_stuck);
31790921014SLuciano Coelho
31890921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(ps, pspoll_timeouts);
31990921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(ps, upsd_timeouts);
32090921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(ps, upsd_max_sptime);
32190921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(ps, upsd_max_apturn);
32290921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(ps, pspoll_max_apturn);
32390921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(ps, pspoll_utilization);
32490921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(ps, upsd_utilization);
32590921014SLuciano Coelho
32690921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(rxpipe, rx_prep_beacon_drop);
32790921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(rxpipe, descr_host_int_trig_rx_data);
32890921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
32990921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(rxpipe, missed_beacon_host_int_trig_rx_data);
33090921014SLuciano Coelho DEBUGFS_FWSTATS_DEL(rxpipe, tx_xfr_host_int_trig_rx_data);
33190921014SLuciano Coelho
33290921014SLuciano Coelho DEBUGFS_DEL(tx_queue_len);
33390921014SLuciano Coelho DEBUGFS_DEL(tx_queue_status);
33490921014SLuciano Coelho DEBUGFS_DEL(retry_count);
33590921014SLuciano Coelho DEBUGFS_DEL(excessive_retries);
33690921014SLuciano Coelho }
33790921014SLuciano Coelho
wl1251_debugfs_add_files(struct wl1251 * wl)33872efec9bSGreg Kroah-Hartman static void wl1251_debugfs_add_files(struct wl1251 *wl)
33990921014SLuciano Coelho {
34090921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(tx, internal_desc_overflow);
34190921014SLuciano Coelho
34290921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(rx, out_of_mem);
34390921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(rx, hdr_overflow);
34490921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(rx, hw_stuck);
34590921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(rx, dropped);
34690921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(rx, fcs_err);
34790921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(rx, xfr_hint_trig);
34890921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(rx, path_reset);
34990921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(rx, reset_counter);
35090921014SLuciano Coelho
35190921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(dma, rx_requested);
35290921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(dma, rx_errors);
35390921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(dma, tx_requested);
35490921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(dma, tx_errors);
35590921014SLuciano Coelho
35690921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(isr, cmd_cmplt);
35790921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(isr, fiqs);
35890921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(isr, rx_headers);
35990921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(isr, rx_mem_overflow);
36090921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(isr, rx_rdys);
36190921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(isr, irqs);
36290921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(isr, tx_procs);
36390921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(isr, decrypt_done);
36490921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(isr, dma0_done);
36590921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(isr, dma1_done);
36690921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(isr, tx_exch_complete);
36790921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(isr, commands);
36890921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(isr, rx_procs);
36990921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(isr, hw_pm_mode_changes);
37090921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(isr, host_acknowledges);
37190921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(isr, pci_pm);
37290921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(isr, wakeups);
37390921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(isr, low_rssi);
37490921014SLuciano Coelho
37590921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(wep, addr_key_count);
37690921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(wep, default_key_count);
37790921014SLuciano Coelho /* skipping wep.reserved */
37890921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(wep, key_not_found);
37990921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(wep, decrypt_fail);
38090921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(wep, packets);
38190921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(wep, interrupt);
38290921014SLuciano Coelho
38390921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(pwr, ps_enter);
38490921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(pwr, elp_enter);
38590921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(pwr, missing_bcns);
38690921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(pwr, wake_on_host);
38790921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(pwr, wake_on_timer_exp);
38890921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(pwr, tx_with_ps);
38990921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(pwr, tx_without_ps);
39090921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(pwr, rcvd_beacons);
39190921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(pwr, power_save_off);
39290921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(pwr, enable_ps);
39390921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(pwr, disable_ps);
39490921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(pwr, fix_tsf_ps);
39590921014SLuciano Coelho /* skipping cont_miss_bcns_spread for now */
39690921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_beacons);
39790921014SLuciano Coelho
39890921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(mic, rx_pkts);
39990921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(mic, calc_failure);
40090921014SLuciano Coelho
40190921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(aes, encrypt_fail);
40290921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(aes, decrypt_fail);
40390921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(aes, encrypt_packets);
40490921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(aes, decrypt_packets);
40590921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(aes, encrypt_interrupt);
40690921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(aes, decrypt_interrupt);
40790921014SLuciano Coelho
40890921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(event, heart_beat);
40990921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(event, calibration);
41090921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(event, rx_mismatch);
41190921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(event, rx_mem_empty);
41290921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(event, rx_pool);
41390921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(event, oom_late);
41490921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(event, phy_transmit_error);
41590921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(event, tx_stuck);
41690921014SLuciano Coelho
41790921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(ps, pspoll_timeouts);
41890921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(ps, upsd_timeouts);
41990921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(ps, upsd_max_sptime);
42090921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(ps, upsd_max_apturn);
42190921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(ps, pspoll_max_apturn);
42290921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(ps, pspoll_utilization);
42390921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(ps, upsd_utilization);
42490921014SLuciano Coelho
42590921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(rxpipe, rx_prep_beacon_drop);
42690921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(rxpipe, descr_host_int_trig_rx_data);
42790921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
42890921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data);
42990921014SLuciano Coelho DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data);
43090921014SLuciano Coelho
43190921014SLuciano Coelho DEBUGFS_ADD(tx_queue_len, wl->debugfs.rootdir);
43290921014SLuciano Coelho DEBUGFS_ADD(tx_queue_status, wl->debugfs.rootdir);
43390921014SLuciano Coelho DEBUGFS_ADD(retry_count, wl->debugfs.rootdir);
43490921014SLuciano Coelho DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir);
43590921014SLuciano Coelho }
43690921014SLuciano Coelho
wl1251_debugfs_reset(struct wl1251 * wl)43790921014SLuciano Coelho void wl1251_debugfs_reset(struct wl1251 *wl)
43890921014SLuciano Coelho {
43990921014SLuciano Coelho if (wl->stats.fw_stats != NULL)
44090921014SLuciano Coelho memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats));
44190921014SLuciano Coelho wl->stats.retry_count = 0;
44290921014SLuciano Coelho wl->stats.excessive_retries = 0;
44390921014SLuciano Coelho }
44490921014SLuciano Coelho
wl1251_debugfs_init(struct wl1251 * wl)44590921014SLuciano Coelho int wl1251_debugfs_init(struct wl1251 *wl)
44690921014SLuciano Coelho {
44772efec9bSGreg Kroah-Hartman wl->stats.fw_stats = kzalloc(sizeof(*wl->stats.fw_stats), GFP_KERNEL);
44872efec9bSGreg Kroah-Hartman if (!wl->stats.fw_stats)
44972efec9bSGreg Kroah-Hartman return -ENOMEM;
45090921014SLuciano Coelho
45190921014SLuciano Coelho wl->debugfs.rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL);
45290921014SLuciano Coelho
45390921014SLuciano Coelho wl->debugfs.fw_statistics = debugfs_create_dir("fw-statistics",
45490921014SLuciano Coelho wl->debugfs.rootdir);
45590921014SLuciano Coelho
45690921014SLuciano Coelho wl->stats.fw_stats_update = jiffies;
45790921014SLuciano Coelho
45872efec9bSGreg Kroah-Hartman wl1251_debugfs_add_files(wl);
45990921014SLuciano Coelho
46090921014SLuciano Coelho return 0;
46190921014SLuciano Coelho }
46290921014SLuciano Coelho
wl1251_debugfs_exit(struct wl1251 * wl)46390921014SLuciano Coelho void wl1251_debugfs_exit(struct wl1251 *wl)
46490921014SLuciano Coelho {
46590921014SLuciano Coelho wl1251_debugfs_delete_files(wl);
46690921014SLuciano Coelho
46790921014SLuciano Coelho kfree(wl->stats.fw_stats);
46890921014SLuciano Coelho wl->stats.fw_stats = NULL;
46990921014SLuciano Coelho
47090921014SLuciano Coelho debugfs_remove(wl->debugfs.fw_statistics);
47190921014SLuciano Coelho wl->debugfs.fw_statistics = NULL;
47290921014SLuciano Coelho
47390921014SLuciano Coelho debugfs_remove(wl->debugfs.rootdir);
47490921014SLuciano Coelho wl->debugfs.rootdir = NULL;
47590921014SLuciano Coelho
47690921014SLuciano Coelho }
477