Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
wl_sysfs.c
Go to the documentation of this file.
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;
43  ssize_t ret = -EINVAL;
44 
45  rcu_read_lock();
46  if (dev_isalive(dev)) {
47  wl_lock(lp, &flags);
48 
49  ret = wl_get_tallies(lp, &tallies);
50  if (ret == 0) {
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  rcu_read_unlock();
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 
122 {
123  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;
129 }
130 
132 {
133  struct device *dev = &(net->dev);
134  struct wl_private *lp = wl_priv(net);
135 
136  if (lp->sysfsCreated)
137  sysfs_remove_group(&dev->kobj, &wlags_group);
138 }