1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * 6pack.c This module implements the 6pack protocol for kernel-based 4 * devices like TTY. It interfaces between a raw TTY and the 5 * kernel's AX.25 protocol layers. 6 * 7 * Authors: Andreas Könsgen <ajk@comnets.uni-bremen.de> 8 * Ralf Baechle DL5RB <ralf@linux-mips.org> 9 * 10 * Quite a lot of stuff "stolen" by Joerg Reuter from slip.c, written by 11 * 12 * Laurence Culhane, <loz@holmes.demon.co.uk> 13 * Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org> 14 */ 15 16 #include <linux/module.h> 17 #include <linux/uaccess.h> 18 #include <linux/bitops.h> 19 #include <linux/string.h> 20 #include <linux/mm.h> 21 #include <linux/interrupt.h> 22 #include <linux/in.h> 23 #include <linux/tty.h> 24 #include <linux/errno.h> 25 #include <linux/netdevice.h> 26 #include <linux/timer.h> 27 #include <linux/slab.h> 28 #include <net/ax25.h> 29 #include <linux/etherdevice.h> 30 #include <linux/skbuff.h> 31 #include <linux/rtnetlink.h> 32 #include <linux/spinlock.h> 33 #include <linux/if_arp.h> 34 #include <linux/init.h> 35 #include <linux/ip.h> 36 #include <linux/tcp.h> 37 #include <linux/semaphore.h> 38 #include <linux/refcount.h> 39 40 /* sixpack priority commands */ 41 #define SIXP_SEOF 0x40 /* start and end of a 6pack frame */ 42 #define SIXP_TX_URUN 0x48 /* transmit overrun */ 43 #define SIXP_RX_ORUN 0x50 /* receive overrun */ 44 #define SIXP_RX_BUF_OVL 0x58 /* receive buffer overflow */ 45 46 #define SIXP_CHKSUM 0xFF /* valid checksum of a 6pack frame */ 47 48 /* masks to get certain bits out of the status bytes sent by the TNC */ 49 50 #define SIXP_CMD_MASK 0xC0 51 #define SIXP_CHN_MASK 0x07 52 #define SIXP_PRIO_CMD_MASK 0x80 53 #define SIXP_STD_CMD_MASK 0x40 54 #define SIXP_PRIO_DATA_MASK 0x38 55 #define SIXP_TX_MASK 0x20 56 #define SIXP_RX_MASK 0x10 57 #define SIXP_RX_DCD_MASK 0x18 58 #define SIXP_LEDS_ON 0x78 59 #define SIXP_LEDS_OFF 0x60 60 #define SIXP_CON 0x08 61 #define SIXP_STA 0x10 62 63 #define SIXP_FOUND_TNC 0xe9 64 #define SIXP_CON_ON 0x68 65 #define SIXP_DCD_MASK 0x08 66 #define SIXP_DAMA_OFF 0 67 68 /* default level 2 parameters */ 69 #define SIXP_TXDELAY 25 /* 250 ms */ 70 #define SIXP_PERSIST 50 /* in 256ths */ 71 #define SIXP_SLOTTIME 10 /* 100 ms */ 72 #define SIXP_INIT_RESYNC_TIMEOUT (3*HZ/2) /* in 1 s */ 73 #define SIXP_RESYNC_TIMEOUT 5*HZ /* in 1 s */ 74 75 /* 6pack configuration. */ 76 #define SIXP_NRUNIT 31 /* MAX number of 6pack channels */ 77 #define SIXP_MTU 256 /* Default MTU */ 78 79 enum sixpack_flags { 80 SIXPF_ERROR, /* Parity, etc. error */ 81 }; 82 83 struct sixpack { 84 /* Various fields. */ 85 struct tty_struct *tty; /* ptr to TTY structure */ 86 struct net_device *dev; /* easy for intr handling */ 87 88 /* These are pointers to the malloc()ed frame buffers. */ 89 int rcount; /* received chars counter */ 90 unsigned char *xbuff; /* transmitter buffer */ 91 unsigned char *xhead; /* next byte to XMIT */ 92 int xleft; /* bytes left in XMIT queue */ 93 94 u8 raw_buf[4]; 95 u8 cooked_buf[400]; 96 97 unsigned int rx_count; 98 unsigned int rx_count_cooked; 99 spinlock_t rxlock; 100 101 unsigned long flags; /* Flag values/ mode etc */ 102 unsigned char mode; /* 6pack mode */ 103 104 /* 6pack stuff */ 105 unsigned char tx_delay; 106 unsigned char persistence; 107 unsigned char slottime; 108 unsigned char duplex; 109 unsigned char led_state; 110 u8 status; 111 u8 status1; 112 unsigned char status2; 113 unsigned char tx_enable; 114 unsigned char tnc_state; 115 116 struct timer_list tx_t; 117 struct timer_list resync_t; 118 spinlock_t lock; 119 }; 120 121 #define AX25_6PACK_HEADER_LEN 0 122 123 static void sixpack_decode(struct sixpack *, const u8 *, size_t); 124 static int encode_sixpack(unsigned char *, unsigned char *, int, unsigned char); 125 126 /* 127 * Perform the persistence/slottime algorithm for CSMA access. If the 128 * persistence check was successful, write the data to the serial driver. 129 * Note that in case of DAMA operation, the data is not sent here. 130 */ 131 132 static void sp_xmit_on_air(struct timer_list *t) 133 { 134 struct sixpack *sp = timer_container_of(sp, t, tx_t); 135 int actual, when = sp->slottime; 136 static unsigned char random; 137 138 random = random * 17 + 41; 139 140 if (((sp->status1 & SIXP_DCD_MASK) == 0) && (random < sp->persistence)) { 141 sp->led_state = 0x70; 142 sp->tty->ops->write(sp->tty, &sp->led_state, 1); 143 sp->tx_enable = 1; 144 actual = sp->tty->ops->write(sp->tty, sp->xbuff, sp->status2); 145 sp->xleft -= actual; 146 sp->xhead += actual; 147 sp->led_state = 0x60; 148 sp->tty->ops->write(sp->tty, &sp->led_state, 1); 149 sp->status2 = 0; 150 } else 151 mod_timer(&sp->tx_t, jiffies + ((when + 1) * HZ) / 100); 152 } 153 154 /* ----> 6pack timer interrupt handler and friends. <---- */ 155 156 /* Encapsulate one AX.25 frame and stuff into a TTY queue. */ 157 static void sp_encaps(struct sixpack *sp, unsigned char *icp, int len) 158 { 159 unsigned char *msg, *p = icp; 160 int actual, count; 161 162 if (len > AX25_MTU + 73) { 163 msg = "oversized transmit packet!"; 164 goto out_drop; 165 } 166 167 if (p[0] > 5) { 168 msg = "invalid KISS command"; 169 goto out_drop; 170 } 171 172 if ((p[0] != 0) && (len > 2)) { 173 msg = "KISS control packet too long"; 174 goto out_drop; 175 } 176 177 if ((p[0] == 0) && (len < 15)) { 178 msg = "bad AX.25 packet to transmit"; 179 goto out_drop; 180 } 181 182 count = encode_sixpack(p, sp->xbuff, len, sp->tx_delay); 183 set_bit(TTY_DO_WRITE_WAKEUP, &sp->tty->flags); 184 185 switch (p[0]) { 186 case 1: sp->tx_delay = p[1]; 187 return; 188 case 2: sp->persistence = p[1]; 189 return; 190 case 3: sp->slottime = p[1]; 191 return; 192 case 4: /* ignored */ 193 return; 194 case 5: sp->duplex = p[1]; 195 return; 196 } 197 198 if (p[0] != 0) 199 return; 200 201 /* 202 * In case of fullduplex or DAMA operation, we don't take care about the 203 * state of the DCD or of any timers, as the determination of the 204 * correct time to send is the job of the AX.25 layer. We send 205 * immediately after data has arrived. 206 */ 207 if (sp->duplex == 1) { 208 sp->led_state = 0x70; 209 sp->tty->ops->write(sp->tty, &sp->led_state, 1); 210 sp->tx_enable = 1; 211 actual = sp->tty->ops->write(sp->tty, sp->xbuff, count); 212 sp->xleft = count - actual; 213 sp->xhead = sp->xbuff + actual; 214 sp->led_state = 0x60; 215 sp->tty->ops->write(sp->tty, &sp->led_state, 1); 216 } else { 217 sp->xleft = count; 218 sp->xhead = sp->xbuff; 219 sp->status2 = count; 220 sp_xmit_on_air(&sp->tx_t); 221 } 222 223 return; 224 225 out_drop: 226 sp->dev->stats.tx_dropped++; 227 netif_start_queue(sp->dev); 228 if (net_ratelimit()) 229 printk(KERN_DEBUG "%s: %s - dropped.\n", sp->dev->name, msg); 230 } 231 232 /* Encapsulate an IP datagram and kick it into a TTY queue. */ 233 234 static netdev_tx_t sp_xmit(struct sk_buff *skb, struct net_device *dev) 235 { 236 struct sixpack *sp = netdev_priv(dev); 237 238 if (skb->protocol == htons(ETH_P_IP)) 239 return ax25_ip_xmit(skb); 240 241 spin_lock_bh(&sp->lock); 242 /* We were not busy, so we are now... :-) */ 243 netif_stop_queue(dev); 244 dev->stats.tx_bytes += skb->len; 245 sp_encaps(sp, skb->data, skb->len); 246 spin_unlock_bh(&sp->lock); 247 248 dev_kfree_skb(skb); 249 250 return NETDEV_TX_OK; 251 } 252 253 static int sp_open_dev(struct net_device *dev) 254 { 255 struct sixpack *sp = netdev_priv(dev); 256 257 if (sp->tty == NULL) 258 return -ENODEV; 259 return 0; 260 } 261 262 /* Close the low-level part of the 6pack channel. */ 263 static int sp_close(struct net_device *dev) 264 { 265 struct sixpack *sp = netdev_priv(dev); 266 267 spin_lock_bh(&sp->lock); 268 if (sp->tty) { 269 /* TTY discipline is running. */ 270 clear_bit(TTY_DO_WRITE_WAKEUP, &sp->tty->flags); 271 } 272 netif_stop_queue(dev); 273 spin_unlock_bh(&sp->lock); 274 275 return 0; 276 } 277 278 static int sp_set_mac_address(struct net_device *dev, void *addr) 279 { 280 struct sockaddr_ax25 *sa = addr; 281 282 netif_tx_lock_bh(dev); 283 netif_addr_lock(dev); 284 __dev_addr_set(dev, &sa->sax25_call, AX25_ADDR_LEN); 285 netif_addr_unlock(dev); 286 netif_tx_unlock_bh(dev); 287 288 return 0; 289 } 290 291 static const struct net_device_ops sp_netdev_ops = { 292 .ndo_open = sp_open_dev, 293 .ndo_stop = sp_close, 294 .ndo_start_xmit = sp_xmit, 295 .ndo_set_mac_address = sp_set_mac_address, 296 }; 297 298 static void sp_setup(struct net_device *dev) 299 { 300 /* Finish setting up the DEVICE info. */ 301 dev->netdev_ops = &sp_netdev_ops; 302 dev->mtu = SIXP_MTU; 303 dev->hard_header_len = AX25_MAX_HEADER_LEN; 304 dev->header_ops = &ax25_header_ops; 305 306 dev->addr_len = AX25_ADDR_LEN; 307 dev->type = ARPHRD_AX25; 308 dev->tx_queue_len = 10; 309 310 /* Only activated in AX.25 mode */ 311 memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN); 312 dev_addr_set(dev, (u8 *)&ax25_defaddr); 313 314 dev->flags = 0; 315 } 316 317 /* Send one completely decapsulated IP datagram to the IP layer. */ 318 319 /* 320 * This is the routine that sends the received data to the kernel AX.25. 321 * 'cmd' is the KISS command. For AX.25 data, it is zero. 322 */ 323 324 static void sp_bump(struct sixpack *sp, char cmd) 325 { 326 struct sk_buff *skb; 327 int count; 328 u8 *ptr; 329 330 count = sp->rcount + 1; 331 332 sp->dev->stats.rx_bytes += count; 333 334 if ((skb = dev_alloc_skb(count + 1)) == NULL) 335 goto out_mem; 336 337 ptr = skb_put(skb, count + 1); 338 *ptr++ = cmd; /* KISS command */ 339 340 memcpy(ptr, sp->cooked_buf + 1, count); 341 skb->protocol = ax25_type_trans(skb, sp->dev); 342 netif_rx(skb); 343 sp->dev->stats.rx_packets++; 344 345 return; 346 347 out_mem: 348 sp->dev->stats.rx_dropped++; 349 } 350 351 352 /* ----------------------------------------------------------------------- */ 353 354 /* 355 * Called by the TTY driver when there's room for more data. If we have 356 * more packets to send, we send them here. 357 */ 358 static void sixpack_write_wakeup(struct tty_struct *tty) 359 { 360 struct sixpack *sp = tty->disc_data; 361 int actual; 362 363 if (!sp) 364 return; 365 if (sp->xleft <= 0) { 366 /* Now serial buffer is almost free & we can start 367 * transmission of another packet */ 368 sp->dev->stats.tx_packets++; 369 clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); 370 sp->tx_enable = 0; 371 netif_wake_queue(sp->dev); 372 return; 373 } 374 375 if (sp->tx_enable) { 376 actual = tty->ops->write(tty, sp->xhead, sp->xleft); 377 sp->xleft -= actual; 378 sp->xhead += actual; 379 } 380 } 381 382 /* ----------------------------------------------------------------------- */ 383 384 /* 385 * Handle the 'receiver data ready' interrupt. 386 * This function is called by the tty module in the kernel when 387 * a block of 6pack data has been received, which can now be decapsulated 388 * and sent on to some IP layer for further processing. 389 */ 390 static void sixpack_receive_buf(struct tty_struct *tty, const u8 *cp, 391 const u8 *fp, size_t count) 392 { 393 struct sixpack *sp; 394 395 if (!count) 396 return; 397 398 sp = tty->disc_data; 399 if (!sp) 400 return; 401 402 /* Read the characters out of the buffer */ 403 while (count--) { 404 if (fp && *fp++) { 405 if (!test_and_set_bit(SIXPF_ERROR, &sp->flags)) 406 sp->dev->stats.rx_errors++; 407 cp++; 408 continue; 409 } 410 sixpack_decode(sp, cp, 1); 411 cp++; 412 } 413 414 tty_unthrottle(tty); 415 } 416 417 /* 418 * Try to resync the TNC. Called by the resync timer defined in 419 * decode_prio_command 420 */ 421 422 #define TNC_UNINITIALIZED 0 423 #define TNC_UNSYNC_STARTUP 1 424 #define TNC_UNSYNCED 2 425 #define TNC_IN_SYNC 3 426 427 static void __tnc_set_sync_state(struct sixpack *sp, int new_tnc_state) 428 { 429 char *msg; 430 431 switch (new_tnc_state) { 432 default: /* gcc oh piece-o-crap ... */ 433 case TNC_UNSYNC_STARTUP: 434 msg = "Synchronizing with TNC"; 435 break; 436 case TNC_UNSYNCED: 437 msg = "Lost synchronization with TNC\n"; 438 break; 439 case TNC_IN_SYNC: 440 msg = "Found TNC"; 441 break; 442 } 443 444 sp->tnc_state = new_tnc_state; 445 printk(KERN_INFO "%s: %s\n", sp->dev->name, msg); 446 } 447 448 static inline void tnc_set_sync_state(struct sixpack *sp, int new_tnc_state) 449 { 450 int old_tnc_state = sp->tnc_state; 451 452 if (old_tnc_state != new_tnc_state) 453 __tnc_set_sync_state(sp, new_tnc_state); 454 } 455 456 static void resync_tnc(struct timer_list *t) 457 { 458 struct sixpack *sp = timer_container_of(sp, t, resync_t); 459 static char resync_cmd = 0xe8; 460 461 /* clear any data that might have been received */ 462 463 sp->rx_count = 0; 464 sp->rx_count_cooked = 0; 465 466 /* reset state machine */ 467 468 sp->status = 1; 469 sp->status1 = 1; 470 sp->status2 = 0; 471 472 /* resync the TNC */ 473 474 sp->led_state = 0x60; 475 sp->tty->ops->write(sp->tty, &sp->led_state, 1); 476 sp->tty->ops->write(sp->tty, &resync_cmd, 1); 477 478 479 /* Start resync timer again -- the TNC might be still absent */ 480 mod_timer(&sp->resync_t, jiffies + SIXP_RESYNC_TIMEOUT); 481 } 482 483 static inline int tnc_init(struct sixpack *sp) 484 { 485 unsigned char inbyte = 0xe8; 486 487 tnc_set_sync_state(sp, TNC_UNSYNC_STARTUP); 488 489 sp->tty->ops->write(sp->tty, &inbyte, 1); 490 491 mod_timer(&sp->resync_t, jiffies + SIXP_RESYNC_TIMEOUT); 492 493 return 0; 494 } 495 496 /* 497 * Open the high-level part of the 6pack channel. 498 * This function is called by the TTY module when the 499 * 6pack line discipline is called for. Because we are 500 * sure the tty line exists, we only have to link it to 501 * a free 6pcack channel... 502 */ 503 static int sixpack_open(struct tty_struct *tty) 504 { 505 char *xbuff = NULL; 506 struct net_device *dev; 507 struct sixpack *sp; 508 unsigned long len; 509 int err = 0; 510 511 if (!capable(CAP_NET_ADMIN)) 512 return -EPERM; 513 if (tty->ops->write == NULL) 514 return -EOPNOTSUPP; 515 516 dev = alloc_netdev(sizeof(struct sixpack), "sp%d", NET_NAME_UNKNOWN, 517 sp_setup); 518 if (!dev) { 519 err = -ENOMEM; 520 goto out; 521 } 522 523 sp = netdev_priv(dev); 524 sp->dev = dev; 525 526 spin_lock_init(&sp->lock); 527 spin_lock_init(&sp->rxlock); 528 529 /* !!! length of the buffers. MTU is IP MTU, not PACLEN! */ 530 531 len = dev->mtu * 2; 532 533 xbuff = kmalloc(len + 4, GFP_KERNEL); 534 if (xbuff == NULL) { 535 err = -ENOBUFS; 536 goto out_free; 537 } 538 539 spin_lock_bh(&sp->lock); 540 541 sp->tty = tty; 542 543 sp->xbuff = xbuff; 544 545 sp->rcount = 0; 546 sp->rx_count = 0; 547 sp->rx_count_cooked = 0; 548 sp->xleft = 0; 549 550 sp->flags = 0; /* Clear ESCAPE & ERROR flags */ 551 552 sp->duplex = 0; 553 sp->tx_delay = SIXP_TXDELAY; 554 sp->persistence = SIXP_PERSIST; 555 sp->slottime = SIXP_SLOTTIME; 556 sp->led_state = 0x60; 557 sp->status = 1; 558 sp->status1 = 1; 559 sp->status2 = 0; 560 sp->tx_enable = 0; 561 562 netif_start_queue(dev); 563 564 timer_setup(&sp->tx_t, sp_xmit_on_air, 0); 565 566 timer_setup(&sp->resync_t, resync_tnc, 0); 567 568 spin_unlock_bh(&sp->lock); 569 570 /* Done. We have linked the TTY line to a channel. */ 571 tty->disc_data = sp; 572 tty->receive_room = 65536; 573 574 /* Now we're ready to register. */ 575 err = register_netdev(dev); 576 if (err) 577 goto out_free; 578 579 tnc_init(sp); 580 581 return 0; 582 583 out_free: 584 kfree(xbuff); 585 586 free_netdev(dev); 587 588 out: 589 return err; 590 } 591 592 593 /* 594 * Close down a 6pack channel. 595 * This means flushing out any pending queues, and then restoring the 596 * TTY line discipline to what it was before it got hooked to 6pack 597 * (which usually is TTY again). 598 */ 599 static void sixpack_close(struct tty_struct *tty) 600 { 601 struct sixpack *sp; 602 603 sp = tty->disc_data; 604 if (!sp) 605 return; 606 607 tty->disc_data = NULL; 608 609 /* We must stop the queue to avoid potentially scribbling 610 * on the free buffers. The sp->dead completion is not sufficient 611 * to protect us from sp->xbuff access. 612 */ 613 netif_stop_queue(sp->dev); 614 615 unregister_netdev(sp->dev); 616 617 timer_delete_sync(&sp->tx_t); 618 timer_delete_sync(&sp->resync_t); 619 620 /* Free all 6pack frame buffers after unreg. */ 621 kfree(sp->xbuff); 622 623 free_netdev(sp->dev); 624 } 625 626 /* Perform I/O control on an active 6pack channel. */ 627 static int sixpack_ioctl(struct tty_struct *tty, unsigned int cmd, 628 unsigned long arg) 629 { 630 struct sixpack *sp = tty->disc_data; 631 struct net_device *dev; 632 unsigned int tmp, err; 633 634 if (!sp) 635 return -ENXIO; 636 dev = sp->dev; 637 638 switch(cmd) { 639 case SIOCGIFNAME: 640 err = copy_to_user((void __user *) arg, dev->name, 641 strlen(dev->name) + 1) ? -EFAULT : 0; 642 break; 643 644 case SIOCGIFENCAP: 645 err = put_user(0, (int __user *) arg); 646 break; 647 648 case SIOCSIFENCAP: 649 if (get_user(tmp, (int __user *) arg)) { 650 err = -EFAULT; 651 break; 652 } 653 654 sp->mode = tmp; 655 dev->addr_len = AX25_ADDR_LEN; 656 dev->hard_header_len = AX25_KISS_HEADER_LEN + 657 AX25_MAX_HEADER_LEN + 3; 658 dev->type = ARPHRD_AX25; 659 660 err = 0; 661 break; 662 663 case SIOCSIFHWADDR: { 664 char addr[AX25_ADDR_LEN]; 665 666 if (copy_from_user(&addr, 667 (void __user *)arg, AX25_ADDR_LEN)) { 668 err = -EFAULT; 669 break; 670 } 671 672 netif_tx_lock_bh(dev); 673 __dev_addr_set(dev, &addr, AX25_ADDR_LEN); 674 netif_tx_unlock_bh(dev); 675 err = 0; 676 break; 677 } 678 default: 679 err = tty_mode_ioctl(tty, cmd, arg); 680 } 681 682 return err; 683 } 684 685 static struct tty_ldisc_ops sp_ldisc = { 686 .owner = THIS_MODULE, 687 .num = N_6PACK, 688 .name = "6pack", 689 .open = sixpack_open, 690 .close = sixpack_close, 691 .ioctl = sixpack_ioctl, 692 .receive_buf = sixpack_receive_buf, 693 .write_wakeup = sixpack_write_wakeup, 694 }; 695 696 /* Initialize 6pack control device -- register 6pack line discipline */ 697 698 static int __init sixpack_init_driver(void) 699 { 700 int status; 701 702 /* Register the provided line protocol discipline */ 703 status = tty_register_ldisc(&sp_ldisc); 704 if (status) 705 pr_err("6pack: can't register line discipline (err = %d)\n", status); 706 707 return status; 708 } 709 710 static void __exit sixpack_exit_driver(void) 711 { 712 tty_unregister_ldisc(&sp_ldisc); 713 } 714 715 /* encode an AX.25 packet into 6pack */ 716 717 static int encode_sixpack(unsigned char *tx_buf, unsigned char *tx_buf_raw, 718 int length, unsigned char tx_delay) 719 { 720 int count = 0; 721 unsigned char checksum = 0, buf[400]; 722 int raw_count = 0; 723 724 tx_buf_raw[raw_count++] = SIXP_PRIO_CMD_MASK | SIXP_TX_MASK; 725 tx_buf_raw[raw_count++] = SIXP_SEOF; 726 727 buf[0] = tx_delay; 728 for (count = 1; count < length; count++) 729 buf[count] = tx_buf[count]; 730 731 for (count = 0; count < length; count++) 732 checksum += buf[count]; 733 buf[length] = (unsigned char) 0xff - checksum; 734 735 for (count = 0; count <= length; count++) { 736 if ((count % 3) == 0) { 737 tx_buf_raw[raw_count++] = (buf[count] & 0x3f); 738 tx_buf_raw[raw_count] = ((buf[count] >> 2) & 0x30); 739 } else if ((count % 3) == 1) { 740 tx_buf_raw[raw_count++] |= (buf[count] & 0x0f); 741 tx_buf_raw[raw_count] = ((buf[count] >> 2) & 0x3c); 742 } else { 743 tx_buf_raw[raw_count++] |= (buf[count] & 0x03); 744 tx_buf_raw[raw_count++] = (buf[count] >> 2); 745 } 746 } 747 if ((length % 3) != 2) 748 raw_count++; 749 tx_buf_raw[raw_count++] = SIXP_SEOF; 750 return raw_count; 751 } 752 753 /* decode 4 sixpack-encoded bytes into 3 data bytes */ 754 755 static void decode_data(struct sixpack *sp, u8 inbyte) 756 { 757 u8 *buf; 758 759 if (sp->rx_count != 3) { 760 sp->raw_buf[sp->rx_count++] = inbyte; 761 762 return; 763 } 764 765 if (sp->rx_count_cooked + 2 >= sizeof(sp->cooked_buf)) { 766 pr_err("6pack: cooked buffer overrun, data loss\n"); 767 sp->rx_count = 0; 768 return; 769 } 770 771 buf = sp->raw_buf; 772 sp->cooked_buf[sp->rx_count_cooked++] = 773 buf[0] | ((buf[1] << 2) & 0xc0); 774 sp->cooked_buf[sp->rx_count_cooked++] = 775 (buf[1] & 0x0f) | ((buf[2] << 2) & 0xf0); 776 sp->cooked_buf[sp->rx_count_cooked++] = 777 (buf[2] & 0x03) | (inbyte << 2); 778 sp->rx_count = 0; 779 } 780 781 /* identify and execute a 6pack priority command byte */ 782 783 static void decode_prio_command(struct sixpack *sp, u8 cmd) 784 { 785 ssize_t actual; 786 787 if ((cmd & SIXP_PRIO_DATA_MASK) != 0) { /* idle ? */ 788 789 /* RX and DCD flags can only be set in the same prio command, 790 if the DCD flag has been set without the RX flag in the previous 791 prio command. If DCD has not been set before, something in the 792 transmission has gone wrong. In this case, RX and DCD are 793 cleared in order to prevent the decode_data routine from 794 reading further data that might be corrupt. */ 795 796 if (((sp->status & SIXP_DCD_MASK) == 0) && 797 ((cmd & SIXP_RX_DCD_MASK) == SIXP_RX_DCD_MASK)) { 798 if (sp->status != 1) 799 printk(KERN_DEBUG "6pack: protocol violation\n"); 800 else 801 sp->status = 0; 802 cmd &= ~SIXP_RX_DCD_MASK; 803 } 804 sp->status = cmd & SIXP_PRIO_DATA_MASK; 805 } else { /* output watchdog char if idle */ 806 if ((sp->status2 != 0) && (sp->duplex == 1)) { 807 sp->led_state = 0x70; 808 sp->tty->ops->write(sp->tty, &sp->led_state, 1); 809 sp->tx_enable = 1; 810 actual = sp->tty->ops->write(sp->tty, sp->xbuff, sp->status2); 811 sp->xleft -= actual; 812 sp->xhead += actual; 813 sp->led_state = 0x60; 814 sp->status2 = 0; 815 816 } 817 } 818 819 /* needed to trigger the TNC watchdog */ 820 sp->tty->ops->write(sp->tty, &sp->led_state, 1); 821 822 /* if the state byte has been received, the TNC is present, 823 so the resync timer can be reset. */ 824 825 if (sp->tnc_state == TNC_IN_SYNC) 826 mod_timer(&sp->resync_t, jiffies + SIXP_INIT_RESYNC_TIMEOUT); 827 828 sp->status1 = cmd & SIXP_PRIO_DATA_MASK; 829 } 830 831 /* identify and execute a standard 6pack command byte */ 832 833 static void decode_std_command(struct sixpack *sp, u8 cmd) 834 { 835 u8 checksum = 0, rest = 0; 836 short i; 837 838 switch (cmd & SIXP_CMD_MASK) { /* normal command */ 839 case SIXP_SEOF: 840 if ((sp->rx_count == 0) && (sp->rx_count_cooked == 0)) { 841 if ((sp->status & SIXP_RX_DCD_MASK) == 842 SIXP_RX_DCD_MASK) { 843 sp->led_state = 0x68; 844 sp->tty->ops->write(sp->tty, &sp->led_state, 1); 845 } 846 } else { 847 sp->led_state = 0x60; 848 /* fill trailing bytes with zeroes */ 849 sp->tty->ops->write(sp->tty, &sp->led_state, 1); 850 spin_lock_bh(&sp->rxlock); 851 rest = sp->rx_count; 852 if (rest != 0) 853 for (i = rest; i <= 3; i++) 854 decode_data(sp, 0); 855 if (rest == 2) 856 sp->rx_count_cooked -= 2; 857 else if (rest == 3) 858 sp->rx_count_cooked -= 1; 859 for (i = 0; i < sp->rx_count_cooked; i++) 860 checksum += sp->cooked_buf[i]; 861 if (checksum != SIXP_CHKSUM) { 862 printk(KERN_DEBUG "6pack: bad checksum %2.2x\n", checksum); 863 } else { 864 sp->rcount = sp->rx_count_cooked-2; 865 sp_bump(sp, 0); 866 } 867 sp->rx_count_cooked = 0; 868 spin_unlock_bh(&sp->rxlock); 869 } 870 break; 871 case SIXP_TX_URUN: printk(KERN_DEBUG "6pack: TX underrun\n"); 872 break; 873 case SIXP_RX_ORUN: printk(KERN_DEBUG "6pack: RX overrun\n"); 874 break; 875 case SIXP_RX_BUF_OVL: 876 printk(KERN_DEBUG "6pack: RX buffer overflow\n"); 877 } 878 } 879 880 /* decode a 6pack packet */ 881 882 static void 883 sixpack_decode(struct sixpack *sp, const u8 *pre_rbuff, size_t count) 884 { 885 size_t count1; 886 u8 inbyte; 887 888 for (count1 = 0; count1 < count; count1++) { 889 inbyte = pre_rbuff[count1]; 890 if (inbyte == SIXP_FOUND_TNC) { 891 tnc_set_sync_state(sp, TNC_IN_SYNC); 892 timer_delete(&sp->resync_t); 893 } 894 if ((inbyte & SIXP_PRIO_CMD_MASK) != 0) 895 decode_prio_command(sp, inbyte); 896 else if ((inbyte & SIXP_STD_CMD_MASK) != 0) 897 decode_std_command(sp, inbyte); 898 else if ((sp->status & SIXP_RX_DCD_MASK) == SIXP_RX_DCD_MASK) { 899 spin_lock_bh(&sp->rxlock); 900 decode_data(sp, inbyte); 901 spin_unlock_bh(&sp->rxlock); 902 } 903 } 904 } 905 906 MODULE_AUTHOR("Ralf Baechle DO1GRB <ralf@linux-mips.org>"); 907 MODULE_DESCRIPTION("6pack driver for AX.25"); 908 MODULE_LICENSE("GPL"); 909 MODULE_ALIAS_LDISC(N_6PACK); 910 911 module_init(sixpack_init_driver); 912 module_exit(sixpack_exit_driver); 913