rt61 is not broken on 2.6 kernels, use a daily snapshot instead
[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 }
This page took 0.07969 seconds and 5 git commands to generate.