enable preinit in a few other platforms
[openwrt.git] / package / d80211 / src / ieee80211_sysfs_sta.c
1 /*
2  * Copyright 2003-2005, Devicescape Software, Inc.
3  * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz>
4  *
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.
8  */
9
10 #include <linux/kobject.h>
11 #include <linux/sysfs.h>
12 #include "ieee80211_i.h"
13 #include "ieee80211_key.h"
14 #include "sta_info.h"
15
16 static ssize_t sta_sysfs_show(struct kobject *, struct attribute *, char *);
17 static ssize_t key_sysfs_show(struct kobject *, struct attribute *, char *);
18
19 static struct sysfs_ops sta_ktype_ops = {
20         .show = sta_sysfs_show,
21 };
22
23 static struct sysfs_ops key_ktype_ops = {
24         .show = key_sysfs_show,
25 };
26
27 /* sta attributtes */
28
29 #define STA_SHOW(name, field, format_string)                            \
30 static ssize_t show_sta_##name(const struct sta_info *sta, char *buf)   \
31 {                                                                       \
32         return sprintf(buf, format_string, sta->field);                 \
33 }
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")
38
39 #define STA_SHOW_RATE(name, field)                                      \
40 static ssize_t show_sta_##name(const struct sta_info *sta, char *buf)   \
41 {                                                                       \
42         struct ieee80211_local *local = sta->dev->ieee80211_ptr;        \
43         return sprintf(buf, "%d\n",                                     \
44                        (sta->field >= 0 &&                              \
45                         sta->field < local->num_curr_rates) ?           \
46                        local->curr_rates[sta->field].rate : -1);        \
47 }
48
49 #define __STA_ATTR(name)                                                \
50 static struct sta_attribute sta_attr_##name =                           \
51         __ATTR(name, S_IRUGO, show_sta_##name, NULL)
52
53 #define STA_ATTR(name, field, format)                                   \
54                 STA_SHOW_##format(name, field)                          \
55                 __STA_ATTR(name)
56
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);
79
80 static ssize_t show_sta_flags(const struct sta_info *sta, char *buf)
81 {
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" : "");
93 }
94 __STA_ATTR(flags);
95
96 static ssize_t show_sta_num_ps_buf_frames(const struct sta_info *sta, char *buf)
97 {
98         return sprintf(buf, "%u\n", skb_queue_len(&sta->ps_tx_buf));
99 }
100 __STA_ATTR(num_ps_buf_frames);
101
102 static ssize_t show_sta_last_ack_rssi(const struct sta_info *sta, char *buf)
103 {
104         return sprintf(buf, "%d %d %d\n", sta->last_ack_rssi[0],
105                        sta->last_ack_rssi[1], sta->last_ack_rssi[2]);
106 }
107 __STA_ATTR(last_ack_rssi);
108
109 static ssize_t show_sta_last_ack_ms(const struct sta_info *sta, char *buf)
110 {
111         return sprintf(buf, "%d\n", sta->last_ack ?
112                        jiffies_to_msecs(jiffies - sta->last_ack) : -1);
113 }
114 __STA_ATTR(last_ack_ms);
115
116 static ssize_t show_sta_inactive_ms(const struct sta_info *sta, char *buf)
117 {
118         return sprintf(buf, "%d\n", jiffies_to_msecs(jiffies - sta->last_rx));
119 }
120 __STA_ATTR(inactive_ms);
121
122 static ssize_t show_sta_last_seq_ctrl(const struct sta_info *sta, char *buf)
123 {
124         int i;
125         char *p = buf;
126
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");
130         return (p - buf);
131 }
132 __STA_ATTR(last_seq_ctrl);
133
134 #ifdef CONFIG_D80211_DEBUG_COUNTERS
135 static ssize_t show_sta_wme_rx_queue(const struct sta_info *sta, char *buf)
136 {
137         int i;
138         char *p = buf;
139
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");
143         return (p - buf);
144 }
145 __STA_ATTR(wme_rx_queue);
146
147 static ssize_t show_sta_wme_tx_queue(const struct sta_info *sta, char *buf)
148 {
149         int i;
150         char *p = buf;
151
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");
155         return (p - buf);
156 }
157 __STA_ATTR(wme_tx_queue);
158 #endif
159
160 static struct attribute *sta_ktype_attrs[] = {
161         &sta_attr_aid.attr,
162         &sta_attr_key_idx_compression.attr,
163         &sta_attr_dev.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,
183
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,
193 #endif
194         NULL
195 };
196
197 /* keys attributtes */
198
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,
203                          size_t count);
204 };
205
206 #define KEY_SHOW(name, field, format_string)                            \
207 static ssize_t show_key_##name(const struct ieee80211_key *key, char *buf)\
208 {                                                                       \
209         return sprintf(buf, format_string, key->field);                 \
210 }
211 #define KEY_SHOW_D(name, field) KEY_SHOW(name, field, "%d\n")
212
213 #define __KEY_ATTR(name)                                                \
214 static struct key_attribute key_attr_##name =                           \
215         __ATTR(name, S_IRUSR, show_key_##name, NULL)
216
217 #define KEY_ATTR(name, field, format)                                   \
218                 KEY_SHOW_##format(name, field)                          \
219                 __KEY_ATTR(name)
220
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);
226
227 static ssize_t show_key_algorithm(const struct ieee80211_key *key, char *buf)
228 {
229         char *alg;
230
231         switch (key->alg) {
232         case ALG_WEP:
233                 alg = "WEP";
234                 break;
235         case ALG_TKIP:
236                 alg = "TKIP";
237                 break;
238         case ALG_CCMP:
239                 alg = "CCMP";
240                 break;
241         default:
242                 return 0;
243         }
244         return sprintf(buf, "%s\n", alg);
245 }
246 __KEY_ATTR(algorithm);
247
248 static ssize_t show_key_tx_spec(const struct ieee80211_key *key, char *buf)
249 {
250         const u8 *tpn;
251
252         switch (key->alg) {
253         case ALG_WEP:
254                 return sprintf(buf, "\n");
255         case ALG_TKIP:
256                 return sprintf(buf, "%08x %04x\n", key->u.tkip.iv32,
257                                key->u.tkip.iv16);
258         case ALG_CCMP:
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]);
262         default:
263                 return 0;
264         }
265 }
266 __KEY_ATTR(tx_spec);
267
268 static ssize_t show_key_rx_spec(const struct ieee80211_key *key, char *buf)
269 {
270         int i;
271         const u8 *rpn;
272         char *p = buf;
273
274         switch (key->alg) {
275         case ALG_WEP:
276                 return sprintf(buf, "\n");
277         case ALG_TKIP:
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]);
282                 return (p - buf);
283         case ALG_CCMP:
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]);
288                 }
289                 return (p - buf);
290         default:
291                 return 0;
292         }
293 }
294 __KEY_ATTR(rx_spec);
295
296 static ssize_t show_key_replays(const struct ieee80211_key *key, char *buf)
297 {
298         if (key->alg != ALG_CCMP)
299                 return 0;
300         return sprintf(buf, "%u\n", key->u.ccmp.replays);
301 }
302 __KEY_ATTR(replays);
303
304 static ssize_t show_key_key(const struct ieee80211_key *key, char *buf)
305 {
306         int i;
307         char *p = buf;
308
309         for (i = 0; i < key->keylen; i++)
310                 p += sprintf(p, "%02x", key->key[i]);
311         p += sprintf(p, "\n");
312         return (p - buf);
313 }
314 __KEY_ATTR(key);
315
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,
326         &key_attr_key.attr,
327         NULL
328 };
329
330 /* structures and functions */
331
332 static struct kobj_type sta_ktype = {
333         .release = sta_info_release,
334         .sysfs_ops = &sta_ktype_ops,
335         .default_attrs = sta_ktype_attrs,
336 };
337
338 static struct kobj_type key_ktype = {
339         .release = ieee80211_key_release,
340         .sysfs_ops = &key_ktype_ops,
341         .default_attrs = key_ktype_attrs,
342 };
343
344 static ssize_t sta_sysfs_show(struct kobject *kobj, struct attribute *attr,
345                               char *buf)
346 {
347         struct sta_attribute *sta_attr;
348         struct sta_info *sta;
349
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);
353 }
354
355 static ssize_t key_sysfs_show(struct kobject *kobj, struct attribute *attr,
356                               char *buf)
357 {
358         struct key_attribute *key_attr;
359         struct ieee80211_key *key;
360
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);
364 }
365
366 int ieee80211_sta_kset_sysfs_register(struct ieee80211_local *local)
367 {
368         int res;
369
370         res = kobject_set_name(&local->sta_kset.kobj, "sta");
371         if (res)
372                 return res;
373         local->sta_kset.kobj.parent = &local->class_dev.kobj;
374         local->sta_kset.ktype = &sta_ktype;
375         return kset_register(&local->sta_kset);
376 }
377
378 void ieee80211_sta_kset_sysfs_unregister(struct ieee80211_local *local)
379 {
380         kset_unregister(&local->sta_kset);
381 }
382
383 int ieee80211_key_kset_sysfs_register(struct ieee80211_sub_if_data *sdata)
384 {
385         int res;
386
387         res = kobject_set_name(&sdata->key_kset.kobj, "keys");
388         if (res)
389                 return res;
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);
393 }
394
395 void ieee80211_key_kset_sysfs_unregister(struct ieee80211_sub_if_data *sdata)
396 {
397         kset_unregister(&sdata->key_kset);
398 }
399
400 int ieee80211_sta_sysfs_add(struct sta_info *sta)
401 {
402         return kobject_add(&sta->kobj);
403 }
404
405 void ieee80211_sta_sysfs_remove(struct sta_info *sta)
406 {
407         kobject_del(&sta->kobj);
408 }
409
410 void ieee80211_key_sysfs_set_kset(struct ieee80211_key *key, struct kset *kset)
411 {
412         key->kobj.kset = kset;
413         if (!kset)
414                 key->kobj.ktype = &key_ktype;
415 }
416
417 int ieee80211_key_sysfs_add(struct ieee80211_key *key)
418 {
419         return kobject_add(&key->kobj);
420 }
421
422 void ieee80211_key_sysfs_remove(struct ieee80211_key *key)
423 {
424         if (key)
425                 kobject_del(&key->kobj);
426 }
427
428 int ieee80211_key_sysfs_add_default(struct ieee80211_sub_if_data *sdata)
429 {
430         return sysfs_create_link(&sdata->key_kset.kobj,
431                                  &sdata->default_key->kobj, "default");
432 }
433
434 void ieee80211_key_sysfs_remove_default(struct ieee80211_sub_if_data *sdata)
435 {
436         sysfs_remove_link(&sdata->key_kset.kobj, "default");
437 }