~ubuntu-branches/ubuntu/natty/linux-backports-modules-2.6.38/natty-security

« back to all changes in this revision

Viewing changes to updates/cw-3.0.0/net/mac80211/debugfs_netdev.c

  • Committer: Package Import Robot
  • Author(s): Herton Ronaldo Krzesinski, Herton Ronaldo Krzesinski, Tim Gardner
  • Date: 2011-09-27 18:53:53 UTC
  • Revision ID: package-import@ubuntu.com-20110927185353-kv2b0it2l42t74bh
Tags: 2.6.38-12.8
[ Herton Ronaldo Krzesinski ]

* Bump ABI - Natty ABI 12

[ Tim Gardner ]

* Added compat wireless 3.0.0
  - LP: #819484

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/slab.h>
 
17
#include <linux/notifier.h>
 
18
#include <net/mac80211.h>
 
19
#include <net/cfg80211.h>
 
20
#include "ieee80211_i.h"
 
21
#include "rate.h"
 
22
#include "debugfs.h"
 
23
#include "debugfs_netdev.h"
 
24
 
 
25
static ssize_t ieee80211_if_read(
 
26
        struct ieee80211_sub_if_data *sdata,
 
27
        char __user *userbuf,
 
28
        size_t count, loff_t *ppos,
 
29
        ssize_t (*format)(const struct ieee80211_sub_if_data *, char *, int))
 
30
{
 
31
        char buf[70];
 
32
        ssize_t ret = -EINVAL;
 
33
 
 
34
        read_lock(&dev_base_lock);
 
35
        if (sdata->dev->reg_state == NETREG_REGISTERED)
 
36
                ret = (*format)(sdata, buf, sizeof(buf));
 
37
        read_unlock(&dev_base_lock);
 
38
 
 
39
        if (ret >= 0)
 
40
                ret = simple_read_from_buffer(userbuf, count, ppos, buf, ret);
 
41
 
 
42
        return ret;
 
43
}
 
44
 
 
45
static ssize_t ieee80211_if_write(
 
46
        struct ieee80211_sub_if_data *sdata,
 
47
        const char __user *userbuf,
 
48
        size_t count, loff_t *ppos,
 
49
        ssize_t (*write)(struct ieee80211_sub_if_data *, const char *, int))
 
50
{
 
51
        u8 *buf;
 
52
        ssize_t ret;
 
53
 
 
54
        buf = kmalloc(count, GFP_KERNEL);
 
55
        if (!buf)
 
56
                return -ENOMEM;
 
57
 
 
58
        ret = -EFAULT;
 
59
        if (copy_from_user(buf, userbuf, count))
 
60
                goto freebuf;
 
61
 
 
62
        ret = -ENODEV;
 
63
        rtnl_lock();
 
64
        if (sdata->dev->reg_state == NETREG_REGISTERED)
 
65
                ret = (*write)(sdata, buf, count);
 
66
        rtnl_unlock();
 
67
 
 
68
freebuf:
 
69
        kfree(buf);
 
70
        return ret;
 
71
}
 
72
 
 
73
#define IEEE80211_IF_FMT(name, field, format_string)                    \
 
74
static ssize_t ieee80211_if_fmt_##name(                                 \
 
75
        const struct ieee80211_sub_if_data *sdata, char *buf,           \
 
76
        int buflen)                                                     \
 
77
{                                                                       \
 
78
        return scnprintf(buf, buflen, format_string, sdata->field);     \
 
79
}
 
80
#define IEEE80211_IF_FMT_DEC(name, field)                               \
 
81
                IEEE80211_IF_FMT(name, field, "%d\n")
 
82
#define IEEE80211_IF_FMT_HEX(name, field)                               \
 
83
                IEEE80211_IF_FMT(name, field, "%#x\n")
 
84
#define IEEE80211_IF_FMT_LHEX(name, field)                              \
 
85
                IEEE80211_IF_FMT(name, field, "%#lx\n")
 
86
#define IEEE80211_IF_FMT_SIZE(name, field)                              \
 
87
                IEEE80211_IF_FMT(name, field, "%zd\n")
 
88
 
 
89
#define IEEE80211_IF_FMT_ATOMIC(name, field)                            \
 
90
static ssize_t ieee80211_if_fmt_##name(                                 \
 
91
        const struct ieee80211_sub_if_data *sdata,                      \
 
92
        char *buf, int buflen)                                          \
 
93
{                                                                       \
 
94
        return scnprintf(buf, buflen, "%d\n", atomic_read(&sdata->field));\
 
95
}
 
96
 
 
97
#define IEEE80211_IF_FMT_MAC(name, field)                               \
 
98
static ssize_t ieee80211_if_fmt_##name(                                 \
 
99
        const struct ieee80211_sub_if_data *sdata, char *buf,           \
 
100
        int buflen)                                                     \
 
101
{                                                                       \
 
102
        return scnprintf(buf, buflen, "%pM\n", sdata->field);           \
 
103
}
 
104
 
 
105
#define IEEE80211_IF_FMT_DEC_DIV_16(name, field)                        \
 
106
static ssize_t ieee80211_if_fmt_##name(                                 \
 
107
        const struct ieee80211_sub_if_data *sdata,                      \
 
108
        char *buf, int buflen)                                          \
 
109
{                                                                       \
 
110
        return scnprintf(buf, buflen, "%d\n", sdata->field / 16);       \
 
111
}
 
112
 
 
113
#define __IEEE80211_IF_FILE(name, _write)                               \
 
114
static ssize_t ieee80211_if_read_##name(struct file *file,              \
 
115
                                        char __user *userbuf,           \
 
116
                                        size_t count, loff_t *ppos)     \
 
117
{                                                                       \
 
118
        return ieee80211_if_read(file->private_data,                    \
 
119
                                 userbuf, count, ppos,                  \
 
120
                                 ieee80211_if_fmt_##name);              \
 
121
}                                                                       \
 
122
static const struct file_operations name##_ops = {                      \
 
123
        .read = ieee80211_if_read_##name,                               \
 
124
        .write = (_write),                                              \
 
125
        .open = mac80211_open_file_generic,                             \
 
126
        .llseek = generic_file_llseek,                                  \
 
127
}
 
128
 
 
129
#define __IEEE80211_IF_FILE_W(name)                                     \
 
130
static ssize_t ieee80211_if_write_##name(struct file *file,             \
 
131
                                         const char __user *userbuf,    \
 
132
                                         size_t count, loff_t *ppos)    \
 
133
{                                                                       \
 
134
        return ieee80211_if_write(file->private_data, userbuf, count,   \
 
135
                                  ppos, ieee80211_if_parse_##name);     \
 
136
}                                                                       \
 
137
__IEEE80211_IF_FILE(name, ieee80211_if_write_##name)
 
138
 
 
139
 
 
140
#define IEEE80211_IF_FILE(name, field, format)                          \
 
141
                IEEE80211_IF_FMT_##format(name, field)                  \
 
142
                __IEEE80211_IF_FILE(name, NULL)
 
143
 
 
144
/* common attributes */
 
145
IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC);
 
146
IEEE80211_IF_FILE(rc_rateidx_mask_2ghz, rc_rateidx_mask[IEEE80211_BAND_2GHZ],
 
147
                  HEX);
 
148
IEEE80211_IF_FILE(rc_rateidx_mask_5ghz, rc_rateidx_mask[IEEE80211_BAND_5GHZ],
 
149
                  HEX);
 
150
IEEE80211_IF_FILE(flags, flags, HEX);
 
151
IEEE80211_IF_FILE(state, state, LHEX);
 
152
IEEE80211_IF_FILE(channel_type, vif.bss_conf.channel_type, DEC);
 
153
 
 
154
/* STA attributes */
 
155
IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC);
 
156
IEEE80211_IF_FILE(aid, u.mgd.aid, DEC);
 
157
IEEE80211_IF_FILE(last_beacon, u.mgd.last_beacon_signal, DEC);
 
158
IEEE80211_IF_FILE(ave_beacon, u.mgd.ave_beacon_signal, DEC_DIV_16);
 
159
 
 
160
static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata,
 
161
                              enum ieee80211_smps_mode smps_mode)
 
162
{
 
163
        struct ieee80211_local *local = sdata->local;
 
164
        int err;
 
165
 
 
166
        if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_STATIC_SMPS) &&
 
167
            smps_mode == IEEE80211_SMPS_STATIC)
 
168
                return -EINVAL;
 
169
 
 
170
        /* auto should be dynamic if in PS mode */
 
171
        if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS) &&
 
172
            (smps_mode == IEEE80211_SMPS_DYNAMIC ||
 
173
             smps_mode == IEEE80211_SMPS_AUTOMATIC))
 
174
                return -EINVAL;
 
175
 
 
176
        /* supported only on managed interfaces for now */
 
177
        if (sdata->vif.type != NL80211_IFTYPE_STATION)
 
178
                return -EOPNOTSUPP;
 
179
 
 
180
        mutex_lock(&sdata->u.mgd.mtx);
 
181
        err = __ieee80211_request_smps(sdata, smps_mode);
 
182
        mutex_unlock(&sdata->u.mgd.mtx);
 
183
 
 
184
        return err;
 
185
}
 
186
 
 
187
static const char *smps_modes[IEEE80211_SMPS_NUM_MODES] = {
 
188
        [IEEE80211_SMPS_AUTOMATIC] = "auto",
 
189
        [IEEE80211_SMPS_OFF] = "off",
 
190
        [IEEE80211_SMPS_STATIC] = "static",
 
191
        [IEEE80211_SMPS_DYNAMIC] = "dynamic",
 
192
};
 
193
 
 
194
static ssize_t ieee80211_if_fmt_smps(const struct ieee80211_sub_if_data *sdata,
 
195
                                     char *buf, int buflen)
 
196
{
 
197
        if (sdata->vif.type != NL80211_IFTYPE_STATION)
 
198
                return -EOPNOTSUPP;
 
199
 
 
200
        return snprintf(buf, buflen, "request: %s\nused: %s\n",
 
201
                        smps_modes[sdata->u.mgd.req_smps],
 
202
                        smps_modes[sdata->u.mgd.ap_smps]);
 
203
}
 
204
 
 
205
static ssize_t ieee80211_if_parse_smps(struct ieee80211_sub_if_data *sdata,
 
206
                                       const char *buf, int buflen)
 
207
{
 
208
        enum ieee80211_smps_mode mode;
 
209
 
 
210
        for (mode = 0; mode < IEEE80211_SMPS_NUM_MODES; mode++) {
 
211
                if (strncmp(buf, smps_modes[mode], buflen) == 0) {
 
212
                        int err = ieee80211_set_smps(sdata, mode);
 
213
                        if (!err)
 
214
                                return buflen;
 
215
                        return err;
 
216
                }
 
217
        }
 
218
 
 
219
        return -EINVAL;
 
220
}
 
221
 
 
222
__IEEE80211_IF_FILE_W(smps);
 
223
 
 
224
static ssize_t ieee80211_if_fmt_tkip_mic_test(
 
225
        const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
 
226
{
 
227
        return -EOPNOTSUPP;
 
228
}
 
229
 
 
230
static int hwaddr_aton(const char *txt, u8 *addr)
 
231
{
 
232
        int i;
 
233
 
 
234
        for (i = 0; i < ETH_ALEN; i++) {
 
235
                int a, b;
 
236
 
 
237
                a = hex_to_bin(*txt++);
 
238
                if (a < 0)
 
239
                        return -1;
 
240
                b = hex_to_bin(*txt++);
 
241
                if (b < 0)
 
242
                        return -1;
 
243
                *addr++ = (a << 4) | b;
 
244
                if (i < 5 && *txt++ != ':')
 
245
                        return -1;
 
246
        }
 
247
 
 
248
        return 0;
 
249
}
 
250
 
 
251
static ssize_t ieee80211_if_parse_tkip_mic_test(
 
252
        struct ieee80211_sub_if_data *sdata, const char *buf, int buflen)
 
253
{
 
254
        struct ieee80211_local *local = sdata->local;
 
255
        u8 addr[ETH_ALEN];
 
256
        struct sk_buff *skb;
 
257
        struct ieee80211_hdr *hdr;
 
258
        __le16 fc;
 
259
 
 
260
        /*
 
261
         * Assume colon-delimited MAC address with possible white space
 
262
         * following.
 
263
         */
 
264
        if (buflen < 3 * ETH_ALEN - 1)
 
265
                return -EINVAL;
 
266
        if (hwaddr_aton(buf, addr) < 0)
 
267
                return -EINVAL;
 
268
 
 
269
        if (!ieee80211_sdata_running(sdata))
 
270
                return -ENOTCONN;
 
271
 
 
272
        skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24 + 100);
 
273
        if (!skb)
 
274
                return -ENOMEM;
 
275
        skb_reserve(skb, local->hw.extra_tx_headroom);
 
276
 
 
277
        hdr = (struct ieee80211_hdr *) skb_put(skb, 24);
 
278
        memset(hdr, 0, 24);
 
279
        fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA);
 
280
 
 
281
        switch (sdata->vif.type) {
 
282
        case NL80211_IFTYPE_AP:
 
283
                fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
 
284
                /* DA BSSID SA */
 
285
                memcpy(hdr->addr1, addr, ETH_ALEN);
 
286
                memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
 
287
                memcpy(hdr->addr3, sdata->vif.addr, ETH_ALEN);
 
288
                break;
 
289
        case NL80211_IFTYPE_STATION:
 
290
                fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
 
291
                /* BSSID SA DA */
 
292
                if (sdata->vif.bss_conf.bssid == NULL) {
 
293
                        dev_kfree_skb(skb);
 
294
                        return -ENOTCONN;
 
295
                }
 
296
                memcpy(hdr->addr1, sdata->vif.bss_conf.bssid, ETH_ALEN);
 
297
                memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
 
298
                memcpy(hdr->addr3, addr, ETH_ALEN);
 
299
                break;
 
300
        default:
 
301
                dev_kfree_skb(skb);
 
302
                return -EOPNOTSUPP;
 
303
        }
 
304
        hdr->frame_control = fc;
 
305
 
 
306
        /*
 
307
         * Add some length to the test frame to make it look bit more valid.
 
308
         * The exact contents does not matter since the recipient is required
 
309
         * to drop this because of the Michael MIC failure.
 
310
         */
 
311
        memset(skb_put(skb, 50), 0, 50);
 
312
 
 
313
        IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_TKIP_MIC_FAILURE;
 
314
 
 
315
        ieee80211_tx_skb(sdata, skb);
 
316
 
 
317
        return buflen;
 
318
}
 
319
 
 
320
__IEEE80211_IF_FILE_W(tkip_mic_test);
 
321
 
 
322
/* AP attributes */
 
323
IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC);
 
324
IEEE80211_IF_FILE(dtim_count, u.ap.dtim_count, DEC);
 
325
 
 
326
static ssize_t ieee80211_if_fmt_num_buffered_multicast(
 
327
        const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
 
328
{
 
329
        return scnprintf(buf, buflen, "%u\n",
 
330
                         skb_queue_len(&sdata->u.ap.ps_bc_buf));
 
331
}
 
332
__IEEE80211_IF_FILE(num_buffered_multicast, NULL);
 
333
 
 
334
/* WDS attributes */
 
335
IEEE80211_IF_FILE(peer, u.wds.remote_addr, MAC);
 
336
 
 
337
#ifdef CONFIG_MAC80211_MESH
 
338
/* Mesh stats attributes */
 
339
IEEE80211_IF_FILE(fwded_mcast, u.mesh.mshstats.fwded_mcast, DEC);
 
340
IEEE80211_IF_FILE(fwded_unicast, u.mesh.mshstats.fwded_unicast, DEC);
 
341
IEEE80211_IF_FILE(fwded_frames, u.mesh.mshstats.fwded_frames, DEC);
 
342
IEEE80211_IF_FILE(dropped_frames_ttl, u.mesh.mshstats.dropped_frames_ttl, DEC);
 
343
IEEE80211_IF_FILE(dropped_frames_no_route,
 
344
                u.mesh.mshstats.dropped_frames_no_route, DEC);
 
345
IEEE80211_IF_FILE(estab_plinks, u.mesh.mshstats.estab_plinks, ATOMIC);
 
346
 
 
347
/* Mesh parameters */
 
348
IEEE80211_IF_FILE(dot11MeshMaxRetries,
 
349
                u.mesh.mshcfg.dot11MeshMaxRetries, DEC);
 
350
IEEE80211_IF_FILE(dot11MeshRetryTimeout,
 
351
                u.mesh.mshcfg.dot11MeshRetryTimeout, DEC);
 
352
IEEE80211_IF_FILE(dot11MeshConfirmTimeout,
 
353
                u.mesh.mshcfg.dot11MeshConfirmTimeout, DEC);
 
354
IEEE80211_IF_FILE(dot11MeshHoldingTimeout,
 
355
                u.mesh.mshcfg.dot11MeshHoldingTimeout, DEC);
 
356
IEEE80211_IF_FILE(dot11MeshTTL, u.mesh.mshcfg.dot11MeshTTL, DEC);
 
357
IEEE80211_IF_FILE(element_ttl, u.mesh.mshcfg.element_ttl, DEC);
 
358
IEEE80211_IF_FILE(auto_open_plinks, u.mesh.mshcfg.auto_open_plinks, DEC);
 
359
IEEE80211_IF_FILE(dot11MeshMaxPeerLinks,
 
360
                u.mesh.mshcfg.dot11MeshMaxPeerLinks, DEC);
 
361
IEEE80211_IF_FILE(dot11MeshHWMPactivePathTimeout,
 
362
                u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout, DEC);
 
363
IEEE80211_IF_FILE(dot11MeshHWMPpreqMinInterval,
 
364
                u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval, DEC);
 
365
IEEE80211_IF_FILE(dot11MeshHWMPnetDiameterTraversalTime,
 
366
                u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC);
 
367
IEEE80211_IF_FILE(dot11MeshHWMPmaxPREQretries,
 
368
                u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries, DEC);
 
369
IEEE80211_IF_FILE(path_refresh_time,
 
370
                u.mesh.mshcfg.path_refresh_time, DEC);
 
371
IEEE80211_IF_FILE(min_discovery_timeout,
 
372
                u.mesh.mshcfg.min_discovery_timeout, DEC);
 
373
IEEE80211_IF_FILE(dot11MeshHWMPRootMode,
 
374
                u.mesh.mshcfg.dot11MeshHWMPRootMode, DEC);
 
375
#endif
 
376
 
 
377
 
 
378
#define DEBUGFS_ADD(name) \
 
379
        debugfs_create_file(#name, 0400, sdata->debugfs.dir, \
 
380
                            sdata, &name##_ops);
 
381
 
 
382
#define DEBUGFS_ADD_MODE(name, mode) \
 
383
        debugfs_create_file(#name, mode, sdata->debugfs.dir, \
 
384
                            sdata, &name##_ops);
 
385
 
 
386
static void add_sta_files(struct ieee80211_sub_if_data *sdata)
 
387
{
 
388
        DEBUGFS_ADD(drop_unencrypted);
 
389
        DEBUGFS_ADD(flags);
 
390
        DEBUGFS_ADD(state);
 
391
        DEBUGFS_ADD(channel_type);
 
392
        DEBUGFS_ADD(rc_rateidx_mask_2ghz);
 
393
        DEBUGFS_ADD(rc_rateidx_mask_5ghz);
 
394
 
 
395
        DEBUGFS_ADD(bssid);
 
396
        DEBUGFS_ADD(aid);
 
397
        DEBUGFS_ADD(last_beacon);
 
398
        DEBUGFS_ADD(ave_beacon);
 
399
        DEBUGFS_ADD_MODE(smps, 0600);
 
400
        DEBUGFS_ADD_MODE(tkip_mic_test, 0200);
 
401
}
 
402
 
 
403
static void add_ap_files(struct ieee80211_sub_if_data *sdata)
 
404
{
 
405
        DEBUGFS_ADD(drop_unencrypted);
 
406
        DEBUGFS_ADD(flags);
 
407
        DEBUGFS_ADD(state);
 
408
        DEBUGFS_ADD(channel_type);
 
409
        DEBUGFS_ADD(rc_rateidx_mask_2ghz);
 
410
        DEBUGFS_ADD(rc_rateidx_mask_5ghz);
 
411
 
 
412
        DEBUGFS_ADD(num_sta_ps);
 
413
        DEBUGFS_ADD(dtim_count);
 
414
        DEBUGFS_ADD(num_buffered_multicast);
 
415
        DEBUGFS_ADD_MODE(tkip_mic_test, 0200);
 
416
}
 
417
 
 
418
static void add_wds_files(struct ieee80211_sub_if_data *sdata)
 
419
{
 
420
        DEBUGFS_ADD(drop_unencrypted);
 
421
        DEBUGFS_ADD(flags);
 
422
        DEBUGFS_ADD(state);
 
423
        DEBUGFS_ADD(channel_type);
 
424
        DEBUGFS_ADD(rc_rateidx_mask_2ghz);
 
425
        DEBUGFS_ADD(rc_rateidx_mask_5ghz);
 
426
 
 
427
        DEBUGFS_ADD(peer);
 
428
}
 
429
 
 
430
static void add_vlan_files(struct ieee80211_sub_if_data *sdata)
 
431
{
 
432
        DEBUGFS_ADD(drop_unencrypted);
 
433
        DEBUGFS_ADD(flags);
 
434
        DEBUGFS_ADD(state);
 
435
        DEBUGFS_ADD(channel_type);
 
436
        DEBUGFS_ADD(rc_rateidx_mask_2ghz);
 
437
        DEBUGFS_ADD(rc_rateidx_mask_5ghz);
 
438
}
 
439
 
 
440
static void add_monitor_files(struct ieee80211_sub_if_data *sdata)
 
441
{
 
442
        DEBUGFS_ADD(flags);
 
443
        DEBUGFS_ADD(state);
 
444
        DEBUGFS_ADD(channel_type);
 
445
}
 
446
 
 
447
#ifdef CONFIG_MAC80211_MESH
 
448
 
 
449
static void add_mesh_stats(struct ieee80211_sub_if_data *sdata)
 
450
{
 
451
        struct dentry *dir = debugfs_create_dir("mesh_stats",
 
452
                                                sdata->debugfs.dir);
 
453
 
 
454
#define MESHSTATS_ADD(name)\
 
455
        debugfs_create_file(#name, 0400, dir, sdata, &name##_ops);
 
456
 
 
457
        MESHSTATS_ADD(fwded_mcast);
 
458
        MESHSTATS_ADD(fwded_unicast);
 
459
        MESHSTATS_ADD(fwded_frames);
 
460
        MESHSTATS_ADD(dropped_frames_ttl);
 
461
        MESHSTATS_ADD(dropped_frames_no_route);
 
462
        MESHSTATS_ADD(estab_plinks);
 
463
#undef MESHSTATS_ADD
 
464
}
 
465
 
 
466
static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
 
467
{
 
468
        struct dentry *dir = debugfs_create_dir("mesh_config",
 
469
                                                sdata->debugfs.dir);
 
470
 
 
471
#define MESHPARAMS_ADD(name) \
 
472
        debugfs_create_file(#name, 0600, dir, sdata, &name##_ops);
 
473
 
 
474
        MESHPARAMS_ADD(dot11MeshMaxRetries);
 
475
        MESHPARAMS_ADD(dot11MeshRetryTimeout);
 
476
        MESHPARAMS_ADD(dot11MeshConfirmTimeout);
 
477
        MESHPARAMS_ADD(dot11MeshHoldingTimeout);
 
478
        MESHPARAMS_ADD(dot11MeshTTL);
 
479
        MESHPARAMS_ADD(element_ttl);
 
480
        MESHPARAMS_ADD(auto_open_plinks);
 
481
        MESHPARAMS_ADD(dot11MeshMaxPeerLinks);
 
482
        MESHPARAMS_ADD(dot11MeshHWMPactivePathTimeout);
 
483
        MESHPARAMS_ADD(dot11MeshHWMPpreqMinInterval);
 
484
        MESHPARAMS_ADD(dot11MeshHWMPnetDiameterTraversalTime);
 
485
        MESHPARAMS_ADD(dot11MeshHWMPmaxPREQretries);
 
486
        MESHPARAMS_ADD(path_refresh_time);
 
487
        MESHPARAMS_ADD(min_discovery_timeout);
 
488
 
 
489
#undef MESHPARAMS_ADD
 
490
}
 
491
#endif
 
492
 
 
493
static void add_files(struct ieee80211_sub_if_data *sdata)
 
494
{
 
495
        if (!sdata->debugfs.dir)
 
496
                return;
 
497
 
 
498
        switch (sdata->vif.type) {
 
499
        case NL80211_IFTYPE_MESH_POINT:
 
500
#ifdef CONFIG_MAC80211_MESH
 
501
                add_mesh_stats(sdata);
 
502
                add_mesh_config(sdata);
 
503
#endif
 
504
                break;
 
505
        case NL80211_IFTYPE_STATION:
 
506
                add_sta_files(sdata);
 
507
                break;
 
508
        case NL80211_IFTYPE_ADHOC:
 
509
                /* XXX */
 
510
                break;
 
511
        case NL80211_IFTYPE_AP:
 
512
                add_ap_files(sdata);
 
513
                break;
 
514
        case NL80211_IFTYPE_WDS:
 
515
                add_wds_files(sdata);
 
516
                break;
 
517
        case NL80211_IFTYPE_MONITOR:
 
518
                add_monitor_files(sdata);
 
519
                break;
 
520
        case NL80211_IFTYPE_AP_VLAN:
 
521
                add_vlan_files(sdata);
 
522
                break;
 
523
        default:
 
524
                break;
 
525
        }
 
526
}
 
527
 
 
528
void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata)
 
529
{
 
530
        char buf[10+IFNAMSIZ];
 
531
 
 
532
        sprintf(buf, "netdev:%s", sdata->name);
 
533
        sdata->debugfs.dir = debugfs_create_dir(buf,
 
534
                sdata->local->hw.wiphy->debugfsdir);
 
535
        if (sdata->debugfs.dir)
 
536
                sdata->debugfs.subdir_stations = debugfs_create_dir("stations",
 
537
                        sdata->debugfs.dir);
 
538
        add_files(sdata);
 
539
}
 
540
 
 
541
void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata)
 
542
{
 
543
        if (!sdata->debugfs.dir)
 
544
                return;
 
545
 
 
546
        debugfs_remove_recursive(sdata->debugfs.dir);
 
547
        sdata->debugfs.dir = NULL;
 
548
}
 
549
 
 
550
void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata)
 
551
{
 
552
        struct dentry *dir;
 
553
        char buf[10 + IFNAMSIZ];
 
554
 
 
555
        dir = sdata->debugfs.dir;
 
556
 
 
557
        if (!dir)
 
558
                return;
 
559
 
 
560
        sprintf(buf, "netdev:%s", sdata->name);
 
561
        if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf))
 
562
                printk(KERN_ERR "mac80211: debugfs: failed to rename debugfs "
 
563
                       "dir to %s\n", buf);
 
564
}