fix compat hacks for init_work
[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 struct ieee80211_hw_mode *mode;
193 char *p = buf;
194
195 /* FIXME: Locking? Could register a mode in the meantime. */
196 list_for_each_entry(mode, &local->modes_list, list)
197 p += sprintf(p, "%s\n", ieee80211_mode_str_short(mode->mode));
198
199 return (p - buf);
200 }
201 __IEEE80211_LOCAL_SHOW(modes);
202
203 static ssize_t ieee80211_local_fmt_rate_ctrl_alg(struct ieee80211_local *local,
204 char *buf)
205 {
206 struct rate_control_ref *ref = local->rate_ctrl;
207 if (ref)
208 return sprintf(buf, "%s\n", ref->ops->name);
209 return 0;
210 }
211 __IEEE80211_LOCAL_SHOW(rate_ctrl_alg);
212
213 static struct class_device_attribute ieee80211_class_dev_attrs[] = {
214 __ATTR(add_iface, S_IWUGO, NULL, store_add_iface),
215 __ATTR(remove_iface, S_IWUGO, NULL, store_remove_iface),
216 __ATTR(channel, S_IRUGO, ieee80211_local_show_channel, NULL),
217 __ATTR(frequency, S_IRUGO, ieee80211_local_show_frequency, NULL),
218 __ATTR(radar_detect, S_IRUGO, ieee80211_local_show_radar_detect, NULL),
219 __ATTR(antenna_sel, S_IRUGO, ieee80211_local_show_antenna_sel, NULL),
220 __ATTR(bridge_packets, S_IRUGO, ieee80211_local_show_bridge_packets, NULL),
221 __ATTR(key_tx_rx_threshold, S_IRUGO, ieee80211_local_show_key_tx_rx_threshold, NULL),
222 __ATTR(rts_threshold, S_IRUGO, ieee80211_local_show_rts_threshold, NULL),
223 __ATTR(fragmentation_threshold, S_IRUGO, ieee80211_local_show_fragmentation_threshold, NULL),
224 __ATTR(short_retry_limit, S_IRUGO, ieee80211_local_show_short_retry_limit, NULL),
225 __ATTR(long_retry_limit, S_IRUGO, ieee80211_local_show_long_retry_limit, NULL),
226 __ATTR(total_ps_buffered, S_IRUGO, ieee80211_local_show_total_ps_buffered, NULL),
227 __ATTR(mode, S_IRUGO, ieee80211_local_show_mode, NULL),
228 __ATTR(wep_iv, S_IRUGO, ieee80211_local_show_wep_iv, NULL),
229 __ATTR(tx_power_reduction, S_IRUGO, ieee80211_local_show_tx_power_reduction, NULL),
230 __ATTR(modes, S_IRUGO, ieee80211_local_show_modes, NULL),
231 __ATTR(rate_ctrl_alg, S_IRUGO | S_IWUGO, ieee80211_local_show_rate_ctrl_alg, store_rate_ctrl_alg),
232 {}
233 };
234
235 /* attributes in /sys/class/ieee80211/phyX/statistics/ */
236
237 #define IEEE80211_LOCAL_ATTR(name, field, format) \
238 IEEE80211_LOCAL_SHOW(name, field, format) \
239 static CLASS_DEVICE_ATTR(name, S_IRUGO, ieee80211_local_show_##name, NULL);
240
241 IEEE80211_LOCAL_ATTR(transmitted_fragment_count, dot11TransmittedFragmentCount, "%u");
242 IEEE80211_LOCAL_ATTR(multicast_transmitted_frame_count, dot11MulticastTransmittedFrameCount, "%u");
243 IEEE80211_LOCAL_ATTR(failed_count, dot11FailedCount, "%u");
244 IEEE80211_LOCAL_ATTR(retry_count, dot11RetryCount, "%u");
245 IEEE80211_LOCAL_ATTR(multiple_retry_count, dot11MultipleRetryCount, "%u");
246 IEEE80211_LOCAL_ATTR(frame_duplicate_count, dot11FrameDuplicateCount, "%u");
247 IEEE80211_LOCAL_ATTR(received_fragment_count, dot11ReceivedFragmentCount, "%u");
248 IEEE80211_LOCAL_ATTR(multicast_received_frame_count, dot11MulticastReceivedFrameCount, "%u");
249 IEEE80211_LOCAL_ATTR(transmitted_frame_count, dot11TransmittedFrameCount, "%u");
250 IEEE80211_LOCAL_ATTR(wep_undecryptable_count, dot11WEPUndecryptableCount, "%u");
251 IEEE80211_LOCAL_ATTR(num_scans, scan.num_scans, "%u");
252
253 #ifdef CONFIG_D80211_DEBUG_COUNTERS
254 IEEE80211_LOCAL_ATTR(tx_handlers_drop, tx_handlers_drop, "%u");
255 IEEE80211_LOCAL_ATTR(tx_handlers_queued, tx_handlers_queued, "%u");
256 IEEE80211_LOCAL_ATTR(tx_handlers_drop_unencrypted, tx_handlers_drop_unencrypted, "%u");
257 IEEE80211_LOCAL_ATTR(tx_handlers_drop_fragment, tx_handlers_drop_fragment, "%u");
258 IEEE80211_LOCAL_ATTR(tx_handlers_drop_wep, tx_handlers_drop_wep, "%u");
259 IEEE80211_LOCAL_ATTR(tx_handlers_drop_not_assoc, tx_handlers_drop_not_assoc, "%u");
260 IEEE80211_LOCAL_ATTR(tx_handlers_drop_unauth_port, tx_handlers_drop_unauth_port, "%u");
261 IEEE80211_LOCAL_ATTR(rx_handlers_drop, rx_handlers_drop, "%u");
262 IEEE80211_LOCAL_ATTR(rx_handlers_queued, rx_handlers_queued, "%u");
263 IEEE80211_LOCAL_ATTR(rx_handlers_drop_nullfunc, rx_handlers_drop_nullfunc, "%u");
264 IEEE80211_LOCAL_ATTR(rx_handlers_drop_defrag, rx_handlers_drop_defrag, "%u");
265 IEEE80211_LOCAL_ATTR(rx_handlers_drop_short, rx_handlers_drop_short, "%u");
266 IEEE80211_LOCAL_ATTR(rx_handlers_drop_passive_scan, rx_handlers_drop_passive_scan, "%u");
267 IEEE80211_LOCAL_ATTR(tx_expand_skb_head, tx_expand_skb_head, "%u");
268 IEEE80211_LOCAL_ATTR(tx_expand_skb_head_cloned, tx_expand_skb_head_cloned, "%u");
269 IEEE80211_LOCAL_ATTR(rx_expand_skb_head, rx_expand_skb_head, "%u");
270 IEEE80211_LOCAL_ATTR(rx_expand_skb_head2, rx_expand_skb_head2, "%u");
271 IEEE80211_LOCAL_ATTR(rx_handlers_fragments, rx_handlers_fragments, "%u");
272 IEEE80211_LOCAL_ATTR(tx_status_drop, tx_status_drop, "%u");
273
274 static ssize_t ieee80211_local_fmt_wme_rx_queue(struct ieee80211_local *local,
275 char *buf)
276 {
277 int i;
278 char *p = buf;
279
280 for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
281 p += sprintf(p, "%u\n", local->wme_rx_queue[i]);
282 return (p - buf);
283 }
284 __IEEE80211_LOCAL_SHOW(wme_rx_queue);
285 static CLASS_DEVICE_ATTR(wme_rx_queue, S_IRUGO,
286 ieee80211_local_show_wme_rx_queue, NULL);
287
288 static ssize_t ieee80211_local_fmt_wme_tx_queue(struct ieee80211_local *local,
289 char *buf)
290 {
291 int i;
292 char *p = buf;
293
294 for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
295 p += sprintf(p, "%u\n", local->wme_tx_queue[i]);
296 return (p - buf);
297 }
298 __IEEE80211_LOCAL_SHOW(wme_tx_queue);
299 static CLASS_DEVICE_ATTR(wme_tx_queue, S_IRUGO,
300 ieee80211_local_show_wme_tx_queue, NULL);
301 #endif
302
303 static ssize_t ieee80211_stats_show(struct class_device *dev, char *buf,
304 ssize_t (*format)(struct ieee80211_low_level_stats *, char *))
305 {
306 struct ieee80211_local *local = to_ieee80211_local(dev);
307 struct ieee80211_low_level_stats stats;
308 ssize_t ret = -EINVAL;
309
310 if (!local->ops->get_stats)
311 return -EOPNOTSUPP;
312 ret = rtnl_lock_local(local);
313 if (ret)
314 return ret;
315 ret = local->ops->get_stats(local_to_hw(local), &stats);
316 rtnl_unlock();
317 if (!ret)
318 ret = (*format)(&stats, buf);
319 return ret;
320 }
321
322 #define IEEE80211_STATS_FMT(name, field, format_string) \
323 static ssize_t ieee80211_stats_fmt_##name(struct ieee80211_low_level_stats \
324 *stats, char *buf) \
325 { \
326 return sprintf(buf, format_string, stats->field); \
327 }
328
329 #define __IEEE80211_STATS_SHOW(name) \
330 static ssize_t ieee80211_stats_show_##name(struct class_device *cd, \
331 char *buf) \
332 { \
333 return ieee80211_stats_show(cd, buf, \
334 ieee80211_stats_fmt_##name); \
335 }
336
337 #define IEEE80211_STATS_ATTR(name, field, format) \
338 IEEE80211_STATS_FMT(name, field, format "\n") \
339 __IEEE80211_STATS_SHOW(name) \
340 static CLASS_DEVICE_ATTR(name, S_IRUGO, ieee80211_stats_show_##name, NULL);
341
342 IEEE80211_STATS_ATTR(ack_failure_count, dot11ACKFailureCount, "%u");
343 IEEE80211_STATS_ATTR(rts_failure_count, dot11RTSFailureCount, "%u");
344 IEEE80211_STATS_ATTR(fcs_error_count, dot11FCSErrorCount, "%u");
345 IEEE80211_STATS_ATTR(rts_success_count, dot11RTSSuccessCount, "%u");
346
347 static struct attribute *ieee80211_stats_attrs[] = {
348 &class_device_attr_transmitted_fragment_count.attr,
349 &class_device_attr_multicast_transmitted_frame_count.attr,
350 &class_device_attr_failed_count.attr,
351 &class_device_attr_retry_count.attr,
352 &class_device_attr_multiple_retry_count.attr,
353 &class_device_attr_frame_duplicate_count.attr,
354 &class_device_attr_received_fragment_count.attr,
355 &class_device_attr_multicast_received_frame_count.attr,
356 &class_device_attr_transmitted_frame_count.attr,
357 &class_device_attr_wep_undecryptable_count.attr,
358 &class_device_attr_ack_failure_count.attr,
359 &class_device_attr_rts_failure_count.attr,
360 &class_device_attr_fcs_error_count.attr,
361 &class_device_attr_rts_success_count.attr,
362 &class_device_attr_num_scans.attr,
363 #ifdef CONFIG_D80211_DEBUG_COUNTERS
364 &class_device_attr_tx_handlers_drop.attr,
365 &class_device_attr_tx_handlers_queued.attr,
366 &class_device_attr_tx_handlers_drop_unencrypted.attr,
367 &class_device_attr_tx_handlers_drop_fragment.attr,
368 &class_device_attr_tx_handlers_drop_wep.attr,
369 &class_device_attr_tx_handlers_drop_not_assoc.attr,
370 &class_device_attr_tx_handlers_drop_unauth_port.attr,
371 &class_device_attr_rx_handlers_drop.attr,
372 &class_device_attr_rx_handlers_queued.attr,
373 &class_device_attr_rx_handlers_drop_nullfunc.attr,
374 &class_device_attr_rx_handlers_drop_defrag.attr,
375 &class_device_attr_rx_handlers_drop_short.attr,
376 &class_device_attr_rx_handlers_drop_passive_scan.attr,
377 &class_device_attr_tx_expand_skb_head.attr,
378 &class_device_attr_tx_expand_skb_head_cloned.attr,
379 &class_device_attr_rx_expand_skb_head.attr,
380 &class_device_attr_rx_expand_skb_head2.attr,
381 &class_device_attr_rx_handlers_fragments.attr,
382 &class_device_attr_tx_status_drop.attr,
383 &class_device_attr_wme_rx_queue.attr,
384 &class_device_attr_wme_tx_queue.attr,
385 #endif
386 NULL,
387 };
388
389 static struct attribute_group ieee80211_stats_group = {
390 .name = "statistics",
391 .attrs = ieee80211_stats_attrs,
392 };
393
394 /* attributes in /sys/class/net/X/ */
395
396 static ssize_t ieee80211_if_show(struct class_device *cd, char *buf,
397 ssize_t (*format)(const struct ieee80211_sub_if_data *,
398 char *))
399 {
400 struct net_device *dev = to_net_dev(cd);
401 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
402 ssize_t ret = -EINVAL;
403
404 read_lock(&dev_base_lock);
405 if (dev->reg_state == NETREG_REGISTERED) {
406 ret = (*format)(sdata, buf);
407 }
408 read_unlock(&dev_base_lock);
409 return ret;
410 }
411
412 #define IEEE80211_IF_FMT(name, field, format_string) \
413 static ssize_t ieee80211_if_fmt_##name(const struct \
414 ieee80211_sub_if_data *sdata, char *buf) \
415 { \
416 return sprintf(buf, format_string, sdata->field); \
417 }
418 #define IEEE80211_IF_FMT_DEC(name, field) \
419 IEEE80211_IF_FMT(name, field, "%d\n")
420 #define IEEE80211_IF_FMT_HEX(name, field) \
421 IEEE80211_IF_FMT(name, field, "%#x\n")
422 #define IEEE80211_IF_FMT_SIZE(name, field) \
423 IEEE80211_IF_FMT(name, field, "%zd\n")
424
425 #define IEEE80211_IF_FMT_ATOMIC(name, field) \
426 static ssize_t ieee80211_if_fmt_##name(const struct \
427 ieee80211_sub_if_data *sdata, char *buf) \
428 { \
429 return sprintf(buf, "%d\n", atomic_read(&sdata->field)); \
430 }
431
432 #define IEEE80211_IF_FMT_MAC(name, field) \
433 static ssize_t ieee80211_if_fmt_##name(const struct \
434 ieee80211_sub_if_data *sdata, char *buf) \
435 { \
436 return sprintf(buf, MAC_FMT "\n", MAC_ARG(sdata->field)); \
437 }
438
439 #define __IEEE80211_IF_SHOW(name) \
440 static ssize_t ieee80211_if_show_##name(struct class_device *cd, \
441 char *buf) \
442 { \
443 return ieee80211_if_show(cd, buf, ieee80211_if_fmt_##name); \
444 } \
445 static CLASS_DEVICE_ATTR(name, S_IRUGO, ieee80211_if_show_##name, NULL);
446
447 #define IEEE80211_IF_SHOW(name, field, format) \
448 IEEE80211_IF_FMT_##format(name, field) \
449 __IEEE80211_IF_SHOW(name)
450
451 /* common attributes */
452 IEEE80211_IF_SHOW(channel_use, channel_use, DEC);
453 IEEE80211_IF_SHOW(drop_unencrypted, drop_unencrypted, DEC);
454 IEEE80211_IF_SHOW(eapol, eapol, DEC);
455 IEEE80211_IF_SHOW(ieee8021_x, ieee802_1x, DEC);
456
457 /* STA/IBSS attributes */
458 IEEE80211_IF_SHOW(state, u.sta.state, DEC);
459 IEEE80211_IF_SHOW(bssid, u.sta.bssid, MAC);
460 IEEE80211_IF_SHOW(prev_bssid, u.sta.prev_bssid, MAC);
461 IEEE80211_IF_SHOW(ssid_len, u.sta.ssid_len, SIZE);
462 IEEE80211_IF_SHOW(aid, u.sta.aid, DEC);
463 IEEE80211_IF_SHOW(ap_capab, u.sta.ap_capab, HEX);
464 IEEE80211_IF_SHOW(capab, u.sta.capab, HEX);
465 IEEE80211_IF_SHOW(extra_ie_len, u.sta.extra_ie_len, SIZE);
466 IEEE80211_IF_SHOW(auth_tries, u.sta.auth_tries, DEC);
467 IEEE80211_IF_SHOW(assoc_tries, u.sta.assoc_tries, DEC);
468 IEEE80211_IF_SHOW(auth_algs, u.sta.auth_algs, HEX);
469 IEEE80211_IF_SHOW(auth_alg, u.sta.auth_alg, DEC);
470 IEEE80211_IF_SHOW(auth_transaction, u.sta.auth_transaction, DEC);
471
472 static ssize_t ieee80211_if_fmt_flags(const struct
473 ieee80211_sub_if_data *sdata, char *buf)
474 {
475 return sprintf(buf, "%s%s%s%s%s%s%s\n",
476 sdata->u.sta.ssid_set ? "SSID\n" : "",
477 sdata->u.sta.bssid_set ? "BSSID\n" : "",
478 sdata->u.sta.prev_bssid_set ? "prev BSSID\n" : "",
479 sdata->u.sta.authenticated ? "AUTH\n" : "",
480 sdata->u.sta.associated ? "ASSOC\n" : "",
481 sdata->u.sta.probereq_poll ? "PROBEREQ POLL\n" : "",
482 sdata->u.sta.use_protection ? "CTS prot\n" : "");
483 }
484 __IEEE80211_IF_SHOW(flags);
485
486 /* AP attributes */
487 IEEE80211_IF_SHOW(num_sta_ps, u.ap.num_sta_ps, ATOMIC);
488 IEEE80211_IF_SHOW(dtim_period, u.ap.dtim_period, DEC);
489 IEEE80211_IF_SHOW(dtim_count, u.ap.dtim_count, DEC);
490 IEEE80211_IF_SHOW(num_beacons, u.ap.num_beacons, DEC);
491 IEEE80211_IF_SHOW(force_unicast_rateidx, u.ap.force_unicast_rateidx, DEC);
492 IEEE80211_IF_SHOW(max_ratectrl_rateidx, u.ap.max_ratectrl_rateidx, DEC);
493
494 static ssize_t ieee80211_if_fmt_num_buffered_multicast(const struct
495 ieee80211_sub_if_data *sdata, char *buf)
496 {
497 return sprintf(buf, "%u\n", skb_queue_len(&sdata->u.ap.ps_bc_buf));
498 }
499 __IEEE80211_IF_SHOW(num_buffered_multicast);
500
501 static ssize_t ieee80211_if_fmt_beacon_head_len(const struct
502 ieee80211_sub_if_data *sdata, char *buf)
503 {
504 if (sdata->u.ap.beacon_head)
505 return sprintf(buf, "%d\n", sdata->u.ap.beacon_head_len);
506 return sprintf(buf, "\n");
507 }
508 __IEEE80211_IF_SHOW(beacon_head_len);
509
510 static ssize_t ieee80211_if_fmt_beacon_tail_len(const struct
511 ieee80211_sub_if_data *sdata, char *buf)
512 {
513 if (sdata->u.ap.beacon_tail)
514 return sprintf(buf, "%d\n", sdata->u.ap.beacon_tail_len);
515 return sprintf(buf, "\n");
516 }
517 __IEEE80211_IF_SHOW(beacon_tail_len);
518
519 /* WDS attributes */
520 IEEE80211_IF_SHOW(peer, u.wds.remote_addr, MAC);
521
522 /* VLAN attributes */
523 IEEE80211_IF_SHOW(vlan_id, u.vlan.id, DEC);
524
525 /* MONITOR attributes */
526 static ssize_t ieee80211_if_fmt_mode(const struct
527 ieee80211_sub_if_data *sdata, char *buf)
528 {
529 struct ieee80211_local *local = sdata->local;
530
531 return sprintf(buf, "%s\n",
532 ((local->hw.flags & IEEE80211_HW_MONITOR_DURING_OPER) ||
533 local->open_count == local->monitors) ?
534 "hard" : "soft");
535 }
536 __IEEE80211_IF_SHOW(mode);
537
538 static struct attribute *ieee80211_sta_attrs[] = {
539 &class_device_attr_channel_use.attr,
540 &class_device_attr_drop_unencrypted.attr,
541 &class_device_attr_eapol.attr,
542 &class_device_attr_ieee8021_x.attr,
543 &class_device_attr_state.attr,
544 &class_device_attr_bssid.attr,
545 &class_device_attr_prev_bssid.attr,
546 &class_device_attr_ssid_len.attr,
547 &class_device_attr_aid.attr,
548 &class_device_attr_ap_capab.attr,
549 &class_device_attr_capab.attr,
550 &class_device_attr_extra_ie_len.attr,
551 &class_device_attr_auth_tries.attr,
552 &class_device_attr_assoc_tries.attr,
553 &class_device_attr_auth_algs.attr,
554 &class_device_attr_auth_alg.attr,
555 &class_device_attr_auth_transaction.attr,
556 &class_device_attr_flags.attr,
557 NULL
558 };
559
560 static struct attribute *ieee80211_ap_attrs[] = {
561 &class_device_attr_channel_use.attr,
562 &class_device_attr_drop_unencrypted.attr,
563 &class_device_attr_eapol.attr,
564 &class_device_attr_ieee8021_x.attr,
565 &class_device_attr_num_sta_ps.attr,
566 &class_device_attr_dtim_period.attr,
567 &class_device_attr_dtim_count.attr,
568 &class_device_attr_num_beacons.attr,
569 &class_device_attr_force_unicast_rateidx.attr,
570 &class_device_attr_max_ratectrl_rateidx.attr,
571 &class_device_attr_num_buffered_multicast.attr,
572 &class_device_attr_beacon_head_len.attr,
573 &class_device_attr_beacon_tail_len.attr,
574 NULL
575 };
576
577 static struct attribute *ieee80211_wds_attrs[] = {
578 &class_device_attr_channel_use.attr,
579 &class_device_attr_drop_unencrypted.attr,
580 &class_device_attr_eapol.attr,
581 &class_device_attr_ieee8021_x.attr,
582 &class_device_attr_peer.attr,
583 NULL
584 };
585
586 static struct attribute *ieee80211_vlan_attrs[] = {
587 &class_device_attr_channel_use.attr,
588 &class_device_attr_drop_unencrypted.attr,
589 &class_device_attr_eapol.attr,
590 &class_device_attr_ieee8021_x.attr,
591 &class_device_attr_vlan_id.attr,
592 NULL
593 };
594
595 static struct attribute *ieee80211_monitor_attrs[] = {
596 &class_device_attr_mode.attr,
597 NULL
598 };
599
600 static struct attribute_group ieee80211_sta_group = {
601 .name = "sta",
602 .attrs = ieee80211_sta_attrs,
603 };
604
605 static struct attribute_group ieee80211_ap_group = {
606 .name = "ap",
607 .attrs = ieee80211_ap_attrs,
608 };
609
610 static struct attribute_group ieee80211_wds_group = {
611 .name = "wds",
612 .attrs = ieee80211_wds_attrs,
613 };
614
615 static struct attribute_group ieee80211_vlan_group = {
616 .name = "vlan",
617 .attrs = ieee80211_vlan_attrs,
618 };
619
620 static struct attribute_group ieee80211_monitor_group = {
621 .name = "monitor",
622 .attrs = ieee80211_monitor_attrs,
623 };
624
625 /* /sys/class/ieee80211/phyX functions */
626
627 static void ieee80211_class_dev_release(struct class_device *dev)
628 {
629 ieee80211_release_hw(to_ieee80211_local(dev));
630 }
631
632 #ifdef CONFIG_HOTPLUG
633 static int ieee80211_uevent(struct class_device *cd, char **envp,
634 int num_envp, char *buf, int size)
635 {
636 struct ieee80211_local *local = to_ieee80211_local(cd);
637
638 if (num_envp < 2)
639 return -ENOMEM;
640 envp[0] = buf;
641 if (snprintf(buf, size, "IEEE80211_DEV=phy%d",
642 local->hw.index) + 1 >= size)
643 return -ENOMEM;
644 envp[1] = NULL;
645 return 0;
646 }
647 #endif
648
649 static struct class ieee80211_class = {
650 .name = "ieee80211",
651 .class_dev_attrs = ieee80211_class_dev_attrs,
652 .release = ieee80211_class_dev_release,
653 #ifdef CONFIG_HOTPLUG
654 .uevent = ieee80211_uevent,
655 #endif
656 };
657
658 void ieee80211_dev_sysfs_init(struct ieee80211_local *local)
659 {
660 local->class_dev.class = &ieee80211_class;
661 local->class_dev.class_data = local;
662 class_device_initialize(&local->class_dev);
663 }
664
665 void ieee80211_dev_sysfs_put(struct ieee80211_local *local)
666 {
667 class_device_put(&local->class_dev);
668 }
669
670 int ieee80211_dev_sysfs_add(struct ieee80211_local *local)
671 {
672 int res;
673
674 snprintf(local->class_dev.class_id, BUS_ID_SIZE,
675 "phy%d", local->hw.index);
676 res = class_device_add(&local->class_dev);
677 if (res)
678 return res;
679 res = sysfs_create_group(&local->class_dev.kobj,
680 &ieee80211_stats_group);
681 if (res)
682 class_device_del(&local->class_dev);
683 return res;
684 }
685
686 void ieee80211_dev_sysfs_del(struct ieee80211_local *local)
687 {
688 sysfs_remove_group(&local->class_dev.kobj, &ieee80211_stats_group);
689 class_device_del(&local->class_dev);
690 }
691
692 /* /sys/class/net/X functions */
693
694 static void __ieee80211_remove_if_group(struct kobject *kobj,
695 struct ieee80211_sub_if_data *sdata)
696 {
697 if (sdata->sysfs_group) {
698 sysfs_remove_group(kobj, sdata->sysfs_group);
699 sdata->sysfs_group = NULL;
700 }
701 }
702
703 static inline void ieee80211_remove_if_group(struct kobject *kobj,
704 struct net_device *dev)
705 {
706 __ieee80211_remove_if_group(kobj, IEEE80211_DEV_TO_SUB_IF(dev));
707 }
708
709 static int ieee80211_add_if_group(struct kobject *kobj,
710 struct net_device *dev)
711 {
712 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
713 int res = 0;
714
715 __ieee80211_remove_if_group(kobj, sdata);
716 switch (sdata->type) {
717 case IEEE80211_IF_TYPE_STA:
718 sdata->sysfs_group = &ieee80211_sta_group;
719 break;
720 case IEEE80211_IF_TYPE_AP:
721 sdata->sysfs_group = &ieee80211_ap_group;
722 break;
723 case IEEE80211_IF_TYPE_WDS:
724 sdata->sysfs_group = &ieee80211_wds_group;
725 break;
726 case IEEE80211_IF_TYPE_VLAN:
727 sdata->sysfs_group = &ieee80211_vlan_group;
728 break;
729 case IEEE80211_IF_TYPE_MNTR:
730 sdata->sysfs_group = &ieee80211_monitor_group;
731 break;
732 default:
733 goto out;
734 }
735 res = sysfs_create_group(kobj, sdata->sysfs_group);
736 if (res)
737 sdata->sysfs_group = NULL;
738 out:
739 return res;
740 }
741
742 int ieee80211_sysfs_change_if_type(struct net_device *dev)
743 {
744 return ieee80211_add_if_group(&dev->class_dev.kobj, dev);
745 }
746
747 int ieee80211_sysfs_add_netdevice(struct net_device *dev)
748 {
749 struct ieee80211_local *local = dev->ieee80211_ptr;
750 int res;
751
752 res = sysfs_create_link(&dev->class_dev.kobj, &local->class_dev.kobj,
753 "hw");
754 if (res)
755 goto err_out;
756 res = ieee80211_add_if_group(&dev->class_dev.kobj, dev);
757 if (res)
758 goto err_link;
759 res = ieee80211_key_kset_sysfs_register(IEEE80211_DEV_TO_SUB_IF(dev));
760 return res;
761
762 err_link:
763 sysfs_remove_link(&dev->class_dev.kobj, "hw");
764 err_out:
765 return res;
766 }
767
768 void ieee80211_sysfs_remove_netdevice(struct net_device *dev)
769 {
770 ieee80211_key_kset_sysfs_unregister(IEEE80211_DEV_TO_SUB_IF(dev));
771 ieee80211_remove_if_group(&dev->class_dev.kobj, dev);
772 sysfs_remove_link(&dev->class_dev.kobj, "hw");
773 }
774
775 /* general module functions */
776
777 int ieee80211_sysfs_init(void)
778 {
779 return class_register(&ieee80211_class);
780 }
781
782 void ieee80211_sysfs_deinit(void)
783 {
784 class_unregister(&ieee80211_class);
785 }
This page took 0.092105 seconds and 5 git commands to generate.