~ubuntu-branches/ubuntu/hardy/linux-backports-modules-2.6.24/hardy-security

« back to all changes in this revision

Viewing changes to updates/wireless/iwlwifi/mac80211/modified/net/mac80211/debugfs_netdev.c

  • Committer: Bazaar Package Importer
  • Author(s): , Ben Collins
  • Date: 2008-04-02 06:59:04 UTC
  • Revision ID: james.westby@ubuntu.com-20080402065904-e5knh2gn2hms3xbb
Tags: 2.6.24-14.11
[Ben Collins]

* iwlwifi: Update to iwlwifi-1.2.25 and mac80211-10.0.4
  - LP: #200950
* ubuntu: Slight cleanups to module hiearchy and Makefiles
* mac80211: Enable LED triggers
* iwlwifi: Add LED trigger support (rx and tx only)
  - LP: #176090

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2006   Jiri Benc <jbenc@suse.cz>
 
3
 * Copyright 2007       Johannes Berg <johannes@sipsolutions.net>
 
4
 *
 
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.
 
8
 */
 
9
 
 
10
#include <linux/kernel.h>
 
11
#include <linux/device.h>
 
12
#include <linux/if.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"
 
21
#include "debugfs.h"
 
22
#include "debugfs_netdev.h"
 
23
 
 
24
static ssize_t ieee80211_if_read(
 
25
        struct ieee80211_sub_if_data *sdata,
 
26
        char __user *userbuf,
 
27
        size_t count, loff_t *ppos,
 
28
        ssize_t (*format)(const struct ieee80211_sub_if_data *, char *, int))
 
29
{
 
30
        char buf[70];
 
31
        ssize_t ret = -EINVAL;
 
32
 
 
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);
 
37
        }
 
38
        read_unlock(&dev_base_lock);
 
39
        return ret;
 
40
}
 
41
 
 
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,           \
 
45
        int buflen)                                                     \
 
46
{                                                                       \
 
47
        return scnprintf(buf, buflen, format_string, sdata->field);     \
 
48
}
 
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")
 
55
 
 
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)                                          \
 
60
{                                                                       \
 
61
        return scnprintf(buf, buflen, "%d\n", atomic_read(&sdata->field));\
 
62
}
 
63
 
 
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,           \
 
67
        int buflen)                                                     \
 
68
{                                                                       \
 
69
        return scnprintf(buf, buflen, MAC_FMT "\n", MAC_ARG(sdata->field));\
 
70
}
 
71
 
 
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)     \
 
76
{                                                                       \
 
77
        return ieee80211_if_read(file->private_data,                    \
 
78
                                 userbuf, count, ppos,                  \
 
79
                                 ieee80211_if_fmt_##name);              \
 
80
}                                                                       \
 
81
static const struct file_operations name##_ops = {                      \
 
82
        .read = ieee80211_if_read_##name,                               \
 
83
        .open = mac80211_open_file_generic,                             \
 
84
}
 
85
 
 
86
#define IEEE80211_IF_FILE(name, field, format)                          \
 
87
                IEEE80211_IF_FMT_##format(name, field)                  \
 
88
                __IEEE80211_IF_FILE(name)
 
89
 
 
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)         \
 
94
{                                                                       \
 
95
        struct ieee80211_sub_if_data *sdata = file->private_data;       \
 
96
                                                                        \
 
97
        f(sdata->dev, &sdata->u.sta, &sdata->u.sta.tspec);              \
 
98
                                                                        \
 
99
        return count;                                                   \
 
100
}                                                                       \
 
101
                                                                        \
 
102
static const struct file_operations qos_ ##name## _ops = {              \
 
103
        .write = qos_ ##name## _write,                                  \
 
104
        .open = mac80211_open_file_generic,                             \
 
105
};
 
106
 
 
107
#define DEBUGFS_QOS_ADD(name)                                           \
 
108
        sdata->debugfs.sta.qos.name = debugfs_create_file(#name, 0444, qosd,\
 
109
                sdata, &qos_ ##name## _ops);
 
110
 
 
111
#define DEBUGFS_QOS_DEL(name)                                           \
 
112
        do {                                                            \
 
113
                debugfs_remove(sdata->debugfs.sta.qos.name);            \
 
114
                sdata->debugfs.sta.qos.name = NULL;                     \
 
115
        } while (0)
 
116
 
 
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);
 
121
 
 
122
static ssize_t qos_if_dls_mac(const struct ieee80211_sub_if_data *sdata,
 
123
                              char *buf, int buflen)
 
124
{
 
125
        return scnprintf(buf, buflen, MAC_FMT "\n",
 
126
                         MAC_ARG(sdata->u.sta.dls_mac));
 
127
}
 
128
 
 
129
static ssize_t qos_dls_mac_read(struct file *file,
 
130
                                char __user *userbuf,
 
131
                                size_t count, loff_t *ppos)
 
132
{
 
133
        return ieee80211_if_read(file->private_data,
 
134
                                 userbuf, count, ppos,
 
135
                                 qos_if_dls_mac);
 
136
}
 
137
 
 
138
static ssize_t qos_dls_mac_write(struct file *file, const char __user *userbuf,
 
139
                                 size_t count, loff_t *ppos)
 
140
{
 
141
        struct ieee80211_sub_if_data *sdata = file->private_data;
 
142
        char buf[20];
 
143
        size_t size;
 
144
        u8 m[ETH_ALEN];
 
145
 
 
146
        size = min(sizeof(buf) - 1, count);
 
147
        buf[size] = '\0';
 
148
        if (copy_from_user(buf, userbuf, size))
 
149
                return -EFAULT;
 
150
 
 
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);
 
155
                return -EINVAL;
 
156
        }
 
157
        memcpy(sdata->u.sta.dls_mac, m, ETH_ALEN);
 
158
        return count;
 
159
}
 
160
 
 
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,
 
165
};
 
166
 
 
167
static ssize_t qos_if_dls_op(const struct ieee80211_sub_if_data *sdata,
 
168
                             char *buf, int buflen)
 
169
{
 
170
        return scnprintf(buf, buflen,
 
171
                         "DLS Operation: Setup = 1; Teardown = 2\n");
 
172
}
 
173
 
 
174
static ssize_t qos_dls_op_read(struct file *file, char __user *userbuf,
 
175
                               size_t count, loff_t *ppos)
 
176
{
 
177
        return ieee80211_if_read(file->private_data,
 
178
                                 userbuf, count, ppos,
 
179
                                 qos_if_dls_op);
 
180
}
 
181
 
 
182
static ssize_t qos_dls_op_write(struct file *file, const char __user *userbuf,
 
183
                                 size_t count, loff_t *ppos)
 
184
{
 
185
        struct ieee80211_sub_if_data *sdata = file->private_data;
 
186
        char buf[20];
 
187
        size_t size;
 
188
        unsigned int opt;
 
189
 
 
190
        size = min(sizeof(buf) - 1, count);
 
191
        buf[size] = '\0';
 
192
        if (copy_from_user(buf, userbuf, size))
 
193
                return -EFAULT;
 
194
 
 
195
        if (sscanf(buf, "%u", &opt) != 1) {
 
196
                printk(KERN_ERR "%s: sscanf input error\n", sdata->dev->name);
 
197
                return -EINVAL;
 
198
        }
 
199
        switch (opt) {
 
200
        case 1:
 
201
                ieee80211_send_dls_req(sdata->dev, &sdata->u.sta,
 
202
                                       sdata->u.sta.dls_mac, 0);
 
203
                break;
 
204
        case 2:
 
205
                ieee80211_send_dls_teardown(sdata->dev, &sdata->u.sta,
 
206
                                            sdata->u.sta.dls_mac,
 
207
                                            WLAN_REASON_QSTA_NOT_USE);
 
208
                break;
 
209
        default:
 
210
                printk(KERN_ERR "Unknown DLS Operation: %d\n", opt);
 
211
                break;
 
212
        }
 
213
        return count;
 
214
}
 
215
 
 
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,
 
220
};
 
221
 
 
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)      \
 
226
{                                                                       \
 
227
        char buf[20];                                                   \
 
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); \
 
232
}                                                                       \
 
233
                                                                        \
 
234
static ssize_t tsinfo_ ##_name## _write(struct file *file,              \
 
235
                                        const char __user *userbuf,     \
 
236
                                        size_t count, loff_t *ppos)     \
 
237
{                                                                       \
 
238
        char buf[20];                                                   \
 
239
        size_t size;                                                    \
 
240
        int val;                                                        \
 
241
        struct ieee80211_sub_if_data *sdata = file->private_data;       \
 
242
                                                                        \
 
243
        size = min(sizeof(buf) - 1, count);                             \
 
244
        buf[size] = '\0';                                               \
 
245
        if (copy_from_user(buf, userbuf, size))                         \
 
246
                return -EFAULT;                                         \
 
247
                                                                        \
 
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);\
 
252
                return -EINVAL;                                         \
 
253
        }                                                               \
 
254
        IEEE80211_SET_TSINFO_ ##_name (sdata->u.sta.tspec.ts_info, val);\
 
255
        return count;                                                   \
 
256
}                                                                       \
 
257
                                                                        \
 
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,                             \
 
262
};
 
263
 
 
264
#define DEBUGFS_TSINFO_ADD_TSID                                         \
 
265
        sdata->debugfs.sta.tsinfo.tsid =                                \
 
266
                debugfs_create_file("tsid", 0444, tsinfod,              \
 
267
                                    sdata, &tsinfo_TSID_ops);
 
268
 
 
269
#define DEBUGFS_TSINFO_ADD_DIR                                          \
 
270
        sdata->debugfs.sta.tsinfo.direction =                           \
 
271
                debugfs_create_file("direction", 0444, tsinfod,         \
 
272
                                    sdata, &tsinfo_DIR_ops);
 
273
 
 
274
#define DEBUGFS_TSINFO_ADD_UP                                           \
 
275
        sdata->debugfs.sta.tsinfo.up =                                  \
 
276
                debugfs_create_file("up", 0444, tsinfod,                \
 
277
                                    sdata, &tsinfo_UP_ops);
 
278
 
 
279
#define DEBUGFS_TSINFO_DEL(name)                                        \
 
280
        do {                                                            \
 
281
                debugfs_remove(sdata->debugfs.sta.tsinfo.name);         \
 
282
                sdata->debugfs.sta.tsinfo.name = NULL;                  \
 
283
        } while (0)
 
284
 
 
285
DEBUGFS_TSINFO_FILE(TSID, 8, 15);
 
286
DEBUGFS_TSINFO_FILE(DIR, 0, 3);
 
287
DEBUGFS_TSINFO_FILE(UP, 0, 7);
 
288
 
 
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)       \
 
293
{                                                                       \
 
294
        char buf[20];                                                   \
 
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); \
 
299
}                                                                       \
 
300
                                                                        \
 
301
static ssize_t tspec_ ##name## _write(struct file *file,                \
 
302
                                       const char __user *userbuf,      \
 
303
                                       size_t count, loff_t *ppos)      \
 
304
{                                                                       \
 
305
        char buf[20];                                                   \
 
306
        size_t size;                                                    \
 
307
        struct ieee80211_sub_if_data *sdata = file->private_data;       \
 
308
                                                                        \
 
309
        size = min(sizeof(buf) - 1, count);                             \
 
310
        buf[size] = '\0';                                               \
 
311
        if (copy_from_user(buf, userbuf, size))                         \
 
312
                return -EFAULT;                                         \
 
313
                                                                        \
 
314
        sdata->u.sta.tspec.name = endian_f2(simple_strtoul(buf, NULL, 0));\
 
315
        return count;                                                   \
 
316
}                                                                       \
 
317
                                                                        \
 
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,                             \
 
322
};
 
323
 
 
324
#define DEBUGFS_TSPEC_ADD(name)                                         \
 
325
        sdata->debugfs.sta.tspec.name = debugfs_create_file(#name,      \
 
326
                0444, tspecd, sdata, &tspec_ ##name## _ops);
 
327
 
 
328
#define DEBUGFS_TSPEC_DEL(name)                                         \
 
329
        do {                                                            \
 
330
                debugfs_remove(sdata->debugfs.sta.tspec.name);          \
 
331
                sdata->debugfs.sta.tspec.name = NULL;                   \
 
332
        } while (0)
 
333
 
 
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);
 
349
 
 
350
 
 
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);
 
356
 
 
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);
 
371
 
 
372
static ssize_t ieee80211_if_fmt_flags(
 
373
        const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
 
374
{
 
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->use_protection ? "CTS prot\n" : "");
 
383
}
 
384
__IEEE80211_IF_FILE(flags);
 
385
 
 
386
/* AP attributes */
 
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);
 
393
 
 
394
static ssize_t ieee80211_if_fmt_num_buffered_multicast(
 
395
        const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
 
396
{
 
397
        return scnprintf(buf, buflen, "%u\n",
 
398
                         skb_queue_len(&sdata->u.ap.ps_bc_buf));
 
399
}
 
400
__IEEE80211_IF_FILE(num_buffered_multicast);
 
401
 
 
402
static ssize_t ieee80211_if_fmt_beacon_head_len(
 
403
        const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
 
404
{
 
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");
 
409
}
 
410
__IEEE80211_IF_FILE(beacon_head_len);
 
411
 
 
412
static ssize_t ieee80211_if_fmt_beacon_tail_len(
 
413
        const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
 
414
{
 
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");
 
419
}
 
420
__IEEE80211_IF_FILE(beacon_tail_len);
 
421
 
 
422
/* WDS attributes */
 
423
IEEE80211_IF_FILE(peer, u.wds.remote_addr, MAC);
 
424
 
 
425
/* VLAN attributes */
 
426
IEEE80211_IF_FILE(vlan_id, u.vlan.id, DEC);
 
427
 
 
428
/* MONITOR attributes */
 
429
static ssize_t ieee80211_if_fmt_mode(
 
430
        const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
 
431
{
 
432
        struct ieee80211_local *local = sdata->local;
 
433
 
 
434
        return scnprintf(buf, buflen, "%s\n",
 
435
                         ((local->hw.flags & IEEE80211_HW_MONITOR_DURING_OPER) ||
 
436
                          local->open_count == local->monitors) ?
 
437
                         "hard" : "soft");
 
438
}
 
439
__IEEE80211_IF_FILE(mode);
 
440
 
 
441
 
 
442
#define DEBUGFS_ADD(name, type)\
 
443
        sdata->debugfs.type.name = debugfs_create_file(#name, 0444,\
 
444
                sdata->debugfsdir, sdata, &name##_ops);
 
445
 
 
446
static void add_sta_files(struct ieee80211_sub_if_data *sdata)
 
447
{
 
448
        struct dentry *qosd;
 
449
        struct dentry *tsinfod;
 
450
        struct dentry *tspecd;
 
451
 
 
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);
 
470
 
 
471
        qosd = debugfs_create_dir("qos", sdata->debugfsdir);
 
472
        sdata->debugfs.sta.qos_dir = qosd;
 
473
 
 
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);
 
480
 
 
481
        tsinfod = debugfs_create_dir("ts_info", qosd);
 
482
        sdata->debugfs.sta.tsinfo_dir = tsinfod;
 
483
 
 
484
        DEBUGFS_TSINFO_ADD_TSID;
 
485
        DEBUGFS_TSINFO_ADD_DIR;
 
486
        DEBUGFS_TSINFO_ADD_UP;
 
487
 
 
488
        tspecd = debugfs_create_dir("tspec", qosd);
 
489
        sdata->debugfs.sta.tspec_dir = tspecd;
 
490
 
 
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);
 
506
}
 
507
 
 
508
static void add_ap_files(struct ieee80211_sub_if_data *sdata)
 
509
{
 
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);
 
523
}
 
524
 
 
525
static void add_wds_files(struct ieee80211_sub_if_data *sdata)
 
526
{
 
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);
 
532
}
 
533
 
 
534
static void add_vlan_files(struct ieee80211_sub_if_data *sdata)
 
535
{
 
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);
 
541
}
 
542
 
 
543
static void add_monitor_files(struct ieee80211_sub_if_data *sdata)
 
544
{
 
545
        DEBUGFS_ADD(mode, monitor);
 
546
}
 
547
 
 
548
static void add_files(struct ieee80211_sub_if_data *sdata)
 
549
{
 
550
        if (!sdata->debugfsdir)
 
551
                return;
 
552
 
 
553
        switch (sdata->type) {
 
554
        case IEEE80211_IF_TYPE_STA:
 
555
        case IEEE80211_IF_TYPE_IBSS:
 
556
                add_sta_files(sdata);
 
557
                break;
 
558
        case IEEE80211_IF_TYPE_AP:
 
559
                add_ap_files(sdata);
 
560
                break;
 
561
        case IEEE80211_IF_TYPE_WDS:
 
562
                add_wds_files(sdata);
 
563
                break;
 
564
        case IEEE80211_IF_TYPE_MNTR:
 
565
                add_monitor_files(sdata);
 
566
                break;
 
567
        case IEEE80211_IF_TYPE_VLAN:
 
568
                add_vlan_files(sdata);
 
569
                break;
 
570
        default:
 
571
                break;
 
572
        }
 
573
}
 
574
 
 
575
#define DEBUGFS_DEL(name, type)                                 \
 
576
        do {                                                    \
 
577
                debugfs_remove(sdata->debugfs.type.name);       \
 
578
                sdata->debugfs.type.name = NULL;                \
 
579
        } while (0)
 
580
 
 
581
static void del_sta_files(struct ieee80211_sub_if_data *sdata)
 
582
{
 
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);
 
601
 
 
602
        DEBUGFS_TSINFO_DEL(tsid);
 
603
        DEBUGFS_TSINFO_DEL(direction);
 
604
        DEBUGFS_TSINFO_DEL(up);
 
605
 
 
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);
 
621
 
 
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);
 
628
 
 
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;
 
635
}
 
636
 
 
637
static void del_ap_files(struct ieee80211_sub_if_data *sdata)
 
638
{
 
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);
 
652
}
 
653
 
 
654
static void del_wds_files(struct ieee80211_sub_if_data *sdata)
 
655
{
 
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);
 
661
}
 
662
 
 
663
static void del_vlan_files(struct ieee80211_sub_if_data *sdata)
 
664
{
 
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);
 
670
}
 
671
 
 
672
static void del_monitor_files(struct ieee80211_sub_if_data *sdata)
 
673
{
 
674
        DEBUGFS_DEL(mode, monitor);
 
675
}
 
676
 
 
677
static void del_files(struct ieee80211_sub_if_data *sdata, int type)
 
678
{
 
679
        if (!sdata->debugfsdir)
 
680
                return;
 
681
 
 
682
        switch (type) {
 
683
        case IEEE80211_IF_TYPE_STA:
 
684
        case IEEE80211_IF_TYPE_IBSS:
 
685
                del_sta_files(sdata);
 
686
                break;
 
687
        case IEEE80211_IF_TYPE_AP:
 
688
                del_ap_files(sdata);
 
689
                break;
 
690
        case IEEE80211_IF_TYPE_WDS:
 
691
                del_wds_files(sdata);
 
692
                break;
 
693
        case IEEE80211_IF_TYPE_MNTR:
 
694
                del_monitor_files(sdata);
 
695
                break;
 
696
        case IEEE80211_IF_TYPE_VLAN:
 
697
                del_vlan_files(sdata);
 
698
                break;
 
699
        default:
 
700
                break;
 
701
        }
 
702
}
 
703
 
 
704
static int notif_registered;
 
705
 
 
706
void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata)
 
707
{
 
708
        char buf[10+IFNAMSIZ];
 
709
 
 
710
        if (!notif_registered)
 
711
                return;
 
712
 
 
713
        sprintf(buf, "netdev:%s", sdata->dev->name);
 
714
        sdata->debugfsdir = debugfs_create_dir(buf,
 
715
                sdata->local->hw.wiphy->debugfsdir);
 
716
}
 
717
 
 
718
void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata)
 
719
{
 
720
        del_files(sdata, sdata->type);
 
721
        debugfs_remove(sdata->debugfsdir);
 
722
        sdata->debugfsdir = NULL;
 
723
}
 
724
 
 
725
void ieee80211_debugfs_change_if_type(struct ieee80211_sub_if_data *sdata,
 
726
                                      int oldtype)
 
727
{
 
728
        del_files(sdata, oldtype);
 
729
        add_files(sdata);
 
730
}
 
731
 
 
732
static int netdev_notify(struct notifier_block * nb,
 
733
                         unsigned long state,
 
734
                         void *ndev)
 
735
{
 
736
        struct net_device *dev = ndev;
 
737
        struct dentry *dir;
 
738
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
739
        char buf[10+IFNAMSIZ];
 
740
 
 
741
        if (state != NETDEV_CHANGENAME)
 
742
                return 0;
 
743
 
 
744
        if (!dev->ieee80211_ptr || !dev->ieee80211_ptr->wiphy)
 
745
                return 0;
 
746
 
 
747
        if (dev->ieee80211_ptr->wiphy->privid != mac80211_wiphy_privid)
 
748
                return 0;
 
749
 
 
750
        sprintf(buf, "netdev:%s", dev->name);
 
751
        dir = sdata->debugfsdir;
 
752
        if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf))
 
753
                printk(KERN_ERR "mac80211: debugfs: failed to rename debugfs "
 
754
                       "dir to %s\n", buf);
 
755
 
 
756
        return 0;
 
757
}
 
758
 
 
759
static struct notifier_block mac80211_debugfs_netdev_notifier = {
 
760
        .notifier_call = netdev_notify,
 
761
};
 
762
 
 
763
void ieee80211_debugfs_netdev_init(void)
 
764
{
 
765
        int err;
 
766
 
 
767
        err = register_netdevice_notifier(&mac80211_debugfs_netdev_notifier);
 
768
        if (err) {
 
769
                printk(KERN_ERR
 
770
                       "mac80211: failed to install netdev notifier,"
 
771
                       " disabling per-netdev debugfs!\n");
 
772
        } else
 
773
                notif_registered = 1;
 
774
}
 
775
 
 
776
void ieee80211_debugfs_netdev_exit(void)
 
777
{
 
778
        unregister_netdevice_notifier(&mac80211_debugfs_netdev_notifier);
 
779
        notif_registered = 0;
 
780
}