[PATCH] Add a driver for the Technisat Skystar2 DVB card
[linux-2.6/history.git] / net / core / net-sysfs.c
blobfcb38de5ad40d146f006c05925080a56c61ec0f5
1 /*
2 * net-sysfs.c - network device class and attributes
4 * Copyright (c) 2003 Stephen Hemminger <shemminger@osdl.org>
5 *
6 */
8 #include <linux/config.h>
9 #include <linux/kernel.h>
10 #include <linux/netdevice.h>
11 #include <linux/if_arp.h>
12 #include <net/sock.h>
13 #include <linux/rtnetlink.h>
15 #define to_class_dev(obj) container_of(obj,struct class_device,kobj)
16 #define to_net_dev(class) container_of(class, struct net_device, class_dev)
18 static inline int dev_isalive(const struct net_device *dev)
20 return dev->reg_state == NETREG_REGISTERED;
23 /* use same locking rules as GIF* ioctl's */
24 static ssize_t netdev_show(const struct class_device *cd, char *buf,
25 ssize_t (*format)(const struct net_device *, char *))
27 struct net_device *net = to_net_dev(cd);
28 ssize_t ret = -EINVAL;
30 read_lock(&dev_base_lock);
31 if (dev_isalive(net))
32 ret = (*format)(net, buf);
33 read_unlock(&dev_base_lock);
35 return ret;
38 /* generate a show function for simple field */
39 #define NETDEVICE_SHOW(field, format_string) \
40 static ssize_t format_##field(const struct net_device *net, char *buf) \
41 { \
42 return sprintf(buf, format_string, net->field); \
43 } \
44 static ssize_t show_##field(struct class_device *cd, char *buf) \
45 { \
46 return netdev_show(cd, buf, format_##field); \
50 /* use same locking and permission rules as SIF* ioctl's */
51 static ssize_t netdev_store(struct class_device *dev,
52 const char *buf, size_t len,
53 int (*set)(struct net_device *, unsigned long))
55 struct net_device *net = to_net_dev(dev);
56 char *endp;
57 unsigned long new;
58 int ret = -EINVAL;
60 if (!capable(CAP_NET_ADMIN))
61 return -EPERM;
63 new = simple_strtoul(buf, &endp, 0);
64 if (endp == buf)
65 goto err;
67 rtnl_lock();
68 if (dev_isalive(net)) {
69 if ((ret = (*set)(net, new)) == 0)
70 ret = len;
72 rtnl_unlock();
73 err:
74 return ret;
77 /* generate a read-only network device class attribute */
78 #define NETDEVICE_ATTR(field, format_string) \
79 NETDEVICE_SHOW(field, format_string) \
80 static CLASS_DEVICE_ATTR(field, S_IRUGO, show_##field, NULL) \
82 NETDEVICE_ATTR(addr_len, "%d\n");
83 NETDEVICE_ATTR(iflink, "%d\n");
84 NETDEVICE_ATTR(ifindex, "%d\n");
85 NETDEVICE_ATTR(features, "%#x\n");
86 NETDEVICE_ATTR(type, "%d\n");
88 /* use same locking rules as GIFHWADDR ioctl's */
89 static ssize_t format_addr(char *buf, const unsigned char *addr, int len)
91 int i;
92 char *cp = buf;
94 read_lock(&dev_base_lock);
95 for (i = 0; i < len; i++)
96 cp += sprintf(cp, "%02x%c", addr[i],
97 i == (len - 1) ? '\n' : ':');
98 read_unlock(&dev_base_lock);
99 return cp - buf;
102 static ssize_t show_address(struct class_device *dev, char *buf)
104 struct net_device *net = to_net_dev(dev);
105 if (dev_isalive(net))
106 return format_addr(buf, net->dev_addr, net->addr_len);
107 return -EINVAL;
110 static ssize_t show_broadcast(struct class_device *dev, char *buf)
112 struct net_device *net = to_net_dev(dev);
113 if (dev_isalive(net))
114 return format_addr(buf, net->broadcast, net->addr_len);
115 return -EINVAL;
118 static CLASS_DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
119 static CLASS_DEVICE_ATTR(broadcast, S_IRUGO, show_broadcast, NULL);
121 /* read-write attributes */
122 NETDEVICE_SHOW(mtu, "%d\n");
124 static int change_mtu(struct net_device *net, unsigned long new_mtu)
126 return dev_set_mtu(net, (int) new_mtu);
129 static ssize_t store_mtu(struct class_device *dev, const char *buf, size_t len)
131 return netdev_store(dev, buf, len, change_mtu);
134 static CLASS_DEVICE_ATTR(mtu, S_IRUGO | S_IWUSR, show_mtu, store_mtu);
136 NETDEVICE_SHOW(flags, "%#x\n");
138 static int change_flags(struct net_device *net, unsigned long new_flags)
140 return dev_change_flags(net, (unsigned) new_flags);
143 static ssize_t store_flags(struct class_device *dev, const char *buf, size_t len)
145 return netdev_store(dev, buf, len, change_flags);
148 static CLASS_DEVICE_ATTR(flags, S_IRUGO | S_IWUSR, show_flags, store_flags);
150 NETDEVICE_SHOW(tx_queue_len, "%lu\n");
152 static int change_tx_queue_len(struct net_device *net, unsigned long new_len)
154 net->tx_queue_len = new_len;
155 return 0;
158 static ssize_t store_tx_queue_len(struct class_device *dev, const char *buf, size_t len)
160 return netdev_store(dev, buf, len, change_tx_queue_len);
163 static CLASS_DEVICE_ATTR(tx_queue_len, S_IRUGO | S_IWUSR, show_tx_queue_len,
164 store_tx_queue_len);
167 static struct class_device_attribute *net_class_attributes[] = {
168 &class_device_attr_ifindex,
169 &class_device_attr_iflink,
170 &class_device_attr_addr_len,
171 &class_device_attr_tx_queue_len,
172 &class_device_attr_features,
173 &class_device_attr_mtu,
174 &class_device_attr_flags,
175 &class_device_attr_type,
176 &class_device_attr_address,
177 &class_device_attr_broadcast,
178 NULL
181 struct netstat_fs_entry {
182 struct attribute attr;
183 ssize_t (*show)(const struct net_device_stats *, char *);
184 ssize_t (*store)(struct net_device_stats *, const char *, size_t);
187 static ssize_t net_device_stat_show(unsigned long var, char *buf)
189 return sprintf(buf, "%ld\n", var);
192 /* generate a read-only statistics attribute */
193 #define NETDEVICE_STAT(_NAME) \
194 static ssize_t show_stat_##_NAME(const struct net_device_stats *stats, \
195 char *buf) \
197 return net_device_stat_show(stats->_NAME, buf); \
199 static struct netstat_fs_entry net_stat_##_NAME = { \
200 .attr = {.name = __stringify(_NAME), .mode = S_IRUGO }, \
201 .show = show_stat_##_NAME, \
204 NETDEVICE_STAT(rx_packets);
205 NETDEVICE_STAT(tx_packets);
206 NETDEVICE_STAT(rx_bytes);
207 NETDEVICE_STAT(tx_bytes);
208 NETDEVICE_STAT(rx_errors);
209 NETDEVICE_STAT(tx_errors);
210 NETDEVICE_STAT(rx_dropped);
211 NETDEVICE_STAT(tx_dropped);
212 NETDEVICE_STAT(multicast);
213 NETDEVICE_STAT(collisions);
214 NETDEVICE_STAT(rx_length_errors);
215 NETDEVICE_STAT(rx_over_errors);
216 NETDEVICE_STAT(rx_crc_errors);
217 NETDEVICE_STAT(rx_frame_errors);
218 NETDEVICE_STAT(rx_fifo_errors);
219 NETDEVICE_STAT(rx_missed_errors);
220 NETDEVICE_STAT(tx_aborted_errors);
221 NETDEVICE_STAT(tx_carrier_errors);
222 NETDEVICE_STAT(tx_fifo_errors);
223 NETDEVICE_STAT(tx_heartbeat_errors);
224 NETDEVICE_STAT(tx_window_errors);
225 NETDEVICE_STAT(rx_compressed);
226 NETDEVICE_STAT(tx_compressed);
228 static struct attribute *default_attrs[] = {
229 &net_stat_rx_packets.attr,
230 &net_stat_tx_packets.attr,
231 &net_stat_rx_bytes.attr,
232 &net_stat_tx_bytes.attr,
233 &net_stat_rx_errors.attr,
234 &net_stat_tx_errors.attr,
235 &net_stat_rx_dropped.attr,
236 &net_stat_tx_dropped.attr,
237 &net_stat_multicast.attr,
238 &net_stat_collisions.attr,
239 &net_stat_rx_length_errors.attr,
240 &net_stat_rx_over_errors.attr,
241 &net_stat_rx_crc_errors.attr,
242 &net_stat_rx_frame_errors.attr,
243 &net_stat_rx_fifo_errors.attr,
244 &net_stat_rx_missed_errors.attr,
245 &net_stat_tx_aborted_errors.attr,
246 &net_stat_tx_carrier_errors.attr,
247 &net_stat_tx_fifo_errors.attr,
248 &net_stat_tx_heartbeat_errors.attr,
249 &net_stat_tx_window_errors.attr,
250 &net_stat_rx_compressed.attr,
251 &net_stat_tx_compressed.attr,
252 NULL
256 static ssize_t
257 netstat_attr_show(struct kobject *kobj, struct attribute *attr, char *buf)
259 struct netstat_fs_entry *entry
260 = container_of(attr, struct netstat_fs_entry, attr);
261 struct net_device *dev
262 = to_net_dev(to_class_dev(kobj->parent));
263 struct net_device_stats *stats;
264 ssize_t ret = -EINVAL;
266 read_lock(&dev_base_lock);
267 if (dev_isalive(dev) && entry->show && dev->get_stats &&
268 (stats = (*dev->get_stats)(dev)))
269 ret = entry->show(stats, buf);
270 read_unlock(&dev_base_lock);
271 return ret;
274 static struct sysfs_ops netstat_sysfs_ops = {
275 .show = netstat_attr_show,
278 static struct kobj_type netstat_ktype = {
279 .sysfs_ops = &netstat_sysfs_ops,
280 .default_attrs = default_attrs,
283 #ifdef CONFIG_HOTPLUG
284 static int netdev_hotplug(struct class_device *cd, char **envp,
285 int num_envp, char *buf, int size)
287 struct net_device *dev = to_net_dev(cd);
288 int i = 0;
289 int n;
291 /* pass interface in env to hotplug. */
292 envp[i++] = buf;
293 n = snprintf(buf, size, "INTERFACE=%s", dev->name) + 1;
294 buf += n;
295 size -= n;
297 if ((size <= 0) || (i >= num_envp))
298 return -ENOMEM;
300 envp[i] = 0;
301 return 0;
303 #endif
305 static struct class net_class = {
306 .name = "net",
307 #ifdef CONFIG_HOTPLUG
308 .hotplug = netdev_hotplug,
309 #endif
312 /* Create sysfs entries for network device. */
313 int netdev_register_sysfs(struct net_device *net)
315 struct class_device *class_dev = &(net->class_dev);
316 int i;
317 struct class_device_attribute *attr;
318 int ret;
320 class_dev->class = &net_class;
321 class_dev->class_data = net;
323 strlcpy(class_dev->class_id, net->name, BUS_ID_SIZE);
324 if ((ret = class_device_register(class_dev)))
325 goto out;
327 for (i = 0; (attr = net_class_attributes[i]); i++) {
328 if ((ret = class_device_create_file(class_dev, attr)))
329 goto out_unreg;
332 net->stats_kobj.parent = NULL;
333 if (net->get_stats) {
334 struct kobject *k = &net->stats_kobj;
336 k->parent = &class_dev->kobj;
337 strlcpy(k->name, "statistics", KOBJ_NAME_LEN);
338 k->ktype = &netstat_ktype;
340 if((ret = kobject_register(k)))
341 goto out_unreg;
344 out:
345 return ret;
346 out_unreg:
347 printk(KERN_WARNING "%s: sysfs attribute registration failed %d\n",
348 net->name, ret);
349 class_device_unregister(class_dev);
350 goto out;
353 void netdev_unregister_sysfs(struct net_device *net)
355 if (net->stats_kobj.parent)
356 kobject_unregister(&net->stats_kobj);
358 class_device_unregister(&net->class_dev);
361 int netdev_sysfs_init(void)
363 return class_register(&net_class);