diff options
author | Luis Carlos Cobo <luisca@cozybit.com> | 2008-02-23 09:17:16 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-03-06 15:30:42 -0500 |
commit | 9f42f607058a80bfb7b4f687bb84016ae129cfd1 (patch) | |
tree | 45d8f42dd64e19325cfa668c0f5a5a6a69ecdb78 /net | |
parent | 050ac52cbe1f3de2fb0d06f02c7919ae1f691c9e (diff) |
mac80211: mesh statistics and config through debugfs
This patch contains the debugfs code for mesh statistics and configuration
parameters. Please note that generic support for r/w debugfs attributes has been
added.
Signed-off-by: Luis Carlos Cobo <luisca@cozybit.com>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/debugfs_netdev.c | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 29f7b98ba1fb..107b0fe778d6 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c | |||
@@ -39,6 +39,29 @@ static ssize_t ieee80211_if_read( | |||
39 | return ret; | 39 | return ret; |
40 | } | 40 | } |
41 | 41 | ||
42 | #ifdef CONFIG_MAC80211_MESH | ||
43 | static ssize_t ieee80211_if_write( | ||
44 | struct ieee80211_sub_if_data *sdata, | ||
45 | char const __user *userbuf, | ||
46 | size_t count, loff_t *ppos, | ||
47 | int (*format)(struct ieee80211_sub_if_data *, char *)) | ||
48 | { | ||
49 | char buf[10]; | ||
50 | int buf_size; | ||
51 | |||
52 | memset(buf, 0x00, sizeof(buf)); | ||
53 | buf_size = min(count, (sizeof(buf)-1)); | ||
54 | read_lock(&dev_base_lock); | ||
55 | if (copy_from_user(buf, userbuf, buf_size)) | ||
56 | goto endwrite; | ||
57 | if (sdata->dev->reg_state == NETREG_REGISTERED) | ||
58 | (*format)(sdata, buf); | ||
59 | endwrite: | ||
60 | read_unlock(&dev_base_lock); | ||
61 | return count; | ||
62 | } | ||
63 | #endif | ||
64 | |||
42 | #define IEEE80211_IF_FMT(name, field, format_string) \ | 65 | #define IEEE80211_IF_FMT(name, field, format_string) \ |
43 | static ssize_t ieee80211_if_fmt_##name( \ | 66 | static ssize_t ieee80211_if_fmt_##name( \ |
44 | const struct ieee80211_sub_if_data *sdata, char *buf, \ | 67 | const struct ieee80211_sub_if_data *sdata, char *buf, \ |
@@ -46,6 +69,19 @@ static ssize_t ieee80211_if_fmt_##name( \ | |||
46 | { \ | 69 | { \ |
47 | return scnprintf(buf, buflen, format_string, sdata->field); \ | 70 | return scnprintf(buf, buflen, format_string, sdata->field); \ |
48 | } | 71 | } |
72 | #define IEEE80211_IF_WFMT(name, field, type) \ | ||
73 | static int ieee80211_if_wfmt_##name( \ | ||
74 | struct ieee80211_sub_if_data *sdata, char *buf) \ | ||
75 | { \ | ||
76 | unsigned long tmp; \ | ||
77 | char *endp; \ | ||
78 | \ | ||
79 | tmp = simple_strtoul(buf, &endp, 0); \ | ||
80 | if ((endp == buf) || ((type)tmp != tmp)) \ | ||
81 | return -EINVAL; \ | ||
82 | sdata->field = tmp; \ | ||
83 | return 0; \ | ||
84 | } | ||
49 | #define IEEE80211_IF_FMT_DEC(name, field) \ | 85 | #define IEEE80211_IF_FMT_DEC(name, field) \ |
50 | IEEE80211_IF_FMT(name, field, "%d\n") | 86 | IEEE80211_IF_FMT(name, field, "%d\n") |
51 | #define IEEE80211_IF_FMT_HEX(name, field) \ | 87 | #define IEEE80211_IF_FMT_HEX(name, field) \ |
@@ -88,6 +124,34 @@ static const struct file_operations name##_ops = { \ | |||
88 | IEEE80211_IF_FMT_##format(name, field) \ | 124 | IEEE80211_IF_FMT_##format(name, field) \ |
89 | __IEEE80211_IF_FILE(name) | 125 | __IEEE80211_IF_FILE(name) |
90 | 126 | ||
127 | #define __IEEE80211_IF_WFILE(name) \ | ||
128 | static ssize_t ieee80211_if_read_##name(struct file *file, \ | ||
129 | char __user *userbuf, \ | ||
130 | size_t count, loff_t *ppos) \ | ||
131 | { \ | ||
132 | return ieee80211_if_read(file->private_data, \ | ||
133 | userbuf, count, ppos, \ | ||
134 | ieee80211_if_fmt_##name); \ | ||
135 | } \ | ||
136 | static ssize_t ieee80211_if_write_##name(struct file *file, \ | ||
137 | const char __user *userbuf, \ | ||
138 | size_t count, loff_t *ppos) \ | ||
139 | { \ | ||
140 | return ieee80211_if_write(file->private_data, \ | ||
141 | userbuf, count, ppos, \ | ||
142 | ieee80211_if_wfmt_##name); \ | ||
143 | } \ | ||
144 | static const struct file_operations name##_ops = { \ | ||
145 | .read = ieee80211_if_read_##name, \ | ||
146 | .write = ieee80211_if_write_##name, \ | ||
147 | .open = mac80211_open_file_generic, \ | ||
148 | } | ||
149 | |||
150 | #define IEEE80211_IF_WFILE(name, field, format, type) \ | ||
151 | IEEE80211_IF_FMT_##format(name, field) \ | ||
152 | IEEE80211_IF_WFMT(name, field, type) \ | ||
153 | __IEEE80211_IF_WFILE(name) | ||
154 | |||
91 | /* common attributes */ | 155 | /* common attributes */ |
92 | IEEE80211_IF_FILE(channel_use, channel_use, DEC); | 156 | IEEE80211_IF_FILE(channel_use, channel_use, DEC); |
93 | IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC); | 157 | IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC); |
@@ -106,6 +170,7 @@ IEEE80211_IF_FILE(assoc_tries, u.sta.assoc_tries, DEC); | |||
106 | IEEE80211_IF_FILE(auth_algs, u.sta.auth_algs, HEX); | 170 | IEEE80211_IF_FILE(auth_algs, u.sta.auth_algs, HEX); |
107 | IEEE80211_IF_FILE(auth_alg, u.sta.auth_alg, DEC); | 171 | IEEE80211_IF_FILE(auth_alg, u.sta.auth_alg, DEC); |
108 | IEEE80211_IF_FILE(auth_transaction, u.sta.auth_transaction, DEC); | 172 | IEEE80211_IF_FILE(auth_transaction, u.sta.auth_transaction, DEC); |
173 | IEEE80211_IF_FILE(num_beacons_sta, u.sta.num_beacons, DEC); | ||
109 | 174 | ||
110 | static ssize_t ieee80211_if_fmt_flags( | 175 | static ssize_t ieee80211_if_fmt_flags( |
111 | const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) | 176 | const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) |
@@ -139,6 +204,42 @@ __IEEE80211_IF_FILE(num_buffered_multicast); | |||
139 | /* WDS attributes */ | 204 | /* WDS attributes */ |
140 | IEEE80211_IF_FILE(peer, u.wds.remote_addr, MAC); | 205 | IEEE80211_IF_FILE(peer, u.wds.remote_addr, MAC); |
141 | 206 | ||
207 | #ifdef CONFIG_MAC80211_MESH | ||
208 | /* Mesh stats attributes */ | ||
209 | IEEE80211_IF_FILE(fwded_frames, u.sta.mshstats.fwded_frames, DEC); | ||
210 | IEEE80211_IF_FILE(dropped_frames_ttl, u.sta.mshstats.dropped_frames_ttl, DEC); | ||
211 | IEEE80211_IF_FILE(dropped_frames_no_route, | ||
212 | u.sta.mshstats.dropped_frames_no_route, DEC); | ||
213 | IEEE80211_IF_FILE(estab_plinks, u.sta.mshstats.estab_plinks, ATOMIC); | ||
214 | |||
215 | /* Mesh parameters */ | ||
216 | IEEE80211_IF_WFILE(dot11MeshMaxRetries, | ||
217 | u.sta.mshcfg.dot11MeshMaxRetries, DEC, u8); | ||
218 | IEEE80211_IF_WFILE(dot11MeshRetryTimeout, | ||
219 | u.sta.mshcfg.dot11MeshRetryTimeout, DEC, u16); | ||
220 | IEEE80211_IF_WFILE(dot11MeshConfirmTimeout, | ||
221 | u.sta.mshcfg.dot11MeshConfirmTimeout, DEC, u16); | ||
222 | IEEE80211_IF_WFILE(dot11MeshHoldingTimeout, | ||
223 | u.sta.mshcfg.dot11MeshHoldingTimeout, DEC, u16); | ||
224 | IEEE80211_IF_WFILE(dot11MeshTTL, u.sta.mshcfg.dot11MeshTTL, DEC, u8); | ||
225 | IEEE80211_IF_WFILE(auto_open_plinks, u.sta.mshcfg.auto_open_plinks, DEC, bool); | ||
226 | IEEE80211_IF_WFILE(dot11MeshMaxPeerLinks, | ||
227 | u.sta.mshcfg.dot11MeshMaxPeerLinks, DEC, u16); | ||
228 | IEEE80211_IF_WFILE(dot11MeshHWMPactivePathTimeout, | ||
229 | u.sta.mshcfg.dot11MeshHWMPactivePathTimeout, DEC, u32); | ||
230 | IEEE80211_IF_WFILE(dot11MeshHWMPpreqMinInterval, | ||
231 | u.sta.mshcfg.dot11MeshHWMPpreqMinInterval, DEC, u16); | ||
232 | IEEE80211_IF_WFILE(dot11MeshHWMPnetDiameterTraversalTime, | ||
233 | u.sta.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC, u16); | ||
234 | IEEE80211_IF_WFILE(dot11MeshHWMPmaxPREQretries, | ||
235 | u.sta.mshcfg.dot11MeshHWMPmaxPREQretries, DEC, u8); | ||
236 | IEEE80211_IF_WFILE(path_refresh_time, | ||
237 | u.sta.mshcfg.path_refresh_time, DEC, u32); | ||
238 | IEEE80211_IF_WFILE(min_discovery_timeout, | ||
239 | u.sta.mshcfg.min_discovery_timeout, DEC, u16); | ||
240 | #endif | ||
241 | |||
242 | |||
142 | #define DEBUGFS_ADD(name, type)\ | 243 | #define DEBUGFS_ADD(name, type)\ |
143 | sdata->debugfs.type.name = debugfs_create_file(#name, 0444,\ | 244 | sdata->debugfs.type.name = debugfs_create_file(#name, 0444,\ |
144 | sdata->debugfsdir, sdata, &name##_ops); | 245 | sdata->debugfsdir, sdata, &name##_ops); |
@@ -161,6 +262,7 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata) | |||
161 | DEBUGFS_ADD(auth_alg, sta); | 262 | DEBUGFS_ADD(auth_alg, sta); |
162 | DEBUGFS_ADD(auth_transaction, sta); | 263 | DEBUGFS_ADD(auth_transaction, sta); |
163 | DEBUGFS_ADD(flags, sta); | 264 | DEBUGFS_ADD(flags, sta); |
265 | DEBUGFS_ADD(num_beacons_sta, sta); | ||
164 | } | 266 | } |
165 | 267 | ||
166 | static void add_ap_files(struct ieee80211_sub_if_data *sdata) | 268 | static void add_ap_files(struct ieee80211_sub_if_data *sdata) |
@@ -192,12 +294,57 @@ static void add_monitor_files(struct ieee80211_sub_if_data *sdata) | |||
192 | { | 294 | { |
193 | } | 295 | } |
194 | 296 | ||
297 | #ifdef CONFIG_MAC80211_MESH | ||
298 | #define MESHSTATS_ADD(name)\ | ||
299 | sdata->mesh_stats.name = debugfs_create_file(#name, 0444,\ | ||
300 | sdata->mesh_stats_dir, sdata, &name##_ops); | ||
301 | |||
302 | static void add_mesh_stats(struct ieee80211_sub_if_data *sdata) | ||
303 | { | ||
304 | sdata->mesh_stats_dir = debugfs_create_dir("mesh_stats", | ||
305 | sdata->debugfsdir); | ||
306 | MESHSTATS_ADD(fwded_frames); | ||
307 | MESHSTATS_ADD(dropped_frames_ttl); | ||
308 | MESHSTATS_ADD(dropped_frames_no_route); | ||
309 | MESHSTATS_ADD(estab_plinks); | ||
310 | } | ||
311 | |||
312 | #define MESHPARAMS_ADD(name)\ | ||
313 | sdata->mesh_config.name = debugfs_create_file(#name, 0644,\ | ||
314 | sdata->mesh_config_dir, sdata, &name##_ops); | ||
315 | |||
316 | static void add_mesh_config(struct ieee80211_sub_if_data *sdata) | ||
317 | { | ||
318 | sdata->mesh_config_dir = debugfs_create_dir("mesh_config", | ||
319 | sdata->debugfsdir); | ||
320 | MESHPARAMS_ADD(dot11MeshMaxRetries); | ||
321 | MESHPARAMS_ADD(dot11MeshRetryTimeout); | ||
322 | MESHPARAMS_ADD(dot11MeshConfirmTimeout); | ||
323 | MESHPARAMS_ADD(dot11MeshHoldingTimeout); | ||
324 | MESHPARAMS_ADD(dot11MeshTTL); | ||
325 | MESHPARAMS_ADD(auto_open_plinks); | ||
326 | MESHPARAMS_ADD(dot11MeshMaxPeerLinks); | ||
327 | MESHPARAMS_ADD(dot11MeshHWMPactivePathTimeout); | ||
328 | MESHPARAMS_ADD(dot11MeshHWMPpreqMinInterval); | ||
329 | MESHPARAMS_ADD(dot11MeshHWMPnetDiameterTraversalTime); | ||
330 | MESHPARAMS_ADD(dot11MeshHWMPmaxPREQretries); | ||
331 | MESHPARAMS_ADD(path_refresh_time); | ||
332 | MESHPARAMS_ADD(min_discovery_timeout); | ||
333 | } | ||
334 | #endif | ||
335 | |||
195 | static void add_files(struct ieee80211_sub_if_data *sdata) | 336 | static void add_files(struct ieee80211_sub_if_data *sdata) |
196 | { | 337 | { |
197 | if (!sdata->debugfsdir) | 338 | if (!sdata->debugfsdir) |
198 | return; | 339 | return; |
199 | 340 | ||
200 | switch (sdata->vif.type) { | 341 | switch (sdata->vif.type) { |
342 | case IEEE80211_IF_TYPE_MESH_POINT: | ||
343 | #ifdef CONFIG_MAC80211_MESH | ||
344 | add_mesh_stats(sdata); | ||
345 | add_mesh_config(sdata); | ||
346 | #endif | ||
347 | /* fall through */ | ||
201 | case IEEE80211_IF_TYPE_STA: | 348 | case IEEE80211_IF_TYPE_STA: |
202 | case IEEE80211_IF_TYPE_IBSS: | 349 | case IEEE80211_IF_TYPE_IBSS: |
203 | add_sta_files(sdata); | 350 | add_sta_files(sdata); |
@@ -243,6 +390,7 @@ static void del_sta_files(struct ieee80211_sub_if_data *sdata) | |||
243 | DEBUGFS_DEL(auth_alg, sta); | 390 | DEBUGFS_DEL(auth_alg, sta); |
244 | DEBUGFS_DEL(auth_transaction, sta); | 391 | DEBUGFS_DEL(auth_transaction, sta); |
245 | DEBUGFS_DEL(flags, sta); | 392 | DEBUGFS_DEL(flags, sta); |
393 | DEBUGFS_DEL(num_beacons_sta, sta); | ||
246 | } | 394 | } |
247 | 395 | ||
248 | static void del_ap_files(struct ieee80211_sub_if_data *sdata) | 396 | static void del_ap_files(struct ieee80211_sub_if_data *sdata) |
@@ -274,12 +422,61 @@ static void del_monitor_files(struct ieee80211_sub_if_data *sdata) | |||
274 | { | 422 | { |
275 | } | 423 | } |
276 | 424 | ||
425 | #ifdef CONFIG_MAC80211_MESH | ||
426 | #define MESHSTATS_DEL(name) \ | ||
427 | do { \ | ||
428 | debugfs_remove(sdata->mesh_stats.name); \ | ||
429 | sdata->mesh_stats.name = NULL; \ | ||
430 | } while (0) | ||
431 | |||
432 | static void del_mesh_stats(struct ieee80211_sub_if_data *sdata) | ||
433 | { | ||
434 | MESHSTATS_DEL(fwded_frames); | ||
435 | MESHSTATS_DEL(dropped_frames_ttl); | ||
436 | MESHSTATS_DEL(dropped_frames_no_route); | ||
437 | MESHSTATS_DEL(estab_plinks); | ||
438 | debugfs_remove(sdata->mesh_stats_dir); | ||
439 | sdata->mesh_stats_dir = NULL; | ||
440 | } | ||
441 | |||
442 | #define MESHPARAMS_DEL(name) \ | ||
443 | do { \ | ||
444 | debugfs_remove(sdata->mesh_config.name); \ | ||
445 | sdata->mesh_config.name = NULL; \ | ||
446 | } while (0) | ||
447 | |||
448 | static void del_mesh_config(struct ieee80211_sub_if_data *sdata) | ||
449 | { | ||
450 | MESHPARAMS_DEL(dot11MeshMaxRetries); | ||
451 | MESHPARAMS_DEL(dot11MeshRetryTimeout); | ||
452 | MESHPARAMS_DEL(dot11MeshConfirmTimeout); | ||
453 | MESHPARAMS_DEL(dot11MeshHoldingTimeout); | ||
454 | MESHPARAMS_DEL(dot11MeshTTL); | ||
455 | MESHPARAMS_DEL(auto_open_plinks); | ||
456 | MESHPARAMS_DEL(dot11MeshMaxPeerLinks); | ||
457 | MESHPARAMS_DEL(dot11MeshHWMPactivePathTimeout); | ||
458 | MESHPARAMS_DEL(dot11MeshHWMPpreqMinInterval); | ||
459 | MESHPARAMS_DEL(dot11MeshHWMPnetDiameterTraversalTime); | ||
460 | MESHPARAMS_DEL(dot11MeshHWMPmaxPREQretries); | ||
461 | MESHPARAMS_DEL(path_refresh_time); | ||
462 | MESHPARAMS_DEL(min_discovery_timeout); | ||
463 | debugfs_remove(sdata->mesh_config_dir); | ||
464 | sdata->mesh_config_dir = NULL; | ||
465 | } | ||
466 | #endif | ||
467 | |||
277 | static void del_files(struct ieee80211_sub_if_data *sdata, int type) | 468 | static void del_files(struct ieee80211_sub_if_data *sdata, int type) |
278 | { | 469 | { |
279 | if (!sdata->debugfsdir) | 470 | if (!sdata->debugfsdir) |
280 | return; | 471 | return; |
281 | 472 | ||
282 | switch (type) { | 473 | switch (type) { |
474 | case IEEE80211_IF_TYPE_MESH_POINT: | ||
475 | #ifdef CONFIG_MAC80211_MESH | ||
476 | del_mesh_stats(sdata); | ||
477 | del_mesh_config(sdata); | ||
478 | #endif | ||
479 | /* fall through */ | ||
283 | case IEEE80211_IF_TYPE_STA: | 480 | case IEEE80211_IF_TYPE_STA: |
284 | case IEEE80211_IF_TYPE_IBSS: | 481 | case IEEE80211_IF_TYPE_IBSS: |
285 | del_sta_files(sdata); | 482 | del_sta_files(sdata); |