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;