2 * Copyright 2003-2005, Devicescape Software, Inc.
3 * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
10 #include <linux/kobject.h>
11 #include <linux/sysfs.h>
12 #include "ieee80211_i.h"
13 #include "ieee80211_key.h"
16 static ssize_t
sta_sysfs_show(struct kobject
*, struct attribute
*, char *);
17 static ssize_t
key_sysfs_show(struct kobject
*, struct attribute
*, char *);
19 static struct sysfs_ops sta_ktype_ops
= {
20 .show
= sta_sysfs_show
,
23 static struct sysfs_ops key_ktype_ops
= {
24 .show
= key_sysfs_show
,
29 #define STA_SHOW(name, field, format_string) \
30 static ssize_t show_sta_##name(const struct sta_info *sta, char *buf) \
32 return sprintf(buf, format_string, sta->field); \
34 #define STA_SHOW_D(name, field) STA_SHOW(name, field, "%d\n")
35 #define STA_SHOW_U(name, field) STA_SHOW(name, field, "%u\n")
36 #define STA_SHOW_LU(name, field) STA_SHOW(name, field, "%lu\n")
37 #define STA_SHOW_S(name, field) STA_SHOW(name, field, "%s\n")
39 #define STA_SHOW_RATE(name, field) \
40 static ssize_t show_sta_##name(const struct sta_info *sta, char *buf) \
42 struct ieee80211_local *local = sta->dev->ieee80211_ptr; \
43 return sprintf(buf, "%d\n", \
45 sta->field < local->num_curr_rates) ? \
46 local->curr_rates[sta->field].rate : -1); \
49 #define __STA_ATTR(name) \
50 static struct sta_attribute sta_attr_##name = \
51 __ATTR(name, S_IRUGO, show_sta_##name, NULL)
53 #define STA_ATTR(name, field, format) \
54 STA_SHOW_##format(name, field) \
57 STA_ATTR(aid
, aid
, D
);
58 STA_ATTR(key_idx_compression
, key_idx_compression
, D
);
59 STA_ATTR(dev
, dev
->name
, S
);
60 STA_ATTR(vlan_id
, vlan_id
, D
);
61 STA_ATTR(rx_packets
, rx_packets
, LU
);
62 STA_ATTR(tx_packets
, tx_packets
, LU
);
63 STA_ATTR(rx_bytes
, rx_bytes
, LU
);
64 STA_ATTR(tx_bytes
, tx_bytes
, LU
);
65 STA_ATTR(rx_duplicates
, num_duplicates
, LU
);
66 STA_ATTR(rx_fragments
, rx_fragments
, LU
);
67 STA_ATTR(rx_dropped
, rx_dropped
, LU
);
68 STA_ATTR(tx_fragments
, tx_fragments
, LU
);
69 STA_ATTR(tx_filtered
, tx_filtered_count
, LU
);
70 STA_ATTR(txrate
, txrate
, RATE
);
71 STA_ATTR(last_txrate
, last_txrate
, RATE
);
72 STA_ATTR(tx_retry_failed
, tx_retry_failed
, LU
);
73 STA_ATTR(tx_retry_count
, tx_retry_count
, LU
);
74 STA_ATTR(last_rssi
, last_rssi
, D
);
75 STA_ATTR(last_signal
, last_signal
, D
);
76 STA_ATTR(last_noise
, last_noise
, D
);
77 STA_ATTR(channel_use
, channel_use
, D
);
78 STA_ATTR(wep_weak_iv_count
, wep_weak_iv_count
, D
);
80 static ssize_t
show_sta_flags(const struct sta_info
*sta
, char *buf
)
82 return sprintf(buf
, "%s%s%s%s%s%s%s%s%s",
83 sta
->flags
& WLAN_STA_AUTH
? "AUTH\n" : "",
84 sta
->flags
& WLAN_STA_ASSOC
? "ASSOC\n" : "",
85 sta
->flags
& WLAN_STA_PS
? "PS\n" : "",
86 sta
->flags
& WLAN_STA_TIM
? "TIM\n" : "",
87 sta
->flags
& WLAN_STA_PERM
? "PERM\n" : "",
88 sta
->flags
& WLAN_STA_AUTHORIZED
? "AUTHORIZED\n" : "",
89 sta
->flags
& WLAN_STA_SHORT_PREAMBLE
?
90 "SHORT PREAMBLE\n" : "",
91 sta
->flags
& WLAN_STA_WME
? "WME\n" : "",
92 sta
->flags
& WLAN_STA_WDS
? "WDS\n" : "");
96 static ssize_t
show_sta_num_ps_buf_frames(const struct sta_info
*sta
, char *buf
)
98 return sprintf(buf
, "%u\n", skb_queue_len(&sta
->ps_tx_buf
));
100 __STA_ATTR(num_ps_buf_frames
);
102 static ssize_t
show_sta_last_ack_rssi(const struct sta_info
*sta
, char *buf
)
104 return sprintf(buf
, "%d %d %d\n", sta
->last_ack_rssi
[0],
105 sta
->last_ack_rssi
[1], sta
->last_ack_rssi
[2]);
107 __STA_ATTR(last_ack_rssi
);
109 static ssize_t
show_sta_last_ack_ms(const struct sta_info
*sta
, char *buf
)
111 return sprintf(buf
, "%d\n", sta
->last_ack
?
112 jiffies_to_msecs(jiffies
- sta
->last_ack
) : -1);
114 __STA_ATTR(last_ack_ms
);
116 static ssize_t
show_sta_inactive_ms(const struct sta_info
*sta
, char *buf
)
118 return sprintf(buf
, "%d\n", jiffies_to_msecs(jiffies
- sta
->last_rx
));
120 __STA_ATTR(inactive_ms
);
122 static ssize_t
show_sta_last_seq_ctrl(const struct sta_info
*sta
, char *buf
)
127 for (i
= 0; i
< NUM_RX_DATA_QUEUES
; i
++)
128 p
+= sprintf(p
, "%x ", sta
->last_seq_ctrl
[i
]);
129 p
+= sprintf(p
, "\n");
132 __STA_ATTR(last_seq_ctrl
);
134 #ifdef CONFIG_D80211_DEBUG_COUNTERS
135 static ssize_t
show_sta_wme_rx_queue(const struct sta_info
*sta
, char *buf
)
140 for (i
= 0; i
< NUM_RX_DATA_QUEUES
; i
++)
141 p
+= sprintf(p
, "%u ", sta
->wme_rx_queue
[i
]);
142 p
+= sprintf(p
, "\n");
145 __STA_ATTR(wme_rx_queue
);
147 static ssize_t
show_sta_wme_tx_queue(const struct sta_info
*sta
, char *buf
)
152 for (i
= 0; i
< NUM_RX_DATA_QUEUES
; i
++)
153 p
+= sprintf(p
, "%u ", sta
->wme_tx_queue
[i
]);
154 p
+= sprintf(p
, "\n");
157 __STA_ATTR(wme_tx_queue
);
160 static struct attribute
*sta_ktype_attrs
[] = {
162 &sta_attr_key_idx_compression
.attr
,
164 &sta_attr_vlan_id
.attr
,
165 &sta_attr_rx_packets
.attr
,
166 &sta_attr_tx_packets
.attr
,
167 &sta_attr_rx_bytes
.attr
,
168 &sta_attr_tx_bytes
.attr
,
169 &sta_attr_rx_duplicates
.attr
,
170 &sta_attr_rx_fragments
.attr
,
171 &sta_attr_rx_dropped
.attr
,
172 &sta_attr_tx_fragments
.attr
,
173 &sta_attr_tx_filtered
.attr
,
174 &sta_attr_txrate
.attr
,
175 &sta_attr_last_txrate
.attr
,
176 &sta_attr_tx_retry_failed
.attr
,
177 &sta_attr_tx_retry_count
.attr
,
178 &sta_attr_last_rssi
.attr
,
179 &sta_attr_last_signal
.attr
,
180 &sta_attr_last_noise
.attr
,
181 &sta_attr_channel_use
.attr
,
182 &sta_attr_wep_weak_iv_count
.attr
,
184 &sta_attr_flags
.attr
,
185 &sta_attr_num_ps_buf_frames
.attr
,
186 &sta_attr_last_ack_rssi
.attr
,
187 &sta_attr_last_ack_ms
.attr
,
188 &sta_attr_inactive_ms
.attr
,
189 &sta_attr_last_seq_ctrl
.attr
,
190 #ifdef CONFIG_D80211_DEBUG_COUNTERS
191 &sta_attr_wme_rx_queue
.attr
,
192 &sta_attr_wme_tx_queue
.attr
,
197 /* keys attributtes */
199 struct key_attribute
{
200 struct attribute attr
;
201 ssize_t (*show
)(const struct ieee80211_key
*, char *buf
);
202 ssize_t (*store
)(struct ieee80211_key
*, const char *buf
,
206 #define KEY_SHOW(name, field, format_string) \
207 static ssize_t show_key_##name(const struct ieee80211_key *key, char *buf)\
209 return sprintf(buf, format_string, key->field); \
211 #define KEY_SHOW_D(name, field) KEY_SHOW(name, field, "%d\n")
213 #define __KEY_ATTR(name) \
214 static struct key_attribute key_attr_##name = \
215 __ATTR(name, S_IRUSR, show_key_##name, NULL)
217 #define KEY_ATTR(name, field, format) \
218 KEY_SHOW_##format(name, field) \
221 KEY_ATTR(length
, keylen
, D
);
222 KEY_ATTR(sw_encrypt
, force_sw_encrypt
, D
);
223 KEY_ATTR(index
, keyidx
, D
);
224 KEY_ATTR(hw_index
, hw_key_idx
, D
);
225 KEY_ATTR(tx_rx_count
, tx_rx_count
, D
);
227 static ssize_t
show_key_algorithm(const struct ieee80211_key
*key
, char *buf
)
244 return sprintf(buf
, "%s\n", alg
);
246 __KEY_ATTR(algorithm
);
248 static ssize_t
show_key_tx_spec(const struct ieee80211_key
*key
, char *buf
)
254 return sprintf(buf
, "\n");
256 return sprintf(buf
, "%08x %04x\n", key
->u
.tkip
.iv32
,
259 tpn
= key
->u
.ccmp
.tx_pn
;
260 return sprintf(buf
, "%02x%02x%02x%02x%02x%02x\n", tpn
[0],
261 tpn
[1], tpn
[2], tpn
[3], tpn
[4], tpn
[5]);
268 static ssize_t
show_key_rx_spec(const struct ieee80211_key
*key
, char *buf
)
276 return sprintf(buf
, "\n");
278 for (i
= 0; i
< NUM_RX_DATA_QUEUES
; i
++)
279 p
+= sprintf(p
, "%08x %04x\n",
280 key
->u
.tkip
.iv32_rx
[i
],
281 key
->u
.tkip
.iv16_rx
[i
]);
284 for (i
= 0; i
< NUM_RX_DATA_QUEUES
; i
++) {
285 rpn
= key
->u
.ccmp
.rx_pn
[i
];
286 p
+= sprintf(p
, "%02x%02x%02x%02x%02x%02x\n", rpn
[0],
287 rpn
[1], rpn
[2], rpn
[3], rpn
[4], rpn
[5]);
296 static ssize_t
show_key_replays(const struct ieee80211_key
*key
, char *buf
)
298 if (key
->alg
!= ALG_CCMP
)
300 return sprintf(buf
, "%u\n", key
->u
.ccmp
.replays
);
304 static ssize_t
show_key_key(const struct ieee80211_key
*key
, char *buf
)
309 for (i
= 0; i
< key
->keylen
; i
++)
310 p
+= sprintf(p
, "%02x", key
->key
[i
]);
311 p
+= sprintf(p
, "\n");
316 static struct attribute
*key_ktype_attrs
[] = {
317 &key_attr_length
.attr
,
318 &key_attr_sw_encrypt
.attr
,
319 &key_attr_index
.attr
,
320 &key_attr_hw_index
.attr
,
321 &key_attr_tx_rx_count
.attr
,
322 &key_attr_algorithm
.attr
,
323 &key_attr_tx_spec
.attr
,
324 &key_attr_rx_spec
.attr
,
325 &key_attr_replays
.attr
,
330 /* structures and functions */
332 static struct kobj_type sta_ktype
= {
333 .release
= sta_info_release
,
334 .sysfs_ops
= &sta_ktype_ops
,
335 .default_attrs
= sta_ktype_attrs
,
338 static struct kobj_type key_ktype
= {
339 .release
= ieee80211_key_release
,
340 .sysfs_ops
= &key_ktype_ops
,
341 .default_attrs
= key_ktype_attrs
,
344 static ssize_t
sta_sysfs_show(struct kobject
*kobj
, struct attribute
*attr
,
347 struct sta_attribute
*sta_attr
;
348 struct sta_info
*sta
;
350 sta_attr
= container_of(attr
, struct sta_attribute
, attr
);
351 sta
= container_of(kobj
, struct sta_info
, kobj
);
352 return sta_attr
->show(sta
, buf
);
355 static ssize_t
key_sysfs_show(struct kobject
*kobj
, struct attribute
*attr
,
358 struct key_attribute
*key_attr
;
359 struct ieee80211_key
*key
;
361 key_attr
= container_of(attr
, struct key_attribute
, attr
);
362 key
= container_of(kobj
, struct ieee80211_key
, kobj
);
363 return key_attr
->show(key
, buf
);
366 int ieee80211_sta_kset_sysfs_register(struct ieee80211_local
*local
)
370 res
= kobject_set_name(&local
->sta_kset
.kobj
, "sta");
373 local
->sta_kset
.kobj
.parent
= &local
->class_dev
.kobj
;
374 local
->sta_kset
.ktype
= &sta_ktype
;
375 return kset_register(&local
->sta_kset
);
378 void ieee80211_sta_kset_sysfs_unregister(struct ieee80211_local
*local
)
380 kset_unregister(&local
->sta_kset
);
383 int ieee80211_key_kset_sysfs_register(struct ieee80211_sub_if_data
*sdata
)
387 res
= kobject_set_name(&sdata
->key_kset
.kobj
, "keys");
390 sdata
->key_kset
.kobj
.parent
= &sdata
->dev
->class_dev
.kobj
;
391 sdata
->key_kset
.ktype
= &key_ktype
;
392 return kset_register(&sdata
->key_kset
);
395 void ieee80211_key_kset_sysfs_unregister(struct ieee80211_sub_if_data
*sdata
)
397 kset_unregister(&sdata
->key_kset
);
400 int ieee80211_sta_sysfs_add(struct sta_info
*sta
)
402 return kobject_add(&sta
->kobj
);
405 void ieee80211_sta_sysfs_remove(struct sta_info
*sta
)
407 kobject_del(&sta
->kobj
);
410 void ieee80211_key_sysfs_set_kset(struct ieee80211_key
*key
, struct kset
*kset
)
412 key
->kobj
.kset
= kset
;
414 key
->kobj
.ktype
= &key_ktype
;
417 int ieee80211_key_sysfs_add(struct ieee80211_key
*key
)
419 return kobject_add(&key
->kobj
);
422 void ieee80211_key_sysfs_remove(struct ieee80211_key
*key
)
425 kobject_del(&key
->kobj
);
428 int ieee80211_key_sysfs_add_default(struct ieee80211_sub_if_data
*sdata
)
430 return sysfs_create_link(&sdata
->key_kset
.kobj
,
431 &sdata
->default_key
->kobj
, "default");
434 void ieee80211_key_sysfs_remove_default(struct ieee80211_sub_if_data
*sdata
)
436 sysfs_remove_link(&sdata
->key_kset
.kobj
, "default");