6a60077d7a6579f5d107a75be2b36d1a25cae7da
[openwrt.git] / package / d80211 / src / ieee80211_sysfs.c
1 /*
2 * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9 #include <linux/kernel.h>
10 #include <linux/device.h>
11 #include <linux/if.h>
12 #include <linux/interrupt.h>
13 #include <linux/netdevice.h>
14 #include <linux/rtnetlink.h>
15 #include <net/d80211.h>
16 #include "ieee80211_i.h"
17 #include "ieee80211_rate.h"
18
19 #define to_ieee80211_local(class) \
20 container_of(class, struct ieee80211_local, class_dev)
21 #define to_net_dev(class) \
22 container_of(class, struct net_device, class_dev)
23
24 static inline int rtnl_lock_local(struct ieee80211_local *local)
25 {
26 rtnl_lock();
27 if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED)) {
28 rtnl_unlock();
29 return -ENODEV;
30 }
31 return 0;
32 }
33
34 static const char *ieee80211_mode_str_short(int mode)
35 {
36 switch (mode) {
37 case MODE_IEEE80211A:
38 return "802.11a";
39 case MODE_IEEE80211B:
40 return "802.11b";
41 case MODE_IEEE80211G:
42 return "802.11g";
43 case MODE_ATHEROS_TURBO:
44 return "AtherosTurbo";
45 default:
46 return "UNKNOWN";
47 }
48 }
49
50 static const char *ieee80211_mode_str(int mode)
51 {
52 switch (mode) {
53 case MODE_IEEE80211A:
54 return "IEEE 802.11a";
55 case MODE_IEEE80211B:
56 return "IEEE 802.11b";
57 case MODE_IEEE80211G:
58 return "IEEE 802.11g";
59 case MODE_ATHEROS_TURBO:
60 return "Atheros Turbo (5 GHz)";
61 default:
62 return "UNKNOWN";
63 }
64 }
65
66 /* attributes in /sys/class/ieee80211/phyX/ */
67
68 static ssize_t store_add_iface(struct class_device *dev,
69 const char *buf, size_t len)
70 {
71 struct ieee80211_local *local = to_ieee80211_local(dev);
72 struct net_device *new_dev;
73 int res;
74
75 if (!capable(CAP_NET_ADMIN))
76 return -EPERM;
77 if (len > IFNAMSIZ)
78 return -EINVAL;
79 res = rtnl_lock_local(local);
80 if (res)
81 return res;
82 res = ieee80211_if_add(local->mdev, buf, 0, &new_dev);
83 if (res == 0)
84 ieee80211_if_set_type(new_dev, IEEE80211_IF_TYPE_STA);
85 rtnl_unlock();
86 return res < 0 ? res : len;
87 }
88
89 static ssize_t store_remove_iface(struct class_device *dev,
90 const char *buf, size_t len)
91 {
92 struct ieee80211_local *local = to_ieee80211_local(dev);
93 int res;
94
95 if (!capable(CAP_NET_ADMIN))
96 return -EPERM;
97 if (len > IFNAMSIZ)
98 return -EINVAL;
99 res = rtnl_lock_local(local);
100 if (res)
101 return res;
102 res = ieee80211_if_remove(local->mdev, buf, -1);
103 rtnl_unlock();
104 return res < 0 ? res : len;
105 }
106
107 static ssize_t store_rate_ctrl_alg(struct class_device *dev,
108 const char *buf, size_t len)
109 {
110 struct ieee80211_local *local = to_ieee80211_local(dev);
111 int res;
112
113 if (!capable(CAP_NET_ADMIN))
114 return -EPERM;
115 res = rtnl_lock_local(local);
116 if (res)
117 return res;
118 res = ieee80211_init_rate_ctrl_alg(local, buf);
119 rtnl_unlock();
120 return res < 0 ? res : len;
121 }
122
123 static ssize_t ieee80211_local_show(struct class_device *dev, char *buf,
124 ssize_t (*format)(struct ieee80211_local *, char *))
125 {
126 struct ieee80211_local *local = to_ieee80211_local(dev);
127 ssize_t ret = -EINVAL;
128
129 if (local->reg_state == IEEE80211_DEV_REGISTERED)
130 ret = (*format)(local, buf);
131 return ret;
132 }
133
134 #define IEEE80211_LOCAL_FMT(name, field, format_string) \
135 static ssize_t ieee80211_local_fmt_##name(struct ieee80211_local *local,\
136 char *buf) \
137 { \
138 return sprintf(buf, format_string, local->field); \
139 }
140
141 #define __IEEE80211_LOCAL_SHOW(name) \
142 static ssize_t ieee80211_local_show_##name(struct class_device *cd, \
143 char *buf) \
144 { \
145 return ieee80211_local_show(cd, buf, \
146 ieee80211_local_fmt_##name); \
147 }
148
149 #define IEEE80211_LOCAL_SHOW(name, field, format) \
150 IEEE80211_LOCAL_FMT(name, field, format "\n") \
151 __IEEE80211_LOCAL_SHOW(name)
152
153 IEEE80211_LOCAL_SHOW(channel, hw.conf.channel, "%d");
154 IEEE80211_LOCAL_SHOW(frequency, hw.conf.freq, "%d");
155 IEEE80211_LOCAL_SHOW(radar_detect, hw.conf.radar_detect, "%d");
156 IEEE80211_LOCAL_SHOW(antenna_sel, hw.conf.antenna_sel, "%d");
157 IEEE80211_LOCAL_SHOW(bridge_packets, bridge_packets, "%d");
158 IEEE80211_LOCAL_SHOW(key_tx_rx_threshold, key_tx_rx_threshold, "%d");
159 IEEE80211_LOCAL_SHOW(rts_threshold, rts_threshold, "%d");
160 IEEE80211_LOCAL_SHOW(fragmentation_threshold, fragmentation_threshold, "%d");
161 IEEE80211_LOCAL_SHOW(short_retry_limit, short_retry_limit, "%d");
162 IEEE80211_LOCAL_SHOW(long_retry_limit, long_retry_limit, "%d");
163 IEEE80211_LOCAL_SHOW(total_ps_buffered, total_ps_buffered, "%d");
164
165 static ssize_t ieee80211_local_fmt_mode(struct ieee80211_local *local,
166 char *buf)
167 {
168 return sprintf(buf, "%s\n", ieee80211_mode_str(local->hw.conf.phymode));
169 }
170 __IEEE80211_LOCAL_SHOW(mode);
171
172 static ssize_t ieee80211_local_fmt_wep_iv(struct ieee80211_local *local,
173 char *buf)
174 {
175 return sprintf(buf, "%#06x\n", local->wep_iv & 0xffffff);
176 }
177 __IEEE80211_LOCAL_SHOW(wep_iv);
178
179 static ssize_t ieee80211_local_fmt_tx_power_reduction(struct ieee80211_local
180 *local, char *buf)
181 {
182 short tx_power_reduction = local->hw.conf.tx_power_reduction;
183
184 return sprintf(buf, "%d.%d dBm\n", tx_power_reduction / 10,
185 tx_power_reduction % 10);
186 }
187 __IEEE80211_LOCAL_SHOW(tx_power_reduction);
188
189 static ssize_t ieee80211_local_fmt_modes(struct ieee80211_local *local,
190 char *buf)
191 {
192 int i;
193 struct ieee80211_hw_modes *mode;
194 char *p = buf;
195
196 /* FIXME: locking against ieee80211_update_hw? */
197 for (i = 0; i < local->hw.num_modes; i++) {
198 mode = &local->hw.modes[i];
199 p += sprintf(p, "%s\n", ieee80211_mode_str_short(mode->mode));
200 }
201 return (p - buf);
202 }
203 __IEEE80211_LOCAL_SHOW(modes);
204
205 static ssize_t ieee80211_local_fmt_rate_ctrl_alg(struct ieee80211_local *local,
206 char *buf)
207 {
208 struct rate_control_ref *ref = local->rate_ctrl;
209 if (ref)
210 return sprintf(buf, "%s\n", ref->ops->name);
211 return 0;
212 }
213 __IEEE80211_LOCAL_SHOW(rate_ctrl_alg);
214
215 static struct class_device_attribute ieee80211_class_dev_attrs[] = {
216 __ATTR(add_iface, S_IWUGO, NULL, store_add_iface),
217 __ATTR(remove_iface, S_IWUGO, NULL, store_remove_iface),
218 __ATTR(channel, S_IRUGO, ieee80211_local_show_channel, NULL),
219 __ATTR(frequency, S_IRUGO, ieee80211_local_show_frequency, NULL),
220 __ATTR(radar_detect, S_IRUGO, ieee80211_local_show_radar_detect, NULL),
221 __ATTR(antenna_sel, S_IRUGO, ieee80211_local_show_antenna_sel, NULL),
222 __ATTR(bridge_packets, S_IRUGO, ieee80211_local_show_bridge_packets, NULL),
223 __ATTR(key_tx_rx_threshold, S_IRUGO, ieee80211_local_show_key_tx_rx_threshold, NULL),
224 __ATTR(rts_threshold, S_IRUGO, ieee80211_local_show_rts_threshold, NULL),
225 __ATTR(fragmentation_threshold, S_IRUGO, ieee80211_local_show_fragmentation_threshold, NULL),
226 __ATTR(short_retry_limit, S_IRUGO, ieee80211_local_show_short_retry_limit, NULL),
227 __ATTR(long_retry_limit, S_IRUGO, ieee80211_local_show_long_retry_limit, NULL),
228 __ATTR(total_ps_buffered, S_IRUGO, ieee80211_local_show_total_ps_buffered, NULL),
229 __ATTR(mode, S_IRUGO, ieee80211_local_show_mode, NULL),
230 __ATTR(wep_iv, S_IRUGO, ieee80211_local_show_wep_iv, NULL),
231 __ATTR(tx_power_reduction, S_IRUGO, ieee80211_local_show_tx_power_reduction, NULL),
232 __ATTR(modes, S_IRUGO, ieee80211_local_show_modes, NULL),
233 __ATTR(rate_ctrl_alg, S_IRUGO | S_IWUGO, ieee80211_local_show_rate_ctrl_alg, store_rate_ctrl_alg),
234 {}
235 };
236
237 /* attributes in /sys/class/ieee80211/phyX/statistics/ */
238
239 #define IEEE80211_LOCAL_ATTR(name, field, format) \
240 IEEE80211_LOCAL_SHOW(name, field, format) \
241 static CLASS_DEVICE_ATTR(name, S_IRUGO, ieee80211_local_show_##name, NULL);
242
243 IEEE80211_LOCAL_ATTR(transmitted_fragment_count, dot11TransmittedFragmentCount, "%u");
244 IEEE80211_LOCAL_ATTR(multicast_transmitted_frame_count, dot11MulticastTransmittedFrameCount, "%u");
245 IEEE80211_LOCAL_ATTR(failed_count, dot11FailedCount, "%u");
246 IEEE80211_LOCAL_ATTR(retry_count, dot11RetryCount, "%u");
247 IEEE80211_LOCAL_ATTR(multiple_retry_count, dot11MultipleRetryCount, "%u");
248 IEEE80211_LOCAL_ATTR(frame_duplicate_count, dot11FrameDuplicateCount, "%u");
249 IEEE80211_LOCAL_ATTR(received_fragment_count, dot11ReceivedFragmentCount, "%u");
250 IEEE80211_LOCAL_ATTR(multicast_received_frame_count, dot11MulticastReceivedFrameCount, "%u");
251 IEEE80211_LOCAL_ATTR(transmitted_frame_count, dot11TransmittedFrameCount, "%u");
252 IEEE80211_LOCAL_ATTR(wep_undecryptable_count, dot11WEPUndecryptableCount, "%u");
253 IEEE80211_LOCAL_ATTR(num_scans, scan.num_scans, "%u");
254
255 #ifdef CONFIG_D80211_DEBUG_COUNTERS
256 IEEE80211_LOCAL_ATTR(tx_handlers_drop, tx_handlers_drop, "%u");
257 IEEE80211_LOCAL_ATTR(tx_handlers_queued, tx_handlers_queued, "%u");
258 IEEE80211_LOCAL_ATTR(tx_handlers_drop_unencrypted, tx_handlers_drop_unencrypted, "%u");
259 IEEE80211_LOCAL_ATTR(tx_handlers_drop_fragment, tx_handlers_drop_fragment, "%u");
260 IEEE80211_LOCAL_ATTR(tx_handlers_drop_wep, tx_handlers_drop_wep, "%u");
261 IEEE80211_LOCAL_ATTR(tx_handlers_drop_not_assoc, tx_handlers_drop_not_assoc, "%u");
262 IEEE80211_LOCAL_ATTR(tx_handlers_drop_unauth_port, tx_handlers_drop_unauth_port, "%u");
263 IEEE80211_LOCAL_ATTR(rx_handlers_drop, rx_handlers_drop, "%u");
264 IEEE80211_LOCAL_ATTR(rx_handlers_queued, rx_handlers_queued, "%u");
265 IEEE80211_LOCAL_ATTR(rx_handlers_drop_nullfunc, rx_handlers_drop_nullfunc, "%u");
266 IEEE80211_LOCAL_ATTR(rx_handlers_drop_defrag, rx_handlers_drop_defrag, "%u");
267 IEEE80211_LOCAL_ATTR(rx_handlers_drop_short, rx_handlers_drop_short, "%u");
268 IEEE80211_LOCAL_ATTR(rx_handlers_drop_passive_scan, rx_handlers_drop_passive_scan, "%u");
269 IEEE80211_LOCAL_ATTR(tx_expand_skb_head, tx_expand_skb_head, "%u");
270 IEEE80211_LOCAL_ATTR(tx_expand_skb_head_cloned, tx_expand_skb_head_cloned, "%u");
271 IEEE80211_LOCAL_ATTR(rx_expand_skb_head, rx_expand_skb_head, "%u");
272 IEEE80211_LOCAL_ATTR(rx_expand_skb_head2, rx_expand_skb_head2, "%u");
273 IEEE80211_LOCAL_ATTR(rx_handlers_fragments, rx_handlers_fragments, "%u");
274 IEEE80211_LOCAL_ATTR(tx_status_drop, tx_status_drop, "%u");
275
276 static ssize_t ieee80211_local_fmt_wme_rx_queue(struct ieee80211_local *local,
277 char *buf)
278 {
279 int i;
280 char *p = buf;
281
282 for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
283 p += sprintf(p, "%u\n", local->wme_rx_queue[i]);
284 return (p - buf);
285 }
286 __IEEE80211_LOCAL_SHOW(wme_rx_queue);
287 static CLASS_DEVICE_ATTR(wme_rx_queue, S_IRUGO,
288 ieee80211_local_show_wme_rx_queue, NULL);
289
290 static ssize_t ieee80211_local_fmt_wme_tx_queue(struct ieee80211_local *local,
291 char *buf)
292 {
293 int i;
294 char *p = buf;
295
296 for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
297 p += sprintf(p, "%u\n", local->wme_tx_queue[i]);
298 return (p - buf);
299 }
300 __IEEE80211_LOCAL_SHOW(wme_tx_queue);
301 static CLASS_DEVICE_ATTR(wme_tx_queue, S_IRUGO,
302 ieee80211_local_show_wme_tx_queue, NULL);
303 #endif
304
305 static ssize_t ieee80211_stats_show(struct class_device *dev, char *buf,
306 ssize_t (*format)(struct ieee80211_low_level_stats *, char *))
307 {
308 struct ieee80211_local *local = to_ieee80211_local(dev);
309 struct ieee80211_low_level_stats stats;
310 ssize_t ret = -EINVAL;
311
312 if (!local->ops->get_stats)
313 return -EOPNOTSUPP;
314 ret = rtnl_lock_local(local);
315 if (ret)
316 return ret;
317 ret = local->ops->get_stats(local_to_hw(local), &stats);
318 rtnl_unlock();
319 if (!ret)
320 ret = (*format)(&stats, buf);
321 return ret;
322 }
323
324 #define IEEE80211_STATS_FMT(name, field, format_string) \
325 static ssize_t ieee80211_stats_fmt_##name(struct ieee80211_low_level_stats \
326 *stats, char *buf) \
327 { \
328 return sprintf(buf, format_string, stats->field); \
329 }
330
331 #define __IEEE80211_STATS_SHOW(name) \
332 static ssize_t ieee80211_stats_show_##name(struct class_device *cd, \
333 char *buf) \
334 { \
335 return ieee80211_stats_show(cd, buf, \
336 ieee80211_stats_fmt_##name); \
337 }
338
339 #define IEEE80211_STATS_ATTR(name, field, format) \
340 IEEE80211_STATS_FMT(name, field, format "\n") \
341 __IEEE80211_STATS_SHOW(name) \
342 static CLASS_DEVICE_ATTR(name, S_IRUGO, ieee80211_stats_show_##name, NULL);
343
344 IEEE80211_STATS_ATTR(ack_failure_count, dot11ACKFailureCount, "%u");
345 IEEE80211_STATS_ATTR(rts_failure_count, dot11RTSFailureCount, "%u");
346 IEEE80211_STATS_ATTR(fcs_error_count, dot11FCSErrorCount, "%u");
347 IEEE80211_STATS_ATTR(rts_success_count, dot11RTSSuccessCount, "%u");
348
349 static struct attribute *ieee80211_stats_attrs[] = {
350 &class_device_attr_transmitted_fragment_count.attr,
351 &class_device_attr_multicast_transmitted_frame_count.attr,
352 &class_device_attr_failed_count.attr,
353 &class_device_attr_retry_count.attr,
354 &class_device_attr_multiple_retry_count.attr,
355 &class_device_attr_frame_duplicate_count.attr,
356 &class_device_attr_received_fragment_count.attr,
357 &class_device_attr_multicast_received_frame_count.attr,
358 &class_device_attr_transmitted_frame_count.attr,
359 &class_device_attr_wep_undecryptable_count.attr,
360 &class_device_attr_ack_failure_count.attr,
361 &class_device_attr_rts_failure_count.attr,
362 &class_device_attr_fcs_error_count.attr,
363 &class_device_attr_rts_success_count.attr,
364 &class_device_attr_num_scans.attr,
365 #ifdef CONFIG_D80211_DEBUG_COUNTERS
366 &class_device_attr_tx_handlers_drop.attr,
367 &class_device_attr_tx_handlers_queued.attr,
368 &class_device_attr_tx_handlers_drop_unencrypted.attr,
369 &class_device_attr_tx_handlers_drop_fragment.attr,
370 &class_device_attr_tx_handlers_drop_wep.attr,
371 &class_device_attr_tx_handlers_drop_not_assoc.attr,
372 &class_device_attr_tx_handlers_drop_unauth_port.attr,
373 &class_device_attr_rx_handlers_drop.attr,
374 &class_device_attr_rx_handlers_queued.attr,
375 &class_device_attr_rx_handlers_drop_nullfunc.attr,
376 &class_device_attr_rx_handlers_drop_defrag.attr,
377 &class_device_attr_rx_handlers_drop_short.attr,
378 &class_device_attr_rx_handlers_drop_passive_scan.attr,
379 &class_device_attr_tx_expand_skb_head.attr,
380 &class_device_attr_tx_expand_skb_head_cloned.attr,
381 &class_device_attr_rx_expand_skb_head.attr,
382 &class_device_attr_rx_expand_skb_head2.attr,
383 &class_device_attr_rx_handlers_fragments.attr,
384 &class_device_attr_tx_status_drop.attr,
385 &class_device_attr_wme_rx_queue.attr,
386 &class_device_attr_wme_tx_queue.attr,
387 #endif
388 NULL,
389 };
390
391 static struct attribute_group ieee80211_stats_group = {
392 .name = "statistics",
393 .attrs = ieee80211_stats_attrs,
394 };
395
396 /* attributes in /sys/class/net/X/ */
397
398 static ssize_t ieee80211_if_show(struct class_device *cd, char *buf,
399 ssize_t (*format)(const struct ieee80211_sub_if_data *,
400 char *))
401 {
402 struct net_device *dev = to_net_dev(cd);
403 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
404 ssize_t ret = -EINVAL;
405
406 read_lock(&dev_base_lock);
407 if (dev->reg_state == NETREG_REGISTERED) {
408 ret = (*format)(sdata, buf);
409 }
410 read_unlock(&dev_base_lock);
411 return ret;
412 }
413
414 #define IEEE80211_IF_FMT(name, field, format_string) \
415 static ssize_t ieee80211_if_fmt_##name(const struct \
416 ieee80211_sub_if_data *sdata, char *buf) \
417 { \
418 return sprintf(buf, format_string, sdata->field); \
419 }
420 #define IEEE80211_IF_FMT_DEC(name, field) \
421 IEEE80211_IF_FMT(name, field, "%d\n")
422 #define IEEE80211_IF_FMT_HEX(name, field) \
423 IEEE80211_IF_FMT(name, field, "%#x\n")
424 #define IEEE80211_IF_FMT_SIZE(name, field) \
425 IEEE80211_IF_FMT(name, field, "%zd\n")
426
427 #define IEEE80211_IF_FMT_ATOMIC(name, field) \
428 static ssize_t ieee80211_if_fmt_##name(const struct \
429 ieee80211_sub_if_data *sdata, char *buf) \
430 { \
431 return sprintf(buf, "%d\n", atomic_read(&sdata->field)); \
432 }
433
434 #define IEEE80211_IF_FMT_MAC(name, field) \
435 static ssize_t ieee80211_if_fmt_##name(const struct \
436 ieee80211_sub_if_data *sdata, char *buf) \
437 { \
438 return sprintf(buf, MAC_FMT "\n", MAC_ARG(sdata->field)); \
439 }
440
441 #define __IEEE80211_IF_SHOW(name) \
442 static ssize_t ieee80211_if_show_##name(struct class_device *cd, \
443 char *buf) \
444 { \
445 return ieee80211_if_show(cd, buf, ieee80211_if_fmt_##name); \
446 } \
447 static CLASS_DEVICE_ATTR(name, S_IRUGO, ieee80211_if_show_##name, NULL);
448
449 #define IEEE80211_IF_SHOW(name, field, format) \
450 IEEE80211_IF_FMT_##format(name, field) \
451 __IEEE80211_IF_SHOW(name)
452
453 /* common attributes */
454 IEEE80211_IF_SHOW(channel_use, channel_use, DEC);
455 IEEE80211_IF_SHOW(drop_unencrypted, drop_unencrypted, DEC);
456 IEEE80211_IF_SHOW(eapol, eapol, DEC);
457 IEEE80211_IF_SHOW(ieee8021_x, ieee802_1x, DEC);
458
459 /* STA/IBSS attributes */
460 IEEE80211_IF_SHOW(state, u.sta.state, DEC);
461 IEEE80211_IF_SHOW(bssid, u.sta.bssid, MAC);
462 IEEE80211_IF_SHOW(prev_bssid, u.sta.prev_bssid, MAC);
463 IEEE80211_IF_SHOW(ssid_len, u.sta.ssid_len, SIZE);
464 IEEE80211_IF_SHOW(aid, u.sta.aid, DEC);
465 IEEE80211_IF_SHOW(ap_capab, u.sta.ap_capab, HEX);
466 IEEE80211_IF_SHOW(capab, u.sta.capab, HEX);
467 IEEE80211_IF_SHOW(extra_ie_len, u.sta.extra_ie_len, SIZE);
468 IEEE80211_IF_SHOW(auth_tries, u.sta.auth_tries, DEC);
469 IEEE80211_IF_SHOW(assoc_tries, u.sta.assoc_tries, DEC);
470 IEEE80211_IF_SHOW(auth_algs, u.sta.auth_algs, HEX);
471 IEEE80211_IF_SHOW(auth_alg, u.sta.auth_alg, DEC);
472 IEEE80211_IF_SHOW(auth_transaction, u.sta.auth_transaction, DEC);
473
474 static ssize_t ieee80211_if_fmt_flags(const struct
475 ieee80211_sub_if_data *sdata, char *buf)
476 {
477 return sprintf(buf, "%s%s%s%s%s%s%s\n",
478 sdata->u.sta.ssid_set ? "SSID\n" : "",
479 sdata->u.sta.bssid_set ? "BSSID\n" : "",
480 sdata->u.sta.prev_bssid_set ? "prev BSSID\n" : "",
481 sdata->u.sta.authenticated ? "AUTH\n" : "",
482 sdata->u.sta.associated ? "ASSOC\n" : "",
483 sdata->u.sta.probereq_poll ? "PROBEREQ POLL\n" : "",
484 sdata->u.sta.use_protection ? "CTS prot\n" : "");
485 }
486 __IEEE80211_IF_SHOW(flags);
487
488 /* AP attributes */
489 IEEE80211_IF_SHOW(num_sta_ps, u.ap.num_sta_ps, ATOMIC);
490 IEEE80211_IF_SHOW(dtim_period, u.ap.dtim_period, DEC);
491 IEEE80211_IF_SHOW(dtim_count, u.ap.dtim_count, DEC);
492 IEEE80211_IF_SHOW(num_beacons, u.ap.num_beacons, DEC);
493 IEEE80211_IF_SHOW(force_unicast_rateidx, u.ap.force_unicast_rateidx, DEC);
494 IEEE80211_IF_SHOW(max_ratectrl_rateidx, u.ap.max_ratectrl_rateidx, DEC);
495
496 static ssize_t ieee80211_if_fmt_num_buffered_multicast(const struct
497 ieee80211_sub_if_data *sdata, char *buf)
498 {
499 return sprintf(buf, "%u\n", skb_queue_len(&sdata->u.ap.ps_bc_buf));
500 }
501 __IEEE80211_IF_SHOW(num_buffered_multicast);
502
503 static ssize_t ieee80211_if_fmt_beacon_head_len(const struct
504 ieee80211_sub_if_data *sdata, char *buf)
505 {
506 if (sdata->u.ap.beacon_head)
507 return sprintf(buf, "%d\n", sdata->u.ap.beacon_head_len);
508 return sprintf(buf, "\n");
509 }
510 __IEEE80211_IF_SHOW(beacon_head_len);
511
512 static ssize_t ieee80211_if_fmt_beacon_tail_len(const struct
513 ieee80211_sub_if_data *sdata, char *buf)
514 {
515 if (sdata->u.ap.beacon_tail)
516 return sprintf(buf, "%d\n", sdata->u.ap.beacon_tail_len);
517 return sprintf(buf, "\n");
518 }
519 __IEEE80211_IF_SHOW(beacon_tail_len);
520
521 /* WDS attributes */
522 IEEE80211_IF_SHOW(peer, u.wds.remote_addr, MAC);
523
524 /* VLAN attributes */
525 IEEE80211_IF_SHOW(vlan_id, u.vlan.id, DEC);
526
527 /* MONITOR attributes */
528 static ssize_t ieee80211_if_fmt_mode(const struct
529 ieee80211_sub_if_data *sdata, char *buf)
530 {
531 struct ieee80211_local *local = sdata->local;
532
533 return sprintf(buf, "%s\n",
534 ((local->hw.flags & IEEE80211_HW_MONITOR_DURING_OPER) ||
535 local->open_count == local->monitors) ?
536 "hard" : "soft");
537 }
538 __IEEE80211_IF_SHOW(mode);
539
540 static struct attribute *ieee80211_sta_attrs[] = {
541 &class_device_attr_channel_use.attr,
542 &class_device_attr_drop_unencrypted.attr,
543 &class_device_attr_eapol.attr,
544 &class_device_attr_ieee8021_x.attr,
545 &class_device_attr_state.attr,
546 &class_device_attr_bssid.attr,
547 &class_device_attr_prev_bssid.attr,
548 &class_device_attr_ssid_len.attr,
549 &class_device_attr_aid.attr,
550 &class_device_attr_ap_capab.attr,
551 &class_device_attr_capab.attr,
552 &class_device_attr_extra_ie_len.attr,
553 &class_device_attr_auth_tries.attr,
554 &class_device_attr_assoc_tries.attr,
555 &class_device_attr_auth_algs.attr,
556 &class_device_attr_auth_alg.attr,
557 &class_device_attr_auth_transaction.attr,
558 &class_device_attr_flags.attr,
559 NULL
560 };
561
562 static struct attribute *ieee80211_ap_attrs[] = {
563 &class_device_attr_channel_use.attr,
564 &class_device_attr_drop_unencrypted.attr,
565 &class_device_attr_eapol.attr,
566 &class_device_attr_ieee8021_x.attr,
567 &class_device_attr_num_sta_ps.attr,
568 &class_device_attr_dtim_period.attr,
569 &class_device_attr_dtim_count.attr,
570 &class_device_attr_num_beacons.attr,
571 &class_device_attr_force_unicast_rateidx.attr,
572 &class_device_attr_max_ratectrl_rateidx.attr,
573 &class_device_attr_num_buffered_multicast.attr,
574 &class_device_attr_beacon_head_len.attr,
575 &class_device_attr_beacon_tail_len.attr,
576 NULL
577 };
578
579 static struct attribute *ieee80211_wds_attrs[] = {
580 &class_device_attr_channel_use.attr,
581 &class_device_attr_drop_unencrypted.attr,
582 &class_device_attr_eapol.attr,
583 &class_device_attr_ieee8021_x.attr,
584 &class_device_attr_peer.attr,
585 NULL
586 };
587
588 static struct attribute *ieee80211_vlan_attrs[] = {
589 &class_device_attr_channel_use.attr,
590 &class_device_attr_drop_unencrypted.attr,
591 &class_device_attr_eapol.attr,
592 &class_device_attr_ieee8021_x.attr,
593 &class_device_attr_vlan_id.attr,
594 NULL
595 };
596
597 static struct attribute *ieee80211_monitor_attrs[] = {
598 &class_device_attr_mode.attr,
599 NULL
600 };
601
602 static struct attribute_group ieee80211_sta_group = {
603 .name = "sta",
604 .attrs = ieee80211_sta_attrs,
605 };
606
607 static struct attribute_group ieee80211_ap_group = {
608 .name = "ap",
609 .attrs = ieee80211_ap_attrs,
610 };
611
612 static struct attribute_group ieee80211_wds_group = {
613 .name = "wds",
614 .attrs = ieee80211_wds_attrs,
615 };
616
617 static struct attribute_group ieee80211_vlan_group = {
618 .name = "vlan",
619 .attrs = ieee80211_vlan_attrs,
620 };
621
622 static struct attribute_group ieee80211_monitor_group = {
623 .name = "monitor",
624 .attrs = ieee80211_monitor_attrs,
625 };
626
627 /* /sys/class/ieee80211/phyX functions */
628
629 static void ieee80211_class_dev_release(struct class_device *dev)
630 {
631 ieee80211_release_hw(to_ieee80211_local(dev));
632 }
633
634 #ifdef CONFIG_HOTPLUG
635 static int ieee80211_uevent(struct class_device *cd, char **envp,
636 int num_envp, char *buf, int size)
637 {
638 struct ieee80211_local *local = to_ieee80211_local(cd);
639
640 if (num_envp < 2)
641 return -ENOMEM;
642 envp[0] = buf;
643 if (snprintf(buf, size, "IEEE80211_DEV=phy%d",
644 local->hw.index) + 1 >= size)
645 return -ENOMEM;
646 envp[1] = NULL;
647 return 0;
648 }
649 #endif
650
651 static struct class ieee80211_class = {
652 .name = "ieee80211",
653 .class_dev_attrs = ieee80211_class_dev_attrs,
654 .release = ieee80211_class_dev_release,
655 #ifdef CONFIG_HOTPLUG
656 .uevent = ieee80211_uevent,
657 #endif
658 };
659
660 void ieee80211_dev_sysfs_init(struct ieee80211_local *local)
661 {
662 local->class_dev.class = &ieee80211_class;
663 local->class_dev.class_data = local;
664 class_device_initialize(&local->class_dev);
665 }
666
667 void ieee80211_dev_sysfs_put(struct ieee80211_local *local)
668 {
669 class_device_put(&local->class_dev);
670 }
671
672 int ieee80211_dev_sysfs_add(struct ieee80211_local *local)
673 {
674 int res;
675
676 snprintf(local->class_dev.class_id, BUS_ID_SIZE,
677 "phy%d", local->hw.index);
678 res = class_device_add(&local->class_dev);
679 if (res)
680 return res;
681 res = sysfs_create_group(&local->class_dev.kobj,
682 &ieee80211_stats_group);
683 if (res)
684 class_device_del(&local->class_dev);
685 return res;
686 }
687
688 void ieee80211_dev_sysfs_del(struct ieee80211_local *local)
689 {
690 sysfs_remove_group(&local->class_dev.kobj, &ieee80211_stats_group);
691 class_device_del(&local->class_dev);
692 }
693
694 /* /sys/class/net/X functions */
695
696 static void __ieee80211_remove_if_group(struct kobject *kobj,
697 struct ieee80211_sub_if_data *sdata)
698 {
699 if (sdata->sysfs_group) {
700 sysfs_remove_group(kobj, sdata->sysfs_group);
701 sdata->sysfs_group = NULL;
702 }
703 }
704
705 static inline void ieee80211_remove_if_group(struct kobject *kobj,
706 struct net_device *dev)
707 {
708 __ieee80211_remove_if_group(kobj, IEEE80211_DEV_TO_SUB_IF(dev));
709 }
710
711 static int ieee80211_add_if_group(struct kobject *kobj,
712 struct net_device *dev)
713 {
714 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
715 int res = 0;
716
717 __ieee80211_remove_if_group(kobj, sdata);
718 switch (sdata->type) {
719 case IEEE80211_IF_TYPE_STA:
720 sdata->sysfs_group = &ieee80211_sta_group;
721 break;
722 case IEEE80211_IF_TYPE_AP:
723 sdata->sysfs_group = &ieee80211_ap_group;
724 break;
725 case IEEE80211_IF_TYPE_WDS:
726 sdata->sysfs_group = &ieee80211_wds_group;
727 break;
728 case IEEE80211_IF_TYPE_VLAN:
729 sdata->sysfs_group = &ieee80211_vlan_group;
730 break;
731 case IEEE80211_IF_TYPE_MNTR:
732 sdata->sysfs_group = &ieee80211_monitor_group;
733 break;
734 default:
735 goto out;
736 }
737 res = sysfs_create_group(kobj, sdata->sysfs_group);
738 if (res)
739 sdata->sysfs_group = NULL;
740 out:
741 return res;
742 }
743
744 int ieee80211_sysfs_change_if_type(struct net_device *dev)
745 {
746 return ieee80211_add_if_group(&dev->class_dev.kobj, dev);
747 }
748
749 int ieee80211_sysfs_add_netdevice(struct net_device *dev)
750 {
751 struct ieee80211_local *local = dev->ieee80211_ptr;
752 int res;
753
754 res = sysfs_create_link(&dev->class_dev.kobj, &local->class_dev.kobj,
755 "hw");
756 if (res)
757 goto err_out;
758 res = ieee80211_add_if_group(&dev->class_dev.kobj, dev);
759 if (res)
760 goto err_link;
761 res = ieee80211_key_kset_sysfs_register(IEEE80211_DEV_TO_SUB_IF(dev));
762 return res;
763
764 err_link:
765 sysfs_remove_link(&dev->class_dev.kobj, "hw");
766 err_out:
767 return res;
768 }
769
770 void ieee80211_sysfs_remove_netdevice(struct net_device *dev)
771 {
772 ieee80211_key_kset_sysfs_unregister(IEEE80211_DEV_TO_SUB_IF(dev));
773 ieee80211_remove_if_group(&dev->class_dev.kobj, dev);
774 sysfs_remove_link(&dev->class_dev.kobj, "hw");
775 }
776
777 /* general module functions */
778
779 int ieee80211_sysfs_init(void)
780 {
781 return class_register(&ieee80211_class);
782 }
783
784 void ieee80211_sysfs_deinit(void)
785 {
786 class_unregister(&ieee80211_class);
787 }
This page took 0.095721 seconds and 3 git commands to generate.