2 * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz>
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.
9 #include <linux/kernel.h>
10 #include <linux/device.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"
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)
24 static inline int rtnl_lock_local(struct ieee80211_local
*local
)
27 if (unlikely(local
->reg_state
!= IEEE80211_DEV_REGISTERED
)) {
34 static const char *ieee80211_mode_str_short(int mode
)
43 case MODE_ATHEROS_TURBO
:
44 return "AtherosTurbo";
50 static const char *ieee80211_mode_str(int mode
)
54 return "IEEE 802.11a";
56 return "IEEE 802.11b";
58 return "IEEE 802.11g";
59 case MODE_ATHEROS_TURBO
:
60 return "Atheros Turbo (5 GHz)";
66 /* attributes in /sys/class/ieee80211/phyX/ */
68 static ssize_t
store_add_iface(struct class_device
*dev
,
69 const char *buf
, size_t len
)
71 struct ieee80211_local
*local
= to_ieee80211_local(dev
);
72 struct net_device
*new_dev
;
75 if (!capable(CAP_NET_ADMIN
))
79 res
= rtnl_lock_local(local
);
82 res
= ieee80211_if_add(local
->mdev
, buf
, 0, &new_dev
);
84 ieee80211_if_set_type(new_dev
, IEEE80211_IF_TYPE_STA
);
86 return res
< 0 ? res
: len
;
89 static ssize_t
store_remove_iface(struct class_device
*dev
,
90 const char *buf
, size_t len
)
92 struct ieee80211_local
*local
= to_ieee80211_local(dev
);
95 if (!capable(CAP_NET_ADMIN
))
99 res
= rtnl_lock_local(local
);
102 res
= ieee80211_if_remove(local
->mdev
, buf
, -1);
104 return res
< 0 ? res
: len
;
107 static ssize_t
store_rate_ctrl_alg(struct class_device
*dev
,
108 const char *buf
, size_t len
)
110 struct ieee80211_local
*local
= to_ieee80211_local(dev
);
113 if (!capable(CAP_NET_ADMIN
))
115 res
= rtnl_lock_local(local
);
118 res
= ieee80211_init_rate_ctrl_alg(local
, buf
);
120 return res
< 0 ? res
: len
;
123 static ssize_t
ieee80211_local_show(struct class_device
*dev
, char *buf
,
124 ssize_t (*format
)(struct ieee80211_local
*, char *))
126 struct ieee80211_local
*local
= to_ieee80211_local(dev
);
127 ssize_t ret
= -EINVAL
;
129 if (local
->reg_state
== IEEE80211_DEV_REGISTERED
)
130 ret
= (*format
)(local
, buf
);
134 #define IEEE80211_LOCAL_FMT(name, field, format_string) \
135 static ssize_t ieee80211_local_fmt_##name(struct ieee80211_local *local,\
138 return sprintf(buf, format_string, local->field); \
141 #define __IEEE80211_LOCAL_SHOW(name) \
142 static ssize_t ieee80211_local_show_##name(struct class_device *cd, \
145 return ieee80211_local_show(cd, buf, \
146 ieee80211_local_fmt_##name); \
149 #define IEEE80211_LOCAL_SHOW(name, field, format) \
150 IEEE80211_LOCAL_FMT(name, field, format "\n") \
151 __IEEE80211_LOCAL_SHOW(name)
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");
165 static ssize_t
ieee80211_local_fmt_mode(struct ieee80211_local
*local
,
168 return sprintf(buf
, "%s\n", ieee80211_mode_str(local
->hw
.conf
.phymode
));
170 __IEEE80211_LOCAL_SHOW(mode
);
172 static ssize_t
ieee80211_local_fmt_wep_iv(struct ieee80211_local
*local
,
175 return sprintf(buf
, "%#06x\n", local
->wep_iv
& 0xffffff);
177 __IEEE80211_LOCAL_SHOW(wep_iv
);
179 static ssize_t
ieee80211_local_fmt_tx_power_reduction(struct ieee80211_local
182 short tx_power_reduction
= local
->hw
.conf
.tx_power_reduction
;
184 return sprintf(buf
, "%d.%d dBm\n", tx_power_reduction
/ 10,
185 tx_power_reduction
% 10);
187 __IEEE80211_LOCAL_SHOW(tx_power_reduction
);
189 static ssize_t
ieee80211_local_fmt_modes(struct ieee80211_local
*local
,
192 struct ieee80211_hw_mode
*mode
;
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
));
201 __IEEE80211_LOCAL_SHOW(modes
);
203 static ssize_t
ieee80211_local_fmt_rate_ctrl_alg(struct ieee80211_local
*local
,
206 struct rate_control_ref
*ref
= local
->rate_ctrl
;
208 return sprintf(buf
, "%s\n", ref
->ops
->name
);
211 __IEEE80211_LOCAL_SHOW(rate_ctrl_alg
);
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
),
235 /* attributes in /sys/class/ieee80211/phyX/statistics/ */
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);
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");
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");
274 static ssize_t
ieee80211_local_fmt_wme_rx_queue(struct ieee80211_local
*local
,
280 for (i
= 0; i
< NUM_RX_DATA_QUEUES
; i
++)
281 p
+= sprintf(p
, "%u\n", local
->wme_rx_queue
[i
]);
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
);
288 static ssize_t
ieee80211_local_fmt_wme_tx_queue(struct ieee80211_local
*local
,
294 for (i
= 0; i
< NUM_RX_DATA_QUEUES
; i
++)
295 p
+= sprintf(p
, "%u\n", local
->wme_tx_queue
[i
]);
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
);
303 static ssize_t
ieee80211_stats_show(struct class_device
*dev
, char *buf
,
304 ssize_t (*format
)(struct ieee80211_low_level_stats
*, char *))
306 struct ieee80211_local
*local
= to_ieee80211_local(dev
);
307 struct ieee80211_low_level_stats stats
;
308 ssize_t ret
= -EINVAL
;
310 if (!local
->ops
->get_stats
)
312 ret
= rtnl_lock_local(local
);
315 ret
= local
->ops
->get_stats(local_to_hw(local
), &stats
);
318 ret
= (*format
)(&stats
, buf
);
322 #define IEEE80211_STATS_FMT(name, field, format_string) \
323 static ssize_t ieee80211_stats_fmt_##name(struct ieee80211_low_level_stats \
326 return sprintf(buf, format_string, stats->field); \
329 #define __IEEE80211_STATS_SHOW(name) \
330 static ssize_t ieee80211_stats_show_##name(struct class_device *cd, \
333 return ieee80211_stats_show(cd, buf, \
334 ieee80211_stats_fmt_##name); \
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);
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");
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
,
389 static struct attribute_group ieee80211_stats_group
= {
390 .name
= "statistics",
391 .attrs
= ieee80211_stats_attrs
,
394 /* attributes in /sys/class/net/X/ */
396 static ssize_t
ieee80211_if_show(struct class_device
*cd
, char *buf
,
397 ssize_t (*format
)(const struct ieee80211_sub_if_data
*,
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
;
404 read_lock(&dev_base_lock
);
405 if (dev
->reg_state
== NETREG_REGISTERED
) {
406 ret
= (*format
)(sdata
, buf
);
408 read_unlock(&dev_base_lock
);
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) \
416 return sprintf(buf, format_string, sdata->field); \
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")
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) \
429 return sprintf(buf, "%d\n", atomic_read(&sdata->field)); \
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) \
436 return sprintf(buf, MAC_FMT "\n", MAC_ARG(sdata->field)); \
439 #define __IEEE80211_IF_SHOW(name) \
440 static ssize_t ieee80211_if_show_##name(struct class_device *cd, \
443 return ieee80211_if_show(cd, buf, ieee80211_if_fmt_##name); \
445 static CLASS_DEVICE_ATTR(name, S_IRUGO, ieee80211_if_show_##name, NULL);
447 #define IEEE80211_IF_SHOW(name, field, format) \
448 IEEE80211_IF_FMT_##format(name, field) \
449 __IEEE80211_IF_SHOW(name)
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
);
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
);
472 static ssize_t
ieee80211_if_fmt_flags(const struct
473 ieee80211_sub_if_data
*sdata
, char *buf
)
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" : "");
484 __IEEE80211_IF_SHOW(flags
);
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
);
494 static ssize_t
ieee80211_if_fmt_num_buffered_multicast(const struct
495 ieee80211_sub_if_data
*sdata
, char *buf
)
497 return sprintf(buf
, "%u\n", skb_queue_len(&sdata
->u
.ap
.ps_bc_buf
));
499 __IEEE80211_IF_SHOW(num_buffered_multicast
);
501 static ssize_t
ieee80211_if_fmt_beacon_head_len(const struct
502 ieee80211_sub_if_data
*sdata
, char *buf
)
504 if (sdata
->u
.ap
.beacon_head
)
505 return sprintf(buf
, "%d\n", sdata
->u
.ap
.beacon_head_len
);
506 return sprintf(buf
, "\n");
508 __IEEE80211_IF_SHOW(beacon_head_len
);
510 static ssize_t
ieee80211_if_fmt_beacon_tail_len(const struct
511 ieee80211_sub_if_data
*sdata
, char *buf
)
513 if (sdata
->u
.ap
.beacon_tail
)
514 return sprintf(buf
, "%d\n", sdata
->u
.ap
.beacon_tail_len
);
515 return sprintf(buf
, "\n");
517 __IEEE80211_IF_SHOW(beacon_tail_len
);
520 IEEE80211_IF_SHOW(peer
, u
.wds
.remote_addr
, MAC
);
522 /* VLAN attributes */
523 IEEE80211_IF_SHOW(vlan_id
, u
.vlan
.id
, DEC
);
525 /* MONITOR attributes */
526 static ssize_t
ieee80211_if_fmt_mode(const struct
527 ieee80211_sub_if_data
*sdata
, char *buf
)
529 struct ieee80211_local
*local
= sdata
->local
;
531 return sprintf(buf
, "%s\n",
532 ((local
->hw
.flags
& IEEE80211_HW_MONITOR_DURING_OPER
) ||
533 local
->open_count
== local
->monitors
) ?
536 __IEEE80211_IF_SHOW(mode
);
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
,
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
,
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
,
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
,
595 static struct attribute
*ieee80211_monitor_attrs
[] = {
596 &class_device_attr_mode
.attr
,
600 static struct attribute_group ieee80211_sta_group
= {
602 .attrs
= ieee80211_sta_attrs
,
605 static struct attribute_group ieee80211_ap_group
= {
607 .attrs
= ieee80211_ap_attrs
,
610 static struct attribute_group ieee80211_wds_group
= {
612 .attrs
= ieee80211_wds_attrs
,
615 static struct attribute_group ieee80211_vlan_group
= {
617 .attrs
= ieee80211_vlan_attrs
,
620 static struct attribute_group ieee80211_monitor_group
= {
622 .attrs
= ieee80211_monitor_attrs
,
625 /* /sys/class/ieee80211/phyX functions */
627 static void ieee80211_class_dev_release(struct class_device
*dev
)
629 ieee80211_release_hw(to_ieee80211_local(dev
));
632 #ifdef CONFIG_HOTPLUG
633 static int ieee80211_uevent(struct class_device
*cd
, char **envp
,
634 int num_envp
, char *buf
, int size
)
636 struct ieee80211_local
*local
= to_ieee80211_local(cd
);
641 if (snprintf(buf
, size
, "IEEE80211_DEV=phy%d",
642 local
->hw
.index
) + 1 >= size
)
649 static struct class ieee80211_class
= {
651 .class_dev_attrs
= ieee80211_class_dev_attrs
,
652 .release
= ieee80211_class_dev_release
,
653 #ifdef CONFIG_HOTPLUG
654 .uevent
= ieee80211_uevent
,
658 void ieee80211_dev_sysfs_init(struct ieee80211_local
*local
)
660 local
->class_dev
.class = &ieee80211_class
;
661 local
->class_dev
.class_data
= local
;
662 class_device_initialize(&local
->class_dev
);
665 void ieee80211_dev_sysfs_put(struct ieee80211_local
*local
)
667 class_device_put(&local
->class_dev
);
670 int ieee80211_dev_sysfs_add(struct ieee80211_local
*local
)
674 snprintf(local
->class_dev
.class_id
, BUS_ID_SIZE
,
675 "phy%d", local
->hw
.index
);
676 res
= class_device_add(&local
->class_dev
);
679 res
= sysfs_create_group(&local
->class_dev
.kobj
,
680 &ieee80211_stats_group
);
682 class_device_del(&local
->class_dev
);
686 void ieee80211_dev_sysfs_del(struct ieee80211_local
*local
)
688 sysfs_remove_group(&local
->class_dev
.kobj
, &ieee80211_stats_group
);
689 class_device_del(&local
->class_dev
);
692 /* /sys/class/net/X functions */
694 static void __ieee80211_remove_if_group(struct kobject
*kobj
,
695 struct ieee80211_sub_if_data
*sdata
)
697 if (sdata
->sysfs_group
) {
698 sysfs_remove_group(kobj
, sdata
->sysfs_group
);
699 sdata
->sysfs_group
= NULL
;
703 static inline void ieee80211_remove_if_group(struct kobject
*kobj
,
704 struct net_device
*dev
)
706 __ieee80211_remove_if_group(kobj
, IEEE80211_DEV_TO_SUB_IF(dev
));
709 static int ieee80211_add_if_group(struct kobject
*kobj
,
710 struct net_device
*dev
)
712 struct ieee80211_sub_if_data
*sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
715 __ieee80211_remove_if_group(kobj
, sdata
);
716 switch (sdata
->type
) {
717 case IEEE80211_IF_TYPE_STA
:
718 sdata
->sysfs_group
= &ieee80211_sta_group
;
720 case IEEE80211_IF_TYPE_AP
:
721 sdata
->sysfs_group
= &ieee80211_ap_group
;
723 case IEEE80211_IF_TYPE_WDS
:
724 sdata
->sysfs_group
= &ieee80211_wds_group
;
726 case IEEE80211_IF_TYPE_VLAN
:
727 sdata
->sysfs_group
= &ieee80211_vlan_group
;
729 case IEEE80211_IF_TYPE_MNTR
:
730 sdata
->sysfs_group
= &ieee80211_monitor_group
;
735 res
= sysfs_create_group(kobj
, sdata
->sysfs_group
);
737 sdata
->sysfs_group
= NULL
;
742 int ieee80211_sysfs_change_if_type(struct net_device
*dev
)
744 return ieee80211_add_if_group(&dev
->class_dev
.kobj
, dev
);
747 int ieee80211_sysfs_add_netdevice(struct net_device
*dev
)
749 struct ieee80211_local
*local
= dev
->ieee80211_ptr
;
752 res
= sysfs_create_link(&dev
->class_dev
.kobj
, &local
->class_dev
.kobj
,
756 res
= ieee80211_add_if_group(&dev
->class_dev
.kobj
, dev
);
759 res
= ieee80211_key_kset_sysfs_register(IEEE80211_DEV_TO_SUB_IF(dev
));
763 sysfs_remove_link(&dev
->class_dev
.kobj
, "hw");
768 void ieee80211_sysfs_remove_netdevice(struct net_device
*dev
)
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");
775 /* general module functions */
777 int ieee80211_sysfs_init(void)
779 return class_register(&ieee80211_class
);
782 void ieee80211_sysfs_deinit(void)
784 class_unregister(&ieee80211_class
);