2 * Copyright 2003-2005, Devicescape Software, Inc.
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/config.h>
10 #include <linux/version.h>
11 #include <linux/module.h>
12 #include <linux/netdevice.h>
13 #include <linux/proc_fs.h>
14 #include <linux/delay.h>
18 #include <net/ieee80211.h>
19 #include <net/ieee80211_common.h>
20 #include <net/ieee80211_mgmt.h>
21 #include "ieee80211_i.h"
23 #include "ieee80211_proc.h"
24 #include "rate_control.h"
27 static struct proc_dir_entry *ieee80211_proc;
29 #define PROC_LIMIT (PAGE_SIZE - 80)
32 static char * ieee80211_proc_key(char *p, struct ieee80211_key *key,
41 p += sprintf(p, "key[%d]%s len=%d sw_encrypt=%d idx=%d hwidx=%d "
43 idx, def_key ? "*" : "", key->keylen,
44 key->force_sw_encrypt, key->keyidx, key->hw_key_idx,
48 p += sprintf(p, " alg=WEP");
51 p += sprintf(p, " alg=TKIP iv(tx)=%08x %04x",
52 key->u.tkip.iv32, key->u.tkip.iv16);
53 for (i = 0; i < NUM_RX_DATA_QUEUES; i++) {
54 if (key->u.tkip.iv32_rx[i] == 0 &&
55 key->u.tkip.iv16_rx[i] == 0)
57 p += sprintf(p, " iv(rx %d)=%08x %04x", i,
58 key->u.tkip.iv32_rx[i],
59 key->u.tkip.iv16_rx[i]);
63 tpn = key->u.ccmp.tx_pn;
64 p += sprintf(p, " alg=CCMP PN(tx)=%02x%02x%02x%02x%02x%02x",
65 tpn[0], tpn[1], tpn[2], tpn[3], tpn[4], tpn[5]);
66 for (i = 0; i < NUM_RX_DATA_QUEUES; i++) {
67 rpn = key->u.ccmp.rx_pn[i];
68 if (memcmp(rpn, "\x00\x00\x00\x00\x00\x00", 6) == 0)
70 p += sprintf(p, " PN(rx %d)=%02x%02x%02x%02x%02x%02x",
71 i, rpn[0], rpn[1], rpn[2], rpn[3], rpn[4],
74 p += sprintf(p, " replays=%u", key->u.ccmp.replays);
80 p += sprintf(p, " key=");
81 for (i = 0; i < key->keylen; i++)
82 p += sprintf(p, "%02x", key->key[i]);
83 p += sprintf(p, "\n");
88 static char * ieee80211_proc_sub_if_norm(char *p,
89 struct ieee80211_if_norm *norm)
91 p += sprintf(p, "type=norm\n");
92 if (norm->beacon_head)
93 p += sprintf(p, "beacon_head_len=%d\n", norm->beacon_head_len);
94 if (norm->beacon_tail)
95 p += sprintf(p, "beacon_tail_len=%d\n", norm->beacon_tail_len);
99 "num_buffered_multicast=%u\n"
103 "force_unicast_rateidx=%d\n"
104 "max_ratectrl_rateidx=%d\n",
105 norm->max_aid, atomic_read(&norm->num_sta_ps),
106 skb_queue_len(&norm->ps_bc_buf),
107 norm->dtim_period, norm->dtim_count, norm->num_beacons,
108 norm->force_unicast_rateidx, norm->max_ratectrl_rateidx);
113 static char * ieee80211_proc_sub_if_sta(char *p,
114 struct ieee80211_if_sta *ifsta)
116 p += sprintf(p, "type=sta\n");
120 "prev_bssid=" MACSTR "\n"
128 "flags=%s%s%s%s%s%s%s\n"
131 "auth_transaction=%d\n",
133 MAC2STR(ifsta->bssid),
134 MAC2STR(ifsta->prev_bssid),
142 ifsta->ssid_set ? "[SSID]" : "",
143 ifsta->bssid_set ? "[BSSID]" : "",
144 ifsta->prev_bssid_set ? "[prev BSSID" : "",
145 ifsta->authenticated ? "[AUTH]" : "",
146 ifsta->associated ? "[ASSOC]" : "",
147 ifsta->probereq_poll ? "[PROBEREQ POLL]" : "",
148 ifsta->use_protection ? "[CTS prot]" : "",
151 ifsta->auth_transaction);
156 static char * ieee80211_proc_sub_if(char *p,
157 struct ieee80211_sub_if_data *sdata)
163 p += sprintf(p, "bss=%p\n", sdata->bss);
165 switch (sdata->type) {
166 case IEEE80211_SUB_IF_TYPE_NORM:
167 p = ieee80211_proc_sub_if_norm(p, &sdata->u.norm);
169 case IEEE80211_SUB_IF_TYPE_WDS:
170 p += sprintf(p, "type=wds\n");
171 p += sprintf(p, "wds.peer=" MACSTR "\n",
172 MAC2STR(sdata->u.wds.remote_addr));
174 case IEEE80211_SUB_IF_TYPE_VLAN:
175 p += sprintf(p, "type=vlan\n");
176 p += sprintf(p, "vlan.id=%d\n", sdata->u.vlan.id);
178 case IEEE80211_SUB_IF_TYPE_STA:
179 p = ieee80211_proc_sub_if_sta(p, &sdata->u.sta);
182 p += sprintf(p, "channel_use=%d\n", sdata->channel_use);
183 p += sprintf(p, "drop_unencrypted=%d\n", sdata->drop_unencrypted);
184 p += sprintf(p, "eapol=%d\n", sdata->eapol);
185 p += sprintf(p, "ieee802_1x=%d\n", sdata->ieee802_1x);
191 static int ieee80211_proc_iface_read(char *page, char **start, off_t off,
192 int count, int *eof, void *data)
195 struct net_device *dev = (struct net_device *) data;
196 struct ieee80211_sub_if_data *sdata;
204 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
208 p = ieee80211_proc_sub_if(p, sdata);
210 for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
211 if (sdata->keys[i] == NULL)
214 p = ieee80211_proc_key(p, sdata->keys[i], i,
215 sdata->keys[i] == sdata->default_key);
222 static int ieee80211_proc_sta_read(char *page, char **start, off_t off,
223 int count, int *eof, void *data)
226 struct sta_info *sta = (struct sta_info *) data;
227 struct ieee80211_local *local;
235 if (!sta || !sta->dev)
238 p += sprintf(p, "users=%d\n", atomic_read(&sta->users));
239 p += sprintf(p, "aid=%d\n", sta->aid);
240 p += sprintf(p, "flags=0x%x %s%s%s%s%s%s%s%s%s%s\n", sta->flags,
241 sta->flags & WLAN_STA_AUTH ? "[AUTH]" : "",
242 sta->flags & WLAN_STA_ASSOC ? "[ASSOC]" : "",
243 sta->flags & WLAN_STA_PS ? "[PS]" : "",
244 sta->flags & WLAN_STA_TIM ? "[TIM]" : "",
245 sta->flags & WLAN_STA_PERM ? "[PERM]" : "",
246 sta->flags & WLAN_STA_AUTHORIZED ? "[AUTHORIZED]" : "",
247 sta->flags & WLAN_STA_SHORT_PREAMBLE ?
248 "[SHORT PREAMBLE]" : "",
249 sta->flags & WLAN_STA_WME ? "[WME]" : "",
250 sta->flags & WLAN_STA_WDS ? "[WDS]" : "",
251 sta->flags & WLAN_STA_XR ? "[XR]" : "");
252 p += sprintf(p, "key_idx_compression=%d\n",
253 sta->key_idx_compression);
254 p += sprintf(p, "dev=%s\n", sta->dev->name);
255 if (sta->vlan_id > 0)
256 p += sprintf(p, "vlan_id=%d\n", sta->vlan_id);
257 p += sprintf(p, "rx_packets=%lu\ntx_packets=%lu\nrx_bytes=%lu\n"
258 "tx_bytes=%lu\nrx_duplicates=%lu\nrx_fragments=%lu\n"
259 "rx_dropped=%lu\ntx_fragments=%lu\ntx_filtered=%lu\n",
260 sta->rx_packets, sta->tx_packets,
261 sta->rx_bytes, sta->tx_bytes,
262 sta->num_duplicates, sta->rx_fragments, sta->rx_dropped,
263 sta->tx_fragments, sta->tx_filtered_count);
264 p = ieee80211_proc_key(p, sta->key, 0, 1);
266 local = (struct ieee80211_local *) sta->dev->priv;
267 if (sta->txrate >= 0 && sta->txrate < local->num_curr_rates) {
268 p += sprintf(p, "txrate=%d\n",
269 local->curr_rates[sta->txrate].rate);
271 if (sta->last_txrate >= 0 &&
272 sta->last_txrate < local->num_curr_rates) {
273 p += sprintf(p, "last_txrate=%d\n",
274 local->curr_rates[sta->last_txrate].rate);
276 p += sprintf(p, "num_ps_buf_frames=%u\n",
277 skb_queue_len(&sta->ps_tx_buf));
278 p += sprintf(p, "tx_retry_failed=%lu\n", sta->tx_retry_failed);
279 p += sprintf(p, "tx_retry_count=%lu\n", sta->tx_retry_count);
280 p += sprintf(p, "last_rssi=%d\n", sta->last_rssi);
281 p += sprintf(p, "last_ack_rssi=%d %d %d\n",
282 sta->last_ack_rssi[0], sta->last_ack_rssi[1],
283 sta->last_ack_rssi[2]);
285 p += sprintf(p, "last_ack_ms=%d\n",
286 jiffies_to_msecs(jiffies - sta->last_ack));
287 inactive = jiffies - sta->last_rx;
288 p += sprintf(p, "inactive_msec=%d\n", jiffies_to_msecs(inactive));
289 p += sprintf(p, "channel_use=%d\n", sta->channel_use);
290 p += sprintf(p, "wep_weak_iv_count=%d\n", sta->wep_weak_iv_count);
291 #ifdef CONFIG_IEEE80211_DEBUG_COUNTERS
292 p += sprintf(p, "wme_rx_queue=");
293 for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
294 p += sprintf(p, "%u ", sta->wme_rx_queue[i]);
295 p += sprintf(p, "\n");
297 p += sprintf(p, "wme_tx_queue=");
298 for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
299 p += sprintf(p, "%u ", sta->wme_tx_queue[i]);
300 p += sprintf(p, "\n");
301 #endif /* CONFIG_IEEE80211_DEBUG_COUNTERS */
302 p += sprintf(p, "last_seq_ctrl=");
303 for (i = 0; i < NUM_RX_DATA_QUEUES; i++) {
304 p += sprintf(p, "%x ", sta->last_seq_ctrl[i]);
306 p += sprintf(p, "\n");
308 p += rate_control_status_sta(local, sta, p);
314 static int ieee80211_proc_counters_read(char *page, char **start, off_t off,
315 int count, int *eof, void *data)
318 struct ieee80211_local *local = (struct ieee80211_local *) data;
319 struct ieee80211_low_level_stats stats;
327 "TransmittedFragmentCount=%u\n"
328 "MulticastTransmittedFrameCount=%u\n"
331 "MultipleRetryCount=%d\n"
332 "FrameDuplicateCount=%d\n"
333 "ReceivedFragmentCount=%u\n"
334 "MulticastReceivedFrameCount=%u\n"
335 "TransmittedFrameCount=%u\n"
336 "WEPUndecryptableCount=%u\n",
337 local->dot11TransmittedFragmentCount,
338 local->dot11MulticastTransmittedFrameCount,
339 local->dot11FailedCount,
340 local->dot11RetryCount,
341 local->dot11MultipleRetryCount,
342 local->dot11FrameDuplicateCount,
343 local->dot11ReceivedFragmentCount,
344 local->dot11MulticastReceivedFrameCount,
345 local->dot11TransmittedFrameCount,
346 local->dot11WEPUndecryptableCount);
348 memset(&stats, 0, sizeof(stats));
349 if (local->hw->get_stats &&
350 local->hw->get_stats(local->mdev, &stats) == 0) {
352 "ACKFailureCount=%u\n"
353 "RTSFailureCount=%u\n"
355 "RTSSuccessCount=%u\n",
356 stats.dot11ACKFailureCount,
357 stats.dot11RTSFailureCount,
358 stats.dot11FCSErrorCount,
359 stats.dot11RTSSuccessCount);
366 static int ieee80211_proc_debug_read(char *page, char **start, off_t off,
367 int count, int *eof, void *data)
370 struct ieee80211_local *local = (struct ieee80211_local *) data;
378 #ifdef CONFIG_IEEE80211_DEBUG_COUNTERS
380 "tx_handlers_drop=%u\n"
381 "tx_handlers_queued=%u\n"
382 "tx_handlers_drop_unencrypted=%u\n"
383 "tx_handlers_drop_fragment=%u\n"
384 "tx_handlers_drop_wep=%u\n"
385 "tx_handlers_drop_rate_limit=%u\n"
386 "tx_handlers_drop_not_assoc=%u\n"
387 "tx_handlers_drop_unauth_port=%u\n"
388 "rx_handlers_drop=%u\n"
389 "rx_handlers_queued=%u\n"
390 "rx_handlers_drop_nullfunc=%u\n"
391 "rx_handlers_drop_defrag=%u\n"
392 "rx_handlers_drop_short=%u\n"
393 "rx_handlers_drop_passive_scan=%u\n"
394 "tx_expand_skb_head=%u\n"
395 "tx_expand_skb_head_cloned=%u\n"
396 "rx_expand_skb_head=%u\n"
397 "rx_expand_skb_head2=%u\n"
398 "rx_handlers_fragments=%u\n"
399 "tx_status_drop=%u\n",
400 local->tx_handlers_drop,
401 local->tx_handlers_queued,
402 local->tx_handlers_drop_unencrypted,
403 local->tx_handlers_drop_fragment,
404 local->tx_handlers_drop_wep,
405 local->tx_handlers_drop_rate_limit,
406 local->tx_handlers_drop_not_assoc,
407 local->tx_handlers_drop_unauth_port,
408 local->rx_handlers_drop,
409 local->rx_handlers_queued,
410 local->rx_handlers_drop_nullfunc,
411 local->rx_handlers_drop_defrag,
412 local->rx_handlers_drop_short,
413 local->rx_handlers_drop_passive_scan,
414 local->tx_expand_skb_head,
415 local->tx_expand_skb_head_cloned,
416 local->rx_expand_skb_head,
417 local->rx_expand_skb_head2,
418 local->rx_handlers_fragments,
419 local->tx_status_drop);
422 p += sprintf(p, "wme_rx_queue=");
423 for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
424 p += sprintf(p, " %u", local->wme_rx_queue[i]);
425 p += sprintf(p, "\n");
427 p += sprintf(p, "wme_tx_queue=");
428 for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
429 p += sprintf(p, " %u", local->wme_tx_queue[i]);
430 p += sprintf(p, "\n");
432 #endif /* CONFIG_IEEE80211_DEBUG_COUNTERS */
434 p += sprintf(p, "num_scans=%u\n", local->scan.num_scans);
437 "conf.bss_count=%d\n"
438 "bss_dev_count=%u\n",
439 local->conf.bss_count, local->bss_dev_count);
440 for (i = 0; i < local->conf.bss_count; i++) {
441 p += sprintf(p, "bss_dev[%d]=%p (%s)\n",
442 i, local->bss_devs[i],
443 (i < local->bss_dev_count && local->bss_devs[i]) ?
444 local->bss_devs[i]->name : "N/A");
451 static const char * ieee80211_mode_str_short(int mode)
454 case MODE_IEEE80211A:
456 case MODE_IEEE80211B:
458 case MODE_IEEE80211G:
460 case MODE_ATHEROS_TURBO:
461 return "AtherosTurbo";
468 static const char * ieee80211_mode_str(int mode)
471 case MODE_IEEE80211A:
472 return "IEEE 802.11a";
473 case MODE_IEEE80211B:
474 return "IEEE 802.11b";
475 case MODE_IEEE80211G:
476 return "IEEE 802.11g";
477 case MODE_ATHEROS_TURBO:
478 return "Atheros Turbo (5 GHz)";
485 static int ieee80211_proc_info_read(char *page, char **start, off_t off,
486 int count, int *eof, void *data)
489 struct ieee80211_local *local = (struct ieee80211_local *) data;
491 struct ieee80211_hw_modes *mode;
498 p += sprintf(p, "hw_name=%s\n", local->hw->name);
499 p += sprintf(p, "modes=");
500 for (m = 0; m < local->hw->num_modes; m++) {
501 mode = &local->hw->modes[m];
502 p += sprintf(p, "[%s]", ieee80211_mode_str_short(mode->mode));
504 p += sprintf(p, "\n");
505 if (local->rate_ctrl && local->rate_ctrl_priv)
506 p+= sprintf(p, "rate_ctrl_alg=%s\n", local->rate_ctrl->name);
511 static int ieee80211_proc_config_read(char *page, char **start, off_t off,
512 int count, int *eof, void *data)
515 struct ieee80211_local *local = (struct ieee80211_local *) data;
523 "low_level_driver=%s\n"
531 "tx_power_reduction=%d.%d dBm\n"
532 "bridge_packets=%d\n"
533 "key_tx_rx_threshold=%d\n"
535 "fragmentation_threshold=%d\n"
536 "short_retry_limit=%d\n"
537 "long_retry_limit=%d\n"
538 "total_ps_buffered=%d\n",
539 local->hw->name ? local->hw->name : "N/A",
542 ieee80211_mode_str(local->conf.phymode),
543 local->conf.radar_detect,
544 local->wep_iv & 0xffffff,
545 local->conf.antenna_sel,
546 local->conf.calib_int,
547 local->conf.tx_power_reduction / 10,
548 local->conf.tx_power_reduction % 10,
549 local->bridge_packets,
550 local->key_tx_rx_threshold,
551 local->rts_threshold,
552 local->fragmentation_threshold,
553 local->short_retry_limit,
554 local->long_retry_limit,
555 local->total_ps_buffered);
561 static int ieee80211_proc_channels_read(char *page, char **start, off_t off,
562 int count, int *eof, void *data)
565 struct ieee80211_local *local = (struct ieee80211_local *) data;
567 struct ieee80211_hw_modes *mode;
568 struct ieee80211_channel *chan;
575 p += sprintf(p, "MODE CHAN FREQ TXPOWER ANTMAX FLAGS\n");
576 for (m = 0; m < local->hw->num_modes; m++) {
577 mode = &local->hw->modes[m];
578 for (c = 0; c < mode->num_channels; c++) {
579 chan = &mode->channels[c];
580 p += sprintf(p, "%d %d %d %d %d %s%s%s\n",
581 mode->mode, chan->chan, chan->freq,
582 chan->power_level, chan->antenna_max,
583 chan->flag & IEEE80211_CHAN_W_SCAN ?
585 chan->flag & IEEE80211_CHAN_W_ACTIVE_SCAN
586 ? "[W_ACTIVE_SCAN]" : "",
587 chan->flag & IEEE80211_CHAN_W_IBSS ?
595 static int ieee80211_proc_rates_read(char *page, char **start, off_t off,
596 int count, int *eof, void *data)
599 struct ieee80211_local *local = (struct ieee80211_local *) data;
601 struct ieee80211_rate *rate;
608 p += sprintf(p, "RATE VAL VAL2 MIN_RSSI_ACK MIN_RSSI_ACK_DELTA "
610 for (r = 0; r < local->num_curr_rates; r++) {
611 rate = &local->curr_rates[r];
612 p += sprintf(p, "%d %d %d %d %d 0x%x %s%s%s%s%s%s%s%s\n",
613 rate->rate, rate->val, rate->val2,
614 rate->min_rssi_ack, rate->min_rssi_ack_delta,
616 rate->flags & IEEE80211_RATE_ERP ? "[ERP]" : "",
617 rate->flags & IEEE80211_RATE_BASIC ?
619 rate->flags & IEEE80211_RATE_PREAMBLE2 ?
621 rate->flags & IEEE80211_RATE_SUPPORTED ?
623 rate->flags & IEEE80211_RATE_OFDM ? "[OFDM]" : "",
624 rate->flags & IEEE80211_RATE_CCK ? "[CCK]" : "",
625 rate->flags & IEEE80211_RATE_TURBO ?
627 rate->flags & IEEE80211_RATE_MANDATORY ?
634 static int ieee80211_proc_multicast_read(char *page, char **start, off_t off,
635 int count, int *eof, void *data)
638 struct ieee80211_local *local = (struct ieee80211_local *) data;
645 return rate_control_status_global(local, p);
650 void ieee80211_proc_init_sta(struct ieee80211_local *local,
651 struct sta_info *sta)
654 struct proc_dir_entry *entry;
656 sprintf(buf, MACSTR, MAC2STR(sta->addr));
658 if (!local->proc_sta)
661 entry = create_proc_read_entry(buf, 0, local->proc_sta,
662 ieee80211_proc_sta_read, sta);
664 entry->mode &= ~(S_IRWXG | S_IRWXO);
665 sta->proc_entry_added = 1;
670 void ieee80211_proc_deinit_sta(struct ieee80211_local *local,
671 struct sta_info *sta)
674 sprintf(buf, MACSTR, MAC2STR(sta->addr));
675 if (local->proc_sta) {
676 remove_proc_entry(buf, local->proc_sta);
677 sta->proc_entry_added = 0;
682 void ieee80211_proc_init_virtual(struct net_device *dev)
684 struct proc_dir_entry *entry;
685 struct ieee80211_local *local = (struct ieee80211_local *) dev->priv;
687 if (!local->proc_iface)
690 entry = create_proc_read_entry(dev->name, 0, local->proc_iface,
691 ieee80211_proc_iface_read, dev);
693 entry->mode &= ~(S_IRWXG | S_IRWXO);
697 void ieee80211_proc_deinit_virtual(struct net_device *dev)
699 struct ieee80211_local *local = (struct ieee80211_local *) dev->priv;
701 if (local->proc_iface)
702 remove_proc_entry(dev->name, local->proc_iface);
706 void ieee80211_proc_init_interface(struct ieee80211_local *local)
711 local->proc = proc_mkdir(local->wdev->name, ieee80211_proc);
715 local->proc_sta = proc_mkdir("sta", local->proc);
716 local->proc_iface = proc_mkdir("iface", local->proc);
717 create_proc_read_entry("counters", 0, local->proc,
718 ieee80211_proc_counters_read, local);
719 create_proc_read_entry("config", 0, local->proc,
720 ieee80211_proc_config_read, local);
721 create_proc_read_entry("channels", 0, local->proc,
722 ieee80211_proc_channels_read, local);
723 create_proc_read_entry("rates", 0, local->proc,
724 ieee80211_proc_rates_read, local);
725 create_proc_read_entry("multicast", 0, local->proc,
726 ieee80211_proc_multicast_read, local);
727 create_proc_read_entry("debug", 0, local->proc,
728 ieee80211_proc_debug_read, local);
729 create_proc_read_entry("info", 0, local->proc,
730 ieee80211_proc_info_read, local);
731 ieee80211_proc_init_virtual(local->wdev);
735 void ieee80211_proc_deinit_interface(struct ieee80211_local *local)
740 ieee80211_proc_deinit_virtual(local->wdev);
741 remove_proc_entry("iface", local->proc);
742 remove_proc_entry("sta", local->proc);
743 remove_proc_entry("counters", local->proc);
744 remove_proc_entry("debug", local->proc);
745 remove_proc_entry("config", local->proc);
746 remove_proc_entry("channels", local->proc);
747 remove_proc_entry("rates", local->proc);
748 remove_proc_entry("multicast", local->proc);
749 remove_proc_entry("info", local->proc);
751 remove_proc_entry(local->wdev->name, ieee80211_proc);
755 void ieee80211_proc_init(void)
757 if (proc_net == NULL) {
758 ieee80211_proc = NULL;
762 ieee80211_proc = proc_mkdir("ieee80211", proc_net);
764 printk(KERN_WARNING "Failed to mkdir /proc/net/ieee80211\n");
768 void ieee80211_proc_deinit(void)
773 ieee80211_proc = NULL;
774 remove_proc_entry("ieee80211", proc_net);
777 #endif /* CONFIG_PROC_FS */