aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/debugfs_netdev.c
diff options
context:
space:
mode:
authorMichal Marek <mmarek@suse.cz>2010-10-27 18:15:57 -0400
committerMichal Marek <mmarek@suse.cz>2010-10-27 18:15:57 -0400
commitb74b953b998bcc2db91b694446f3a2619ec32de6 (patch)
tree6ce24caabd730f6ae9287ed0676ec32e6ff31e9d /net/mac80211/debugfs_netdev.c
parentabb438526201c6a79949ad45375c051b6681c253 (diff)
parentf6f94e2ab1b33f0082ac22d71f66385a60d8157f (diff)
Merge commit 'v2.6.36' into kbuild/misc
Update to be able to fix a recent change to scripts/basic/docproc.c (commit eda603f).
Diffstat (limited to 'net/mac80211/debugfs_netdev.c')
-rw-r--r--net/mac80211/debugfs_netdev.c231
1 files changed, 154 insertions, 77 deletions
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 472b2039906c..20b2998fa0ed 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -13,6 +13,7 @@
13#include <linux/interrupt.h> 13#include <linux/interrupt.h>
14#include <linux/netdevice.h> 14#include <linux/netdevice.h>
15#include <linux/rtnetlink.h> 15#include <linux/rtnetlink.h>
16#include <linux/slab.h>
16#include <linux/notifier.h> 17#include <linux/notifier.h>
17#include <net/mac80211.h> 18#include <net/mac80211.h>
18#include <net/cfg80211.h> 19#include <net/cfg80211.h>
@@ -41,6 +42,34 @@ static ssize_t ieee80211_if_read(
41 return ret; 42 return ret;
42} 43}
43 44
45static 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
68freebuf:
69 kfree(buf);
70 return ret;
71}
72
44#define IEEE80211_IF_FMT(name, field, format_string) \ 73#define IEEE80211_IF_FMT(name, field, format_string) \
45static ssize_t ieee80211_if_fmt_##name( \ 74static ssize_t ieee80211_if_fmt_##name( \
46 const struct ieee80211_sub_if_data *sdata, char *buf, \ 75 const struct ieee80211_sub_if_data *sdata, char *buf, \
@@ -71,7 +100,15 @@ static ssize_t ieee80211_if_fmt_##name( \
71 return scnprintf(buf, buflen, "%pM\n", sdata->field); \ 100 return scnprintf(buf, buflen, "%pM\n", sdata->field); \
72} 101}
73 102
74#define __IEEE80211_IF_FILE(name) \ 103#define IEEE80211_IF_FMT_DEC_DIV_16(name, field) \
104static ssize_t ieee80211_if_fmt_##name( \
105 const struct ieee80211_sub_if_data *sdata, \
106 char *buf, int buflen) \
107{ \
108 return scnprintf(buf, buflen, "%d\n", sdata->field / 16); \
109}
110
111#define __IEEE80211_IF_FILE(name, _write) \
75static ssize_t ieee80211_if_read_##name(struct file *file, \ 112static ssize_t ieee80211_if_read_##name(struct file *file, \
76 char __user *userbuf, \ 113 char __user *userbuf, \
77 size_t count, loff_t *ppos) \ 114 size_t count, loff_t *ppos) \
@@ -82,22 +119,101 @@ static ssize_t ieee80211_if_read_##name(struct file *file, \
82} \ 119} \
83static const struct file_operations name##_ops = { \ 120static const struct file_operations name##_ops = { \
84 .read = ieee80211_if_read_##name, \ 121 .read = ieee80211_if_read_##name, \
122 .write = (_write), \
85 .open = mac80211_open_file_generic, \ 123 .open = mac80211_open_file_generic, \
86} 124}
87 125
126#define __IEEE80211_IF_FILE_W(name) \
127static ssize_t ieee80211_if_write_##name(struct file *file, \
128 const char __user *userbuf, \
129 size_t count, loff_t *ppos) \
130{ \
131 return ieee80211_if_write(file->private_data, userbuf, count, \
132 ppos, ieee80211_if_parse_##name); \
133} \
134__IEEE80211_IF_FILE(name, ieee80211_if_write_##name)
135
136
88#define IEEE80211_IF_FILE(name, field, format) \ 137#define IEEE80211_IF_FILE(name, field, format) \
89 IEEE80211_IF_FMT_##format(name, field) \ 138 IEEE80211_IF_FMT_##format(name, field) \
90 __IEEE80211_IF_FILE(name) 139 __IEEE80211_IF_FILE(name, NULL)
91 140
92/* common attributes */ 141/* common attributes */
93IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC); 142IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC);
94IEEE80211_IF_FILE(force_unicast_rateidx, force_unicast_rateidx, DEC); 143IEEE80211_IF_FILE(rc_rateidx_mask_2ghz, rc_rateidx_mask[IEEE80211_BAND_2GHZ],
95IEEE80211_IF_FILE(max_ratectrl_rateidx, max_ratectrl_rateidx, DEC); 144 HEX);
145IEEE80211_IF_FILE(rc_rateidx_mask_5ghz, rc_rateidx_mask[IEEE80211_BAND_5GHZ],
146 HEX);
96 147
97/* STA attributes */ 148/* STA attributes */
98IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC); 149IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC);
99IEEE80211_IF_FILE(aid, u.mgd.aid, DEC); 150IEEE80211_IF_FILE(aid, u.mgd.aid, DEC);
100IEEE80211_IF_FILE(capab, u.mgd.capab, HEX); 151IEEE80211_IF_FILE(last_beacon, u.mgd.last_beacon_signal, DEC);
152IEEE80211_IF_FILE(ave_beacon, u.mgd.ave_beacon_signal, DEC_DIV_16);
153
154static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata,
155 enum ieee80211_smps_mode smps_mode)
156{
157 struct ieee80211_local *local = sdata->local;
158 int err;
159
160 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_STATIC_SMPS) &&
161 smps_mode == IEEE80211_SMPS_STATIC)
162 return -EINVAL;
163
164 /* auto should be dynamic if in PS mode */
165 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS) &&
166 (smps_mode == IEEE80211_SMPS_DYNAMIC ||
167 smps_mode == IEEE80211_SMPS_AUTOMATIC))
168 return -EINVAL;
169
170 /* supported only on managed interfaces for now */
171 if (sdata->vif.type != NL80211_IFTYPE_STATION)
172 return -EOPNOTSUPP;
173
174 mutex_lock(&local->iflist_mtx);
175 err = __ieee80211_request_smps(sdata, smps_mode);
176 mutex_unlock(&local->iflist_mtx);
177
178 return err;
179}
180
181static const char *smps_modes[IEEE80211_SMPS_NUM_MODES] = {
182 [IEEE80211_SMPS_AUTOMATIC] = "auto",
183 [IEEE80211_SMPS_OFF] = "off",
184 [IEEE80211_SMPS_STATIC] = "static",
185 [IEEE80211_SMPS_DYNAMIC] = "dynamic",
186};
187
188static ssize_t ieee80211_if_fmt_smps(const struct ieee80211_sub_if_data *sdata,
189 char *buf, int buflen)
190{
191 if (sdata->vif.type != NL80211_IFTYPE_STATION)
192 return -EOPNOTSUPP;
193
194 return snprintf(buf, buflen, "request: %s\nused: %s\n",
195 smps_modes[sdata->u.mgd.req_smps],
196 smps_modes[sdata->u.mgd.ap_smps]);
197}
198
199static ssize_t ieee80211_if_parse_smps(struct ieee80211_sub_if_data *sdata,
200 const char *buf, int buflen)
201{
202 enum ieee80211_smps_mode mode;
203
204 for (mode = 0; mode < IEEE80211_SMPS_NUM_MODES; mode++) {
205 if (strncmp(buf, smps_modes[mode], buflen) == 0) {
206 int err = ieee80211_set_smps(sdata, mode);
207 if (!err)
208 return buflen;
209 return err;
210 }
211 }
212
213 return -EINVAL;
214}
215
216__IEEE80211_IF_FILE_W(smps);
101 217
102/* AP attributes */ 218/* AP attributes */
103IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC); 219IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC);
@@ -109,7 +225,7 @@ static ssize_t ieee80211_if_fmt_num_buffered_multicast(
109 return scnprintf(buf, buflen, "%u\n", 225 return scnprintf(buf, buflen, "%u\n",
110 skb_queue_len(&sdata->u.ap.ps_bc_buf)); 226 skb_queue_len(&sdata->u.ap.ps_bc_buf));
111} 227}
112__IEEE80211_IF_FILE(num_buffered_multicast); 228__IEEE80211_IF_FILE(num_buffered_multicast, NULL);
113 229
114/* WDS attributes */ 230/* WDS attributes */
115IEEE80211_IF_FILE(peer, u.wds.remote_addr, MAC); 231IEEE80211_IF_FILE(peer, u.wds.remote_addr, MAC);
@@ -154,46 +270,52 @@ IEEE80211_IF_FILE(dot11MeshHWMPRootMode,
154#endif 270#endif
155 271
156 272
157#define DEBUGFS_ADD(name, type) \ 273#define DEBUGFS_ADD(name) \
158 debugfs_create_file(#name, 0400, sdata->debugfs.dir, \ 274 debugfs_create_file(#name, 0400, sdata->debugfs.dir, \
159 sdata, &name##_ops); 275 sdata, &name##_ops);
160 276
277#define DEBUGFS_ADD_MODE(name, mode) \
278 debugfs_create_file(#name, mode, sdata->debugfs.dir, \
279 sdata, &name##_ops);
280
161static void add_sta_files(struct ieee80211_sub_if_data *sdata) 281static void add_sta_files(struct ieee80211_sub_if_data *sdata)
162{ 282{
163 DEBUGFS_ADD(drop_unencrypted, sta); 283 DEBUGFS_ADD(drop_unencrypted);
164 DEBUGFS_ADD(force_unicast_rateidx, sta); 284 DEBUGFS_ADD(rc_rateidx_mask_2ghz);
165 DEBUGFS_ADD(max_ratectrl_rateidx, sta); 285 DEBUGFS_ADD(rc_rateidx_mask_5ghz);
166 286
167 DEBUGFS_ADD(bssid, sta); 287 DEBUGFS_ADD(bssid);
168 DEBUGFS_ADD(aid, sta); 288 DEBUGFS_ADD(aid);
169 DEBUGFS_ADD(capab, sta); 289 DEBUGFS_ADD(last_beacon);
290 DEBUGFS_ADD(ave_beacon);
291 DEBUGFS_ADD_MODE(smps, 0600);
170} 292}
171 293
172static void add_ap_files(struct ieee80211_sub_if_data *sdata) 294static void add_ap_files(struct ieee80211_sub_if_data *sdata)
173{ 295{
174 DEBUGFS_ADD(drop_unencrypted, ap); 296 DEBUGFS_ADD(drop_unencrypted);
175 DEBUGFS_ADD(force_unicast_rateidx, ap); 297 DEBUGFS_ADD(rc_rateidx_mask_2ghz);
176 DEBUGFS_ADD(max_ratectrl_rateidx, ap); 298 DEBUGFS_ADD(rc_rateidx_mask_5ghz);
177 299
178 DEBUGFS_ADD(num_sta_ps, ap); 300 DEBUGFS_ADD(num_sta_ps);
179 DEBUGFS_ADD(dtim_count, ap); 301 DEBUGFS_ADD(dtim_count);
180 DEBUGFS_ADD(num_buffered_multicast, ap); 302 DEBUGFS_ADD(num_buffered_multicast);
181} 303}
182 304
183static void add_wds_files(struct ieee80211_sub_if_data *sdata) 305static void add_wds_files(struct ieee80211_sub_if_data *sdata)
184{ 306{
185 DEBUGFS_ADD(drop_unencrypted, wds); 307 DEBUGFS_ADD(drop_unencrypted);
186 DEBUGFS_ADD(force_unicast_rateidx, wds); 308 DEBUGFS_ADD(rc_rateidx_mask_2ghz);
187 DEBUGFS_ADD(max_ratectrl_rateidx, wds); 309 DEBUGFS_ADD(rc_rateidx_mask_5ghz);
188 310
189 DEBUGFS_ADD(peer, wds); 311 DEBUGFS_ADD(peer);
190} 312}
191 313
192static void add_vlan_files(struct ieee80211_sub_if_data *sdata) 314static void add_vlan_files(struct ieee80211_sub_if_data *sdata)
193{ 315{
194 DEBUGFS_ADD(drop_unencrypted, vlan); 316 DEBUGFS_ADD(drop_unencrypted);
195 DEBUGFS_ADD(force_unicast_rateidx, vlan); 317 DEBUGFS_ADD(rc_rateidx_mask_2ghz);
196 DEBUGFS_ADD(max_ratectrl_rateidx, vlan); 318 DEBUGFS_ADD(rc_rateidx_mask_5ghz);
197} 319}
198 320
199static void add_monitor_files(struct ieee80211_sub_if_data *sdata) 321static void add_monitor_files(struct ieee80211_sub_if_data *sdata)
@@ -280,16 +402,11 @@ static void add_files(struct ieee80211_sub_if_data *sdata)
280 } 402 }
281} 403}
282 404
283static int notif_registered;
284
285void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata) 405void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata)
286{ 406{
287 char buf[10+IFNAMSIZ]; 407 char buf[10+IFNAMSIZ];
288 408
289 if (!notif_registered) 409 sprintf(buf, "netdev:%s", sdata->name);
290 return;
291
292 sprintf(buf, "netdev:%s", sdata->dev->name);
293 sdata->debugfs.dir = debugfs_create_dir(buf, 410 sdata->debugfs.dir = debugfs_create_dir(buf,
294 sdata->local->hw.wiphy->debugfsdir); 411 sdata->local->hw.wiphy->debugfsdir);
295 add_files(sdata); 412 add_files(sdata);
@@ -304,58 +421,18 @@ void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata)
304 sdata->debugfs.dir = NULL; 421 sdata->debugfs.dir = NULL;
305} 422}
306 423
307static int netdev_notify(struct notifier_block *nb, 424void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata)
308 unsigned long state,
309 void *ndev)
310{ 425{
311 struct net_device *dev = ndev;
312 struct dentry *dir; 426 struct dentry *dir;
313 struct ieee80211_sub_if_data *sdata; 427 char buf[10 + IFNAMSIZ];
314 char buf[10+IFNAMSIZ];
315
316 if (state != NETDEV_CHANGENAME)
317 return 0;
318
319 if (!dev->ieee80211_ptr || !dev->ieee80211_ptr->wiphy)
320 return 0;
321
322 if (dev->ieee80211_ptr->wiphy->privid != mac80211_wiphy_privid)
323 return 0;
324
325 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
326 428
327 dir = sdata->debugfs.dir; 429 dir = sdata->debugfs.dir;
328 430
329 if (!dir) 431 if (!dir)
330 return 0; 432 return;
331 433
332 sprintf(buf, "netdev:%s", dev->name); 434 sprintf(buf, "netdev:%s", sdata->name);
333 if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf)) 435 if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf))
334 printk(KERN_ERR "mac80211: debugfs: failed to rename debugfs " 436 printk(KERN_ERR "mac80211: debugfs: failed to rename debugfs "
335 "dir to %s\n", buf); 437 "dir to %s\n", buf);
336
337 return 0;
338}
339
340static struct notifier_block mac80211_debugfs_netdev_notifier = {
341 .notifier_call = netdev_notify,
342};
343
344void ieee80211_debugfs_netdev_init(void)
345{
346 int err;
347
348 err = register_netdevice_notifier(&mac80211_debugfs_netdev_notifier);
349 if (err) {
350 printk(KERN_ERR
351 "mac80211: failed to install netdev notifier,"
352 " disabling per-netdev debugfs!\n");
353 } else
354 notif_registered = 1;
355}
356
357void ieee80211_debugfs_netdev_exit(void)
358{
359 unregister_netdevice_notifier(&mac80211_debugfs_netdev_notifier);
360 notif_registered = 0;
361} 438}