1 /*
2 * 6pack.c This module implements the 6pack protocol for kernel-based
3 * devices like TTY. It interfaces between a raw TTY and the
4 * kernel's AX.25 protocol layers.
5 *
6 * Version: @(#)6pack.c 0.3.0 04/07/98
7 *
8 * Authors: Andreas K�nsgen <ajk@iehk.rwth-aachen.de>
9 * Changes for SuSE Kernel 2.4.21-99 (stolen from 2.6.0-test8)
10 * to avoid the "resyncing TNC" messages:
11 * Tim Fischer <tim.fischer@onlinehome.de>
12 *
13 * Quite a lot of stuff "stolen" by J�rg Reuter from slip.c, written by
14 *
15 * Laurence Culhane, <loz@holmes.demon.co.uk>
16 * Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
17 *
18 */
19
20 #include <linux/config.h>
21 #include <linux/module.h>
22 #include <asm/system.h>
23 #include <asm/uaccess.h>
24 #include <asm/bitops.h>
25 #include <linux/string.h>
26 #include <linux/mm.h>
27 #include <linux/interrupt.h>
28 #include <linux/in.h>
29 #include <linux/tty.h>
30 #include <linux/errno.h>
31 #include <linux/netdevice.h>
32 #include <linux/timer.h>
33 #include <net/ax25.h>
34 #include <linux/etherdevice.h>
35 #include <linux/skbuff.h>
36 #include <linux/rtnetlink.h>
37 #include <linux/if_arp.h>
38 #include <linux/init.h>
39 #include <linux/ip.h>
40 #include <linux/tcp.h>
41
42 #define SIXPACK_VERSION "Revision: 0.3.0"
43
44 /* sixpack priority commands */
45 #define SIXP_SEOF 0x40 /* start and end of a 6pack frame */
46 #define SIXP_TX_URUN 0x48 /* transmit overrun */
47 #define SIXP_RX_ORUN 0x50 /* receive overrun */
48 #define SIXP_RX_BUF_OVL 0x58 /* receive buffer overflow */
49
50 #define SIXP_CHKSUM 0xFF /* valid checksum of a 6pack frame */
51
52 /* masks to get certain bits out of the status bytes sent by the TNC */
53
54 #define SIXP_CMD_MASK 0xC0
55 #define SIXP_CHN_MASK 0x07
56 #define SIXP_PRIO_CMD_MASK 0x80
57 #define SIXP_STD_CMD_MASK 0x40
58 #define SIXP_PRIO_DATA_MASK 0x38
59 #define SIXP_TX_MASK 0x20
60 #define SIXP_RX_MASK 0x10
61 #define SIXP_RX_DCD_MASK 0x18
62 #define SIXP_LEDS_ON 0x78
63 #define SIXP_LEDS_OFF 0x60
64 #define SIXP_CON 0x08
65 #define SIXP_STA 0x10
66
67 #define SIXP_FOUND_TNC 0xe9
68 #define SIXP_CON_ON 0x68
69 #define SIXP_DCD_MASK 0x08
70 #define SIXP_DAMA_OFF 0
71
72 /* default level 2 parameters */
73 #define SIXP_TXDELAY (HZ/4) /* in 1 s */
74 #define SIXP_PERSIST 50 /* in 256ths */
75 #define SIXP_SLOTTIME (HZ/10) /* in 1 s */
76 #define SIXP_INIT_RESYNC_TIMEOUT (3*HZ/2) /* in 1 s */
77 #define SIXP_RESYNC_TIMEOUT 5*HZ /* in 1 s */
78
79 /* 6pack configuration. */
80 #define SIXP_NRUNIT 31 /* MAX number of 6pack channels */
81 #define SIXP_MTU 256 /* Default MTU */
82
83 enum sixpack_flags {
84 SIXPF_INUSE, /* Channel in use */
85 SIXPF_ERROR, /* Parity, etc. error */
86 };
87
88 struct sixpack {
89 int magic;
90
91 /* Various fields. */
92 struct tty_struct *tty; /* ptr to TTY structure */
93 struct net_device *dev; /* easy for intr handling */
94
95 /* These are pointers to the malloc()ed frame buffers. */
96 unsigned char *rbuff; /* receiver buffer */
97 int rcount; /* received chars counter */
98 unsigned char *xbuff; /* transmitter buffer */
99 unsigned char *xhead; /* pointer to next byte to XMIT */
100 int xleft; /* bytes left in XMIT queue */
101
102 unsigned char raw_buf[4];
103 unsigned char cooked_buf[400];
104
105 unsigned int rx_count;
106 unsigned int rx_count_cooked;
107
108 /* 6pack interface statistics. */
109 struct net_device_stats stats;
110
111 int mtu; /* Our mtu (to spot changes!) */
112 int buffsize; /* Max buffers sizes */
113
114 unsigned long flags; /* Flag values/ mode etc */
115 unsigned char mode; /* 6pack mode */
116
117 /* 6pack stuff */
118 unsigned char tx_delay;
119 unsigned char persistance;
120 unsigned char slottime;
121 unsigned char duplex;
122 unsigned char led_state;
123 unsigned char status;
124 unsigned char status1;
125 unsigned char status2;
126 unsigned char tx_enable;
127 unsigned char tnc_ok;
128
129 struct timer_list tx_t;
130 struct timer_list resync_t;
131 };
132
133 #define AX25_6PACK_HEADER_LEN 0
134 #define SIXPACK_MAGIC 0x5304
135
136 typedef struct sixpack_ctrl {
137 struct sixpack ctrl; /* 6pack things */
138 struct net_device dev; /* the device */
139 } sixpack_ctrl_t;
140 static sixpack_ctrl_t **sixpack_ctrls;
141
142 int sixpack_maxdev = SIXP_NRUNIT; /* Can be overridden with insmod! */
143 MODULE_PARM(sixpack_maxdev, "i");
144 MODULE_PARM_DESC(sixpack_maxdev, "number of 6PACK devices");
145
146 static void sp_start_tx_timer(struct sixpack *);
147 static void sp_xmit_on_air(unsigned long);
148 static void resync_tnc(unsigned long);
149 static void sixpack_decode(struct sixpack *, unsigned char[], int);
150 static int encode_sixpack(unsigned char *, unsigned char *, int, unsigned char);
151 static int sixpack_init(struct net_device *dev);
152
153 static void decode_prio_command(unsigned char, struct sixpack *);
154 static void decode_std_command(unsigned char, struct sixpack *);
155 static void decode_data(unsigned char, struct sixpack *);
156
157 static int tnc_init(struct sixpack *);
158
159 /* Find a free 6pack channel, and link in this `tty' line. */
sp_alloc(void)160 static inline struct sixpack *sp_alloc(void)
161 {
162 sixpack_ctrl_t *spp = NULL;
163 int i;
164
165 for (i = 0; i < sixpack_maxdev; i++) {
166 spp = sixpack_ctrls[i];
167
168 if (spp == NULL)
169 break;
170
171 if (!test_and_set_bit(SIXPF_INUSE, &spp->ctrl.flags))
172 break;
173 }
174
175 /* Too many devices... */
176 if (i >= sixpack_maxdev)
177 return NULL;
178
179 /* If no channels are available, allocate one */
180 if (!spp &&
181 (sixpack_ctrls[i] = (sixpack_ctrl_t *)kmalloc(sizeof(sixpack_ctrl_t),
182 GFP_KERNEL)) != NULL) {
183 spp = sixpack_ctrls[i];
184 memset(spp, 0, sizeof(sixpack_ctrl_t));
185
186 /* Initialize channel control data */
187 set_bit(SIXPF_INUSE, &spp->ctrl.flags);
188 spp->ctrl.tty = NULL;
189 sprintf(spp->dev.name, "sp%d", i);
190 spp->dev.base_addr = i;
191 spp->dev.priv = (void *) &spp->ctrl;
192 spp->dev.next = NULL;
193 spp->dev.init = sixpack_init;
194 }
195
196 if (spp != NULL) {
197 /* register device so that it can be ifconfig'ed */
198 /* sixpack_init() will be called as a side-effect */
199 /* SIDE-EFFECT WARNING: sixpack_init() CLEARS spp->ctrl ! */
200
201 if (register_netdev(&spp->dev) == 0) {
202 set_bit(SIXPF_INUSE, &spp->ctrl.flags);
203 spp->ctrl.dev = &spp->dev;
204 spp->dev.priv = (void *) &spp->ctrl;
205 SET_MODULE_OWNER(&spp->dev);
206 return &spp->ctrl;
207 } else {
208 clear_bit(SIXPF_INUSE, &spp->ctrl.flags);
209 printk(KERN_WARNING "sp_alloc() - register_netdev() failure.\n");
210 }
211 }
212
213 return NULL;
214 }
215
216
217 /* Free a 6pack channel. */
sp_free(struct sixpack * sp)218 static inline void sp_free(struct sixpack *sp)
219 {
220 /* Free all 6pack frame buffers. */
221 if (sp->rbuff)
222 kfree(sp->rbuff);
223 sp->rbuff = NULL;
224 if (sp->xbuff)
225 kfree(sp->xbuff);
226 sp->xbuff = NULL;
227
228 if (!test_and_clear_bit(SIXPF_INUSE, &sp->flags))
229 printk(KERN_WARNING "%s: sp_free for already free unit.\n", sp->dev->name);
230 }
231
232
233 /* Send one completely decapsulated IP datagram to the IP layer. */
234
235 /* This is the routine that sends the received data to the kernel AX.25.
236 'cmd' is the KISS command. For AX.25 data, it is zero. */
237
sp_bump(struct sixpack * sp,char cmd)238 static void sp_bump(struct sixpack *sp, char cmd)
239 {
240 struct sk_buff *skb;
241 int count;
242 unsigned char *ptr;
243
244 count = sp->rcount+1;
245
246 sp->stats.rx_bytes += count;
247
248 if ((skb = dev_alloc_skb(count)) == NULL) {
249 printk(KERN_DEBUG "%s: memory squeeze, dropping packet.\n", sp->dev->name);
250 sp->stats.rx_dropped++;
251 return;
252 }
253
254 skb->dev = sp->dev;
255 ptr = skb_put(skb, count);
256 *ptr++ = cmd; /* KISS command */
257
258 memcpy(ptr, (sp->cooked_buf)+1, count);
259 skb->mac.raw = skb->data;
260 skb->protocol = htons(ETH_P_AX25);
261 netif_rx(skb);
262 sp->stats.rx_packets++;
263 }
264
265
266 /* ----------------------------------------------------------------------- */
267
268 /* Encapsulate one AX.25 frame and stuff into a TTY queue. */
sp_encaps(struct sixpack * sp,unsigned char * icp,int len)269 static void sp_encaps(struct sixpack *sp, unsigned char *icp, int len)
270 {
271 unsigned char *p;
272 int actual, count;
273
274 if (len > sp->mtu) { /* sp->mtu = AX25_MTU = max. PACLEN = 256 */
275 printk(KERN_DEBUG "%s: truncating oversized transmit packet!\n", sp->dev->name);
276 sp->stats.tx_dropped++;
277 netif_start_queue(sp->dev);
278 return;
279 }
280
281 p = icp;
282
283 if (p[0] > 5) {
284 printk(KERN_DEBUG "%s: invalid KISS command -- dropped\n", sp->dev->name);
285 netif_start_queue(sp->dev);
286 return;
287 }
288
289 if ((p[0] != 0) && (len > 2)) {
290 printk(KERN_DEBUG "%s: KISS control packet too long -- dropped\n", sp->dev->name);
291 netif_start_queue(sp->dev);
292 return;
293 }
294
295 if ((p[0] == 0) && (len < 15)) {
296 printk(KERN_DEBUG "%s: bad AX.25 packet to transmit -- dropped\n", sp->dev->name);
297 netif_start_queue(sp->dev);
298 sp->stats.tx_dropped++;
299 return;
300 }
301
302 count = encode_sixpack(p, (unsigned char *) sp->xbuff, len, sp->tx_delay);
303 sp->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
304
305 switch (p[0]) {
306 case 1: sp->tx_delay = p[1]; return;
307 case 2: sp->persistance = p[1]; return;
308 case 3: sp->slottime = p[1]; return;
309 case 4: /* ignored */ return;
310 case 5: sp->duplex = p[1]; return;
311 }
312
313 if (p[0] == 0) {
314 /* in case of fullduplex or DAMA operation, we don't take care
315 about the state of the DCD or of any timers, as the determination
316 of the correct time to send is the job of the AX.25 layer. We send
317 immediately after data has arrived. */
318 if (sp->duplex == 1) {
319 sp->led_state = 0x70;
320 sp->tty->driver.write(sp->tty, 0, &sp->led_state, 1);
321 sp->tx_enable = 1;
322 actual = sp->tty->driver.write(sp->tty, 0, sp->xbuff, count);
323 sp->xleft = count - actual;
324 sp->xhead = sp->xbuff + actual;
325 sp->led_state = 0x60;
326 sp->tty->driver.write(sp->tty, 0, &sp->led_state, 1);
327 } else {
328 sp->xleft = count;
329 sp->xhead = sp->xbuff;
330 sp->status2 = count;
331 if (sp->duplex == 0)
332 sp_start_tx_timer(sp);
333 }
334 }
335 }
336
337 /*
338 * Called by the TTY driver when there's room for more data. If we have
339 * more packets to send, we send them here.
340 */
sixpack_write_wakeup(struct tty_struct * tty)341 static void sixpack_write_wakeup(struct tty_struct *tty)
342 {
343 int actual;
344 struct sixpack *sp = (struct sixpack *) tty->disc_data;
345
346 /* First make sure we're connected. */
347 if (!sp || sp->magic != SIXPACK_MAGIC ||
348 !netif_running(sp->dev))
349 return;
350
351 if (sp->xleft <= 0) {
352 /* Now serial buffer is almost free & we can start
353 * transmission of another packet */
354 sp->stats.tx_packets++;
355 tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
356 sp->tx_enable = 0;
357 netif_wake_queue(sp->dev);
358 return;
359 }
360
361 if (sp->tx_enable == 1) {
362 actual = tty->driver.write(tty, 0, sp->xhead, sp->xleft);
363 sp->xleft -= actual;
364 sp->xhead += actual;
365 }
366 }
367
368 /* ----------------------------------------------------------------------- */
369
370 /* Encapsulate an IP datagram and kick it into a TTY queue. */
371
sp_xmit(struct sk_buff * skb,struct net_device * dev)372 static int sp_xmit(struct sk_buff *skb, struct net_device *dev)
373 {
374 struct sixpack *sp = (struct sixpack *) dev->priv;
375
376 /* We were not busy, so we are now... :-) */
377 netif_stop_queue(dev);
378 sp->stats.tx_bytes += skb->len;
379 sp_encaps(sp, skb->data, skb->len);
380 dev_kfree_skb(skb);
381 return 0;
382 }
383
384
385 /* perform the persistence/slottime algorithm for CSMA access. If the persistence
386 check was successful, write the data to the serial driver. Note that in case
387 of DAMA operation, the data is not sent here. */
388
sp_xmit_on_air(unsigned long channel)389 static void sp_xmit_on_air(unsigned long channel)
390 {
391 struct sixpack *sp = (struct sixpack *) channel;
392 int actual;
393 static unsigned char random;
394
395 random = random * 17 + 41;
396
397 if (((sp->status1 & SIXP_DCD_MASK) == 0) && (random < sp->persistance)) {
398 sp->led_state = 0x70;
399 sp->tty->driver.write(sp->tty, 0, &sp->led_state, 1);
400 sp->tx_enable = 1;
401 actual = sp->tty->driver.write(sp->tty, 0, sp->xbuff, sp->status2);
402 sp->xleft -= actual;
403 sp->xhead += actual;
404 sp->led_state = 0x60;
405 sp->tty->driver.write(sp->tty, 0, &sp->led_state, 1);
406 sp->status2 = 0;
407 } else
408 sp_start_tx_timer(sp);
409 }
410
411
412 /* Return the frame type ID */
sp_header(struct sk_buff * skb,struct net_device * dev,unsigned short type,void * daddr,void * saddr,unsigned len)413 static int sp_header(struct sk_buff *skb, struct net_device *dev, unsigned short type,
414 void *daddr, void *saddr, unsigned len)
415 {
416 #ifdef CONFIG_INET
417 if (type != htons(ETH_P_AX25))
418 return ax25_encapsulate(skb, dev, type, daddr, saddr, len);
419 #endif
420 return 0;
421 }
422
423
sp_rebuild_header(struct sk_buff * skb)424 static int sp_rebuild_header(struct sk_buff *skb)
425 {
426 #ifdef CONFIG_INET
427 return ax25_rebuild_header(skb);
428 #else
429 return 0;
430 #endif
431 }
432
433
434 /* Open the low-level part of the 6pack channel. */
sp_open(struct net_device * dev)435 static int sp_open(struct net_device *dev)
436 {
437 struct sixpack *sp = (struct sixpack *) dev->priv;
438 unsigned long len;
439
440 if (sp->tty == NULL)
441 return -ENODEV;
442
443 /*
444 * Allocate the 6pack frame buffers:
445 *
446 * rbuff Receive buffer.
447 * xbuff Transmit buffer.
448 */
449
450 /* !!! length of the buffers. MTU is IP MTU, not PACLEN!
451 */
452
453 len = dev->mtu * 2;
454
455 if ((sp->rbuff = kmalloc(len + 4, GFP_KERNEL)) == NULL)
456 return -ENOMEM;
457
458 if ((sp->xbuff = kmalloc(len + 4, GFP_KERNEL)) == NULL) {
459 kfree(sp->rbuff);
460 return -ENOMEM;
461 }
462
463 sp->mtu = AX25_MTU + 73;
464 sp->buffsize = len;
465 sp->rcount = 0;
466 sp->rx_count = 0;
467 sp->rx_count_cooked = 0;
468 sp->xleft = 0;
469
470 sp->flags &= (1 << SIXPF_INUSE); /* Clear ESCAPE & ERROR flags */
471
472 sp->duplex = 0;
473 sp->tx_delay = SIXP_TXDELAY;
474 sp->persistance = SIXP_PERSIST;
475 sp->slottime = SIXP_SLOTTIME;
476 sp->led_state = 0x60;
477 sp->status = 1;
478 sp->status1 = 1;
479 sp->status2 = 0;
480 sp->tnc_ok = 0;
481 sp->tx_enable = 0;
482
483 netif_start_queue(dev);
484
485 init_timer(&sp->tx_t);
486 init_timer(&sp->resync_t);
487 return 0;
488 }
489
490
491 /* Close the low-level part of the 6pack channel. */
sp_close(struct net_device * dev)492 static int sp_close(struct net_device *dev)
493 {
494 struct sixpack *sp = (struct sixpack *) dev->priv;
495
496 if (sp->tty == NULL)
497 return -EBUSY;
498
499 sp->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
500
501 netif_stop_queue(dev);
502 return 0;
503 }
504
sixpack_receive_room(struct tty_struct * tty)505 static int sixpack_receive_room(struct tty_struct *tty)
506 {
507 return 65536; /* We can handle an infinite amount of data. :-) */
508 }
509
510 /* !!! receive state machine */
511
512 /*
513 * Handle the 'receiver data ready' interrupt.
514 * This function is called by the 'tty_io' module in the kernel when
515 * a block of 6pack data has been received, which can now be decapsulated
516 * and sent on to some IP layer for further processing.
517 */
sixpack_receive_buf(struct tty_struct * tty,const unsigned char * cp,char * fp,int count)518 static void sixpack_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
519 {
520 unsigned char buf[512];
521 unsigned long flags;
522 int count1;
523
524 struct sixpack *sp = (struct sixpack *) tty->disc_data;
525
526 if (!sp || sp->magic != SIXPACK_MAGIC ||
527 !netif_running(sp->dev) || !count)
528 return;
529
530 save_flags(flags);
531 cli();
532 memcpy(buf, cp, count<sizeof(buf)? count:sizeof(buf));
533 restore_flags(flags);
534
535 /* Read the characters out of the buffer */
536
537 count1 = count;
538 while (count) {
539 count--;
540 if (fp && *fp++) {
541 if (!test_and_set_bit(SIXPF_ERROR, &sp->flags))
542 sp->stats.rx_errors++;
543 continue;
544 }
545 }
546 sixpack_decode(sp, buf, count1);
547 }
548
549 /*
550 * Open the high-level part of the 6pack channel.
551 * This function is called by the TTY module when the
552 * 6pack line discipline is called for. Because we are
553 * sure the tty line exists, we only have to link it to
554 * a free 6pcack channel...
555 */
sixpack_open(struct tty_struct * tty)556 static int sixpack_open(struct tty_struct *tty)
557 {
558 struct sixpack *sp = (struct sixpack *) tty->disc_data;
559 int err;
560
561 /* First make sure we're not already connected. */
562
563 if (sp && sp->magic == SIXPACK_MAGIC)
564 return -EEXIST;
565
566 /* OK. Find a free 6pack channel to use. */
567 if ((sp = sp_alloc()) == NULL)
568 return -ENFILE;
569 sp->tty = tty;
570 tty->disc_data = sp;
571 if (tty->driver.flush_buffer)
572 tty->driver.flush_buffer(tty);
573
574 tty_ldisc_flush(tty);
575
576 /* Restore default settings */
577 sp->dev->type = ARPHRD_AX25;
578
579 /* Perform the low-level 6pack initialization. */
580 if ((err = sp_open(sp->dev)))
581 return err;
582
583 /* Done. We have linked the TTY line to a channel. */
584
585 tnc_init(sp);
586
587 return sp->dev->base_addr;
588 }
589
590
591 /*
592 * Close down a 6pack channel.
593 * This means flushing out any pending queues, and then restoring the
594 * TTY line discipline to what it was before it got hooked to 6pack
595 * (which usually is TTY again).
596 */
sixpack_close(struct tty_struct * tty)597 static void sixpack_close(struct tty_struct *tty)
598 {
599 struct sixpack *sp = (struct sixpack *) tty->disc_data;
600
601 /* First make sure we're connected. */
602 if (!sp || sp->magic != SIXPACK_MAGIC)
603 return;
604
605 rtnl_lock();
606 dev_close(sp->dev);
607
608 del_timer(&sp->tx_t);
609 del_timer(&sp->resync_t);
610
611 tty->disc_data = 0;
612 sp->tty = NULL;
613
614 sp_free(sp);
615 unregister_netdevice(sp->dev);
616 rtnl_unlock();
617 }
618
619
sp_get_stats(struct net_device * dev)620 static struct net_device_stats *sp_get_stats(struct net_device *dev)
621 {
622 struct sixpack *sp = (struct sixpack *) dev->priv;
623 return &sp->stats;
624 }
625
626
sp_set_mac_address(struct net_device * dev,void * addr)627 static int sp_set_mac_address(struct net_device *dev, void *addr)
628 {
629 return copy_from_user(dev->dev_addr, addr, AX25_ADDR_LEN) ? -EFAULT : 0;
630 }
631
sp_set_dev_mac_address(struct net_device * dev,void * addr)632 static int sp_set_dev_mac_address(struct net_device *dev, void *addr)
633 {
634 struct sockaddr *sa = addr;
635 memcpy(dev->dev_addr, sa->sa_data, AX25_ADDR_LEN);
636 return 0;
637 }
638
639
640 /* Perform I/O control on an active 6pack channel. */
sixpack_ioctl(struct tty_struct * tty,void * file,int cmd,void * arg)641 static int sixpack_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
642 {
643 struct sixpack *sp = (struct sixpack *) tty->disc_data;
644 unsigned int tmp;
645
646 /* First make sure we're connected. */
647 if (!sp || sp->magic != SIXPACK_MAGIC)
648 return -EINVAL;
649
650 switch(cmd) {
651 case SIOCGIFNAME:
652 return copy_to_user(arg, sp->dev->name, strlen(sp->dev->name) + 1) ? -EFAULT : 0;
653
654 case SIOCGIFENCAP:
655 return put_user(0, (int *)arg);
656
657 case SIOCSIFENCAP:
658 if (get_user(tmp, (int *) arg))
659 return -EFAULT;
660
661 sp->mode = tmp;
662 sp->dev->addr_len = AX25_ADDR_LEN; /* sizeof an AX.25 addr */
663 sp->dev->hard_header_len = AX25_KISS_HEADER_LEN + AX25_MAX_HEADER_LEN + 3;
664 sp->dev->type = ARPHRD_AX25;
665
666 return 0;
667
668 case SIOCSIFHWADDR:
669 return sp_set_mac_address(sp->dev, arg);
670
671 /* Allow stty to read, but not set, the serial port */
672 case TCGETS:
673 case TCGETA:
674 return n_tty_ioctl(tty, (struct file *) file, cmd, (unsigned long) arg);
675
676 default:
677 return -ENOIOCTLCMD;
678 }
679 }
680
sp_open_dev(struct net_device * dev)681 static int sp_open_dev(struct net_device *dev)
682 {
683 struct sixpack *sp = (struct sixpack *) dev->priv;
684 if (sp->tty == NULL)
685 return -ENODEV;
686 return 0;
687 }
688
689 /* Fill in our line protocol discipline */
690 static struct tty_ldisc sp_ldisc = {
691 magic: TTY_LDISC_MAGIC,
692 name: "6pack",
693 open: sixpack_open,
694 close: sixpack_close,
695 ioctl: (int (*)(struct tty_struct *, struct file *,
696 unsigned int, unsigned long)) sixpack_ioctl,
697 receive_buf: sixpack_receive_buf,
698 receive_room: sixpack_receive_room,
699 write_wakeup: sixpack_write_wakeup,
700 };
701
702 /* Initialize 6pack control device -- register 6pack line discipline */
703
704 static char msg_banner[] __initdata = KERN_INFO "AX.25: 6pack driver, " SIXPACK_VERSION " (dynamic channels, max=%d)\n";
705 static char msg_nomem[] __initdata = KERN_ERR "6pack: can't allocate sixpack_ctrls[] array! No 6pack available.\n";
706 static char msg_regfail[] __initdata = KERN_ERR "6pack: can't register line discipline (err = %d)\n";
707
sixpack_init_driver(void)708 static int __init sixpack_init_driver(void)
709 {
710 int status;
711
712 /* Do sanity checks on maximum device parameter. */
713 if (sixpack_maxdev < 4)
714 sixpack_maxdev = 4;
715
716 printk(msg_banner, sixpack_maxdev);
717
718 sixpack_ctrls = (sixpack_ctrl_t **) kmalloc(sizeof(void*)*sixpack_maxdev, GFP_KERNEL);
719 if (sixpack_ctrls == NULL) {
720 printk(msg_nomem);
721 return -ENOMEM;
722 }
723
724 /* Clear the pointer array, we allocate devices when we need them */
725 memset(sixpack_ctrls, 0, sizeof(void*)*sixpack_maxdev); /* Pointers */
726
727 /* Register the provided line protocol discipline */
728 if ((status = tty_register_ldisc(N_6PACK, &sp_ldisc)) != 0) {
729 printk(msg_regfail, status);
730 kfree(sixpack_ctrls);
731 }
732
733 return status;
734 }
735
736 static const char msg_unregfail[] __exitdata = KERN_ERR "6pack: can't unregister line discipline (err = %d)\n";
737
sixpack_exit_driver(void)738 static void __exit sixpack_exit_driver(void)
739 {
740 int i;
741
742 if ((i = tty_register_ldisc(N_6PACK, NULL)))
743 printk(msg_unregfail, i);
744
745 for (i = 0; i < sixpack_maxdev; i++) {
746 if (sixpack_ctrls[i]) {
747 /*
748 * VSV = if dev->start==0, then device
749 * unregistered while close proc.
750 */
751 if (netif_running(&sixpack_ctrls[i]->dev))
752 unregister_netdev(&sixpack_ctrls[i]->dev);
753
754 kfree(sixpack_ctrls[i]);
755 }
756 }
757 kfree(sixpack_ctrls);
758 }
759
760
761 /* Initialize the 6pack driver. Called by DDI. */
sixpack_init(struct net_device * dev)762 static int sixpack_init(struct net_device *dev)
763 {
764 struct sixpack *sp = (struct sixpack *) dev->priv;
765
766 static char ax25_bcast[AX25_ADDR_LEN] =
767 {'Q'<<1,'S'<<1,'T'<<1,' '<<1,' '<<1,' '<<1,'0'<<1};
768 static char ax25_test[AX25_ADDR_LEN] =
769 {'L'<<1,'I'<<1,'N'<<1,'U'<<1,'X'<<1,' '<<1,'1'<<1};
770
771 if (sp == NULL) /* Allocation failed ?? */
772 return -ENODEV;
773
774 /* Set up the "6pack Control Block". (And clear statistics) */
775
776 memset(sp, 0, sizeof (struct sixpack));
777 sp->magic = SIXPACK_MAGIC;
778 sp->dev = dev;
779
780 /* Finish setting up the DEVICE info. */
781 dev->mtu = SIXP_MTU;
782 dev->hard_start_xmit = sp_xmit;
783 dev->open = sp_open_dev;
784 dev->stop = sp_close;
785 dev->hard_header = sp_header;
786 dev->get_stats = sp_get_stats;
787 dev->set_mac_address = sp_set_dev_mac_address;
788 dev->hard_header_len = AX25_MAX_HEADER_LEN;
789 dev->addr_len = AX25_ADDR_LEN;
790 dev->type = ARPHRD_AX25;
791 dev->tx_queue_len = 10;
792 dev->rebuild_header = sp_rebuild_header;
793 dev->tx_timeout = NULL;
794
795 memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN); /* Only activated in AX.25 mode */
796 memcpy(dev->dev_addr, ax25_test, AX25_ADDR_LEN); /* "" "" "" "" */
797
798 /* New-style flags. */
799 dev->flags = 0;
800
801 return 0;
802 }
803
804
805
806
807 /* ----> 6pack timer interrupt handler and friends. <---- */
sp_start_tx_timer(struct sixpack * sp)808 static void sp_start_tx_timer(struct sixpack *sp)
809 {
810 int when = sp->slottime;
811
812 del_timer(&sp->tx_t);
813 sp->tx_t.data = (unsigned long) sp;
814 sp->tx_t.function = sp_xmit_on_air;
815 sp->tx_t.expires = jiffies + ((when+1)*HZ)/100;
816 add_timer(&sp->tx_t);
817 }
818
819
820 /* encode an AX.25 packet into 6pack */
821
encode_sixpack(unsigned char * tx_buf,unsigned char * tx_buf_raw,int length,unsigned char tx_delay)822 static int encode_sixpack(unsigned char *tx_buf, unsigned char *tx_buf_raw, int length, unsigned char tx_delay)
823 {
824 int count = 0;
825 unsigned char checksum = 0, buf[400];
826 int raw_count = 0;
827
828 tx_buf_raw[raw_count++] = SIXP_PRIO_CMD_MASK | SIXP_TX_MASK;
829 tx_buf_raw[raw_count++] = SIXP_SEOF;
830
831 buf[0] = tx_delay;
832 for (count = 1; count < length; count++)
833 buf[count] = tx_buf[count];
834
835 for (count = 0; count < length; count++)
836 checksum += buf[count];
837 buf[length] = (unsigned char) 0xff - checksum;
838
839 for (count = 0; count <= length; count++) {
840 if ((count % 3) == 0) {
841 tx_buf_raw[raw_count++] = (buf[count] & 0x3f);
842 tx_buf_raw[raw_count] = ((buf[count] >> 2) & 0x30);
843 } else if ((count % 3) == 1) {
844 tx_buf_raw[raw_count++] |= (buf[count] & 0x0f);
845 tx_buf_raw[raw_count] = ((buf[count] >> 2) & 0x3c);
846 } else {
847 tx_buf_raw[raw_count++] |= (buf[count] & 0x03);
848 tx_buf_raw[raw_count++] = (buf[count] >> 2);
849 }
850 }
851 if ((length % 3) != 2)
852 raw_count++;
853 tx_buf_raw[raw_count++] = SIXP_SEOF;
854 return raw_count;
855 }
856
857
858 /* decode a 6pack packet */
859
860 static void
sixpack_decode(struct sixpack * sp,unsigned char pre_rbuff[],int count)861 sixpack_decode(struct sixpack *sp, unsigned char pre_rbuff[], int count)
862 {
863 unsigned char inbyte;
864 int count1;
865
866 for (count1 = 0; count1 < count; count1++) {
867 inbyte = pre_rbuff[count1];
868 if (inbyte == SIXP_FOUND_TNC) {
869 printk(KERN_INFO "6pack: TNC found.\n");
870 sp->tnc_ok = 1;
871 del_timer(&sp->resync_t);
872 }
873 if ((inbyte & SIXP_PRIO_CMD_MASK) != 0)
874 decode_prio_command(inbyte, sp);
875 else if ((inbyte & SIXP_STD_CMD_MASK) != 0)
876 decode_std_command(inbyte, sp);
877 else if ((sp->status & SIXP_RX_DCD_MASK) == SIXP_RX_DCD_MASK)
878 decode_data(inbyte, sp);
879 }
880 }
881
tnc_init(struct sixpack * sp)882 static int tnc_init(struct sixpack *sp)
883 {
884 unsigned char inbyte = 0xe8;
885
886 sp->tty->driver.write(sp->tty, 0, &inbyte, 1);
887
888 del_timer(&sp->resync_t);
889 sp->resync_t.data = (unsigned long) sp;
890 sp->resync_t.function = resync_tnc;
891 sp->resync_t.expires = jiffies + SIXP_RESYNC_TIMEOUT;
892 add_timer(&sp->resync_t);
893
894 return 0;
895 }
896
897
898 /* identify and execute a 6pack priority command byte */
899
decode_prio_command(unsigned char cmd,struct sixpack * sp)900 static void decode_prio_command(unsigned char cmd, struct sixpack *sp)
901 {
902 unsigned char channel;
903 int actual;
904
905 channel = cmd & SIXP_CHN_MASK;
906 if ((cmd & SIXP_PRIO_DATA_MASK) != 0) { /* idle ? */
907
908 /* RX and DCD flags can only be set in the same prio command,
909 if the DCD flag has been set without the RX flag in the previous
910 prio command. If DCD has not been set before, something in the
911 transmission has gone wrong. In this case, RX and DCD are
912 cleared in order to prevent the decode_data routine from
913 reading further data that might be corrupt. */
914
915 if (((sp->status & SIXP_DCD_MASK) == 0) &&
916 ((cmd & SIXP_RX_DCD_MASK) == SIXP_RX_DCD_MASK)) {
917 if (sp->status != 1)
918 printk(KERN_DEBUG "6pack: protocol violation\n");
919 else
920 sp->status = 0;
921 cmd &= ~SIXP_RX_DCD_MASK;
922 }
923 sp->status = cmd & SIXP_PRIO_DATA_MASK;
924 }
925 else { /* output watchdog char if idle */
926 if ((sp->status2 != 0) && (sp->duplex == 1)) {
927 sp->led_state = 0x70;
928 sp->tty->driver.write(sp->tty, 0, &sp->led_state, 1);
929 sp->tx_enable = 1;
930 actual = sp->tty->driver.write(sp->tty, 0, sp->xbuff, sp->status2);
931 sp->xleft -= actual;
932 sp->xhead += actual;
933 sp->led_state = 0x60;
934 sp->status2 = 0;
935
936 }
937 }
938
939 /* needed to trigger the TNC watchdog */
940 sp->tty->driver.write(sp->tty, 0, &sp->led_state, 1);
941
942 /* if the state byte has been received, the TNC is present,
943 so the resync timer can be reset. */
944
945 if (sp->tnc_ok == 1) {
946 del_timer(&sp->resync_t);
947 sp->resync_t.data = (unsigned long) sp;
948 sp->resync_t.function = resync_tnc;
949 sp->resync_t.expires = jiffies + SIXP_INIT_RESYNC_TIMEOUT;
950 add_timer(&sp->resync_t);
951 }
952
953 sp->status1 = cmd & SIXP_PRIO_DATA_MASK;
954 }
955
956 /* try to resync the TNC. Called by the resync timer defined in
957 decode_prio_command */
958
resync_tnc(unsigned long channel)959 static void resync_tnc(unsigned long channel)
960 {
961 static char resync_cmd = 0xe8;
962 struct sixpack *sp = (struct sixpack *) channel;
963
964 printk(KERN_INFO "6pack: resyncing TNC\n");
965
966 /* clear any data that might have been received */
967
968 sp->rx_count = 0;
969 sp->rx_count_cooked = 0;
970
971 /* reset state machine */
972
973 sp->status = 1;
974 sp->status1 = 1;
975 sp->status2 = 0;
976 sp->tnc_ok = 0;
977
978 /* resync the TNC */
979
980 sp->led_state = 0x60;
981 sp->tty->driver.write(sp->tty, 0, &sp->led_state, 1);
982 sp->tty->driver.write(sp->tty, 0, &resync_cmd, 1);
983
984
985 /* Start resync timer again -- the TNC might be still absent */
986
987 del_timer(&sp->resync_t);
988 sp->resync_t.data = (unsigned long) sp;
989 sp->resync_t.function = resync_tnc;
990 sp->resync_t.expires = jiffies + SIXP_RESYNC_TIMEOUT;
991 add_timer(&sp->resync_t);
992 }
993
994
995
996 /* identify and execute a standard 6pack command byte */
997
decode_std_command(unsigned char cmd,struct sixpack * sp)998 static void decode_std_command(unsigned char cmd, struct sixpack *sp)
999 {
1000 unsigned char checksum = 0, rest = 0, channel;
1001 short i;
1002
1003 channel = cmd & SIXP_CHN_MASK;
1004 switch (cmd & SIXP_CMD_MASK) { /* normal command */
1005 case SIXP_SEOF:
1006 if ((sp->rx_count == 0) && (sp->rx_count_cooked == 0)) {
1007 if ((sp->status & SIXP_RX_DCD_MASK) ==
1008 SIXP_RX_DCD_MASK) {
1009 sp->led_state = 0x68;
1010 sp->tty->driver.write(sp->tty, 0, &sp->led_state, 1);
1011 }
1012 } else {
1013 sp->led_state = 0x60;
1014 /* fill trailing bytes with zeroes */
1015 sp->tty->driver.write(sp->tty, 0, &sp->led_state, 1);
1016 rest = sp->rx_count;
1017 if (rest != 0)
1018 for (i = rest; i <= 3; i++)
1019 decode_data(0, sp);
1020 if (rest == 2)
1021 sp->rx_count_cooked -= 2;
1022 else if (rest == 3)
1023 sp->rx_count_cooked -= 1;
1024 for (i = 0; i < sp->rx_count_cooked; i++)
1025 checksum += sp->cooked_buf[i];
1026 if (checksum != SIXP_CHKSUM) {
1027 printk(KERN_DEBUG "6pack: bad checksum %2.2x\n", checksum);
1028 } else {
1029 sp->rcount = sp->rx_count_cooked-2;
1030 sp_bump(sp, 0);
1031 }
1032 sp->rx_count_cooked = 0;
1033 }
1034 break;
1035 case SIXP_TX_URUN: printk(KERN_DEBUG "6pack: TX underrun\n");
1036 break;
1037 case SIXP_RX_ORUN: printk(KERN_DEBUG "6pack: RX overrun\n");
1038 break;
1039 case SIXP_RX_BUF_OVL:
1040 printk(KERN_DEBUG "6pack: RX buffer overflow\n");
1041 }
1042 }
1043
1044 /* decode 4 sixpack-encoded bytes into 3 data bytes */
1045
decode_data(unsigned char inbyte,struct sixpack * sp)1046 static void decode_data(unsigned char inbyte, struct sixpack *sp)
1047 {
1048 unsigned char *buf;
1049
1050 if (sp->rx_count != 3)
1051 sp->raw_buf[sp->rx_count++] = inbyte;
1052 else {
1053 buf = sp->raw_buf;
1054 sp->cooked_buf[sp->rx_count_cooked++] =
1055 buf[0] | ((buf[1] << 2) & 0xc0);
1056 sp->cooked_buf[sp->rx_count_cooked++] =
1057 (buf[1] & 0x0f) | ((buf[2] << 2) & 0xf0);
1058 sp->cooked_buf[sp->rx_count_cooked++] =
1059 (buf[2] & 0x03) | (inbyte << 2);
1060 sp->rx_count = 0;
1061 }
1062 }
1063
1064
1065 MODULE_AUTHOR("Andreas K�nsgen <ajk@ccac.rwth-aachen.de>");
1066 MODULE_DESCRIPTION("6pack driver for AX.25");
1067 MODULE_LICENSE("GPL");
1068
1069 module_init(sixpack_init_driver);
1070 module_exit(sixpack_exit_driver);
1071