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 size_t count1; 395 396 if (!count) 397 return; 398 399 sp = tty->disc_data; 400 if (!sp) 401 return; 402 403 /* Read the characters out of the buffer */ 404 count1 = count; 405 while (count) { 406 count--; 407 if (fp && *fp++) { 408 if (!test_and_set_bit(SIXPF_ERROR, &sp->flags)) 409 sp->dev->stats.rx_errors++; 410 continue; 411 } 412 } 413 sixpack_decode(sp, cp, count1); 414 415 tty_unthrottle(tty); 416 } 417 418 /* 419 * Try to resync the TNC. Called by the resync timer defined in 420 * decode_prio_command 421 */ 422 423 #define TNC_UNINITIALIZED 0 424 #define TNC_UNSYNC_STARTUP 1 425 #define TNC_UNSYNCED 2 426 #define TNC_IN_SYNC 3 427 428 static void __tnc_set_sync_state(struct sixpack *sp, int new_tnc_state) 429 { 430 char *msg; 431 432 switch (new_tnc_state) { 433 default: /* gcc oh piece-o-crap ... */ 434 case TNC_UNSYNC_STARTUP: 435 msg = "Synchronizing with TNC"; 436 break; 437 case TNC_UNSYNCED: 438 msg = "Lost synchronization with TNC\n"; 439 break; 440 case TNC_IN_SYNC: 441 msg = "Found TNC"; 442 break; 443 } 444 445 sp->tnc_state = new_tnc_state; 446 printk(KERN_INFO "%s: %s\n", sp->dev->name, msg); 447 } 448 449 static inline void tnc_set_sync_state(struct sixpack *sp, int new_tnc_state) 450 { 451 int old_tnc_state = sp->tnc_state; 452 453 if (old_tnc_state != new_tnc_state) 454 __tnc_set_sync_state(sp, new_tnc_state); 455 } 456 457 static void resync_tnc(struct timer_list *t) 458 { 459 struct sixpack *sp = timer_container_of(sp, t, resync_t); 460 static char resync_cmd = 0xe8; 461 462 /* clear any data that might have been received */ 463 464 sp->rx_count = 0; 465 sp->rx_count_cooked = 0; 466 467 /* reset state machine */ 468 469 sp->status = 1; 470 sp->status1 = 1; 471 sp->status2 = 0; 472 473 /* resync the TNC */ 474 475 sp->led_state = 0x60; 476 sp->tty->ops->write(sp->tty, &sp->led_state, 1); 477 sp->tty->ops->write(sp->tty, &resync_cmd, 1); 478 479 480 /* Start resync timer again -- the TNC might be still absent */ 481 mod_timer(&sp->resync_t, jiffies + SIXP_RESYNC_TIMEOUT); 482 } 483 484 static inline int tnc_init(struct sixpack *sp) 485 { 486 unsigned char inbyte = 0xe8; 487 488 tnc_set_sync_state(sp, TNC_UNSYNC_STARTUP); 489 490 sp->tty->ops->write(sp->tty, &inbyte, 1); 491 492 mod_timer(&sp->resync_t, jiffies + SIXP_RESYNC_TIMEOUT); 493 494 return 0; 495 } 496 497 /* 498 * Open the high-level part of the 6pack channel. 499 * This function is called by the TTY module when the 500 * 6pack line discipline is called for. Because we are 501 * sure the tty line exists, we only have to link it to 502 * a free 6pcack channel... 503 */ 504 static int sixpack_open(struct tty_struct *tty) 505 { 506 char *xbuff = NULL; 507 struct net_device *dev; 508 struct sixpack *sp; 509 unsigned long len; 510 int err = 0; 511 512 if (!capable(CAP_NET_ADMIN)) 513 return -EPERM; 514 if (tty->ops->write == NULL) 515 return -EOPNOTSUPP; 516 517 dev = alloc_netdev(sizeof(struct sixpack), "sp%d", NET_NAME_UNKNOWN, 518 sp_setup); 519 if (!dev) { 520 err = -ENOMEM; 521 goto out; 522 } 523 524 sp = netdev_priv(dev); 525 sp->dev = dev; 526 527 spin_lock_init(&sp->lock); 528 spin_lock_init(&sp->rxlock); 529 530 /* !!! length of the buffers. MTU is IP MTU, not PACLEN! */ 531 532 len = dev->mtu * 2; 533 534 xbuff = kmalloc(len + 4, GFP_KERNEL); 535 if (xbuff == NULL) { 536 err = -ENOBUFS; 537 goto out_free; 538 } 539 540 spin_lock_bh(&sp->lock); 541 542 sp->tty = tty; 543 544 sp->xbuff = xbuff; 545 546 sp->rcount = 0; 547 sp->rx_count = 0; 548 sp->rx_count_cooked = 0; 549 sp->xleft = 0; 550 551 sp->flags = 0; /* Clear ESCAPE & ERROR flags */ 552 553 sp->duplex = 0; 554 sp->tx_delay = SIXP_TXDELAY; 555 sp->persistence = SIXP_PERSIST; 556 sp->slottime = SIXP_SLOTTIME; 557 sp->led_state = 0x60; 558 sp->status = 1; 559 sp->status1 = 1; 560 sp->status2 = 0; 561 sp->tx_enable = 0; 562 563 netif_start_queue(dev); 564 565 timer_setup(&sp->tx_t, sp_xmit_on_air, 0); 566 567 timer_setup(&sp->resync_t, resync_tnc, 0); 568 569 spin_unlock_bh(&sp->lock); 570 571 /* Done. We have linked the TTY line to a channel. */ 572 tty->disc_data = sp; 573 tty->receive_room = 65536; 574 575 /* Now we're ready to register. */ 576 err = register_netdev(dev); 577 if (err) 578 goto out_free; 579 580 tnc_init(sp); 581 582 return 0; 583 584 out_free: 585 kfree(xbuff); 586 587 free_netdev(dev); 588 589 out: 590 return err; 591 } 592 593 594 /* 595 * Close down a 6pack channel. 596 * This means flushing out any pending queues, and then restoring the 597 * TTY line discipline to what it was before it got hooked to 6pack 598 * (which usually is TTY again). 599 */ 600 static void sixpack_close(struct tty_struct *tty) 601 { 602 struct sixpack *sp; 603 604 sp = tty->disc_data; 605 if (!sp) 606 return; 607 608 tty->disc_data = NULL; 609 610 /* We must stop the queue to avoid potentially scribbling 611 * on the free buffers. The sp->dead completion is not sufficient 612 * to protect us from sp->xbuff access. 613 */ 614 netif_stop_queue(sp->dev); 615 616 unregister_netdev(sp->dev); 617 618 timer_delete_sync(&sp->tx_t); 619 timer_delete_sync(&sp->resync_t); 620 621 /* Free all 6pack frame buffers after unreg. */ 622 kfree(sp->xbuff); 623 624 free_netdev(sp->dev); 625 } 626 627 /* Perform I/O control on an active 6pack channel. */ 628 static int sixpack_ioctl(struct tty_struct *tty, unsigned int cmd, 629 unsigned long arg) 630 { 631 struct sixpack *sp = tty->disc_data; 632 struct net_device *dev; 633 unsigned int tmp, err; 634 635 if (!sp) 636 return -ENXIO; 637 dev = sp->dev; 638 639 switch(cmd) { 640 case SIOCGIFNAME: 641 err = copy_to_user((void __user *) arg, dev->name, 642 strlen(dev->name) + 1) ? -EFAULT : 0; 643 break; 644 645 case SIOCGIFENCAP: 646 err = put_user(0, (int __user *) arg); 647 break; 648 649 case SIOCSIFENCAP: 650 if (get_user(tmp, (int __user *) arg)) { 651 err = -EFAULT; 652 break; 653 } 654 655 sp->mode = tmp; 656 dev->addr_len = AX25_ADDR_LEN; 657 dev->hard_header_len = AX25_KISS_HEADER_LEN + 658 AX25_MAX_HEADER_LEN + 3; 659 dev->type = ARPHRD_AX25; 660 661 err = 0; 662 break; 663 664 case SIOCSIFHWADDR: { 665 char addr[AX25_ADDR_LEN]; 666 667 if (copy_from_user(&addr, 668 (void __user *)arg, AX25_ADDR_LEN)) { 669 err = -EFAULT; 670 break; 671 } 672 673 netif_tx_lock_bh(dev); 674 __dev_addr_set(dev, &addr, AX25_ADDR_LEN); 675 netif_tx_unlock_bh(dev); 676 err = 0; 677 break; 678 } 679 default: 680 err = tty_mode_ioctl(tty, cmd, arg); 681 } 682 683 return err; 684 } 685 686 static struct tty_ldisc_ops sp_ldisc = { 687 .owner = THIS_MODULE, 688 .num = N_6PACK, 689 .name = "6pack", 690 .open = sixpack_open, 691 .close = sixpack_close, 692 .ioctl = sixpack_ioctl, 693 .receive_buf = sixpack_receive_buf, 694 .write_wakeup = sixpack_write_wakeup, 695 }; 696 697 /* Initialize 6pack control device -- register 6pack line discipline */ 698 699 static int __init sixpack_init_driver(void) 700 { 701 int status; 702 703 /* Register the provided line protocol discipline */ 704 status = tty_register_ldisc(&sp_ldisc); 705 if (status) 706 pr_err("6pack: can't register line discipline (err = %d)\n", status); 707 708 return status; 709 } 710 711 static void __exit sixpack_exit_driver(void) 712 { 713 tty_unregister_ldisc(&sp_ldisc); 714 } 715 716 /* encode an AX.25 packet into 6pack */ 717 718 static int encode_sixpack(unsigned char *tx_buf, unsigned char *tx_buf_raw, 719 int length, unsigned char tx_delay) 720 { 721 int count = 0; 722 unsigned char checksum = 0, buf[400]; 723 int raw_count = 0; 724 725 tx_buf_raw[raw_count++] = SIXP_PRIO_CMD_MASK | SIXP_TX_MASK; 726 tx_buf_raw[raw_count++] = SIXP_SEOF; 727 728 buf[0] = tx_delay; 729 for (count = 1; count < length; count++) 730 buf[count] = tx_buf[count]; 731 732 for (count = 0; count < length; count++) 733 checksum += buf[count]; 734 buf[length] = (unsigned char) 0xff - checksum; 735 736 for (count = 0; count <= length; count++) { 737 if ((count % 3) == 0) { 738 tx_buf_raw[raw_count++] = (buf[count] & 0x3f); 739 tx_buf_raw[raw_count] = ((buf[count] >> 2) & 0x30); 740 } else if ((count % 3) == 1) { 741 tx_buf_raw[raw_count++] |= (buf[count] & 0x0f); 742 tx_buf_raw[raw_count] = ((buf[count] >> 2) & 0x3c); 743 } else { 744 tx_buf_raw[raw_count++] |= (buf[count] & 0x03); 745 tx_buf_raw[raw_count++] = (buf[count] >> 2); 746 } 747 } 748 if ((length % 3) != 2) 749 raw_count++; 750 tx_buf_raw[raw_count++] = SIXP_SEOF; 751 return raw_count; 752 } 753 754 /* decode 4 sixpack-encoded bytes into 3 data bytes */ 755 756 static void decode_data(struct sixpack *sp, u8 inbyte) 757 { 758 u8 *buf; 759 760 if (sp->rx_count != 3) { 761 sp->raw_buf[sp->rx_count++] = inbyte; 762 763 return; 764 } 765 766 if (sp->rx_count_cooked + 2 >= sizeof(sp->cooked_buf)) { 767 pr_err("6pack: cooked buffer overrun, data loss\n"); 768 sp->rx_count = 0; 769 return; 770 } 771 772 buf = sp->raw_buf; 773 sp->cooked_buf[sp->rx_count_cooked++] = 774 buf[0] | ((buf[1] << 2) & 0xc0); 775 sp->cooked_buf[sp->rx_count_cooked++] = 776 (buf[1] & 0x0f) | ((buf[2] << 2) & 0xf0); 777 sp->cooked_buf[sp->rx_count_cooked++] = 778 (buf[2] & 0x03) | (inbyte << 2); 779 sp->rx_count = 0; 780 } 781 782 /* identify and execute a 6pack priority command byte */ 783 784 static void decode_prio_command(struct sixpack *sp, u8 cmd) 785 { 786 ssize_t actual; 787 788 if ((cmd & SIXP_PRIO_DATA_MASK) != 0) { /* idle ? */ 789 790 /* RX and DCD flags can only be set in the same prio command, 791 if the DCD flag has been set without the RX flag in the previous 792 prio command. If DCD has not been set before, something in the 793 transmission has gone wrong. In this case, RX and DCD are 794 cleared in order to prevent the decode_data routine from 795 reading further data that might be corrupt. */ 796 797 if (((sp->status & SIXP_DCD_MASK) == 0) && 798 ((cmd & SIXP_RX_DCD_MASK) == SIXP_RX_DCD_MASK)) { 799 if (sp->status != 1) 800 printk(KERN_DEBUG "6pack: protocol violation\n"); 801 else 802 sp->status = 0; 803 cmd &= ~SIXP_RX_DCD_MASK; 804 } 805 sp->status = cmd & SIXP_PRIO_DATA_MASK; 806 } else { /* output watchdog char if idle */ 807 if ((sp->status2 != 0) && (sp->duplex == 1)) { 808 sp->led_state = 0x70; 809 sp->tty->ops->write(sp->tty, &sp->led_state, 1); 810 sp->tx_enable = 1; 811 actual = sp->tty->ops->write(sp->tty, sp->xbuff, sp->status2); 812 sp->xleft -= actual; 813 sp->xhead += actual; 814 sp->led_state = 0x60; 815 sp->status2 = 0; 816 817 } 818 } 819 820 /* needed to trigger the TNC watchdog */ 821 sp->tty->ops->write(sp->tty, &sp->led_state, 1); 822 823 /* if the state byte has been received, the TNC is present, 824 so the resync timer can be reset. */ 825 826 if (sp->tnc_state == TNC_IN_SYNC) 827 mod_timer(&sp->resync_t, jiffies + SIXP_INIT_RESYNC_TIMEOUT); 828 829 sp->status1 = cmd & SIXP_PRIO_DATA_MASK; 830 } 831 832 /* identify and execute a standard 6pack command byte */ 833 834 static void decode_std_command(struct sixpack *sp, u8 cmd) 835 { 836 u8 checksum = 0, rest = 0; 837 short i; 838 839 switch (cmd & SIXP_CMD_MASK) { /* normal command */ 840 case SIXP_SEOF: 841 if ((sp->rx_count == 0) && (sp->rx_count_cooked == 0)) { 842 if ((sp->status & SIXP_RX_DCD_MASK) == 843 SIXP_RX_DCD_MASK) { 844 sp->led_state = 0x68; 845 sp->tty->ops->write(sp->tty, &sp->led_state, 1); 846 } 847 } else { 848 sp->led_state = 0x60; 849 /* fill trailing bytes with zeroes */ 850 sp->tty->ops->write(sp->tty, &sp->led_state, 1); 851 spin_lock_bh(&sp->rxlock); 852 rest = sp->rx_count; 853 if (rest != 0) 854 for (i = rest; i <= 3; i++) 855 decode_data(sp, 0); 856 if (rest == 2) 857 sp->rx_count_cooked -= 2; 858 else if (rest == 3) 859 sp->rx_count_cooked -= 1; 860 for (i = 0; i < sp->rx_count_cooked; i++) 861 checksum += sp->cooked_buf[i]; 862 if (checksum != SIXP_CHKSUM) { 863 printk(KERN_DEBUG "6pack: bad checksum %2.2x\n", checksum); 864 } else { 865 sp->rcount = sp->rx_count_cooked-2; 866 sp_bump(sp, 0); 867 } 868 sp->rx_count_cooked = 0; 869 spin_unlock_bh(&sp->rxlock); 870 } 871 break; 872 case SIXP_TX_URUN: printk(KERN_DEBUG "6pack: TX underrun\n"); 873 break; 874 case SIXP_RX_ORUN: printk(KERN_DEBUG "6pack: RX overrun\n"); 875 break; 876 case SIXP_RX_BUF_OVL: 877 printk(KERN_DEBUG "6pack: RX buffer overflow\n"); 878 } 879 } 880 881 /* decode a 6pack packet */ 882 883 static void 884 sixpack_decode(struct sixpack *sp, const u8 *pre_rbuff, size_t count) 885 { 886 size_t count1; 887 u8 inbyte; 888 889 for (count1 = 0; count1 < count; count1++) { 890 inbyte = pre_rbuff[count1]; 891 if (inbyte == SIXP_FOUND_TNC) { 892 tnc_set_sync_state(sp, TNC_IN_SYNC); 893 timer_delete(&sp->resync_t); 894 } 895 if ((inbyte & SIXP_PRIO_CMD_MASK) != 0) 896 decode_prio_command(sp, inbyte); 897 else if ((inbyte & SIXP_STD_CMD_MASK) != 0) 898 decode_std_command(sp, inbyte); 899 else if ((sp->status & SIXP_RX_DCD_MASK) == SIXP_RX_DCD_MASK) { 900 spin_lock_bh(&sp->rxlock); 901 decode_data(sp, inbyte); 902 spin_unlock_bh(&sp->rxlock); 903 } 904 } 905 } 906 907 MODULE_AUTHOR("Ralf Baechle DO1GRB <ralf@linux-mips.org>"); 908 MODULE_DESCRIPTION("6pack driver for AX.25"); 909 MODULE_LICENSE("GPL"); 910 MODULE_ALIAS_LDISC(N_6PACK); 911 912 module_init(sixpack_init_driver); 913 module_exit(sixpack_exit_driver); 914