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                    (HZ/4)  /* in 1 s */
  72#define SIXP_PERSIST                    50      /* in 256ths */
  73#define SIXP_SLOTTIME                   (HZ/10) /* in 1 s */
  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        memcpy(dev->dev_addr, &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->needs_free_netdev  = true;
 310        dev->mtu                = SIXP_MTU;
 311        dev->hard_header_len    = AX25_MAX_HEADER_LEN;
 312        dev->header_ops         = &ax25_header_ops;
 313
 314        dev->addr_len           = AX25_ADDR_LEN;
 315        dev->type               = ARPHRD_AX25;
 316        dev->tx_queue_len       = 10;
 317
 318        /* Only activated in AX.25 mode */
 319        memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
 320        memcpy(dev->dev_addr, &ax25_defaddr, AX25_ADDR_LEN);
 321
 322        dev->flags              = 0;
 323}
 324
 325/* Send one completely decapsulated IP datagram to the IP layer. */
 326
 327/*
 328 * This is the routine that sends the received data to the kernel AX.25.
 329 * 'cmd' is the KISS command. For AX.25 data, it is zero.
 330 */
 331
 332static void sp_bump(struct sixpack *sp, char cmd)
 333{
 334        struct sk_buff *skb;
 335        int count;
 336        unsigned char *ptr;
 337
 338        count = sp->rcount + 1;
 339
 340        sp->dev->stats.rx_bytes += count;
 341
 342        if ((skb = dev_alloc_skb(count + 1)) == NULL)
 343                goto out_mem;
 344
 345        ptr = skb_put(skb, count + 1);
 346        *ptr++ = cmd;   /* KISS command */
 347
 348        memcpy(ptr, sp->cooked_buf + 1, count);
 349        skb->protocol = ax25_type_trans(skb, sp->dev);
 350        netif_rx(skb);
 351        sp->dev->stats.rx_packets++;
 352
 353        return;
 354
 355out_mem:
 356        sp->dev->stats.rx_dropped++;
 357}
 358
 359
 360/* ----------------------------------------------------------------------- */
 361
 362/*
 363 * We have a potential race on dereferencing tty->disc_data, because the tty
 364 * layer provides no locking at all - thus one cpu could be running
 365 * sixpack_receive_buf while another calls sixpack_close, which zeroes
 366 * tty->disc_data and frees the memory that sixpack_receive_buf is using.  The
 367 * best way to fix this is to use a rwlock in the tty struct, but for now we
 368 * use a single global rwlock for all ttys in ppp line discipline.
 369 */
 370static DEFINE_RWLOCK(disc_data_lock);
 371                                                                                
 372static struct sixpack *sp_get(struct tty_struct *tty)
 373{
 374        struct sixpack *sp;
 375
 376        read_lock(&disc_data_lock);
 377        sp = tty->disc_data;
 378        if (sp)
 379                refcount_inc(&sp->refcnt);
 380        read_unlock(&disc_data_lock);
 381
 382        return sp;
 383}
 384
 385static void sp_put(struct sixpack *sp)
 386{
 387        if (refcount_dec_and_test(&sp->refcnt))
 388                complete(&sp->dead);
 389}
 390
 391/*
 392 * Called by the TTY driver when there's room for more data.  If we have
 393 * more packets to send, we send them here.
 394 */
 395static void sixpack_write_wakeup(struct tty_struct *tty)
 396{
 397        struct sixpack *sp = sp_get(tty);
 398        int actual;
 399
 400        if (!sp)
 401                return;
 402        if (sp->xleft <= 0)  {
 403                /* Now serial buffer is almost free & we can start
 404                 * transmission of another packet */
 405                sp->dev->stats.tx_packets++;
 406                clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
 407                sp->tx_enable = 0;
 408                netif_wake_queue(sp->dev);
 409                goto out;
 410        }
 411
 412        if (sp->tx_enable) {
 413                actual = tty->ops->write(tty, sp->xhead, sp->xleft);
 414                sp->xleft -= actual;
 415                sp->xhead += actual;
 416        }
 417
 418out:
 419        sp_put(sp);
 420}
 421
 422/* ----------------------------------------------------------------------- */
 423
 424/*
 425 * Handle the 'receiver data ready' interrupt.
 426 * This function is called by the tty module in the kernel when
 427 * a block of 6pack data has been received, which can now be decapsulated
 428 * and sent on to some IP layer for further processing.
 429 */
 430static void sixpack_receive_buf(struct tty_struct *tty,
 431        const unsigned char *cp, const char *fp, int count)
 432{
 433        struct sixpack *sp;
 434        int count1;
 435
 436        if (!count)
 437                return;
 438
 439        sp = sp_get(tty);
 440        if (!sp)
 441                return;
 442
 443        /* Read the characters out of the buffer */
 444        count1 = count;
 445        while (count) {
 446                count--;
 447                if (fp && *fp++) {
 448                        if (!test_and_set_bit(SIXPF_ERROR, &sp->flags))
 449                                sp->dev->stats.rx_errors++;
 450                        continue;
 451                }
 452        }
 453        sixpack_decode(sp, cp, count1);
 454
 455        sp_put(sp);
 456        tty_unthrottle(tty);
 457}
 458
 459/*
 460 * Try to resync the TNC. Called by the resync timer defined in
 461 * decode_prio_command
 462 */
 463
 464#define TNC_UNINITIALIZED       0
 465#define TNC_UNSYNC_STARTUP      1
 466#define TNC_UNSYNCED            2
 467#define TNC_IN_SYNC             3
 468
 469static void __tnc_set_sync_state(struct sixpack *sp, int new_tnc_state)
 470{
 471        char *msg;
 472
 473        switch (new_tnc_state) {
 474        default:                        /* gcc oh piece-o-crap ... */
 475        case TNC_UNSYNC_STARTUP:
 476                msg = "Synchronizing with TNC";
 477                break;
 478        case TNC_UNSYNCED:
 479                msg = "Lost synchronization with TNC\n";
 480                break;
 481        case TNC_IN_SYNC:
 482                msg = "Found TNC";
 483                break;
 484        }
 485
 486        sp->tnc_state = new_tnc_state;
 487        printk(KERN_INFO "%s: %s\n", sp->dev->name, msg);
 488}
 489
 490static inline void tnc_set_sync_state(struct sixpack *sp, int new_tnc_state)
 491{
 492        int old_tnc_state = sp->tnc_state;
 493
 494        if (old_tnc_state != new_tnc_state)
 495                __tnc_set_sync_state(sp, new_tnc_state);
 496}
 497
 498static void resync_tnc(struct timer_list *t)
 499{
 500        struct sixpack *sp = from_timer(sp, t, resync_t);
 501        static char resync_cmd = 0xe8;
 502
 503        /* clear any data that might have been received */
 504
 505        sp->rx_count = 0;
 506        sp->rx_count_cooked = 0;
 507
 508        /* reset state machine */
 509
 510        sp->status = 1;
 511        sp->status1 = 1;
 512        sp->status2 = 0;
 513
 514        /* resync the TNC */
 515
 516        sp->led_state = 0x60;
 517        sp->tty->ops->write(sp->tty, &sp->led_state, 1);
 518        sp->tty->ops->write(sp->tty, &resync_cmd, 1);
 519
 520
 521        /* Start resync timer again -- the TNC might be still absent */
 522        mod_timer(&sp->resync_t, jiffies + SIXP_RESYNC_TIMEOUT);
 523}
 524
 525static inline int tnc_init(struct sixpack *sp)
 526{
 527        unsigned char inbyte = 0xe8;
 528
 529        tnc_set_sync_state(sp, TNC_UNSYNC_STARTUP);
 530
 531        sp->tty->ops->write(sp->tty, &inbyte, 1);
 532
 533        mod_timer(&sp->resync_t, jiffies + SIXP_RESYNC_TIMEOUT);
 534
 535        return 0;
 536}
 537
 538/*
 539 * Open the high-level part of the 6pack channel.
 540 * This function is called by the TTY module when the
 541 * 6pack line discipline is called for.  Because we are
 542 * sure the tty line exists, we only have to link it to
 543 * a free 6pcack channel...
 544 */
 545static int sixpack_open(struct tty_struct *tty)
 546{
 547        char *rbuff = NULL, *xbuff = NULL;
 548        struct net_device *dev;
 549        struct sixpack *sp;
 550        unsigned long len;
 551        int err = 0;
 552
 553        if (!capable(CAP_NET_ADMIN))
 554                return -EPERM;
 555        if (tty->ops->write == NULL)
 556                return -EOPNOTSUPP;
 557
 558        dev = alloc_netdev(sizeof(struct sixpack), "sp%d", NET_NAME_UNKNOWN,
 559                           sp_setup);
 560        if (!dev) {
 561                err = -ENOMEM;
 562                goto out;
 563        }
 564
 565        sp = netdev_priv(dev);
 566        sp->dev = dev;
 567
 568        spin_lock_init(&sp->lock);
 569        refcount_set(&sp->refcnt, 1);
 570        init_completion(&sp->dead);
 571
 572        /* !!! length of the buffers. MTU is IP MTU, not PACLEN!  */
 573
 574        len = dev->mtu * 2;
 575
 576        rbuff = kmalloc(len + 4, GFP_KERNEL);
 577        xbuff = kmalloc(len + 4, GFP_KERNEL);
 578
 579        if (rbuff == NULL || xbuff == NULL) {
 580                err = -ENOBUFS;
 581                goto out_free;
 582        }
 583
 584        spin_lock_bh(&sp->lock);
 585
 586        sp->tty = tty;
 587
 588        sp->rbuff       = rbuff;
 589        sp->xbuff       = xbuff;
 590
 591        sp->mtu         = AX25_MTU + 73;
 592        sp->buffsize    = len;
 593        sp->rcount      = 0;
 594        sp->rx_count    = 0;
 595        sp->rx_count_cooked = 0;
 596        sp->xleft       = 0;
 597
 598        sp->flags       = 0;            /* Clear ESCAPE & ERROR flags */
 599
 600        sp->duplex      = 0;
 601        sp->tx_delay    = SIXP_TXDELAY;
 602        sp->persistence = SIXP_PERSIST;
 603        sp->slottime    = SIXP_SLOTTIME;
 604        sp->led_state   = 0x60;
 605        sp->status      = 1;
 606        sp->status1     = 1;
 607        sp->status2     = 0;
 608        sp->tx_enable   = 0;
 609
 610        netif_start_queue(dev);
 611
 612        timer_setup(&sp->tx_t, sp_xmit_on_air, 0);
 613
 614        timer_setup(&sp->resync_t, resync_tnc, 0);
 615
 616        spin_unlock_bh(&sp->lock);
 617
 618        /* Done.  We have linked the TTY line to a channel. */
 619        tty->disc_data = sp;
 620        tty->receive_room = 65536;
 621
 622        /* Now we're ready to register. */
 623        err = register_netdev(dev);
 624        if (err)
 625                goto out_free;
 626
 627        tnc_init(sp);
 628
 629        return 0;
 630
 631out_free:
 632        kfree(xbuff);
 633        kfree(rbuff);
 634
 635        free_netdev(dev);
 636
 637out:
 638        return err;
 639}
 640
 641
 642/*
 643 * Close down a 6pack channel.
 644 * This means flushing out any pending queues, and then restoring the
 645 * TTY line discipline to what it was before it got hooked to 6pack
 646 * (which usually is TTY again).
 647 */
 648static void sixpack_close(struct tty_struct *tty)
 649{
 650        struct sixpack *sp;
 651
 652        write_lock_irq(&disc_data_lock);
 653        sp = tty->disc_data;
 654        tty->disc_data = NULL;
 655        write_unlock_irq(&disc_data_lock);
 656        if (!sp)
 657                return;
 658
 659        /*
 660         * We have now ensured that nobody can start using ap from now on, but
 661         * we have to wait for all existing users to finish.
 662         */
 663        if (!refcount_dec_and_test(&sp->refcnt))
 664                wait_for_completion(&sp->dead);
 665
 666        /* We must stop the queue to avoid potentially scribbling
 667         * on the free buffers. The sp->dead completion is not sufficient
 668         * to protect us from sp->xbuff access.
 669         */
 670        netif_stop_queue(sp->dev);
 671
 672        del_timer_sync(&sp->tx_t);
 673        del_timer_sync(&sp->resync_t);
 674
 675        /* Free all 6pack frame buffers. */
 676        kfree(sp->rbuff);
 677        kfree(sp->xbuff);
 678
 679        unregister_netdev(sp->dev);
 680}
 681
 682/* Perform I/O control on an active 6pack channel. */
 683static int sixpack_ioctl(struct tty_struct *tty, struct file *file,
 684        unsigned int cmd, unsigned long arg)
 685{
 686        struct sixpack *sp = sp_get(tty);
 687        struct net_device *dev;
 688        unsigned int tmp, err;
 689
 690        if (!sp)
 691                return -ENXIO;
 692        dev = sp->dev;
 693
 694        switch(cmd) {
 695        case SIOCGIFNAME:
 696                err = copy_to_user((void __user *) arg, dev->name,
 697                                   strlen(dev->name) + 1) ? -EFAULT : 0;
 698                break;
 699
 700        case SIOCGIFENCAP:
 701                err = put_user(0, (int __user *) arg);
 702                break;
 703
 704        case SIOCSIFENCAP:
 705                if (get_user(tmp, (int __user *) arg)) {
 706                        err = -EFAULT;
 707                        break;
 708                }
 709
 710                sp->mode = tmp;
 711                dev->addr_len        = AX25_ADDR_LEN;
 712                dev->hard_header_len = AX25_KISS_HEADER_LEN +
 713                                       AX25_MAX_HEADER_LEN + 3;
 714                dev->type            = ARPHRD_AX25;
 715
 716                err = 0;
 717                break;
 718
 719        case SIOCSIFHWADDR: {
 720                        char addr[AX25_ADDR_LEN];
 721
 722                        if (copy_from_user(&addr,
 723                                           (void __user *)arg, AX25_ADDR_LEN)) {
 724                                err = -EFAULT;
 725                                break;
 726                        }
 727
 728                        netif_tx_lock_bh(dev);
 729                        memcpy(dev->dev_addr, &addr, AX25_ADDR_LEN);
 730                        netif_tx_unlock_bh(dev);
 731                        err = 0;
 732                        break;
 733                }
 734        default:
 735                err = tty_mode_ioctl(tty, file, cmd, arg);
 736        }
 737
 738        sp_put(sp);
 739
 740        return err;
 741}
 742
 743static struct tty_ldisc_ops sp_ldisc = {
 744        .owner          = THIS_MODULE,
 745        .num            = N_6PACK,
 746        .name           = "6pack",
 747        .open           = sixpack_open,
 748        .close          = sixpack_close,
 749        .ioctl          = sixpack_ioctl,
 750        .receive_buf    = sixpack_receive_buf,
 751        .write_wakeup   = sixpack_write_wakeup,
 752};
 753
 754/* Initialize 6pack control device -- register 6pack line discipline */
 755
 756static const char msg_banner[]  __initconst = KERN_INFO \
 757        "AX.25: 6pack driver, " SIXPACK_VERSION "\n";
 758static const char msg_regfail[] __initconst = KERN_ERR  \
 759        "6pack: can't register line discipline (err = %d)\n";
 760
 761static int __init sixpack_init_driver(void)
 762{
 763        int status;
 764
 765        printk(msg_banner);
 766
 767        /* Register the provided line protocol discipline */
 768        status = tty_register_ldisc(&sp_ldisc);
 769        if (status)
 770                printk(msg_regfail, status);
 771
 772        return status;
 773}
 774
 775static void __exit sixpack_exit_driver(void)
 776{
 777        tty_unregister_ldisc(&sp_ldisc);
 778}
 779
 780/* encode an AX.25 packet into 6pack */
 781
 782static int encode_sixpack(unsigned char *tx_buf, unsigned char *tx_buf_raw,
 783        int length, unsigned char tx_delay)
 784{
 785        int count = 0;
 786        unsigned char checksum = 0, buf[400];
 787        int raw_count = 0;
 788
 789        tx_buf_raw[raw_count++] = SIXP_PRIO_CMD_MASK | SIXP_TX_MASK;
 790        tx_buf_raw[raw_count++] = SIXP_SEOF;
 791
 792        buf[0] = tx_delay;
 793        for (count = 1; count < length; count++)
 794                buf[count] = tx_buf[count];
 795
 796        for (count = 0; count < length; count++)
 797                checksum += buf[count];
 798        buf[length] = (unsigned char) 0xff - checksum;
 799
 800        for (count = 0; count <= length; count++) {
 801                if ((count % 3) == 0) {
 802                        tx_buf_raw[raw_count++] = (buf[count] & 0x3f);
 803                        tx_buf_raw[raw_count] = ((buf[count] >> 2) & 0x30);
 804                } else if ((count % 3) == 1) {
 805                        tx_buf_raw[raw_count++] |= (buf[count] & 0x0f);
 806                        tx_buf_raw[raw_count] = ((buf[count] >> 2) & 0x3c);
 807                } else {
 808                        tx_buf_raw[raw_count++] |= (buf[count] & 0x03);
 809                        tx_buf_raw[raw_count++] = (buf[count] >> 2);
 810                }
 811        }
 812        if ((length % 3) != 2)
 813                raw_count++;
 814        tx_buf_raw[raw_count++] = SIXP_SEOF;
 815        return raw_count;
 816}
 817
 818/* decode 4 sixpack-encoded bytes into 3 data bytes */
 819
 820static void decode_data(struct sixpack *sp, unsigned char inbyte)
 821{
 822        unsigned char *buf;
 823
 824        if (sp->rx_count != 3) {
 825                sp->raw_buf[sp->rx_count++] = inbyte;
 826
 827                return;
 828        }
 829
 830        if (sp->rx_count_cooked + 2 >= sizeof(sp->cooked_buf)) {
 831                pr_err("6pack: cooked buffer overrun, data loss\n");
 832                sp->rx_count = 0;
 833                return;
 834        }
 835
 836        buf = sp->raw_buf;
 837        sp->cooked_buf[sp->rx_count_cooked++] =
 838                buf[0] | ((buf[1] << 2) & 0xc0);
 839        sp->cooked_buf[sp->rx_count_cooked++] =
 840                (buf[1] & 0x0f) | ((buf[2] << 2) & 0xf0);
 841        sp->cooked_buf[sp->rx_count_cooked++] =
 842                (buf[2] & 0x03) | (inbyte << 2);
 843        sp->rx_count = 0;
 844}
 845
 846/* identify and execute a 6pack priority command byte */
 847
 848static void decode_prio_command(struct sixpack *sp, unsigned char cmd)
 849{
 850        int actual;
 851
 852        if ((cmd & SIXP_PRIO_DATA_MASK) != 0) {     /* idle ? */
 853
 854        /* RX and DCD flags can only be set in the same prio command,
 855           if the DCD flag has been set without the RX flag in the previous
 856           prio command. If DCD has not been set before, something in the
 857           transmission has gone wrong. In this case, RX and DCD are
 858           cleared in order to prevent the decode_data routine from
 859           reading further data that might be corrupt. */
 860
 861                if (((sp->status & SIXP_DCD_MASK) == 0) &&
 862                        ((cmd & SIXP_RX_DCD_MASK) == SIXP_RX_DCD_MASK)) {
 863                                if (sp->status != 1)
 864                                        printk(KERN_DEBUG "6pack: protocol violation\n");
 865                                else
 866                                        sp->status = 0;
 867                                cmd &= ~SIXP_RX_DCD_MASK;
 868                }
 869                sp->status = cmd & SIXP_PRIO_DATA_MASK;
 870        } else { /* output watchdog char if idle */
 871                if ((sp->status2 != 0) && (sp->duplex == 1)) {
 872                        sp->led_state = 0x70;
 873                        sp->tty->ops->write(sp->tty, &sp->led_state, 1);
 874                        sp->tx_enable = 1;
 875                        actual = sp->tty->ops->write(sp->tty, sp->xbuff, sp->status2);
 876                        sp->xleft -= actual;
 877                        sp->xhead += actual;
 878                        sp->led_state = 0x60;
 879                        sp->status2 = 0;
 880
 881                }
 882        }
 883
 884        /* needed to trigger the TNC watchdog */
 885        sp->tty->ops->write(sp->tty, &sp->led_state, 1);
 886
 887        /* if the state byte has been received, the TNC is present,
 888           so the resync timer can be reset. */
 889
 890        if (sp->tnc_state == TNC_IN_SYNC)
 891                mod_timer(&sp->resync_t, jiffies + SIXP_INIT_RESYNC_TIMEOUT);
 892
 893        sp->status1 = cmd & SIXP_PRIO_DATA_MASK;
 894}
 895
 896/* identify and execute a standard 6pack command byte */
 897
 898static void decode_std_command(struct sixpack *sp, unsigned char cmd)
 899{
 900        unsigned char checksum = 0, rest = 0;
 901        short i;
 902
 903        switch (cmd & SIXP_CMD_MASK) {     /* normal command */
 904        case SIXP_SEOF:
 905                if ((sp->rx_count == 0) && (sp->rx_count_cooked == 0)) {
 906                        if ((sp->status & SIXP_RX_DCD_MASK) ==
 907                                SIXP_RX_DCD_MASK) {
 908                                sp->led_state = 0x68;
 909                                sp->tty->ops->write(sp->tty, &sp->led_state, 1);
 910                        }
 911                } else {
 912                        sp->led_state = 0x60;
 913                        /* fill trailing bytes with zeroes */
 914                        sp->tty->ops->write(sp->tty, &sp->led_state, 1);
 915                        rest = sp->rx_count;
 916                        if (rest != 0)
 917                                 for (i = rest; i <= 3; i++)
 918                                        decode_data(sp, 0);
 919                        if (rest == 2)
 920                                sp->rx_count_cooked -= 2;
 921                        else if (rest == 3)
 922                                sp->rx_count_cooked -= 1;
 923                        for (i = 0; i < sp->rx_count_cooked; i++)
 924                                checksum += sp->cooked_buf[i];
 925                        if (checksum != SIXP_CHKSUM) {
 926                                printk(KERN_DEBUG "6pack: bad checksum %2.2x\n", checksum);
 927                        } else {
 928                                sp->rcount = sp->rx_count_cooked-2;
 929                                sp_bump(sp, 0);
 930                        }
 931                        sp->rx_count_cooked = 0;
 932                }
 933                break;
 934        case SIXP_TX_URUN: printk(KERN_DEBUG "6pack: TX underrun\n");
 935                break;
 936        case SIXP_RX_ORUN: printk(KERN_DEBUG "6pack: RX overrun\n");
 937                break;
 938        case SIXP_RX_BUF_OVL:
 939                printk(KERN_DEBUG "6pack: RX buffer overflow\n");
 940        }
 941}
 942
 943/* decode a 6pack packet */
 944
 945static void
 946sixpack_decode(struct sixpack *sp, const unsigned char *pre_rbuff, int count)
 947{
 948        unsigned char inbyte;
 949        int count1;
 950
 951        for (count1 = 0; count1 < count; count1++) {
 952                inbyte = pre_rbuff[count1];
 953                if (inbyte == SIXP_FOUND_TNC) {
 954                        tnc_set_sync_state(sp, TNC_IN_SYNC);
 955                        del_timer(&sp->resync_t);
 956                }
 957                if ((inbyte & SIXP_PRIO_CMD_MASK) != 0)
 958                        decode_prio_command(sp, inbyte);
 959                else if ((inbyte & SIXP_STD_CMD_MASK) != 0)
 960                        decode_std_command(sp, inbyte);
 961                else if ((sp->status & SIXP_RX_DCD_MASK) == SIXP_RX_DCD_MASK)
 962                        decode_data(sp, inbyte);
 963        }
 964}
 965
 966MODULE_AUTHOR("Ralf Baechle DO1GRB <ralf@linux-mips.org>");
 967MODULE_DESCRIPTION("6pack driver for AX.25");
 968MODULE_LICENSE("GPL");
 969MODULE_ALIAS_LDISC(N_6PACK);
 970
 971module_init(sixpack_init_driver);
 972module_exit(sixpack_exit_driver);
 973