blob: 864e01a736c87c396eaccd1f741f80c8f4404527 [file] [log] [blame]
Henk de Groot68c0bdf2009-09-27 11:12:52 +02001/*
2 * ex: sw=4
3 */
4
5#include <linux/kernel.h>
6#include <linux/netdevice.h>
7#include <linux/if_arp.h>
8#include <net/sock.h>
9#include <linux/rtnetlink.h>
10#include <linux/wireless.h>
11#include <net/iw_handler.h>
12#include <linux/sysfs.h>
13
14#include <debug.h>
15#include <hcf.h>
16#include <hcfdef.h>
17
18#include <wl_if.h>
19#include <wl_internal.h>
20#include <wl_util.h>
21#include <wl_main.h>
22#include <wl_wext.h>
23#include <wl_priv.h>
24
25static inline int dev_isalive(const struct net_device *dev)
26{
27 return dev->reg_state == NETREG_REGISTERED;
28}
29
30/*
31 * empirically even if tallies are defined as 32 bits entities, only
32 * high 16 bits are relevant; low half is always zero. It means tallies
33 * are pretty much useless for traffic counting but at least give overview
34 * about where error come from
35 */
36static ssize_t show_tallies(struct device *d, struct device_attribute *attr,
37 char *buf)
38{
39 struct net_device *dev = to_net_dev(d);
40 struct wl_private *lp = wl_priv(dev);
41 unsigned long flags;
42 CFG_HERMES_TALLIES_STRCT tallies;
43 ssize_t ret = -EINVAL;
44
45 read_lock(&dev_base_lock);
46 if (dev_isalive(dev)) {
47 wl_lock(lp, &flags);
48
49 if ((ret = wl_get_tallies(lp, &tallies)) == 0) {
50 wl_unlock(lp, &flags);
51 ret = snprintf(buf, PAGE_SIZE,
52 "TxUnicastFrames: %u\n"
53 "TxMulticastFrames: %u\n"
54 "TxFragments: %u\n"
55 "TxUnicastOctets: %u\n"
56 "TxMulticastOctets: %u\n"
57 "TxDeferredTransmissions: %u\n"
58 "TxSingleRetryFrames: %u\n"
59 "TxMultipleRetryFrames: %u\n"
60 "TxRetryLimitExceeded: %u\n"
61 "TxDiscards: %u\n"
62 "RxUnicastFrames: %u\n"
63 "RxMulticastFrames: %u\n"
64 "RxFragments: %u\n"
65 "RxUnicastOctets: %u\n"
66 "RxMulticastOctets: %u\n"
67 "RxFCSErrors: %u\n"
68 "RxDiscardsNoBuffer: %u\n"
69 "TxDiscardsWrongSA: %u\n"
70 "RxWEPUndecryptable: %u\n"
71 "RxMsgInMsgFragments: %u\n"
72 "RxMsgInBadMsgFragments: %u\n"
73 "RxDiscardsWEPICVError: %u\n"
74 "RxDiscardsWEPExcluded: %u\n"
75 ,
76 (unsigned int)tallies.TxUnicastFrames,
77 (unsigned int)tallies.TxMulticastFrames,
78 (unsigned int)tallies.TxFragments,
79 (unsigned int)tallies.TxUnicastOctets,
80 (unsigned int)tallies.TxMulticastOctets,
81 (unsigned int)tallies.TxDeferredTransmissions,
82 (unsigned int)tallies.TxSingleRetryFrames,
83 (unsigned int)tallies.TxMultipleRetryFrames,
84 (unsigned int)tallies.TxRetryLimitExceeded,
85 (unsigned int)tallies.TxDiscards,
86 (unsigned int)tallies.RxUnicastFrames,
87 (unsigned int)tallies.RxMulticastFrames,
88 (unsigned int)tallies.RxFragments,
89 (unsigned int)tallies.RxUnicastOctets,
90 (unsigned int)tallies.RxMulticastOctets,
91 (unsigned int)tallies.RxFCSErrors,
92 (unsigned int)tallies.RxDiscardsNoBuffer,
93 (unsigned int)tallies.TxDiscardsWrongSA,
94 (unsigned int)tallies.RxWEPUndecryptable,
95 (unsigned int)tallies.RxMsgInMsgFragments,
96 (unsigned int)tallies.RxMsgInBadMsgFragments,
97 (unsigned int)tallies.RxDiscardsWEPICVError,
98 (unsigned int)tallies.RxDiscardsWEPExcluded);
99 } else {
100 wl_unlock( lp, &flags );
101 }
102 }
103
104 read_unlock(&dev_base_lock);
105 return ret;
106}
107
108static DEVICE_ATTR(tallies, S_IRUGO, show_tallies, NULL);
109
110static struct attribute *wlags_attrs[] = {
111 &dev_attr_tallies.attr,
112 NULL
113};
114
115static struct attribute_group wlags_group = {
116 .name = "wlags",
117 .attrs = wlags_attrs,
118};
119
120void register_wlags_sysfs(struct net_device *net)
121{
122 struct device *dev = &(net->dev);
123 struct wl_private *lp = wl_priv(net);
124
125 lp->sysfsCreated = sysfs_create_group(&dev->kobj, &wlags_group);
126}
127
128void unregister_wlags_sysfs(struct net_device *net)
129{
130 struct device *dev = &(net->dev);
131 struct wl_private *lp = wl_priv(net);
132
133 if (lp->sysfsCreated)
134 sysfs_remove_group(&dev->kobj, &wlags_group);
135}