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");