Commit | Line | Data |
---|---|---|
68c0bdff HG |
1 | /* |
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 | ||
25 | static 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 | */ | |
36 | static 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 | ||
491dbc8d JP |
49 | ret = wl_get_tallies(lp, &tallies); |
50 | if (ret == 0) { | |
68c0bdff HG |
51 | 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 | ||
105 | read_unlock(&dev_base_lock); | |
106 | return ret; | |
107 | } | |
108 | ||
109 | static DEVICE_ATTR(tallies, S_IRUGO, show_tallies, NULL); | |
110 | ||
111 | static struct attribute *wlags_attrs[] = { | |
112 | &dev_attr_tallies.attr, | |
113 | NULL | |
114 | }; | |
115 | ||
116 | static struct attribute_group wlags_group = { | |
117 | .name = "wlags", | |
118 | .attrs = wlags_attrs, | |
119 | }; | |
120 | ||
121 | void register_wlags_sysfs(struct net_device *net) | |
122 | { | |
123 | struct device *dev = &(net->dev); | |
124 | struct wl_private *lp = wl_priv(net); | |
125 | ||
126 | lp->sysfsCreated = sysfs_create_group(&dev->kobj, &wlags_group); | |
127 | } | |
128 | ||
129 | void unregister_wlags_sysfs(struct net_device *net) | |
130 | { | |
131 | struct device *dev = &(net->dev); | |
132 | struct wl_private *lp = wl_priv(net); | |
133 | ||
134 | if (lp->sysfsCreated) | |
135 | sysfs_remove_group(&dev->kobj, &wlags_group); | |
136 | } |