1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40#include <linux/module.h>
41#include <linux/moduleparam.h>
42
43#include <linux/uaccess.h>
44#include <linux/bitops.h>
45#include <linux/string.h>
46#include <linux/tty.h>
47#include <linux/errno.h>
48#include <linux/netdevice.h>
49#include <linux/skbuff.h>
50#include <linux/rtnetlink.h>
51#include <linux/if_arp.h>
52#include <linux/if_ether.h>
53#include <linux/sched.h>
54#include <linux/delay.h>
55#include <linux/init.h>
56#include <linux/kernel.h>
57#include <linux/can.h>
58#include <linux/can/skb.h>
59
60static __initconst const char banner[] =
61 KERN_INFO "slcan: serial line CAN interface driver\n";
62
63MODULE_ALIAS_LDISC(N_SLCAN);
64MODULE_DESCRIPTION("serial line CAN interface");
65MODULE_LICENSE("GPL");
66MODULE_AUTHOR("Oliver Hartkopp <socketcan@hartkopp.net>");
67
68#define SLCAN_MAGIC 0x53CA
69
70static int maxdev = 10;
71
72
73module_param(maxdev, int, 0);
74MODULE_PARM_DESC(maxdev, "Maximum number of slcan interfaces");
75
76
77#define SLC_MTU (sizeof("T1111222281122334455667788EA5F\r")+1)
78
79struct slcan {
80 int magic;
81
82
83 struct tty_struct *tty;
84 struct net_device *dev;
85 spinlock_t lock;
86
87
88 unsigned char rbuff[SLC_MTU];
89 int rcount;
90 unsigned char xbuff[SLC_MTU];
91 unsigned char *xhead;
92 int xleft;
93
94 unsigned long flags;
95#define SLF_INUSE 0
96#define SLF_ERROR 1
97};
98
99static struct net_device **slcan_devs;
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141static void slc_bump(struct slcan *sl)
142{
143 struct sk_buff *skb;
144 struct can_frame cf;
145 int i, dlc_pos, tmp;
146 unsigned long ultmp;
147 char cmd = sl->rbuff[0];
148
149 if ((cmd != 't') && (cmd != 'T') && (cmd != 'r') && (cmd != 'R'))
150 return;
151
152 if (cmd & 0x20)
153 dlc_pos = 4;
154 else
155 dlc_pos = 9;
156
157 if (!((sl->rbuff[dlc_pos] >= '0') && (sl->rbuff[dlc_pos] < '9')))
158 return;
159
160 cf.can_dlc = sl->rbuff[dlc_pos] - '0';
161
162 sl->rbuff[dlc_pos] = 0;
163
164 if (strict_strtoul(sl->rbuff+1, 16, &ultmp))
165 return;
166
167 cf.can_id = ultmp;
168
169 if (!(cmd & 0x20))
170 cf.can_id |= CAN_EFF_FLAG;
171
172 if ((cmd | 0x20) == 'r')
173 cf.can_id |= CAN_RTR_FLAG;
174
175 *(u64 *) (&cf.data) = 0;
176
177 for (i = 0, dlc_pos++; i < cf.can_dlc; i++) {
178 tmp = hex_to_bin(sl->rbuff[dlc_pos++]);
179 if (tmp < 0)
180 return;
181 cf.data[i] = (tmp << 4);
182 tmp = hex_to_bin(sl->rbuff[dlc_pos++]);
183 if (tmp < 0)
184 return;
185 cf.data[i] |= tmp;
186 }
187
188 skb = dev_alloc_skb(sizeof(struct can_frame) +
189 sizeof(struct can_skb_priv));
190 if (!skb)
191 return;
192
193 skb->dev = sl->dev;
194 skb->protocol = htons(ETH_P_CAN);
195 skb->pkt_type = PACKET_BROADCAST;
196 skb->ip_summed = CHECKSUM_UNNECESSARY;
197
198 can_skb_reserve(skb);
199 can_skb_prv(skb)->ifindex = sl->dev->ifindex;
200
201 memcpy(skb_put(skb, sizeof(struct can_frame)),
202 &cf, sizeof(struct can_frame));
203 netif_rx_ni(skb);
204
205 sl->dev->stats.rx_packets++;
206 sl->dev->stats.rx_bytes += cf.can_dlc;
207}
208
209
210static void slcan_unesc(struct slcan *sl, unsigned char s)
211{
212
213 if ((s == '\r') || (s == '\a')) {
214 if (!test_and_clear_bit(SLF_ERROR, &sl->flags) &&
215 (sl->rcount > 4)) {
216 slc_bump(sl);
217 }
218 sl->rcount = 0;
219 } else {
220 if (!test_bit(SLF_ERROR, &sl->flags)) {
221 if (sl->rcount < SLC_MTU) {
222 sl->rbuff[sl->rcount++] = s;
223 return;
224 } else {
225 sl->dev->stats.rx_over_errors++;
226 set_bit(SLF_ERROR, &sl->flags);
227 }
228 }
229 }
230}
231
232
233
234
235
236
237static void slc_encaps(struct slcan *sl, struct can_frame *cf)
238{
239 int actual, idx, i;
240 char cmd;
241
242 if (cf->can_id & CAN_RTR_FLAG)
243 cmd = 'R';
244 else
245 cmd = 'T';
246
247 if (cf->can_id & CAN_EFF_FLAG)
248 sprintf(sl->xbuff, "%c%08X%d", cmd,
249 cf->can_id & CAN_EFF_MASK, cf->can_dlc);
250 else
251 sprintf(sl->xbuff, "%c%03X%d", cmd | 0x20,
252 cf->can_id & CAN_SFF_MASK, cf->can_dlc);
253
254 idx = strlen(sl->xbuff);
255
256 for (i = 0; i < cf->can_dlc; i++)
257 sprintf(&sl->xbuff[idx + 2*i], "%02X", cf->data[i]);
258
259 strcat(sl->xbuff, "\r");
260
261
262
263
264
265
266
267
268
269 set_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
270 actual = sl->tty->ops->write(sl->tty, sl->xbuff, strlen(sl->xbuff));
271 sl->xleft = strlen(sl->xbuff) - actual;
272 sl->xhead = sl->xbuff + actual;
273 sl->dev->stats.tx_bytes += cf->can_dlc;
274}
275
276
277
278
279
280static void slcan_write_wakeup(struct tty_struct *tty)
281{
282 int actual;
283 struct slcan *sl = (struct slcan *) tty->disc_data;
284
285
286 if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev))
287 return;
288
289 if (sl->xleft <= 0) {
290
291
292 sl->dev->stats.tx_packets++;
293 clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
294 netif_wake_queue(sl->dev);
295 return;
296 }
297
298 actual = tty->ops->write(tty, sl->xhead, sl->xleft);
299 sl->xleft -= actual;
300 sl->xhead += actual;
301}
302
303
304static netdev_tx_t slc_xmit(struct sk_buff *skb, struct net_device *dev)
305{
306 struct slcan *sl = netdev_priv(dev);
307
308 if (skb->len != sizeof(struct can_frame))
309 goto out;
310
311 spin_lock(&sl->lock);
312 if (!netif_running(dev)) {
313 spin_unlock(&sl->lock);
314 printk(KERN_WARNING "%s: xmit: iface is down\n", dev->name);
315 goto out;
316 }
317 if (sl->tty == NULL) {
318 spin_unlock(&sl->lock);
319 goto out;
320 }
321
322 netif_stop_queue(sl->dev);
323 slc_encaps(sl, (struct can_frame *) skb->data);
324 spin_unlock(&sl->lock);
325
326out:
327 kfree_skb(skb);
328 return NETDEV_TX_OK;
329}
330
331
332
333
334
335
336
337static int slc_close(struct net_device *dev)
338{
339 struct slcan *sl = netdev_priv(dev);
340
341 spin_lock_bh(&sl->lock);
342 if (sl->tty) {
343
344 clear_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
345 }
346 netif_stop_queue(dev);
347 sl->rcount = 0;
348 sl->xleft = 0;
349 spin_unlock_bh(&sl->lock);
350
351 return 0;
352}
353
354
355static int slc_open(struct net_device *dev)
356{
357 struct slcan *sl = netdev_priv(dev);
358
359 if (sl->tty == NULL)
360 return -ENODEV;
361
362 sl->flags &= (1 << SLF_INUSE);
363 netif_start_queue(dev);
364 return 0;
365}
366
367
368static void slc_free_netdev(struct net_device *dev)
369{
370 int i = dev->base_addr;
371 free_netdev(dev);
372 slcan_devs[i] = NULL;
373}
374
375static const struct net_device_ops slc_netdev_ops = {
376 .ndo_open = slc_open,
377 .ndo_stop = slc_close,
378 .ndo_start_xmit = slc_xmit,
379};
380
381static void slc_setup(struct net_device *dev)
382{
383 dev->netdev_ops = &slc_netdev_ops;
384 dev->destructor = slc_free_netdev;
385
386 dev->hard_header_len = 0;
387 dev->addr_len = 0;
388 dev->tx_queue_len = 10;
389
390 dev->mtu = sizeof(struct can_frame);
391 dev->type = ARPHRD_CAN;
392
393
394 dev->flags = IFF_NOARP;
395 dev->features = NETIF_F_HW_CSUM;
396}
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411static void slcan_receive_buf(struct tty_struct *tty,
412 const unsigned char *cp, char *fp, int count)
413{
414 struct slcan *sl = (struct slcan *) tty->disc_data;
415
416 if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev))
417 return;
418
419
420 while (count--) {
421 if (fp && *fp++) {
422 if (!test_and_set_bit(SLF_ERROR, &sl->flags))
423 sl->dev->stats.rx_errors++;
424 cp++;
425 continue;
426 }
427 slcan_unesc(sl, *cp++);
428 }
429}
430
431
432
433
434
435
436static void slc_sync(void)
437{
438 int i;
439 struct net_device *dev;
440 struct slcan *sl;
441
442 for (i = 0; i < maxdev; i++) {
443 dev = slcan_devs[i];
444 if (dev == NULL)
445 break;
446
447 sl = netdev_priv(dev);
448 if (sl->tty)
449 continue;
450 if (dev->flags & IFF_UP)
451 dev_close(dev);
452 }
453}
454
455
456static struct slcan *slc_alloc(dev_t line)
457{
458 int i;
459 char name[IFNAMSIZ];
460 struct net_device *dev = NULL;
461 struct slcan *sl;
462
463 for (i = 0; i < maxdev; i++) {
464 dev = slcan_devs[i];
465 if (dev == NULL)
466 break;
467
468 }
469
470
471 if (i >= maxdev)
472 return NULL;
473
474 sprintf(name, "slcan%d", i);
475 dev = alloc_netdev(sizeof(*sl), name, slc_setup);
476 if (!dev)
477 return NULL;
478
479 dev->base_addr = i;
480 sl = netdev_priv(dev);
481
482
483 sl->magic = SLCAN_MAGIC;
484 sl->dev = dev;
485 spin_lock_init(&sl->lock);
486 slcan_devs[i] = dev;
487
488 return sl;
489}
490
491
492
493
494
495
496
497
498
499
500
501static int slcan_open(struct tty_struct *tty)
502{
503 struct slcan *sl;
504 int err;
505
506 if (!capable(CAP_NET_ADMIN))
507 return -EPERM;
508
509 if (tty->ops->write == NULL)
510 return -EOPNOTSUPP;
511
512
513
514
515
516 rtnl_lock();
517
518
519 slc_sync();
520
521 sl = tty->disc_data;
522
523 err = -EEXIST;
524
525 if (sl && sl->magic == SLCAN_MAGIC)
526 goto err_exit;
527
528
529 err = -ENFILE;
530 sl = slc_alloc(tty_devnum(tty));
531 if (sl == NULL)
532 goto err_exit;
533
534 sl->tty = tty;
535 tty->disc_data = sl;
536
537 if (!test_bit(SLF_INUSE, &sl->flags)) {
538
539 sl->rcount = 0;
540 sl->xleft = 0;
541
542 set_bit(SLF_INUSE, &sl->flags);
543
544 err = register_netdevice(sl->dev);
545 if (err)
546 goto err_free_chan;
547 }
548
549
550 rtnl_unlock();
551 tty->receive_room = 65536;
552
553
554 return 0;
555
556err_free_chan:
557 sl->tty = NULL;
558 tty->disc_data = NULL;
559 clear_bit(SLF_INUSE, &sl->flags);
560
561err_exit:
562 rtnl_unlock();
563
564
565 return err;
566}
567
568
569
570
571
572
573
574
575
576static void slcan_close(struct tty_struct *tty)
577{
578 struct slcan *sl = (struct slcan *) tty->disc_data;
579
580
581 if (!sl || sl->magic != SLCAN_MAGIC || sl->tty != tty)
582 return;
583
584 tty->disc_data = NULL;
585 sl->tty = NULL;
586
587
588 unregister_netdev(sl->dev);
589
590}
591
592static int slcan_hangup(struct tty_struct *tty)
593{
594 slcan_close(tty);
595 return 0;
596}
597
598
599static int slcan_ioctl(struct tty_struct *tty, struct file *file,
600 unsigned int cmd, unsigned long arg)
601{
602 struct slcan *sl = (struct slcan *) tty->disc_data;
603 unsigned int tmp;
604
605
606 if (!sl || sl->magic != SLCAN_MAGIC)
607 return -EINVAL;
608
609 switch (cmd) {
610 case SIOCGIFNAME:
611 tmp = strlen(sl->dev->name) + 1;
612 if (copy_to_user((void __user *)arg, sl->dev->name, tmp))
613 return -EFAULT;
614 return 0;
615
616 case SIOCSIFHWADDR:
617 return -EINVAL;
618
619 default:
620 return tty_mode_ioctl(tty, file, cmd, arg);
621 }
622}
623
624static struct tty_ldisc_ops slc_ldisc = {
625 .owner = THIS_MODULE,
626 .magic = TTY_LDISC_MAGIC,
627 .name = "slcan",
628 .open = slcan_open,
629 .close = slcan_close,
630 .hangup = slcan_hangup,
631 .ioctl = slcan_ioctl,
632 .receive_buf = slcan_receive_buf,
633 .write_wakeup = slcan_write_wakeup,
634};
635
636static int __init slcan_init(void)
637{
638 int status;
639
640 if (maxdev < 4)
641 maxdev = 4;
642
643 printk(banner);
644 printk(KERN_INFO "slcan: %d dynamic interface channels.\n", maxdev);
645
646 slcan_devs = kzalloc(sizeof(struct net_device *)*maxdev, GFP_KERNEL);
647 if (!slcan_devs)
648 return -ENOMEM;
649
650
651 status = tty_register_ldisc(N_SLCAN, &slc_ldisc);
652 if (status) {
653 printk(KERN_ERR "slcan: can't register line discipline\n");
654 kfree(slcan_devs);
655 }
656 return status;
657}
658
659static void __exit slcan_exit(void)
660{
661 int i;
662 struct net_device *dev;
663 struct slcan *sl;
664 unsigned long timeout = jiffies + HZ;
665 int busy = 0;
666
667 if (slcan_devs == NULL)
668 return;
669
670
671
672 do {
673 if (busy)
674 msleep_interruptible(100);
675
676 busy = 0;
677 for (i = 0; i < maxdev; i++) {
678 dev = slcan_devs[i];
679 if (!dev)
680 continue;
681 sl = netdev_priv(dev);
682 spin_lock_bh(&sl->lock);
683 if (sl->tty) {
684 busy++;
685 tty_hangup(sl->tty);
686 }
687 spin_unlock_bh(&sl->lock);
688 }
689 } while (busy && time_before(jiffies, timeout));
690
691
692
693
694 for (i = 0; i < maxdev; i++) {
695 dev = slcan_devs[i];
696 if (!dev)
697 continue;
698 slcan_devs[i] = NULL;
699
700 sl = netdev_priv(dev);
701 if (sl->tty) {
702 printk(KERN_ERR "%s: tty discipline still running\n",
703 dev->name);
704
705 dev->destructor = NULL;
706 }
707
708 unregister_netdev(dev);
709 }
710
711 kfree(slcan_devs);
712 slcan_devs = NULL;
713
714 i = tty_unregister_ldisc(N_SLCAN);
715 if (i)
716 printk(KERN_ERR "slcan: can't unregister ldisc (err %d)\n", i);
717}
718
719module_init(slcan_init);
720module_exit(slcan_exit);
721