usb: gadget: f_hid: add dev to configfs
[cascardo/linux.git] / net / mac80211 / debugfs.c
1 /*
2  * mac80211 debugfs for wireless PHYs
3  *
4  * Copyright 2007       Johannes Berg <johannes@sipsolutions.net>
5  * Copyright 2013-2014  Intel Mobile Communications GmbH
6  *
7  * GPLv2
8  *
9  */
10
11 #include <linux/debugfs.h>
12 #include <linux/rtnetlink.h>
13 #include <linux/vmalloc.h>
14 #include "ieee80211_i.h"
15 #include "driver-ops.h"
16 #include "rate.h"
17 #include "debugfs.h"
18
19 #define DEBUGFS_FORMAT_BUFFER_SIZE 100
20
21 int mac80211_format_buffer(char __user *userbuf, size_t count,
22                                   loff_t *ppos, char *fmt, ...)
23 {
24         va_list args;
25         char buf[DEBUGFS_FORMAT_BUFFER_SIZE];
26         int res;
27
28         va_start(args, fmt);
29         res = vscnprintf(buf, sizeof(buf), fmt, args);
30         va_end(args);
31
32         return simple_read_from_buffer(userbuf, count, ppos, buf, res);
33 }
34
35 #define DEBUGFS_READONLY_FILE_FN(name, fmt, value...)                   \
36 static ssize_t name## _read(struct file *file, char __user *userbuf,    \
37                             size_t count, loff_t *ppos)                 \
38 {                                                                       \
39         struct ieee80211_local *local = file->private_data;             \
40                                                                         \
41         return mac80211_format_buffer(userbuf, count, ppos,             \
42                                       fmt "\n", ##value);               \
43 }
44
45 #define DEBUGFS_READONLY_FILE_OPS(name)                 \
46 static const struct file_operations name## _ops = {                     \
47         .read = name## _read,                                           \
48         .open = simple_open,                                            \
49         .llseek = generic_file_llseek,                                  \
50 };
51
52 #define DEBUGFS_READONLY_FILE(name, fmt, value...)              \
53         DEBUGFS_READONLY_FILE_FN(name, fmt, value)              \
54         DEBUGFS_READONLY_FILE_OPS(name)
55
56 #define DEBUGFS_ADD(name)                                               \
57         debugfs_create_file(#name, 0400, phyd, local, &name## _ops);
58
59 #define DEBUGFS_ADD_MODE(name, mode)                                    \
60         debugfs_create_file(#name, mode, phyd, local, &name## _ops);
61
62
63 DEBUGFS_READONLY_FILE(user_power, "%d",
64                       local->user_power_level);
65 DEBUGFS_READONLY_FILE(power, "%d",
66                       local->hw.conf.power_level);
67 DEBUGFS_READONLY_FILE(total_ps_buffered, "%d",
68                       local->total_ps_buffered);
69 DEBUGFS_READONLY_FILE(wep_iv, "%#08x",
70                       local->wep_iv & 0xffffff);
71 DEBUGFS_READONLY_FILE(rate_ctrl_alg, "%s",
72         local->rate_ctrl ? local->rate_ctrl->ops->name : "hw/driver");
73
74 struct aqm_info {
75         struct ieee80211_local *local;
76         size_t size;
77         size_t len;
78         unsigned char buf[0];
79 };
80
81 #define AQM_HDR_LEN 200
82 #define AQM_HW_ENTRY_LEN 40
83 #define AQM_TXQ_ENTRY_LEN 110
84
85 static int aqm_open(struct inode *inode, struct file *file)
86 {
87         struct ieee80211_local *local = inode->i_private;
88         struct ieee80211_sub_if_data *sdata;
89         struct sta_info *sta;
90         struct txq_info *txqi;
91         struct fq *fq = &local->fq;
92         struct aqm_info *info = NULL;
93         int len = 0;
94         int i;
95
96         if (!local->ops->wake_tx_queue)
97                 return -EOPNOTSUPP;
98
99         len += AQM_HDR_LEN;
100         len += 6 * AQM_HW_ENTRY_LEN;
101
102         rcu_read_lock();
103         list_for_each_entry_rcu(sdata, &local->interfaces, list)
104                 len += AQM_TXQ_ENTRY_LEN;
105         list_for_each_entry_rcu(sta, &local->sta_list, list)
106                 len += AQM_TXQ_ENTRY_LEN * ARRAY_SIZE(sta->sta.txq);
107         rcu_read_unlock();
108
109         info = vmalloc(len);
110         if (!info)
111                 return -ENOMEM;
112
113         spin_lock_bh(&local->fq.lock);
114         rcu_read_lock();
115
116         file->private_data = info;
117         info->local = local;
118         info->size = len;
119         len = 0;
120
121         len += scnprintf(info->buf + len, info->size - len,
122                          "* hw\n"
123                          "access name value\n"
124                          "R fq_flows_cnt %u\n"
125                          "R fq_backlog %u\n"
126                          "R fq_overlimit %u\n"
127                          "R fq_collisions %u\n"
128                          "RW fq_limit %u\n"
129                          "RW fq_quantum %u\n",
130                          fq->flows_cnt,
131                          fq->backlog,
132                          fq->overlimit,
133                          fq->collisions,
134                          fq->limit,
135                          fq->quantum);
136
137         len += scnprintf(info->buf + len,
138                          info->size - len,
139                          "* vif\n"
140                          "ifname addr ac backlog-bytes backlog-packets flows overlimit collisions tx-bytes tx-packets\n");
141
142         list_for_each_entry_rcu(sdata, &local->interfaces, list) {
143                 txqi = to_txq_info(sdata->vif.txq);
144                 len += scnprintf(info->buf + len, info->size - len,
145                                  "%s %pM %u %u %u %u %u %u %u %u\n",
146                                  sdata->name,
147                                  sdata->vif.addr,
148                                  txqi->txq.ac,
149                                  txqi->tin.backlog_bytes,
150                                  txqi->tin.backlog_packets,
151                                  txqi->tin.flows,
152                                  txqi->tin.overlimit,
153                                  txqi->tin.collisions,
154                                  txqi->tin.tx_bytes,
155                                  txqi->tin.tx_packets);
156         }
157
158         len += scnprintf(info->buf + len,
159                          info->size - len,
160                          "* sta\n"
161                          "ifname addr tid ac backlog-bytes backlog-packets flows overlimit collisions tx-bytes tx-packets\n");
162
163         list_for_each_entry_rcu(sta, &local->sta_list, list) {
164                 sdata = sta->sdata;
165                 for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
166                         txqi = to_txq_info(sta->sta.txq[i]);
167                         len += scnprintf(info->buf + len, info->size - len,
168                                          "%s %pM %d %d %u %u %u %u %u %u %u\n",
169                                          sdata->name,
170                                          sta->sta.addr,
171                                          txqi->txq.tid,
172                                          txqi->txq.ac,
173                                          txqi->tin.backlog_bytes,
174                                          txqi->tin.backlog_packets,
175                                          txqi->tin.flows,
176                                          txqi->tin.overlimit,
177                                          txqi->tin.collisions,
178                                          txqi->tin.tx_bytes,
179                                          txqi->tin.tx_packets);
180                 }
181         }
182
183         info->len = len;
184
185         rcu_read_unlock();
186         spin_unlock_bh(&local->fq.lock);
187
188         return 0;
189 }
190
191 static int aqm_release(struct inode *inode, struct file *file)
192 {
193         vfree(file->private_data);
194         return 0;
195 }
196
197 static ssize_t aqm_read(struct file *file,
198                         char __user *user_buf,
199                         size_t count,
200                         loff_t *ppos)
201 {
202         struct aqm_info *info = file->private_data;
203
204         return simple_read_from_buffer(user_buf, count, ppos,
205                                        info->buf, info->len);
206 }
207
208 static ssize_t aqm_write(struct file *file,
209                          const char __user *user_buf,
210                          size_t count,
211                          loff_t *ppos)
212 {
213         struct aqm_info *info = file->private_data;
214         struct ieee80211_local *local = info->local;
215         char buf[100];
216         size_t len;
217
218         if (count > sizeof(buf))
219                 return -EINVAL;
220
221         if (copy_from_user(buf, user_buf, count))
222                 return -EFAULT;
223
224         buf[sizeof(buf) - 1] = '\0';
225         len = strlen(buf);
226         if (len > 0 && buf[len-1] == '\n')
227                 buf[len-1] = 0;
228
229         if (sscanf(buf, "fq_limit %u", &local->fq.limit) == 1)
230                 return count;
231         else if (sscanf(buf, "fq_quantum %u", &local->fq.quantum) == 1)
232                 return count;
233
234         return -EINVAL;
235 }
236
237 static const struct file_operations aqm_ops = {
238         .write = aqm_write,
239         .read = aqm_read,
240         .open = aqm_open,
241         .release = aqm_release,
242         .llseek = default_llseek,
243 };
244
245 #ifdef CONFIG_PM
246 static ssize_t reset_write(struct file *file, const char __user *user_buf,
247                            size_t count, loff_t *ppos)
248 {
249         struct ieee80211_local *local = file->private_data;
250
251         rtnl_lock();
252         __ieee80211_suspend(&local->hw, NULL);
253         __ieee80211_resume(&local->hw);
254         rtnl_unlock();
255
256         return count;
257 }
258
259 static const struct file_operations reset_ops = {
260         .write = reset_write,
261         .open = simple_open,
262         .llseek = noop_llseek,
263 };
264 #endif
265
266 static const char *hw_flag_names[] = {
267 #define FLAG(F) [IEEE80211_HW_##F] = #F
268         FLAG(HAS_RATE_CONTROL),
269         FLAG(RX_INCLUDES_FCS),
270         FLAG(HOST_BROADCAST_PS_BUFFERING),
271         FLAG(SIGNAL_UNSPEC),
272         FLAG(SIGNAL_DBM),
273         FLAG(NEED_DTIM_BEFORE_ASSOC),
274         FLAG(SPECTRUM_MGMT),
275         FLAG(AMPDU_AGGREGATION),
276         FLAG(SUPPORTS_PS),
277         FLAG(PS_NULLFUNC_STACK),
278         FLAG(SUPPORTS_DYNAMIC_PS),
279         FLAG(MFP_CAPABLE),
280         FLAG(WANT_MONITOR_VIF),
281         FLAG(NO_AUTO_VIF),
282         FLAG(SW_CRYPTO_CONTROL),
283         FLAG(SUPPORT_FAST_XMIT),
284         FLAG(REPORTS_TX_ACK_STATUS),
285         FLAG(CONNECTION_MONITOR),
286         FLAG(QUEUE_CONTROL),
287         FLAG(SUPPORTS_PER_STA_GTK),
288         FLAG(AP_LINK_PS),
289         FLAG(TX_AMPDU_SETUP_IN_HW),
290         FLAG(SUPPORTS_RC_TABLE),
291         FLAG(P2P_DEV_ADDR_FOR_INTF),
292         FLAG(TIMING_BEACON_ONLY),
293         FLAG(SUPPORTS_HT_CCK_RATES),
294         FLAG(CHANCTX_STA_CSA),
295         FLAG(SUPPORTS_CLONED_SKBS),
296         FLAG(SINGLE_SCAN_ON_ALL_BANDS),
297         FLAG(TDLS_WIDER_BW),
298         FLAG(SUPPORTS_AMSDU_IN_AMPDU),
299         FLAG(BEACON_TX_STATUS),
300         FLAG(NEEDS_UNIQUE_STA_ADDR),
301         FLAG(SUPPORTS_REORDERING_BUFFER),
302         FLAG(USES_RSS),
303         FLAG(TX_AMSDU),
304         FLAG(TX_FRAG_LIST),
305 #undef FLAG
306 };
307
308 static ssize_t hwflags_read(struct file *file, char __user *user_buf,
309                             size_t count, loff_t *ppos)
310 {
311         struct ieee80211_local *local = file->private_data;
312         size_t bufsz = 30 * NUM_IEEE80211_HW_FLAGS;
313         char *buf = kzalloc(bufsz, GFP_KERNEL);
314         char *pos = buf, *end = buf + bufsz - 1;
315         ssize_t rv;
316         int i;
317
318         if (!buf)
319                 return -ENOMEM;
320
321         /* fail compilation if somebody adds or removes
322          * a flag without updating the name array above
323          */
324         BUILD_BUG_ON(ARRAY_SIZE(hw_flag_names) != NUM_IEEE80211_HW_FLAGS);
325
326         for (i = 0; i < NUM_IEEE80211_HW_FLAGS; i++) {
327                 if (test_bit(i, local->hw.flags))
328                         pos += scnprintf(pos, end - pos, "%s\n",
329                                          hw_flag_names[i]);
330         }
331
332         rv = simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
333         kfree(buf);
334         return rv;
335 }
336
337 static ssize_t queues_read(struct file *file, char __user *user_buf,
338                            size_t count, loff_t *ppos)
339 {
340         struct ieee80211_local *local = file->private_data;
341         unsigned long flags;
342         char buf[IEEE80211_MAX_QUEUES * 20];
343         int q, res = 0;
344
345         spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
346         for (q = 0; q < local->hw.queues; q++)
347                 res += sprintf(buf + res, "%02d: %#.8lx/%d\n", q,
348                                 local->queue_stop_reasons[q],
349                                 skb_queue_len(&local->pending[q]));
350         spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
351
352         return simple_read_from_buffer(user_buf, count, ppos, buf, res);
353 }
354
355 DEBUGFS_READONLY_FILE_OPS(hwflags);
356 DEBUGFS_READONLY_FILE_OPS(queues);
357
358 /* statistics stuff */
359
360 static ssize_t format_devstat_counter(struct ieee80211_local *local,
361         char __user *userbuf,
362         size_t count, loff_t *ppos,
363         int (*printvalue)(struct ieee80211_low_level_stats *stats, char *buf,
364                           int buflen))
365 {
366         struct ieee80211_low_level_stats stats;
367         char buf[20];
368         int res;
369
370         rtnl_lock();
371         res = drv_get_stats(local, &stats);
372         rtnl_unlock();
373         if (res)
374                 return res;
375         res = printvalue(&stats, buf, sizeof(buf));
376         return simple_read_from_buffer(userbuf, count, ppos, buf, res);
377 }
378
379 #define DEBUGFS_DEVSTATS_FILE(name)                                     \
380 static int print_devstats_##name(struct ieee80211_low_level_stats *stats,\
381                                  char *buf, int buflen)                 \
382 {                                                                       \
383         return scnprintf(buf, buflen, "%u\n", stats->name);             \
384 }                                                                       \
385 static ssize_t stats_ ##name## _read(struct file *file,                 \
386                                      char __user *userbuf,              \
387                                      size_t count, loff_t *ppos)        \
388 {                                                                       \
389         return format_devstat_counter(file->private_data,               \
390                                       userbuf,                          \
391                                       count,                            \
392                                       ppos,                             \
393                                       print_devstats_##name);           \
394 }                                                                       \
395                                                                         \
396 static const struct file_operations stats_ ##name## _ops = {            \
397         .read = stats_ ##name## _read,                                  \
398         .open = simple_open,                                            \
399         .llseek = generic_file_llseek,                                  \
400 };
401
402 #define DEBUGFS_STATS_ADD(name)                                 \
403         debugfs_create_u32(#name, 0400, statsd, &local->name);
404 #define DEBUGFS_DEVSTATS_ADD(name)                                      \
405         debugfs_create_file(#name, 0400, statsd, local, &stats_ ##name## _ops);
406
407 DEBUGFS_DEVSTATS_FILE(dot11ACKFailureCount);
408 DEBUGFS_DEVSTATS_FILE(dot11RTSFailureCount);
409 DEBUGFS_DEVSTATS_FILE(dot11FCSErrorCount);
410 DEBUGFS_DEVSTATS_FILE(dot11RTSSuccessCount);
411
412 void debugfs_hw_add(struct ieee80211_local *local)
413 {
414         struct dentry *phyd = local->hw.wiphy->debugfsdir;
415         struct dentry *statsd;
416
417         if (!phyd)
418                 return;
419
420         local->debugfs.keys = debugfs_create_dir("keys", phyd);
421
422         DEBUGFS_ADD(total_ps_buffered);
423         DEBUGFS_ADD(wep_iv);
424         DEBUGFS_ADD(queues);
425 #ifdef CONFIG_PM
426         DEBUGFS_ADD_MODE(reset, 0200);
427 #endif
428         DEBUGFS_ADD(hwflags);
429         DEBUGFS_ADD(user_power);
430         DEBUGFS_ADD(power);
431         DEBUGFS_ADD_MODE(aqm, 0600);
432
433         statsd = debugfs_create_dir("statistics", phyd);
434
435         /* if the dir failed, don't put all the other things into the root! */
436         if (!statsd)
437                 return;
438
439 #ifdef CONFIG_MAC80211_DEBUG_COUNTERS
440         DEBUGFS_STATS_ADD(dot11TransmittedFragmentCount);
441         DEBUGFS_STATS_ADD(dot11MulticastTransmittedFrameCount);
442         DEBUGFS_STATS_ADD(dot11FailedCount);
443         DEBUGFS_STATS_ADD(dot11RetryCount);
444         DEBUGFS_STATS_ADD(dot11MultipleRetryCount);
445         DEBUGFS_STATS_ADD(dot11FrameDuplicateCount);
446         DEBUGFS_STATS_ADD(dot11ReceivedFragmentCount);
447         DEBUGFS_STATS_ADD(dot11MulticastReceivedFrameCount);
448         DEBUGFS_STATS_ADD(dot11TransmittedFrameCount);
449         DEBUGFS_STATS_ADD(tx_handlers_drop);
450         DEBUGFS_STATS_ADD(tx_handlers_queued);
451         DEBUGFS_STATS_ADD(tx_handlers_drop_wep);
452         DEBUGFS_STATS_ADD(tx_handlers_drop_not_assoc);
453         DEBUGFS_STATS_ADD(tx_handlers_drop_unauth_port);
454         DEBUGFS_STATS_ADD(rx_handlers_drop);
455         DEBUGFS_STATS_ADD(rx_handlers_queued);
456         DEBUGFS_STATS_ADD(rx_handlers_drop_nullfunc);
457         DEBUGFS_STATS_ADD(rx_handlers_drop_defrag);
458         DEBUGFS_STATS_ADD(tx_expand_skb_head);
459         DEBUGFS_STATS_ADD(tx_expand_skb_head_cloned);
460         DEBUGFS_STATS_ADD(rx_expand_skb_head_defrag);
461         DEBUGFS_STATS_ADD(rx_handlers_fragments);
462         DEBUGFS_STATS_ADD(tx_status_drop);
463 #endif
464         DEBUGFS_DEVSTATS_ADD(dot11ACKFailureCount);
465         DEBUGFS_DEVSTATS_ADD(dot11RTSFailureCount);
466         DEBUGFS_DEVSTATS_ADD(dot11FCSErrorCount);
467         DEBUGFS_DEVSTATS_ADD(dot11RTSSuccessCount);
468 }