blob: 1508f04b3c6f58a18e7af8c3fe7df519090aa7d3 [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
Eric Dumazet88923842010-10-29 15:19:27 +020045 rcu_read_lock();
Henk de Groot68c0bdf2009-09-27 11:12:52 +020046 if (dev_isalive(dev)) {
47 wl_lock(lp, &flags);
48
Joe Perches491dbc82010-03-24 22:17:07 -070049 ret = wl_get_tallies(lp, &tallies);
50 if (ret == 0) {
Henk de Groot68c0bdf2009-09-27 11:12:52 +020051 wl_unlock(lp, &flags);
52 ret = snprintf(buf, PAGE_SIZE,
53 "TxUnicastFrames: %u\n"
54 "TxMulticastFrames: %u\n"
55 "TxFragments: %u\n"
56 "TxUnicastOctets: %u\n"
57 "TxMulticastOctets: %u\n"
58 "TxDeferredTransmissions: %u\n"
59 "TxSingleRetryFrames: %u\n"
60 "TxMultipleRetryFrames: %u\n"
61 "TxRetryLimitExceeded: %u\n"
62 "TxDiscards: %u\n"
63 "RxUnicastFrames: %u\n"
64 "RxMulticastFrames: %u\n"
65 "RxFragments: %u\n"
66 "RxUnicastOctets: %u\n"
67 "RxMulticastOctets: %u\n"
68 "RxFCSErrors: %u\n"
69 "RxDiscardsNoBuffer: %u\n"
70 "TxDiscardsWrongSA: %u\n"
71 "RxWEPUndecryptable: %u\n"
72 "RxMsgInMsgFragments: %u\n"
73 "RxMsgInBadMsgFragments: %u\n"
74 "RxDiscardsWEPICVError: %u\n"
75 "RxDiscardsWEPExcluded: %u\n"
76 ,
77 (unsigned int)tallies.TxUnicastFrames,
78 (unsigned int)tallies.TxMulticastFrames,
79 (unsigned int)tallies.TxFragments,
80 (unsigned int)tallies.TxUnicastOctets,
81 (unsigned int)tallies.TxMulticastOctets,
82 (unsigned int)tallies.TxDeferredTransmissions,
83 (unsigned int)tallies.TxSingleRetryFrames,
84 (unsigned int)tallies.TxMultipleRetryFrames,
85 (unsigned int)tallies.TxRetryLimitExceeded,
86 (unsigned int)tallies.TxDiscards,
87 (unsigned int)tallies.RxUnicastFrames,
88 (unsigned int)tallies.RxMulticastFrames,
89 (unsigned int)tallies.RxFragments,
90 (unsigned int)tallies.RxUnicastOctets,
91 (unsigned int)tallies.RxMulticastOctets,
92 (unsigned int)tallies.RxFCSErrors,
93 (unsigned int)tallies.RxDiscardsNoBuffer,
94 (unsigned int)tallies.TxDiscardsWrongSA,
95 (unsigned int)tallies.RxWEPUndecryptable,
96 (unsigned int)tallies.RxMsgInMsgFragments,
97 (unsigned int)tallies.RxMsgInBadMsgFragments,
98 (unsigned int)tallies.RxDiscardsWEPICVError,
99 (unsigned int)tallies.RxDiscardsWEPExcluded);
100 } else {
101 wl_unlock( lp, &flags );
102 }
103 }
104
Eric Dumazet88923842010-10-29 15:19:27 +0200105 rcu_read_unlock();
Henk de Groot68c0bdf2009-09-27 11:12:52 +0200106 return ret;
107}
108
109static DEVICE_ATTR(tallies, S_IRUGO, show_tallies, NULL);
110
111static struct attribute *wlags_attrs[] = {
112 &dev_attr_tallies.attr,
113 NULL
114};
115
116static struct attribute_group wlags_group = {
117 .name = "wlags",
118 .attrs = wlags_attrs,
119};
120
121void register_wlags_sysfs(struct net_device *net)
122{
David Kilroy1ca61672011-10-09 12:11:31 +0100123 struct device *dev = &(net->dev);
124 struct wl_private *lp = wl_priv(net);
125 int err;
126 err = sysfs_create_group(&dev->kobj, &wlags_group);
127 if (!err)
128 lp->sysfsCreated = true;
Henk de Groot68c0bdf2009-09-27 11:12:52 +0200129}
130
131void unregister_wlags_sysfs(struct net_device *net)
132{
David Kilroy1ca61672011-10-09 12:11:31 +0100133 struct device *dev = &(net->dev);
134 struct wl_private *lp = wl_priv(net);
Henk de Groot68c0bdf2009-09-27 11:12:52 +0200135
David Kilroy1ca61672011-10-09 12:11:31 +0100136 if (lp->sysfsCreated)
137 sysfs_remove_group(&dev->kobj, &wlags_group);
Henk de Groot68c0bdf2009-09-27 11:12:52 +0200138}