]> rtime.felk.cvut.cz Git - socketcan-devel.git/blob - kernel/2.6/drivers/net/can/sysfs.c
Add modifiers for sampling-point and sjw to can_if start/stop script.
[socketcan-devel.git] / kernel / 2.6 / drivers / net / can / sysfs.c
1 /*
2  * $Id: dev.c 542 2007-11-07 13:57:16Z thuermann $
3  *
4  * Copyright (C) 2007-2008 Wolfgang Grandegger <wg@grandegger.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the version 2 of the GNU General Public License
8  * as published by the Free Software Foundation
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19
20 #include <linux/capability.h>
21 #include <linux/kernel.h>
22 #include <linux/version.h>
23 #include <linux/netdevice.h>
24 #include <linux/if_arp.h>
25 #include <net/sock.h>
26 #include <linux/rtnetlink.h>
27
28 #include <socketcan/can.h>
29 #include <socketcan/can/dev.h>
30
31 #include "sysfs.h"
32
33 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
34 int strict_strtoul(const char *cp, unsigned int base, unsigned long *res)
35 {
36         char *tail;
37         unsigned long val;
38         size_t len;
39
40         *res = 0;
41         len = strlen(cp);
42         if (len == 0)
43                 return -EINVAL;
44
45         val = simple_strtoul(cp, &tail, base);
46         if ((*tail == '\0') ||
47                 ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {
48                 *res = val;
49                 return 0;
50         }
51
52         return -EINVAL;
53 }
54 #endif
55
56 #ifdef CONFIG_SYSFS
57
58 /*
59  * SYSFS access functions and attributes. Use same locking as
60  * net/core/net-sysfs.c does.
61  */
62 static inline int dev_isalive(const struct net_device *dev)
63 {
64         return dev->reg_state <= NETREG_REGISTERED;
65 }
66
67 /* use same locking rules as GIF* ioctl's */
68 static ssize_t can_dev_show(struct device *d,
69                             struct device_attribute *attr, char *buf,
70                             ssize_t (*fmt)(struct net_device *, char *))
71 {
72         struct net_device *dev = to_net_dev(d);
73         ssize_t ret = -EINVAL;
74
75         read_lock(&dev_base_lock);
76         if (dev_isalive(dev))
77                 ret = (*fmt)(dev, buf);
78         read_unlock(&dev_base_lock);
79
80         return ret;
81 }
82
83 /* generate a show function for simple field */
84 #define CAN_DEV_SHOW(field, fmt_string)                                 \
85 static ssize_t fmt_can_##field(struct net_device *dev, char *buf)       \
86 {                                                                       \
87         struct can_priv *priv = netdev_priv(dev);                       \
88         return sprintf(buf, fmt_string, priv->field);                   \
89 }                                                                       \
90 static ssize_t show_can_##field(struct device *d,                       \
91                                 struct device_attribute *attr,          \
92                                 char *buf)                              \
93 {                                                                       \
94         return can_dev_show(d, attr, buf, fmt_can_##field);             \
95 }
96
97 /* use same locking and permission rules as SIF* ioctl's */
98 static ssize_t can_dev_store(struct device *d, struct device_attribute *attr,
99                              const char *buf, size_t len,
100                              int (*set)(struct net_device *, unsigned long))
101 {
102         struct net_device *dev = to_net_dev(d);
103         unsigned long new;
104         int ret = -EINVAL;
105
106         if (!capable(CAP_NET_ADMIN))
107                 return -EPERM;
108
109         ret = strict_strtoul(buf, 0, &new);
110         if (ret)
111                 goto out;
112
113         rtnl_lock();
114         if (dev_isalive(dev)) {
115                 ret = (*set)(dev, new);
116                 if (!ret)
117                         ret = len;
118         }
119         rtnl_unlock();
120 out:
121         return ret;
122 }
123
124 #define CAN_CREATE_FILE(_dev, _name)                                    \
125         if (device_create_file(&_dev->dev, &dev_attr_##_name))          \
126                 dev_err(ND2D(_dev),                                     \
127                         "Couldn't create device file for ##_name\n")
128
129 #define CAN_REMOVE_FILE(_dev, _name)                                    \
130         device_remove_file(&_dev->dev, &dev_attr_##_name)               \
131
132 CAN_DEV_SHOW(ctrlmode, "0x%x\n");
133
134 static int change_can_ctrlmode(struct net_device *dev, unsigned long ctrlmode)
135 {
136         struct can_priv *priv = netdev_priv(dev);
137
138         if (priv->state != CAN_STATE_STOPPED)
139                 return -EBUSY;
140
141         priv->ctrlmode = ctrlmode;
142
143         return 0;
144 }
145
146 static ssize_t store_can_ctrlmode(struct device *dev,
147                                   struct device_attribute *attr,
148                                   const char *buf, size_t len)
149 {
150         return can_dev_store(dev, attr, buf, len, change_can_ctrlmode);
151 }
152
153 static DEVICE_ATTR(can_ctrlmode, S_IRUGO | S_IWUSR,
154                    show_can_ctrlmode, store_can_ctrlmode);
155
156 static const char *can_state_names[] = {
157         "active", "bus-warn", "bus-pass" , "bus-off",
158         "stopped", "sleeping", "unkown"
159 };
160
161 static ssize_t printf_can_state(struct net_device *dev, char *buf)
162 {
163         struct can_priv *priv = netdev_priv(dev);
164         enum can_state state;
165         int err = 0;
166
167         if (priv->do_get_state) {
168                 err = priv->do_get_state(dev, &state);
169                 if (err)
170                         goto out;
171                 priv->state = state;
172         } else
173                 state = priv->state;
174
175         if (state >= ARRAY_SIZE(can_state_names))
176                 state = ARRAY_SIZE(can_state_names) - 1;
177         err = sprintf(buf, "%s\n", can_state_names[state]);
178 out:
179         return err;
180 }
181
182 static ssize_t show_can_state(struct device *d,
183                               struct device_attribute *attr, char *buf)
184 {
185         return can_dev_show(d, attr, buf, printf_can_state);
186 }
187
188 static DEVICE_ATTR(can_state, S_IRUGO, show_can_state, NULL);
189
190 CAN_DEV_SHOW(restart_ms, "%d\n");
191
192 static int change_can_restart_ms(struct net_device *dev, unsigned long ms)
193 {
194         struct can_priv *priv = netdev_priv(dev);
195
196         if (priv->restart_ms < 0)
197                 return -EOPNOTSUPP;
198         if (priv->state != CAN_STATE_STOPPED)
199                 return -EBUSY;
200         priv->restart_ms = ms;
201         return 0;
202 }
203
204 static ssize_t store_can_restart_ms(struct device *dev,
205                                     struct device_attribute *attr,
206                                     const char *buf, size_t len)
207 {
208         return can_dev_store(dev, attr, buf, len, change_can_restart_ms);
209 }
210
211 static DEVICE_ATTR(can_restart_ms, S_IRUGO | S_IWUSR,
212                    show_can_restart_ms, store_can_restart_ms);
213
214 static ssize_t printf_can_echo(struct net_device *dev, char *buf)
215 {
216         return sprintf(buf, "%d\n", dev->flags & IFF_ECHO ? 1 : 0);
217 }
218
219 static ssize_t show_can_echo(struct device *d,
220                           struct device_attribute *attr, char *buf)
221 {
222         return can_dev_show(d, attr, buf, printf_can_echo);
223 }
224
225 static int change_can_echo(struct net_device *dev, unsigned long on)
226 {
227         if (on)
228                 dev->flags |= IFF_ECHO;
229         else
230                 dev->flags &= ~IFF_ECHO;
231         return 0;
232 }
233
234 static ssize_t store_can_echo(struct device *dev,
235                               struct device_attribute *attr,
236                               const char *buf, size_t len)
237 {
238         return can_dev_store(dev, attr, buf, len, change_can_echo);
239 }
240
241 static DEVICE_ATTR(can_echo, S_IRUGO | S_IWUSR, show_can_echo, store_can_echo);
242
243 static int change_can_restart(struct net_device *dev, unsigned long on)
244 {
245         return can_restart_now(dev);
246 }
247
248 static ssize_t store_can_restart(struct device *dev,
249                                  struct device_attribute *attr,
250                                  const char *buf, size_t len)
251 {
252         return can_dev_store(dev, attr, buf, len, change_can_restart);
253 }
254
255 static DEVICE_ATTR(can_restart, S_IWUSR, NULL, store_can_restart);
256
257 /* Show a given attribute if the CAN bittiming group */
258 static ssize_t can_btc_show(const struct device *d,
259                             struct device_attribute *attr, char *buf,
260                             unsigned long offset)
261 {
262         struct net_device *dev = to_net_dev(d);
263         struct can_priv *priv = netdev_priv(dev);
264         struct can_bittiming_const *btc = priv->bittiming_const;
265         ssize_t ret = -EINVAL;
266
267         WARN_ON(offset >= sizeof(struct can_bittiming_const) ||
268                 offset % sizeof(u32) != 0);
269
270         read_lock(&dev_base_lock);
271         if (dev_isalive(dev) && btc)
272                 ret = sprintf(buf, "%d\n",
273                               *(u32 *)(((u8 *)btc) + offset));
274
275         read_unlock(&dev_base_lock);
276         return ret;
277 }
278
279 /* Generate a read-only bittiming const attribute */
280 #define CAN_BT_CONST_ENTRY(name)                                        \
281 static ssize_t show_##name(struct device *d,                            \
282                            struct device_attribute *attr, char *buf)    \
283 {                                                                       \
284         return can_btc_show(d, attr, buf,                               \
285                             offsetof(struct can_bittiming_const, name));\
286 }                                                                       \
287 static DEVICE_ATTR(hw_##name, S_IRUGO, show_##name, NULL)
288
289 CAN_BT_CONST_ENTRY(tseg1_min);
290 CAN_BT_CONST_ENTRY(tseg1_max);
291 CAN_BT_CONST_ENTRY(tseg2_min);
292 CAN_BT_CONST_ENTRY(tseg2_max);
293 CAN_BT_CONST_ENTRY(sjw_max);
294 CAN_BT_CONST_ENTRY(brp_min);
295 CAN_BT_CONST_ENTRY(brp_max);
296 CAN_BT_CONST_ENTRY(brp_inc);
297
298 static ssize_t can_bt_show(const struct device *d,
299                            struct device_attribute *attr, char *buf,
300                            unsigned long offset)
301 {
302         struct net_device *dev = to_net_dev(d);
303         struct can_priv *priv = netdev_priv(dev);
304         struct can_bittiming *bt = &priv->bittiming;
305         ssize_t ret = -EINVAL;
306         u32 *ptr, val;
307
308         WARN_ON(offset >= sizeof(struct can_bittiming) ||
309                 offset % sizeof(u32) != 0);
310
311         read_lock(&dev_base_lock);
312         if (dev_isalive(dev)) {
313                 ptr = (u32 *)(((u8 *)bt) + offset);
314                 if (ptr == &bt->sample_point &&
315                     priv->state != CAN_STATE_STOPPED)
316                         val = can_sample_point(bt);
317                 else
318                         val = *ptr;
319                 ret = sprintf(buf, "%d\n", val);
320         }
321         read_unlock(&dev_base_lock);
322         return ret;
323 }
324
325 static ssize_t can_bt_store(const struct device *d,
326                             struct device_attribute *attr,
327                             const char *buf, size_t count,
328                             unsigned long offset)
329 {
330         struct net_device *dev = to_net_dev(d);
331         struct can_priv *priv = netdev_priv(dev);
332         struct can_bittiming *bt = &priv->bittiming;
333         unsigned long new;
334         ssize_t ret = -EINVAL;
335         u32 *ptr;
336
337         if (priv->state != CAN_STATE_STOPPED)
338                 return -EBUSY;
339
340         WARN_ON(offset >= sizeof(struct can_bittiming) ||
341                 offset % sizeof(u32) != 0);
342
343         ret = strict_strtoul(buf, 0, &new);
344         if (ret)
345                 goto out;
346
347         ptr = (u32 *)(((u8 *)bt) + offset);
348         rtnl_lock();
349         if (dev_isalive(dev)) {
350                 *ptr = (u32)new;
351
352                 if ((ptr == &bt->bitrate) || (ptr == &bt->sample_point)) {
353                         bt->tq = 0;
354                         bt->brp = 0;
355                         bt->sjw = 0;
356                         bt->prop_seg = 0;
357                         bt->phase_seg1 = 0;
358                         bt->phase_seg2 = 0;
359                 } else {
360                         bt->bitrate = 0;
361                         bt->sample_point = 0;
362                 }
363                 ret = count;
364         }
365         rtnl_unlock();
366 out:
367         return ret;
368 }
369
370 static ssize_t fmt_can_clock(struct net_device *dev, char *buf)
371 {
372         struct can_priv *priv = netdev_priv(dev);
373
374         return sprintf(buf, "%d\n", priv->clock.freq);
375 }
376
377 static ssize_t show_can_clock(struct device *d,
378                               struct device_attribute *attr,
379                               char *buf)
380 {
381         return can_dev_show(d, attr, buf, fmt_can_clock);
382 }
383 static DEVICE_ATTR(hw_clock, S_IRUGO, show_can_clock, NULL);
384
385 #define CAN_BT_ENTRY(name)                                              \
386 static ssize_t show_##name(struct device *d,                            \
387                            struct device_attribute *attr, char *buf)    \
388 {                                                                       \
389         return can_bt_show(d, attr, buf,                                \
390                            offsetof(struct can_bittiming, name));       \
391 }                                                                       \
392 static ssize_t store_##name(struct device *d,                           \
393                             struct device_attribute *attr,              \
394                             const char *buf, size_t count)              \
395 {                                                                       \
396         return can_bt_store(d, attr, buf, count,                        \
397                             offsetof(struct can_bittiming, name));      \
398 }                                                                       \
399 static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_##name, store_##name)
400
401 CAN_BT_ENTRY(bitrate);
402 CAN_BT_ENTRY(sample_point);
403 CAN_BT_ENTRY(tq);
404 CAN_BT_ENTRY(prop_seg);
405 CAN_BT_ENTRY(phase_seg1);
406 CAN_BT_ENTRY(phase_seg2);
407 CAN_BT_ENTRY(sjw);
408
409 static struct attribute *can_bittiming_attrs[] = {
410         &dev_attr_hw_tseg1_min.attr,
411         &dev_attr_hw_tseg1_max.attr,
412         &dev_attr_hw_tseg2_max.attr,
413         &dev_attr_hw_tseg2_min.attr,
414         &dev_attr_hw_sjw_max.attr,
415         &dev_attr_hw_brp_min.attr,
416         &dev_attr_hw_brp_max.attr,
417         &dev_attr_hw_brp_inc.attr,
418         &dev_attr_hw_clock.attr,
419         &dev_attr_bitrate.attr,
420         &dev_attr_sample_point.attr,
421         &dev_attr_tq.attr,
422         &dev_attr_prop_seg.attr,
423         &dev_attr_phase_seg1.attr,
424         &dev_attr_phase_seg2.attr,
425         &dev_attr_sjw.attr,
426         NULL
427 };
428
429 /* Minimal number of attributes to support intelligent CAN controllers */
430 static struct attribute *can_bittiming_min_attrs[] = {
431         &dev_attr_bitrate.attr,
432         NULL
433 };
434
435 static struct attribute_group can_bittiming_group = {
436         .name = "can_bittiming",
437         .attrs = can_bittiming_attrs,
438 };
439
440 /* Show a given attribute in the CAN statistics group */
441 static ssize_t can_stat_show(const struct device *d,
442                              struct device_attribute *attr, char *buf,
443                              unsigned long offset)
444 {
445         struct net_device *dev = to_net_dev(d);
446         struct can_priv *priv = netdev_priv(dev);
447         struct can_device_stats *stats = &priv->can_stats;
448         ssize_t ret = -EINVAL;
449
450         WARN_ON(offset >= sizeof(struct can_device_stats) ||
451                 offset % sizeof(unsigned long) != 0);
452
453         read_lock(&dev_base_lock);
454         if (dev_isalive(dev))
455                 ret = sprintf(buf, "%d\n",
456                               *(u32 *)(((u8 *)stats) + offset));
457
458         read_unlock(&dev_base_lock);
459         return ret;
460 }
461
462 /* Generate a read-only CAN statistics attribute */
463 #define CAN_STAT_ENTRY(name)                                            \
464 static ssize_t show_##name(struct device *d,                            \
465                            struct device_attribute *attr, char *buf)    \
466 {                                                                       \
467         return can_stat_show(d, attr, buf,                              \
468                              offsetof(struct can_device_stats, name));  \
469 }                                                                       \
470 static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
471
472 CAN_STAT_ENTRY(error_warning);
473 CAN_STAT_ENTRY(error_passive);
474 CAN_STAT_ENTRY(bus_off);
475 CAN_STAT_ENTRY(bus_error);
476 CAN_STAT_ENTRY(arbitration_lost);
477 CAN_STAT_ENTRY(restarts);
478
479 static struct attribute *can_statistics_attrs[] = {
480         &dev_attr_error_warning.attr,
481         &dev_attr_error_passive.attr,
482         &dev_attr_bus_off.attr,
483         &dev_attr_bus_error.attr,
484         &dev_attr_arbitration_lost.attr,
485         &dev_attr_restarts.attr,
486         NULL
487 };
488
489 static struct attribute_group can_statistics_group = {
490         .name = "can_statistics",
491         .attrs = can_statistics_attrs,
492 };
493
494 void can_create_sysfs(struct net_device *dev)
495 {
496         struct can_priv *priv = netdev_priv(dev);
497         int err;
498
499         CAN_CREATE_FILE(dev, can_ctrlmode);
500         CAN_CREATE_FILE(dev, can_echo);
501         CAN_CREATE_FILE(dev, can_restart);
502         CAN_CREATE_FILE(dev, can_state);
503         CAN_CREATE_FILE(dev, can_restart_ms);
504
505         err = sysfs_create_group(&(dev->dev.kobj),
506                                  &can_statistics_group);
507         if (err) {
508                 printk(KERN_EMERG
509                        "couldn't create sysfs group for CAN statistics\n");
510         }
511
512         if (!priv->bittiming_const)
513                 can_bittiming_group.attrs = can_bittiming_min_attrs;
514         err = sysfs_create_group(&(dev->dev.kobj), &can_bittiming_group);
515         if (err) {
516                 printk(KERN_EMERG "couldn't create sysfs "
517                        "group for CAN bittiming\n");
518         }
519 }
520
521 void can_remove_sysfs(struct net_device *dev)
522 {
523         struct can_priv *priv = netdev_priv(dev);
524
525         CAN_REMOVE_FILE(dev, can_ctrlmode);
526         CAN_REMOVE_FILE(dev, can_echo);
527         CAN_REMOVE_FILE(dev, can_state);
528         CAN_REMOVE_FILE(dev, can_restart);
529         CAN_REMOVE_FILE(dev, can_restart_ms);
530
531         sysfs_remove_group(&(dev->dev.kobj), &can_statistics_group);
532         if (priv->bittiming_const)
533                 sysfs_remove_group(&(dev->dev.kobj), &can_bittiming_group);
534 }
535
536 #endif /* CONFIG_SYSFS */
537
538
539