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