2 * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz>
3 * Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
10 #include <linux/kernel.h>
11 #include <linux/device.h>
13 #include <linux/interrupt.h>
14 #include <linux/netdevice.h>
15 #include <linux/rtnetlink.h>
16 #include <linux/notifier.h>
17 #include <net/mac80211.h>
18 #include <net/cfg80211.h>
19 #include "ieee80211_i.h"
20 #include "ieee80211_rate.h"
22 #include "debugfs_netdev.h"
24 static ssize_t
ieee80211_if_read(
25 struct ieee80211_sub_if_data
*sdata
,
27 size_t count
, loff_t
*ppos
,
28 ssize_t (*format
)(const struct ieee80211_sub_if_data
*, char *, int))
31 ssize_t ret
= -EINVAL
;
33 read_lock(&dev_base_lock
);
34 if (sdata
->dev
->reg_state
== NETREG_REGISTERED
) {
35 ret
= (*format
)(sdata
, buf
, sizeof(buf
));
36 ret
= simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
38 read_unlock(&dev_base_lock
);
42 #define IEEE80211_IF_FMT(name, field, format_string) \
43 static ssize_t ieee80211_if_fmt_##name( \
44 const struct ieee80211_sub_if_data *sdata, char *buf, \
47 return scnprintf(buf, buflen, format_string, sdata->field); \
49 #define IEEE80211_IF_FMT_DEC(name, field) \
50 IEEE80211_IF_FMT(name, field, "%d\n")
51 #define IEEE80211_IF_FMT_HEX(name, field) \
52 IEEE80211_IF_FMT(name, field, "%#x\n")
53 #define IEEE80211_IF_FMT_SIZE(name, field) \
54 IEEE80211_IF_FMT(name, field, "%zd\n")
56 #define IEEE80211_IF_FMT_ATOMIC(name, field) \
57 static ssize_t ieee80211_if_fmt_##name( \
58 const struct ieee80211_sub_if_data *sdata, \
59 char *buf, int buflen) \
61 return scnprintf(buf, buflen, "%d\n", atomic_read(&sdata->field));\
64 #define IEEE80211_IF_FMT_MAC(name, field) \
65 static ssize_t ieee80211_if_fmt_##name( \
66 const struct ieee80211_sub_if_data *sdata, char *buf, \
69 return scnprintf(buf, buflen, MAC_FMT "\n", MAC_ARG(sdata->field));\
72 #define __IEEE80211_IF_FILE(name) \
73 static ssize_t ieee80211_if_read_##name(struct file *file, \
74 char __user *userbuf, \
75 size_t count, loff_t *ppos) \
77 return ieee80211_if_read(file->private_data, \
78 userbuf, count, ppos, \
79 ieee80211_if_fmt_##name); \
81 static const struct file_operations name##_ops = { \
82 .read = ieee80211_if_read_##name, \
83 .open = mac80211_open_file_generic, \
86 #define IEEE80211_IF_FILE(name, field, format) \
87 IEEE80211_IF_FMT_##format(name, field) \
88 __IEEE80211_IF_FILE(name)
90 #define DEBUGFS_QOS_FILE(name, f) \
91 static ssize_t qos_ ##name## _write(struct file *file, \
92 const char __user *userbuf, \
93 size_t count, loff_t *ppos) \
95 struct ieee80211_sub_if_data *sdata = file->private_data; \
97 f(sdata->dev, &sdata->u.sta, &sdata->u.sta.tspec); \
102 static const struct file_operations qos_ ##name## _ops = { \
103 .write = qos_ ##name## _write, \
104 .open = mac80211_open_file_generic, \
107 #define DEBUGFS_QOS_ADD(name) \
108 sdata->debugfs.sta.qos.name = debugfs_create_file(#name, 0444, qosd,\
109 sdata, &qos_ ##name## _ops);
111 #define DEBUGFS_QOS_DEL(name) \
113 debugfs_remove(sdata->debugfs.sta.qos.name); \
114 sdata->debugfs.sta.qos.name = NULL; \
117 DEBUGFS_QOS_FILE(addts_11e
, ieee80211_send_addts
);
118 DEBUGFS_QOS_FILE(addts_wmm
, wmm_send_addts
);
119 DEBUGFS_QOS_FILE(delts_11e
, ieee80211_send_delts
);
120 DEBUGFS_QOS_FILE(delts_wmm
, wmm_send_delts
);
122 static ssize_t
qos_if_dls_mac(const struct ieee80211_sub_if_data
*sdata
,
123 char *buf
, int buflen
)
125 return scnprintf(buf
, buflen
, MAC_FMT
"\n",
126 MAC_ARG(sdata
->u
.sta
.dls_mac
));
129 static ssize_t
qos_dls_mac_read(struct file
*file
,
130 char __user
*userbuf
,
131 size_t count
, loff_t
*ppos
)
133 return ieee80211_if_read(file
->private_data
,
134 userbuf
, count
, ppos
,
138 static ssize_t
qos_dls_mac_write(struct file
*file
, const char __user
*userbuf
,
139 size_t count
, loff_t
*ppos
)
141 struct ieee80211_sub_if_data
*sdata
= file
->private_data
;
146 size
= min(sizeof(buf
) - 1, count
);
148 if (copy_from_user(buf
, userbuf
, size
))
151 if (sscanf(buf
, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
152 &((u8
*)(m
))[0], &((u8
*)(m
))[1], &((u8
*)(m
))[2],
153 &((u8
*)(m
))[3], &((u8
*)(m
))[4], &((u8
*)(m
))[5]) != ETH_ALEN
){
154 printk(KERN_ERR
"%s: sscanf input error\n", sdata
->dev
->name
);
157 memcpy(sdata
->u
.sta
.dls_mac
, m
, ETH_ALEN
);
161 static const struct file_operations qos_dls_mac_ops
= {
162 .read
= qos_dls_mac_read
,
163 .write
= qos_dls_mac_write
,
164 .open
= mac80211_open_file_generic
,
167 static ssize_t
qos_if_dls_op(const struct ieee80211_sub_if_data
*sdata
,
168 char *buf
, int buflen
)
170 return scnprintf(buf
, buflen
,
171 "DLS Operation: Setup = 1; Teardown = 2\n");
174 static ssize_t
qos_dls_op_read(struct file
*file
, char __user
*userbuf
,
175 size_t count
, loff_t
*ppos
)
177 return ieee80211_if_read(file
->private_data
,
178 userbuf
, count
, ppos
,
182 static ssize_t
qos_dls_op_write(struct file
*file
, const char __user
*userbuf
,
183 size_t count
, loff_t
*ppos
)
185 struct ieee80211_sub_if_data
*sdata
= file
->private_data
;
190 size
= min(sizeof(buf
) - 1, count
);
192 if (copy_from_user(buf
, userbuf
, size
))
195 if (sscanf(buf
, "%u", &opt
) != 1) {
196 printk(KERN_ERR
"%s: sscanf input error\n", sdata
->dev
->name
);
201 ieee80211_send_dls_req(sdata
->dev
, &sdata
->u
.sta
,
202 sdata
->u
.sta
.dls_mac
, 0);
205 ieee80211_send_dls_teardown(sdata
->dev
, &sdata
->u
.sta
,
206 sdata
->u
.sta
.dls_mac
,
207 WLAN_REASON_QSTA_NOT_USE
);
210 printk(KERN_ERR
"Unknown DLS Operation: %d\n", opt
);
216 static const struct file_operations qos_dls_op_ops
= {
217 .read
= qos_dls_op_read
,
218 .write
= qos_dls_op_write
,
219 .open
= mac80211_open_file_generic
,
222 #define DEBUGFS_TSINFO_FILE(_name, min_val, max_val) \
223 static ssize_t tsinfo_ ##_name## _read(struct file *file, \
224 char __user *userbuf, \
225 size_t count, loff_t *ppos) \
228 struct ieee80211_sub_if_data *sdata = file->private_data; \
229 int res = scnprintf(buf, count, "%u\n", \
230 IEEE80211_TSINFO_## _name (sdata->u.sta.tspec.ts_info));\
231 return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
234 static ssize_t tsinfo_ ##_name## _write(struct file *file, \
235 const char __user *userbuf, \
236 size_t count, loff_t *ppos) \
241 struct ieee80211_sub_if_data *sdata = file->private_data; \
243 size = min(sizeof(buf) - 1, count); \
245 if (copy_from_user(buf, userbuf, size)) \
248 val = simple_strtoul(buf, NULL, 0); \
249 if ((val < min_val) || (val > max_val)) { \
250 printk(KERN_ERR "%s: set value (%u) out of range " \
251 "[%u, %u]\n",sdata->dev->name,val,min_val,max_val);\
254 IEEE80211_SET_TSINFO_ ##_name (sdata->u.sta.tspec.ts_info, val);\
258 static const struct file_operations tsinfo_ ##_name## _ops = { \
259 .read = tsinfo_ ##_name## _read, \
260 .write = tsinfo_ ##_name## _write, \
261 .open = mac80211_open_file_generic, \
264 #define DEBUGFS_TSINFO_ADD_TSID \
265 sdata->debugfs.sta.tsinfo.tsid = \
266 debugfs_create_file("tsid", 0444, tsinfod, \
267 sdata, &tsinfo_TSID_ops);
269 #define DEBUGFS_TSINFO_ADD_DIR \
270 sdata->debugfs.sta.tsinfo.direction = \
271 debugfs_create_file("direction", 0444, tsinfod, \
272 sdata, &tsinfo_DIR_ops);
274 #define DEBUGFS_TSINFO_ADD_UP \
275 sdata->debugfs.sta.tsinfo.up = \
276 debugfs_create_file("up", 0444, tsinfod, \
277 sdata, &tsinfo_UP_ops);
279 #define DEBUGFS_TSINFO_DEL(name) \
281 debugfs_remove(sdata->debugfs.sta.tsinfo.name); \
282 sdata->debugfs.sta.tsinfo.name = NULL; \
285 DEBUGFS_TSINFO_FILE(TSID
, 8, 15);
286 DEBUGFS_TSINFO_FILE(DIR, 0, 3);
287 DEBUGFS_TSINFO_FILE(UP
, 0, 7);
289 #define DEBUGFS_TSPEC_FILE(name, format_string, endian_f1, endian_f2) \
290 static ssize_t tspec_ ##name## _read(struct file *file, \
291 char __user *userbuf, \
292 size_t count, loff_t *ppos) \
295 struct ieee80211_sub_if_data *sdata = file->private_data; \
296 int res = scnprintf(buf, count, format_string "\n", \
297 endian_f1(sdata->u.sta.tspec.name)); \
298 return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
301 static ssize_t tspec_ ##name## _write(struct file *file, \
302 const char __user *userbuf, \
303 size_t count, loff_t *ppos) \
307 struct ieee80211_sub_if_data *sdata = file->private_data; \
309 size = min(sizeof(buf) - 1, count); \
311 if (copy_from_user(buf, userbuf, size)) \
314 sdata->u.sta.tspec.name = endian_f2(simple_strtoul(buf, NULL, 0));\
318 static const struct file_operations tspec_ ##name## _ops = { \
319 .read = tspec_ ##name## _read, \
320 .write = tspec_ ##name## _write, \
321 .open = mac80211_open_file_generic, \
324 #define DEBUGFS_TSPEC_ADD(name) \
325 sdata->debugfs.sta.tspec.name = debugfs_create_file(#name, \
326 0444, tspecd, sdata, &tspec_ ##name## _ops);
328 #define DEBUGFS_TSPEC_DEL(name) \
330 debugfs_remove(sdata->debugfs.sta.tspec.name); \
331 sdata->debugfs.sta.tspec.name = NULL; \
334 DEBUGFS_TSPEC_FILE(nominal_msdu_size
, "%hu", le16_to_cpu
, cpu_to_le16
);
335 DEBUGFS_TSPEC_FILE(max_msdu_size
, "%hu", le16_to_cpu
, cpu_to_le16
);
336 DEBUGFS_TSPEC_FILE(min_service_interval
, "%u", le32_to_cpu
, cpu_to_le32
);
337 DEBUGFS_TSPEC_FILE(max_service_interval
, "%u", le32_to_cpu
, cpu_to_le32
);
338 DEBUGFS_TSPEC_FILE(inactivity_interval
, "%u", le32_to_cpu
, cpu_to_le32
);
339 DEBUGFS_TSPEC_FILE(suspension_interval
, "%u", le32_to_cpu
, cpu_to_le32
);
340 DEBUGFS_TSPEC_FILE(service_start_time
, "%u", le32_to_cpu
, cpu_to_le32
);
341 DEBUGFS_TSPEC_FILE(min_data_rate
, "%u", le32_to_cpu
, cpu_to_le32
);
342 DEBUGFS_TSPEC_FILE(mean_data_rate
, "%u", le32_to_cpu
, cpu_to_le32
);
343 DEBUGFS_TSPEC_FILE(peak_data_rate
, "%u", le32_to_cpu
, cpu_to_le32
);
344 DEBUGFS_TSPEC_FILE(burst_size
, "%u", le32_to_cpu
, cpu_to_le32
);
345 DEBUGFS_TSPEC_FILE(delay_bound
, "%u", le32_to_cpu
, cpu_to_le32
);
346 DEBUGFS_TSPEC_FILE(min_phy_rate
, "%u", le32_to_cpu
, cpu_to_le32
);
347 DEBUGFS_TSPEC_FILE(surplus_band_allow
, "%hu", le16_to_cpu
, cpu_to_le16
);
348 DEBUGFS_TSPEC_FILE(medium_time
, "%hu", le16_to_cpu
, cpu_to_le16
);
351 /* common attributes */
352 IEEE80211_IF_FILE(channel_use
, channel_use
, DEC
);
353 IEEE80211_IF_FILE(drop_unencrypted
, drop_unencrypted
, DEC
);
354 IEEE80211_IF_FILE(eapol
, eapol
, DEC
);
355 IEEE80211_IF_FILE(ieee8021_x
, ieee802_1x
, DEC
);
357 /* STA/IBSS attributes */
358 IEEE80211_IF_FILE(state
, u
.sta
.state
, DEC
);
359 IEEE80211_IF_FILE(bssid
, u
.sta
.bssid
, MAC
);
360 IEEE80211_IF_FILE(prev_bssid
, u
.sta
.prev_bssid
, MAC
);
361 IEEE80211_IF_FILE(ssid_len
, u
.sta
.ssid_len
, SIZE
);
362 IEEE80211_IF_FILE(aid
, u
.sta
.aid
, DEC
);
363 IEEE80211_IF_FILE(ap_capab
, u
.sta
.ap_capab
, HEX
);
364 IEEE80211_IF_FILE(capab
, u
.sta
.capab
, HEX
);
365 IEEE80211_IF_FILE(extra_ie_len
, u
.sta
.extra_ie_len
, SIZE
);
366 IEEE80211_IF_FILE(auth_tries
, u
.sta
.auth_tries
, DEC
);
367 IEEE80211_IF_FILE(assoc_tries
, u
.sta
.assoc_tries
, DEC
);
368 IEEE80211_IF_FILE(auth_algs
, u
.sta
.auth_algs
, HEX
);
369 IEEE80211_IF_FILE(auth_alg
, u
.sta
.auth_alg
, DEC
);
370 IEEE80211_IF_FILE(auth_transaction
, u
.sta
.auth_transaction
, DEC
);
372 static ssize_t
ieee80211_if_fmt_flags(
373 const struct ieee80211_sub_if_data
*sdata
, char *buf
, int buflen
)
375 return scnprintf(buf
, buflen
, "%s%s%s%s%s%s%s\n",
376 sdata
->u
.sta
.ssid_set
? "SSID\n" : "",
377 sdata
->u
.sta
.bssid_set
? "BSSID\n" : "",
378 sdata
->u
.sta
.prev_bssid_set
? "prev BSSID\n" : "",
379 sdata
->u
.sta
.authenticated
? "AUTH\n" : "",
380 sdata
->u
.sta
.associated
? "ASSOC\n" : "",
381 sdata
->u
.sta
.probereq_poll
? "PROBEREQ POLL\n" : "",
382 sdata
->u
.sta
.use_protection
? "CTS prot\n" : "");
384 __IEEE80211_IF_FILE(flags
);
387 IEEE80211_IF_FILE(num_sta_ps
, u
.ap
.num_sta_ps
, ATOMIC
);
388 IEEE80211_IF_FILE(dtim_period
, u
.ap
.dtim_period
, DEC
);
389 IEEE80211_IF_FILE(dtim_count
, u
.ap
.dtim_count
, DEC
);
390 IEEE80211_IF_FILE(num_beacons
, u
.ap
.num_beacons
, DEC
);
391 IEEE80211_IF_FILE(force_unicast_rateidx
, u
.ap
.force_unicast_rateidx
, DEC
);
392 IEEE80211_IF_FILE(max_ratectrl_rateidx
, u
.ap
.max_ratectrl_rateidx
, DEC
);
394 static ssize_t
ieee80211_if_fmt_num_buffered_multicast(
395 const struct ieee80211_sub_if_data
*sdata
, char *buf
, int buflen
)
397 return scnprintf(buf
, buflen
, "%u\n",
398 skb_queue_len(&sdata
->u
.ap
.ps_bc_buf
));
400 __IEEE80211_IF_FILE(num_buffered_multicast
);
402 static ssize_t
ieee80211_if_fmt_beacon_head_len(
403 const struct ieee80211_sub_if_data
*sdata
, char *buf
, int buflen
)
405 if (sdata
->u
.ap
.beacon_head
)
406 return scnprintf(buf
, buflen
, "%d\n",
407 sdata
->u
.ap
.beacon_head_len
);
408 return scnprintf(buf
, buflen
, "\n");
410 __IEEE80211_IF_FILE(beacon_head_len
);
412 static ssize_t
ieee80211_if_fmt_beacon_tail_len(
413 const struct ieee80211_sub_if_data
*sdata
, char *buf
, int buflen
)
415 if (sdata
->u
.ap
.beacon_tail
)
416 return scnprintf(buf
, buflen
, "%d\n",
417 sdata
->u
.ap
.beacon_tail_len
);
418 return scnprintf(buf
, buflen
, "\n");
420 __IEEE80211_IF_FILE(beacon_tail_len
);
423 IEEE80211_IF_FILE(peer
, u
.wds
.remote_addr
, MAC
);
425 /* VLAN attributes */
426 IEEE80211_IF_FILE(vlan_id
, u
.vlan
.id
, DEC
);
428 /* MONITOR attributes */
429 static ssize_t
ieee80211_if_fmt_mode(
430 const struct ieee80211_sub_if_data
*sdata
, char *buf
, int buflen
)
432 struct ieee80211_local
*local
= sdata
->local
;
434 return scnprintf(buf
, buflen
, "%s\n",
435 ((local
->hw
.flags
& IEEE80211_HW_MONITOR_DURING_OPER
) ||
436 local
->open_count
== local
->monitors
) ?
439 __IEEE80211_IF_FILE(mode
);
442 #define DEBUGFS_ADD(name, type)\
443 sdata->debugfs.type.name = debugfs_create_file(#name, 0444,\
444 sdata->debugfsdir, sdata, &name##_ops);
446 static void add_sta_files(struct ieee80211_sub_if_data
*sdata
)
449 struct dentry
*tsinfod
;
450 struct dentry
*tspecd
;
452 DEBUGFS_ADD(channel_use
, sta
);
453 DEBUGFS_ADD(drop_unencrypted
, sta
);
454 DEBUGFS_ADD(eapol
, sta
);
455 DEBUGFS_ADD(ieee8021_x
, sta
);
456 DEBUGFS_ADD(state
, sta
);
457 DEBUGFS_ADD(bssid
, sta
);
458 DEBUGFS_ADD(prev_bssid
, sta
);
459 DEBUGFS_ADD(ssid_len
, sta
);
460 DEBUGFS_ADD(aid
, sta
);
461 DEBUGFS_ADD(ap_capab
, sta
);
462 DEBUGFS_ADD(capab
, sta
);
463 DEBUGFS_ADD(extra_ie_len
, sta
);
464 DEBUGFS_ADD(auth_tries
, sta
);
465 DEBUGFS_ADD(assoc_tries
, sta
);
466 DEBUGFS_ADD(auth_algs
, sta
);
467 DEBUGFS_ADD(auth_alg
, sta
);
468 DEBUGFS_ADD(auth_transaction
, sta
);
469 DEBUGFS_ADD(flags
, sta
);
471 qosd
= debugfs_create_dir("qos", sdata
->debugfsdir
);
472 sdata
->debugfs
.sta
.qos_dir
= qosd
;
474 DEBUGFS_QOS_ADD(addts_11e
);
475 DEBUGFS_QOS_ADD(addts_wmm
);
476 DEBUGFS_QOS_ADD(delts_11e
);
477 DEBUGFS_QOS_ADD(delts_wmm
);
478 DEBUGFS_QOS_ADD(dls_mac
);
479 DEBUGFS_QOS_ADD(dls_op
);
481 tsinfod
= debugfs_create_dir("ts_info", qosd
);
482 sdata
->debugfs
.sta
.tsinfo_dir
= tsinfod
;
484 DEBUGFS_TSINFO_ADD_TSID
;
485 DEBUGFS_TSINFO_ADD_DIR
;
486 DEBUGFS_TSINFO_ADD_UP
;
488 tspecd
= debugfs_create_dir("tspec", qosd
);
489 sdata
->debugfs
.sta
.tspec_dir
= tspecd
;
491 DEBUGFS_TSPEC_ADD(nominal_msdu_size
);
492 DEBUGFS_TSPEC_ADD(max_msdu_size
);
493 DEBUGFS_TSPEC_ADD(min_service_interval
);
494 DEBUGFS_TSPEC_ADD(max_service_interval
);
495 DEBUGFS_TSPEC_ADD(inactivity_interval
);
496 DEBUGFS_TSPEC_ADD(suspension_interval
);
497 DEBUGFS_TSPEC_ADD(service_start_time
);
498 DEBUGFS_TSPEC_ADD(min_data_rate
);
499 DEBUGFS_TSPEC_ADD(mean_data_rate
);
500 DEBUGFS_TSPEC_ADD(peak_data_rate
);
501 DEBUGFS_TSPEC_ADD(burst_size
);
502 DEBUGFS_TSPEC_ADD(delay_bound
);
503 DEBUGFS_TSPEC_ADD(min_phy_rate
);
504 DEBUGFS_TSPEC_ADD(surplus_band_allow
);
505 DEBUGFS_TSPEC_ADD(medium_time
);
508 static void add_ap_files(struct ieee80211_sub_if_data
*sdata
)
510 DEBUGFS_ADD(channel_use
, ap
);
511 DEBUGFS_ADD(drop_unencrypted
, ap
);
512 DEBUGFS_ADD(eapol
, ap
);
513 DEBUGFS_ADD(ieee8021_x
, ap
);
514 DEBUGFS_ADD(num_sta_ps
, ap
);
515 DEBUGFS_ADD(dtim_period
, ap
);
516 DEBUGFS_ADD(dtim_count
, ap
);
517 DEBUGFS_ADD(num_beacons
, ap
);
518 DEBUGFS_ADD(force_unicast_rateidx
, ap
);
519 DEBUGFS_ADD(max_ratectrl_rateidx
, ap
);
520 DEBUGFS_ADD(num_buffered_multicast
, ap
);
521 DEBUGFS_ADD(beacon_head_len
, ap
);
522 DEBUGFS_ADD(beacon_tail_len
, ap
);
525 static void add_wds_files(struct ieee80211_sub_if_data
*sdata
)
527 DEBUGFS_ADD(channel_use
, wds
);
528 DEBUGFS_ADD(drop_unencrypted
, wds
);
529 DEBUGFS_ADD(eapol
, wds
);
530 DEBUGFS_ADD(ieee8021_x
, wds
);
531 DEBUGFS_ADD(peer
, wds
);
534 static void add_vlan_files(struct ieee80211_sub_if_data
*sdata
)
536 DEBUGFS_ADD(channel_use
, vlan
);
537 DEBUGFS_ADD(drop_unencrypted
, vlan
);
538 DEBUGFS_ADD(eapol
, vlan
);
539 DEBUGFS_ADD(ieee8021_x
, vlan
);
540 DEBUGFS_ADD(vlan_id
, vlan
);
543 static void add_monitor_files(struct ieee80211_sub_if_data
*sdata
)
545 DEBUGFS_ADD(mode
, monitor
);
548 static void add_files(struct ieee80211_sub_if_data
*sdata
)
550 if (!sdata
->debugfsdir
)
553 switch (sdata
->type
) {
554 case IEEE80211_IF_TYPE_STA
:
555 case IEEE80211_IF_TYPE_IBSS
:
556 add_sta_files(sdata
);
558 case IEEE80211_IF_TYPE_AP
:
561 case IEEE80211_IF_TYPE_WDS
:
562 add_wds_files(sdata
);
564 case IEEE80211_IF_TYPE_MNTR
:
565 add_monitor_files(sdata
);
567 case IEEE80211_IF_TYPE_VLAN
:
568 add_vlan_files(sdata
);
575 #define DEBUGFS_DEL(name, type) \
577 debugfs_remove(sdata->debugfs.type.name); \
578 sdata->debugfs.type.name = NULL; \
581 static void del_sta_files(struct ieee80211_sub_if_data
*sdata
)
583 DEBUGFS_DEL(channel_use
, sta
);
584 DEBUGFS_DEL(drop_unencrypted
, sta
);
585 DEBUGFS_DEL(eapol
, sta
);
586 DEBUGFS_DEL(ieee8021_x
, sta
);
587 DEBUGFS_DEL(state
, sta
);
588 DEBUGFS_DEL(bssid
, sta
);
589 DEBUGFS_DEL(prev_bssid
, sta
);
590 DEBUGFS_DEL(ssid_len
, sta
);
591 DEBUGFS_DEL(aid
, sta
);
592 DEBUGFS_DEL(ap_capab
, sta
);
593 DEBUGFS_DEL(capab
, sta
);
594 DEBUGFS_DEL(extra_ie_len
, sta
);
595 DEBUGFS_DEL(auth_tries
, sta
);
596 DEBUGFS_DEL(assoc_tries
, sta
);
597 DEBUGFS_DEL(auth_algs
, sta
);
598 DEBUGFS_DEL(auth_alg
, sta
);
599 DEBUGFS_DEL(auth_transaction
, sta
);
600 DEBUGFS_DEL(flags
, sta
);
602 DEBUGFS_TSINFO_DEL(tsid
);
603 DEBUGFS_TSINFO_DEL(direction
);
604 DEBUGFS_TSINFO_DEL(up
);
606 DEBUGFS_TSPEC_DEL(nominal_msdu_size
);
607 DEBUGFS_TSPEC_DEL(max_msdu_size
);
608 DEBUGFS_TSPEC_DEL(min_service_interval
);
609 DEBUGFS_TSPEC_DEL(max_service_interval
);
610 DEBUGFS_TSPEC_DEL(inactivity_interval
);
611 DEBUGFS_TSPEC_DEL(suspension_interval
);
612 DEBUGFS_TSPEC_DEL(service_start_time
);
613 DEBUGFS_TSPEC_DEL(min_data_rate
);
614 DEBUGFS_TSPEC_DEL(mean_data_rate
);
615 DEBUGFS_TSPEC_DEL(peak_data_rate
);
616 DEBUGFS_TSPEC_DEL(burst_size
);
617 DEBUGFS_TSPEC_DEL(delay_bound
);
618 DEBUGFS_TSPEC_DEL(min_phy_rate
);
619 DEBUGFS_TSPEC_DEL(surplus_band_allow
);
620 DEBUGFS_TSPEC_DEL(medium_time
);
622 DEBUGFS_QOS_DEL(addts_11e
);
623 DEBUGFS_QOS_DEL(addts_wmm
);
624 DEBUGFS_QOS_DEL(delts_11e
);
625 DEBUGFS_QOS_DEL(delts_wmm
);
626 DEBUGFS_QOS_DEL(dls_mac
);
627 DEBUGFS_QOS_DEL(dls_op
);
629 debugfs_remove(sdata
->debugfs
.sta
.tspec_dir
);
630 sdata
->debugfs
.sta
.tspec_dir
= NULL
;
631 debugfs_remove(sdata
->debugfs
.sta
.tsinfo_dir
);
632 sdata
->debugfs
.sta
.tsinfo_dir
= NULL
;
633 debugfs_remove(sdata
->debugfs
.sta
.qos_dir
);
634 sdata
->debugfs
.sta
.qos_dir
= NULL
;
637 static void del_ap_files(struct ieee80211_sub_if_data
*sdata
)
639 DEBUGFS_DEL(channel_use
, ap
);
640 DEBUGFS_DEL(drop_unencrypted
, ap
);
641 DEBUGFS_DEL(eapol
, ap
);
642 DEBUGFS_DEL(ieee8021_x
, ap
);
643 DEBUGFS_DEL(num_sta_ps
, ap
);
644 DEBUGFS_DEL(dtim_period
, ap
);
645 DEBUGFS_DEL(dtim_count
, ap
);
646 DEBUGFS_DEL(num_beacons
, ap
);
647 DEBUGFS_DEL(force_unicast_rateidx
, ap
);
648 DEBUGFS_DEL(max_ratectrl_rateidx
, ap
);
649 DEBUGFS_DEL(num_buffered_multicast
, ap
);
650 DEBUGFS_DEL(beacon_head_len
, ap
);
651 DEBUGFS_DEL(beacon_tail_len
, ap
);
654 static void del_wds_files(struct ieee80211_sub_if_data
*sdata
)
656 DEBUGFS_DEL(channel_use
, wds
);
657 DEBUGFS_DEL(drop_unencrypted
, wds
);
658 DEBUGFS_DEL(eapol
, wds
);
659 DEBUGFS_DEL(ieee8021_x
, wds
);
660 DEBUGFS_DEL(peer
, wds
);
663 static void del_vlan_files(struct ieee80211_sub_if_data
*sdata
)
665 DEBUGFS_DEL(channel_use
, vlan
);
666 DEBUGFS_DEL(drop_unencrypted
, vlan
);
667 DEBUGFS_DEL(eapol
, vlan
);
668 DEBUGFS_DEL(ieee8021_x
, vlan
);
669 DEBUGFS_DEL(vlan_id
, vlan
);
672 static void del_monitor_files(struct ieee80211_sub_if_data
*sdata
)
674 DEBUGFS_DEL(mode
, monitor
);
677 static void del_files(struct ieee80211_sub_if_data
*sdata
, int type
)
679 if (!sdata
->debugfsdir
)
683 case IEEE80211_IF_TYPE_STA
:
684 case IEEE80211_IF_TYPE_IBSS
:
685 del_sta_files(sdata
);
687 case IEEE80211_IF_TYPE_AP
:
690 case IEEE80211_IF_TYPE_WDS
:
691 del_wds_files(sdata
);
693 case IEEE80211_IF_TYPE_MNTR
:
694 del_monitor_files(sdata
);
696 case IEEE80211_IF_TYPE_VLAN
:
697 del_vlan_files(sdata
);
704 static int notif_registered
;
706 void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data
*sdata
)
708 char buf
[10+IFNAMSIZ
];
710 if (!notif_registered
)
713 sprintf(buf
, "netdev:%s", sdata
->dev
->name
);
714 sdata
->debugfsdir
= debugfs_create_dir(buf
,
715 sdata
->local
->hw
.wiphy
->debugfsdir
);
718 void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data
*sdata
)
720 del_files(sdata
, sdata
->type
);
721 debugfs_remove(sdata
->debugfsdir
);
722 sdata
->debugfsdir
= NULL
;
725 void ieee80211_debugfs_change_if_type(struct ieee80211_sub_if_data
*sdata
,
728 del_files(sdata
, oldtype
);
732 static int netdev_notify(struct notifier_block
* nb
,
736 struct net_device
*dev
= ndev
;
738 char buf[10+IFNAMSIZ];
741 if (state
!= NETDEV_CHANGENAME
)
744 if (!dev
->ieee80211_ptr
|| !dev
->ieee80211_ptr
->wiphy
)
747 if (dev
->ieee80211_ptr
->wiphy
->privid
!= mac80211_wiphy_privid
)
751 sprintf(buf, "netdev:%s", dev->name);
752 debugfs_rename(IEEE80211_DEV_TO_SUB_IF(dev)->debugfsdir, buf);
758 static struct notifier_block mac80211_debugfs_netdev_notifier
= {
759 .notifier_call
= netdev_notify
,
762 void ieee80211_debugfs_netdev_init(void)
766 err
= register_netdevice_notifier(&mac80211_debugfs_netdev_notifier
);
769 "mac80211: failed to install netdev notifier,"
770 " disabling per-netdev debugfs!\n");
772 notif_registered
= 1;
775 void ieee80211_debugfs_netdev_exit(void)
777 unregister_netdevice_notifier(&mac80211_debugfs_netdev_notifier
);
778 notif_registered
= 0;