mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
142 lines
3.6 KiB
142 lines
3.6 KiB
/* |
|
* This file implement the Wireless Extensions proc API. |
|
* |
|
* Authors : Jean Tourrilhes - HPL - <[email protected]> |
|
* Copyright (c) 1997-2007 Jean Tourrilhes, All Rights Reserved. |
|
* |
|
* (As all part of the Linux kernel, this file is GPL) |
|
*/ |
|
|
|
/* |
|
* The /proc/net/wireless file is a human readable user-space interface |
|
* exporting various wireless specific statistics from the wireless devices. |
|
* This is the most popular part of the Wireless Extensions ;-) |
|
* |
|
* This interface is a pure clone of /proc/net/dev (in net/core/dev.c). |
|
* The content of the file is basically the content of "struct iw_statistics". |
|
*/ |
|
|
|
#include <linux/module.h> |
|
#include <linux/proc_fs.h> |
|
#include <linux/seq_file.h> |
|
#include <linux/wireless.h> |
|
#include <linux/netdevice.h> |
|
#include <linux/rtnetlink.h> |
|
#include <net/iw_handler.h> |
|
#include <net/wext.h> |
|
|
|
|
|
static void wireless_seq_printf_stats(struct seq_file *seq, |
|
struct net_device *dev) |
|
{ |
|
/* Get stats from the driver */ |
|
struct iw_statistics *stats = get_wireless_stats(dev); |
|
static struct iw_statistics nullstats = {}; |
|
|
|
/* show device if it's wireless regardless of current stats */ |
|
if (!stats) { |
|
#ifdef CONFIG_WIRELESS_EXT |
|
if (dev->wireless_handlers) |
|
stats = &nullstats; |
|
#endif |
|
#ifdef CONFIG_CFG80211 |
|
if (dev->ieee80211_ptr) |
|
stats = &nullstats; |
|
#endif |
|
} |
|
|
|
if (stats) { |
|
seq_printf(seq, "%6s: %04x %3d%c %3d%c %3d%c %6d %6d %6d " |
|
"%6d %6d %6d\n", |
|
dev->name, stats->status, stats->qual.qual, |
|
stats->qual.updated & IW_QUAL_QUAL_UPDATED |
|
? '.' : ' ', |
|
((__s32) stats->qual.level) - |
|
((stats->qual.updated & IW_QUAL_DBM) ? 0x100 : 0), |
|
stats->qual.updated & IW_QUAL_LEVEL_UPDATED |
|
? '.' : ' ', |
|
((__s32) stats->qual.noise) - |
|
((stats->qual.updated & IW_QUAL_DBM) ? 0x100 : 0), |
|
stats->qual.updated & IW_QUAL_NOISE_UPDATED |
|
? '.' : ' ', |
|
stats->discard.nwid, stats->discard.code, |
|
stats->discard.fragment, stats->discard.retries, |
|
stats->discard.misc, stats->miss.beacon); |
|
|
|
if (stats != &nullstats) |
|
stats->qual.updated &= ~IW_QUAL_ALL_UPDATED; |
|
} |
|
} |
|
|
|
/* ---------------------------------------------------------------- */ |
|
/* |
|
* Print info for /proc/net/wireless (print all entries) |
|
*/ |
|
static int wireless_dev_seq_show(struct seq_file *seq, void *v) |
|
{ |
|
might_sleep(); |
|
|
|
if (v == SEQ_START_TOKEN) |
|
seq_printf(seq, "Inter-| sta-| Quality | Discarded " |
|
"packets | Missed | WE\n" |
|
" face | tus | link level noise | nwid " |
|
"crypt frag retry misc | beacon | %d\n", |
|
WIRELESS_EXT); |
|
else |
|
wireless_seq_printf_stats(seq, v); |
|
return 0; |
|
} |
|
|
|
static void *wireless_dev_seq_start(struct seq_file *seq, loff_t *pos) |
|
{ |
|
struct net *net = seq_file_net(seq); |
|
loff_t off; |
|
struct net_device *dev; |
|
|
|
rtnl_lock(); |
|
if (!*pos) |
|
return SEQ_START_TOKEN; |
|
|
|
off = 1; |
|
for_each_netdev(net, dev) |
|
if (off++ == *pos) |
|
return dev; |
|
return NULL; |
|
} |
|
|
|
static void *wireless_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) |
|
{ |
|
struct net *net = seq_file_net(seq); |
|
|
|
++*pos; |
|
|
|
return v == SEQ_START_TOKEN ? |
|
first_net_device(net) : next_net_device(v); |
|
} |
|
|
|
static void wireless_dev_seq_stop(struct seq_file *seq, void *v) |
|
{ |
|
rtnl_unlock(); |
|
} |
|
|
|
static const struct seq_operations wireless_seq_ops = { |
|
.start = wireless_dev_seq_start, |
|
.next = wireless_dev_seq_next, |
|
.stop = wireless_dev_seq_stop, |
|
.show = wireless_dev_seq_show, |
|
}; |
|
|
|
int __net_init wext_proc_init(struct net *net) |
|
{ |
|
/* Create /proc/net/wireless entry */ |
|
if (!proc_create_net("wireless", 0444, net->proc_net, |
|
&wireless_seq_ops, sizeof(struct seq_net_private))) |
|
return -ENOMEM; |
|
|
|
return 0; |
|
} |
|
|
|
void __net_exit wext_proc_exit(struct net *net) |
|
{ |
|
remove_proc_entry("wireless", net->proc_net); |
|
}
|
|
|