1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* |
3 | * This file is part of wl1271 |
4 | * |
5 | * Copyright (C) 2009 Nokia Corporation |
6 | * |
7 | * Contact: Luciano Coelho <luciano.coelho@nokia.com> |
8 | */ |
9 | |
10 | #ifndef __DEBUGFS_H__ |
11 | #define __DEBUGFS_H__ |
12 | |
13 | #include "wlcore.h" |
14 | |
15 | __printf(4, 5) int wl1271_format_buffer(char __user *userbuf, size_t count, |
16 | loff_t *ppos, char *fmt, ...); |
17 | |
18 | int wl1271_debugfs_init(struct wl1271 *wl); |
19 | void wl1271_debugfs_exit(struct wl1271 *wl); |
20 | void wl1271_debugfs_reset(struct wl1271 *wl); |
21 | void wl1271_debugfs_update_stats(struct wl1271 *wl); |
22 | |
23 | #define DEBUGFS_FORMAT_BUFFER_SIZE 256 |
24 | |
25 | #define DEBUGFS_READONLY_FILE(name, fmt, value...) \ |
26 | static ssize_t name## _read(struct file *file, char __user *userbuf, \ |
27 | size_t count, loff_t *ppos) \ |
28 | { \ |
29 | struct wl1271 *wl = file->private_data; \ |
30 | return wl1271_format_buffer(userbuf, count, ppos, \ |
31 | fmt "\n", ##value); \ |
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 | do { \ |
42 | debugfs_create_file(#name, 0400, parent, \ |
43 | wl, &name## _ops); \ |
44 | } while (0) |
45 | |
46 | |
47 | #define DEBUGFS_ADD_PREFIX(prefix, name, parent) \ |
48 | do { \ |
49 | debugfs_create_file(#name, 0400, parent, \ |
50 | wl, &prefix## _## name## _ops); \ |
51 | } while (0) |
52 | |
53 | #define DEBUGFS_FWSTATS_FILE(sub, name, fmt, struct_type) \ |
54 | static ssize_t sub## _ ##name## _read(struct file *file, \ |
55 | char __user *userbuf, \ |
56 | size_t count, loff_t *ppos) \ |
57 | { \ |
58 | struct wl1271 *wl = file->private_data; \ |
59 | struct struct_type *stats = wl->stats.fw_stats; \ |
60 | \ |
61 | wl1271_debugfs_update_stats(wl); \ |
62 | \ |
63 | return wl1271_format_buffer(userbuf, count, ppos, fmt "\n", \ |
64 | stats->sub.name); \ |
65 | } \ |
66 | \ |
67 | static const struct file_operations sub## _ ##name## _ops = { \ |
68 | .read = sub## _ ##name## _read, \ |
69 | .open = simple_open, \ |
70 | .llseek = generic_file_llseek, \ |
71 | }; |
72 | |
73 | #define DEBUGFS_FWSTATS_FILE_ARRAY(sub, name, len, struct_type) \ |
74 | static ssize_t sub## _ ##name## _read(struct file *file, \ |
75 | char __user *userbuf, \ |
76 | size_t count, loff_t *ppos) \ |
77 | { \ |
78 | struct wl1271 *wl = file->private_data; \ |
79 | struct struct_type *stats = wl->stats.fw_stats; \ |
80 | char buf[DEBUGFS_FORMAT_BUFFER_SIZE] = ""; \ |
81 | int pos = 0; \ |
82 | int i; \ |
83 | \ |
84 | wl1271_debugfs_update_stats(wl); \ |
85 | \ |
86 | for (i = 0; i < len && pos < sizeof(buf); i++) \ |
87 | pos += snprintf(buf + pos, sizeof(buf) - pos, \ |
88 | "[%d] = %d\n", i, stats->sub.name[i]); \ |
89 | \ |
90 | return wl1271_format_buffer(userbuf, count, ppos, "%s", buf); \ |
91 | } \ |
92 | \ |
93 | static const struct file_operations sub## _ ##name## _ops = { \ |
94 | .read = sub## _ ##name## _read, \ |
95 | .open = simple_open, \ |
96 | .llseek = generic_file_llseek, \ |
97 | }; |
98 | |
99 | #define DEBUGFS_FWSTATS_ADD(sub, name) \ |
100 | DEBUGFS_ADD(sub## _ ##name, stats) |
101 | |
102 | |
103 | #endif /* WL1271_DEBUGFS_H */ |
104 | |