linux/drivers/net/wan/cycx_x25.c
<<
>>
Prefs
   1/*
   2* cycx_x25.c    Cyclom 2X WAN Link Driver.  X.25 module.
   3*
   4* Author:       Arnaldo Carvalho de Melo <acme@conectiva.com.br>
   5*
   6* Copyright:    (c) 1998-2003 Arnaldo Carvalho de Melo
   7*
   8* Based on sdla_x25.c by Gene Kozin <genek@compuserve.com>
   9*
  10*               This program is free software; you can redistribute it and/or
  11*               modify it under the terms of the GNU General Public License
  12*               as published by the Free Software Foundation; either version
  13*               2 of the License, or (at your option) any later version.
  14* ============================================================================
  15* 2001/01/12    acme            use dev_kfree_skb_irq on interrupt context
  16* 2000/04/02    acme            dprintk, cycx_debug
  17*                               fixed the bug introduced in get_dev_by_lcn and
  18*                               get_dev_by_dte_addr by the anonymous hacker
  19*                               that converted this driver to softnet
  20* 2000/01/08    acme            cleanup
  21* 1999/10/27    acme            use ARPHRD_HWX25 so that the X.25 stack know
  22*                               that we have a X.25 stack implemented in
  23*                               firmware onboard
  24* 1999/10/18    acme            support for X.25 sockets in if_send,
  25*                               beware: socket(AF_X25...) IS WORK IN PROGRESS,
  26*                               TCP/IP over X.25 via wanrouter not affected,
  27*                               working.
  28* 1999/10/09    acme            chan_disc renamed to chan_disconnect,
  29*                               began adding support for X.25 sockets:
  30*                               conf->protocol in new_if
  31* 1999/10/05    acme            fixed return E... to return -E...
  32* 1999/08/10    acme            serialized access to the card thru a spinlock
  33*                               in x25_exec
  34* 1999/08/09    acme            removed per channel spinlocks
  35*                               removed references to enable_tx_int
  36* 1999/05/28    acme            fixed nibble_to_byte, ackvc now properly treated
  37*                               if_send simplified
  38* 1999/05/25    acme            fixed t1, t2, t21 & t23 configuration
  39*                               use spinlocks instead of cli/sti in some points
  40* 1999/05/24    acme            finished the x25_get_stat function
  41* 1999/05/23    acme            dev->type = ARPHRD_X25 (tcpdump only works,
  42*                               AFAIT, with ARPHRD_ETHER). This seems to be
  43*                               needed to use socket(AF_X25)...
  44*                               Now the config file must specify a peer media
  45*                               address for svc channels over a crossover cable.
  46*                               Removed hold_timeout from x25_channel_t,
  47*                               not used.
  48*                               A little enhancement in the DEBUG processing
  49* 1999/05/22    acme            go to DISCONNECTED in disconnect_confirm_intr,
  50*                               instead of chan_disc.
  51* 1999/05/16    marcelo         fixed timer initialization in SVCs
  52* 1999/01/05    acme            x25_configure now get (most of) all
  53*                               parameters...
  54* 1999/01/05    acme            pktlen now (correctly) uses log2 (value
  55*                               configured)
  56* 1999/01/03    acme            judicious use of data types (u8, u16, u32, etc)
  57* 1999/01/03    acme            cyx_isr: reset dpmbase to acknowledge
  58*                               indication (interrupt from cyclom 2x)
  59* 1999/01/02    acme            cyx_isr: first hackings...
  60* 1999/01/0203  acme            when initializing an array don't give less
  61*                               elements than declared...
  62*                               example: char send_cmd[6] = "?\xFF\x10";
  63*                               you'll gonna lose a couple hours, 'cause your
  64*                               brain won't admit that there's an error in the
  65*                               above declaration...  the side effect is that
  66*                               memset is put into the unresolved symbols
  67*                               instead of using the inline memset functions...
  68* 1999/01/02    acme            began chan_connect, chan_send, x25_send
  69* 1998/12/31    acme            x25_configure
  70*                               this code can be compiled as non module
  71* 1998/12/27    acme            code cleanup
  72*                               IPX code wiped out! let's decrease code
  73*                               complexity for now, remember: I'm learning! :)
  74*                               bps_to_speed_code OK
  75* 1998/12/26    acme            Minimal debug code cleanup
  76* 1998/08/08    acme            Initial version.
  77*/
  78
  79#define CYCLOMX_X25_DEBUG 1
  80
  81#include <linux/ctype.h>        /* isdigit() */
  82#include <linux/errno.h>        /* return codes */
  83#include <linux/if_arp.h>       /* ARPHRD_HWX25 */
  84#include <linux/kernel.h>       /* printk(), and other useful stuff */
  85#include <linux/module.h>
  86#include <linux/string.h>       /* inline memset(), etc. */
  87#include <linux/sched.h>
  88#include <linux/slab.h>         /* kmalloc(), kfree() */
  89#include <linux/stddef.h>       /* offsetof(), etc. */
  90#include <linux/wanrouter.h>    /* WAN router definitions */
  91
  92#include <asm/byteorder.h>      /* htons(), etc. */
  93
  94#include <linux/cyclomx.h>      /* Cyclom 2X common user API definitions */
  95#include <linux/cycx_x25.h>     /* X.25 firmware API definitions */
  96
  97#include <net/x25device.h>
  98
  99/* Defines & Macros */
 100#define CYCX_X25_MAX_CMD_RETRY 5
 101#define CYCX_X25_CHAN_MTU 2048  /* unfragmented logical channel MTU */
 102
 103/* Data Structures */
 104/* This is an extension of the 'struct net_device' we create for each network
 105   interface to keep the rest of X.25 channel-specific data. */
 106struct cycx_x25_channel {
 107        /* This member must be first. */
 108        struct net_device *slave;       /* WAN slave */
 109
 110        char name[WAN_IFNAME_SZ+1];     /* interface name, ASCIIZ */
 111        char addr[WAN_ADDRESS_SZ+1];    /* media address, ASCIIZ */
 112        char *local_addr;               /* local media address, ASCIIZ -
 113                                           svc thru crossover cable */
 114        s16 lcn;                        /* logical channel number/conn.req.key*/
 115        u8 link;
 116        struct timer_list timer;        /* timer used for svc channel disc. */
 117        u16 protocol;                   /* ethertype, 0 - multiplexed */
 118        u8 svc;                         /* 0 - permanent, 1 - switched */
 119        u8 state;                       /* channel state */
 120        u8 drop_sequence;               /* mark sequence for dropping */
 121        u32 idle_tmout;                 /* sec, before disconnecting */
 122        struct sk_buff *rx_skb;         /* receive socket buffer */
 123        struct cycx_device *card;       /* -> owner */
 124        struct net_device_stats ifstats;/* interface statistics */
 125};
 126
 127/* Function Prototypes */
 128/* WAN link driver entry points. These are called by the WAN router module. */
 129static int cycx_wan_update(struct wan_device *wandev),
 130           cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev,
 131                           wanif_conf_t *conf),
 132           cycx_wan_del_if(struct wan_device *wandev, struct net_device *dev);
 133
 134/* Network device interface */
 135static int cycx_netdevice_init(struct net_device *dev);
 136static int cycx_netdevice_open(struct net_device *dev);
 137static int cycx_netdevice_stop(struct net_device *dev);
 138static int cycx_netdevice_hard_header(struct sk_buff *skb,
 139                                      struct net_device *dev, u16 type,
 140                                      const void *daddr, const void *saddr,
 141                                      unsigned len);
 142static int cycx_netdevice_rebuild_header(struct sk_buff *skb);
 143static netdev_tx_t cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
 144                                                        struct net_device *dev);
 145
 146static struct net_device_stats *
 147                        cycx_netdevice_get_stats(struct net_device *dev);
 148
 149/* Interrupt handlers */
 150static void cycx_x25_irq_handler(struct cycx_device *card),
 151            cycx_x25_irq_tx(struct cycx_device *card, struct cycx_x25_cmd *cmd),
 152            cycx_x25_irq_rx(struct cycx_device *card, struct cycx_x25_cmd *cmd),
 153            cycx_x25_irq_log(struct cycx_device *card,
 154                             struct cycx_x25_cmd *cmd),
 155            cycx_x25_irq_stat(struct cycx_device *card,
 156                              struct cycx_x25_cmd *cmd),
 157            cycx_x25_irq_connect_confirm(struct cycx_device *card,
 158                                         struct cycx_x25_cmd *cmd),
 159            cycx_x25_irq_disconnect_confirm(struct cycx_device *card,
 160                                            struct cycx_x25_cmd *cmd),
 161            cycx_x25_irq_connect(struct cycx_device *card,
 162                                 struct cycx_x25_cmd *cmd),
 163            cycx_x25_irq_disconnect(struct cycx_device *card,
 164                                    struct cycx_x25_cmd *cmd),
 165            cycx_x25_irq_spurious(struct cycx_device *card,
 166                                  struct cycx_x25_cmd *cmd);
 167
 168/* X.25 firmware interface functions */
 169static int cycx_x25_configure(struct cycx_device *card,
 170                              struct cycx_x25_config *conf),
 171           cycx_x25_get_stats(struct cycx_device *card),
 172           cycx_x25_send(struct cycx_device *card, u8 link, u8 lcn, u8 bitm,
 173                         int len, void *buf),
 174           cycx_x25_connect_response(struct cycx_device *card,
 175                                struct cycx_x25_channel *chan),
 176           cycx_x25_disconnect_response(struct cycx_device *card, u8 link,
 177                                        u8 lcn);
 178
 179/* channel functions */
 180static int cycx_x25_chan_connect(struct net_device *dev),
 181           cycx_x25_chan_send(struct net_device *dev, struct sk_buff *skb);
 182
 183static void cycx_x25_chan_disconnect(struct net_device *dev),
 184            cycx_x25_chan_send_event(struct net_device *dev, u8 event);
 185
 186/* Miscellaneous functions */
 187static void cycx_x25_set_chan_state(struct net_device *dev, u8 state),
 188            cycx_x25_chan_timer(unsigned long d);
 189
 190static void nibble_to_byte(u8 *s, u8 *d, u8 len, u8 nibble),
 191            reset_timer(struct net_device *dev);
 192
 193static u8 bps_to_speed_code(u32 bps);
 194static u8 cycx_log2(u32 n);
 195
 196static unsigned dec_to_uint(u8 *str, int len);
 197
 198static struct net_device *cycx_x25_get_dev_by_lcn(struct wan_device *wandev,
 199                                                  s16 lcn);
 200static struct net_device *
 201        cycx_x25_get_dev_by_dte_addr(struct wan_device *wandev, char *dte);
 202
 203static void cycx_x25_chan_setup(struct net_device *dev);
 204
 205#ifdef CYCLOMX_X25_DEBUG
 206static void hex_dump(char *msg, unsigned char *p, int len);
 207static void cycx_x25_dump_config(struct cycx_x25_config *conf);
 208static void cycx_x25_dump_stats(struct cycx_x25_stats *stats);
 209static void cycx_x25_dump_devs(struct wan_device *wandev);
 210#else
 211#define hex_dump(msg, p, len)
 212#define cycx_x25_dump_config(conf)
 213#define cycx_x25_dump_stats(stats)
 214#define cycx_x25_dump_devs(wandev)
 215#endif
 216/* Public Functions */
 217
 218/* X.25 Protocol Initialization routine.
 219 *
 220 * This routine is called by the main Cyclom 2X module during setup.  At this
 221 * point adapter is completely initialized and X.25 firmware is running.
 222 *  o configure adapter
 223 *  o initialize protocol-specific fields of the adapter data space.
 224 *
 225 * Return:      0       o.k.
 226 *              < 0     failure.  */
 227int cycx_x25_wan_init(struct cycx_device *card, wandev_conf_t *conf)
 228{
 229        struct cycx_x25_config cfg;
 230
 231        /* Verify configuration ID */
 232        if (conf->config_id != WANCONFIG_X25) {
 233                printk(KERN_INFO "%s: invalid configuration ID %u!\n",
 234                                 card->devname, conf->config_id);
 235                return -EINVAL;
 236        }
 237
 238        /* Initialize protocol-specific fields */
 239        card->mbox  = card->hw.dpmbase + X25_MBOX_OFFS;
 240        card->u.x.connection_keys = 0;
 241        spin_lock_init(&card->u.x.lock);
 242
 243        /* Configure adapter. Here we set reasonable defaults, then parse
 244         * device configuration structure and set configuration options.
 245         * Most configuration options are verified and corrected (if
 246         * necessary) since we can't rely on the adapter to do so and don't
 247         * want it to fail either. */
 248        memset(&cfg, 0, sizeof(cfg));
 249        cfg.link = 0;
 250        cfg.clock = conf->clocking == WANOPT_EXTERNAL ? 8 : 55;
 251        cfg.speed = bps_to_speed_code(conf->bps);
 252        cfg.n3win = 7;
 253        cfg.n2win = 2;
 254        cfg.n2 = 5;
 255        cfg.nvc = 1;
 256        cfg.npvc = 1;
 257        cfg.flags = 0x02; /* default = V35 */
 258        cfg.t1 = 10;   /* line carrier timeout */
 259        cfg.t2 = 29;   /* tx timeout */
 260        cfg.t21 = 180; /* CALL timeout */
 261        cfg.t23 = 180; /* CLEAR timeout */
 262
 263        /* adjust MTU */
 264        if (!conf->mtu || conf->mtu >= 512)
 265                card->wandev.mtu = 512;
 266        else if (conf->mtu >= 256)
 267                card->wandev.mtu = 256;
 268        else if (conf->mtu >= 128)
 269                card->wandev.mtu = 128;
 270        else
 271                card->wandev.mtu = 64;
 272
 273        cfg.pktlen = cycx_log2(card->wandev.mtu);
 274
 275        if (conf->station == WANOPT_DTE) {
 276                cfg.locaddr = 3; /* DTE */
 277                cfg.remaddr = 1; /* DCE */
 278        } else {
 279                cfg.locaddr = 1; /* DCE */
 280                cfg.remaddr = 3; /* DTE */
 281        }
 282
 283        if (conf->interface == WANOPT_RS232)
 284                cfg.flags = 0;      /* FIXME just reset the 2nd bit */
 285
 286        if (conf->u.x25.hi_pvc) {
 287                card->u.x.hi_pvc = min_t(unsigned int, conf->u.x25.hi_pvc, 4095);
 288                card->u.x.lo_pvc = min_t(unsigned int, conf->u.x25.lo_pvc, card->u.x.hi_pvc);
 289        }
 290
 291        if (conf->u.x25.hi_svc) {
 292                card->u.x.hi_svc = min_t(unsigned int, conf->u.x25.hi_svc, 4095);
 293                card->u.x.lo_svc = min_t(unsigned int, conf->u.x25.lo_svc, card->u.x.hi_svc);
 294        }
 295
 296        if (card->u.x.lo_pvc == 255)
 297                cfg.npvc = 0;
 298        else
 299                cfg.npvc = card->u.x.hi_pvc - card->u.x.lo_pvc + 1;
 300
 301        cfg.nvc = card->u.x.hi_svc - card->u.x.lo_svc + 1 + cfg.npvc;
 302
 303        if (conf->u.x25.hdlc_window)
 304                cfg.n2win = min_t(unsigned int, conf->u.x25.hdlc_window, 7);
 305
 306        if (conf->u.x25.pkt_window)
 307                cfg.n3win = min_t(unsigned int, conf->u.x25.pkt_window, 7);
 308
 309        if (conf->u.x25.t1)
 310                cfg.t1 = min_t(unsigned int, conf->u.x25.t1, 30);
 311
 312        if (conf->u.x25.t2)
 313                cfg.t2 = min_t(unsigned int, conf->u.x25.t2, 30);
 314
 315        if (conf->u.x25.t11_t21)
 316                cfg.t21 = min_t(unsigned int, conf->u.x25.t11_t21, 30);
 317
 318        if (conf->u.x25.t13_t23)
 319                cfg.t23 = min_t(unsigned int, conf->u.x25.t13_t23, 30);
 320
 321        if (conf->u.x25.n2)
 322                cfg.n2 = min_t(unsigned int, conf->u.x25.n2, 30);
 323
 324        /* initialize adapter */
 325        if (cycx_x25_configure(card, &cfg))
 326                return -EIO;
 327
 328        /* Initialize protocol-specific fields of adapter data space */
 329        card->wandev.bps        = conf->bps;
 330        card->wandev.interface  = conf->interface;
 331        card->wandev.clocking   = conf->clocking;
 332        card->wandev.station    = conf->station;
 333        card->isr               = cycx_x25_irq_handler;
 334        card->exec              = NULL;
 335        card->wandev.update     = cycx_wan_update;
 336        card->wandev.new_if     = cycx_wan_new_if;
 337        card->wandev.del_if     = cycx_wan_del_if;
 338        card->wandev.state      = WAN_DISCONNECTED;
 339
 340        return 0;
 341}
 342
 343/* WAN Device Driver Entry Points */
 344/* Update device status & statistics. */
 345static int cycx_wan_update(struct wan_device *wandev)
 346{
 347        /* sanity checks */
 348        if (!wandev || !wandev->private)
 349                return -EFAULT;
 350
 351        if (wandev->state == WAN_UNCONFIGURED)
 352                return -ENODEV;
 353
 354        cycx_x25_get_stats(wandev->private);
 355
 356        return 0;
 357}
 358
 359/* Create new logical channel.
 360 * This routine is called by the router when ROUTER_IFNEW IOCTL is being
 361 * handled.
 362 * o parse media- and hardware-specific configuration
 363 * o make sure that a new channel can be created
 364 * o allocate resources, if necessary
 365 * o prepare network device structure for registration.
 366 *
 367 * Return:      0       o.k.
 368 *              < 0     failure (channel will not be created) */
 369static int cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev,
 370                           wanif_conf_t *conf)
 371{
 372        struct cycx_device *card = wandev->private;
 373        struct cycx_x25_channel *chan;
 374        int err = 0;
 375
 376        if (!conf->name[0] || strlen(conf->name) > WAN_IFNAME_SZ) {
 377                printk(KERN_INFO "%s: invalid interface name!\n",
 378                       card->devname);
 379                return -EINVAL;
 380        }
 381
 382        dev = alloc_netdev(sizeof(struct cycx_x25_channel), conf->name,
 383                             cycx_x25_chan_setup);
 384        if (!dev)
 385                return -ENOMEM;
 386
 387        chan = netdev_priv(dev);
 388        strcpy(chan->name, conf->name);
 389        chan->card = card;
 390        chan->link = conf->port;
 391        chan->protocol = conf->protocol ? ETH_P_X25 : ETH_P_IP;
 392        chan->rx_skb = NULL;
 393        /* only used in svc connected thru crossover cable */
 394        chan->local_addr = NULL;
 395
 396        if (conf->addr[0] == '@') {     /* SVC */
 397                int len = strlen(conf->local_addr);
 398
 399                if (len) {
 400                        if (len > WAN_ADDRESS_SZ) {
 401                                printk(KERN_ERR "%s: %s local addr too long!\n",
 402                                                wandev->name, chan->name);
 403                                err = -EINVAL;
 404                                goto error;
 405                        } else {
 406                                chan->local_addr = kmalloc(len + 1, GFP_KERNEL);
 407
 408                                if (!chan->local_addr) {
 409                                        err = -ENOMEM;
 410                                        goto error;
 411                                }
 412                        }
 413
 414                        strncpy(chan->local_addr, conf->local_addr,
 415                                WAN_ADDRESS_SZ);
 416                }
 417
 418                chan->svc = 1;
 419                strncpy(chan->addr, &conf->addr[1], WAN_ADDRESS_SZ);
 420                init_timer(&chan->timer);
 421                chan->timer.function    = cycx_x25_chan_timer;
 422                chan->timer.data        = (unsigned long)dev;
 423
 424                /* Set channel timeouts (default if not specified) */
 425                chan->idle_tmout = conf->idle_timeout ? conf->idle_timeout : 90;
 426        } else if (isdigit(conf->addr[0])) {    /* PVC */
 427                s16 lcn = dec_to_uint(conf->addr, 0);
 428
 429                if (lcn >= card->u.x.lo_pvc && lcn <= card->u.x.hi_pvc)
 430                        chan->lcn = lcn;
 431                else {
 432                        printk(KERN_ERR
 433                                "%s: PVC %u is out of range on interface %s!\n",
 434                                wandev->name, lcn, chan->name);
 435                        err = -EINVAL;
 436                        goto error;
 437                }
 438        } else {
 439                printk(KERN_ERR "%s: invalid media address on interface %s!\n",
 440                                wandev->name, chan->name);
 441                err = -EINVAL;
 442                goto error;
 443        }
 444
 445        return 0;
 446
 447error:
 448        free_netdev(dev);
 449        return err;
 450}
 451
 452/* Delete logical channel. */
 453static int cycx_wan_del_if(struct wan_device *wandev, struct net_device *dev)
 454{
 455        struct cycx_x25_channel *chan = netdev_priv(dev);
 456
 457        if (chan->svc) {
 458                kfree(chan->local_addr);
 459                if (chan->state == WAN_CONNECTED)
 460                        del_timer(&chan->timer);
 461        }
 462
 463        return 0;
 464}
 465
 466
 467/* Network Device Interface */
 468
 469static const struct header_ops cycx_header_ops = {
 470        .create = cycx_netdevice_hard_header,
 471        .rebuild = cycx_netdevice_rebuild_header,
 472};
 473
 474static const struct net_device_ops cycx_netdev_ops = {
 475        .ndo_init       = cycx_netdevice_init,
 476        .ndo_open       = cycx_netdevice_open,
 477        .ndo_stop       = cycx_netdevice_stop,
 478        .ndo_start_xmit = cycx_netdevice_hard_start_xmit,
 479        .ndo_get_stats  = cycx_netdevice_get_stats,
 480};
 481
 482static void cycx_x25_chan_setup(struct net_device *dev)
 483{
 484        /* Initialize device driver entry points */
 485        dev->netdev_ops         = &cycx_netdev_ops;
 486        dev->header_ops         = &cycx_header_ops;
 487
 488        /* Initialize media-specific parameters */
 489        dev->mtu                = CYCX_X25_CHAN_MTU;
 490        dev->type               = ARPHRD_HWX25; /* ARP h/w type */
 491        dev->hard_header_len    = 0;            /* media header length */
 492        dev->addr_len           = 0;            /* hardware address length */
 493}
 494
 495/* Initialize Linux network interface.
 496 *
 497 * This routine is called only once for each interface, during Linux network
 498 * interface registration.  Returning anything but zero will fail interface
 499 * registration. */
 500static int cycx_netdevice_init(struct net_device *dev)
 501{
 502        struct cycx_x25_channel *chan = netdev_priv(dev);
 503        struct cycx_device *card = chan->card;
 504        struct wan_device *wandev = &card->wandev;
 505
 506        if (!chan->svc)
 507                *(__be16*)dev->dev_addr = htons(chan->lcn);
 508
 509        /* Initialize hardware parameters (just for reference) */
 510        dev->irq                = wandev->irq;
 511        dev->dma                = wandev->dma;
 512        dev->base_addr          = wandev->ioport;
 513        dev->mem_start          = (unsigned long)wandev->maddr;
 514        dev->mem_end            = (unsigned long)(wandev->maddr +
 515                                                  wandev->msize - 1);
 516        dev->flags              |= IFF_NOARP;
 517
 518        /* Set transmit buffer queue length */
 519        dev->tx_queue_len       = 10;
 520
 521        /* Initialize socket buffers */
 522        cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
 523
 524        return 0;
 525}
 526
 527/* Open network interface.
 528 * o prevent module from unloading by incrementing use count
 529 * o if link is disconnected then initiate connection
 530 *
 531 * Return 0 if O.k. or errno.  */
 532static int cycx_netdevice_open(struct net_device *dev)
 533{
 534        if (netif_running(dev))
 535                return -EBUSY; /* only one open is allowed */
 536
 537        netif_start_queue(dev);
 538        return 0;
 539}
 540
 541/* Close network interface.
 542 * o reset flags.
 543 * o if there's no more open channels then disconnect physical link. */
 544static int cycx_netdevice_stop(struct net_device *dev)
 545{
 546        struct cycx_x25_channel *chan = netdev_priv(dev);
 547
 548        netif_stop_queue(dev);
 549
 550        if (chan->state == WAN_CONNECTED || chan->state == WAN_CONNECTING)
 551                cycx_x25_chan_disconnect(dev);
 552
 553        return 0;
 554}
 555
 556/* Build media header.
 557 * o encapsulate packet according to encapsulation type.
 558 *
 559 * The trick here is to put packet type (Ethertype) into 'protocol' field of
 560 * the socket buffer, so that we don't forget it.  If encapsulation fails,
 561 * set skb->protocol to 0 and discard packet later.
 562 *
 563 * Return:      media header length. */
 564static int cycx_netdevice_hard_header(struct sk_buff *skb,
 565                                      struct net_device *dev, u16 type,
 566                                      const void *daddr, const void *saddr,
 567                                      unsigned len)
 568{
 569        skb->protocol = htons(type);
 570
 571        return dev->hard_header_len;
 572}
 573
 574/* * Re-build media header.
 575 * Return:      1       physical address resolved.
 576 *              0       physical address not resolved */
 577static int cycx_netdevice_rebuild_header(struct sk_buff *skb)
 578{
 579        return 1;
 580}
 581
 582/* Send a packet on a network interface.
 583 * o set busy flag (marks start of the transmission).
 584 * o check link state. If link is not up, then drop the packet.
 585 * o check channel status. If it's down then initiate a call.
 586 * o pass a packet to corresponding WAN device.
 587 * o free socket buffer
 588 *
 589 * Return:      0       complete (socket buffer must be freed)
 590 *              non-0   packet may be re-transmitted (tbusy must be set)
 591 *
 592 * Notes:
 593 * 1. This routine is called either by the protocol stack or by the "net
 594 *    bottom half" (with interrupts enabled).
 595 * 2. Setting tbusy flag will inhibit further transmit requests from the
 596 *    protocol stack and can be used for flow control with protocol layer. */
 597static netdev_tx_t cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
 598                                                        struct net_device *dev)
 599{
 600        struct cycx_x25_channel *chan = netdev_priv(dev);
 601        struct cycx_device *card = chan->card;
 602
 603        if (!chan->svc)
 604                chan->protocol = ntohs(skb->protocol);
 605
 606        if (card->wandev.state != WAN_CONNECTED)
 607                ++chan->ifstats.tx_dropped;
 608        else if (chan->svc && chan->protocol &&
 609                 chan->protocol != ntohs(skb->protocol)) {
 610                printk(KERN_INFO
 611                       "%s: unsupported Ethertype 0x%04X on interface %s!\n",
 612                       card->devname, ntohs(skb->protocol), dev->name);
 613                ++chan->ifstats.tx_errors;
 614        } else if (chan->protocol == ETH_P_IP) {
 615                switch (chan->state) {
 616                case WAN_DISCONNECTED:
 617                        if (cycx_x25_chan_connect(dev)) {
 618                                netif_stop_queue(dev);
 619                                return NETDEV_TX_BUSY;
 620                        }
 621                        /* fall thru */
 622                case WAN_CONNECTED:
 623                        reset_timer(dev);
 624                        dev->trans_start = jiffies;
 625                        netif_stop_queue(dev);
 626
 627                        if (cycx_x25_chan_send(dev, skb))
 628                                return NETDEV_TX_BUSY;
 629
 630                        break;
 631                default:
 632                        ++chan->ifstats.tx_dropped;
 633                        ++card->wandev.stats.tx_dropped;
 634        }
 635        } else { /* chan->protocol == ETH_P_X25 */
 636                switch (skb->data[0]) {
 637                case 0: break;
 638                case 1: /* Connect request */
 639                        cycx_x25_chan_connect(dev);
 640                        goto free_packet;
 641                case 2: /* Disconnect request */
 642                        cycx_x25_chan_disconnect(dev);
 643                        goto free_packet;
 644                default:
 645                        printk(KERN_INFO
 646                               "%s: unknown %d x25-iface request on %s!\n",
 647                               card->devname, skb->data[0], dev->name);
 648                        ++chan->ifstats.tx_errors;
 649                        goto free_packet;
 650                }
 651
 652                skb_pull(skb, 1); /* Remove control byte */
 653                reset_timer(dev);
 654                dev->trans_start = jiffies;
 655                netif_stop_queue(dev);
 656
 657                if (cycx_x25_chan_send(dev, skb)) {
 658                        /* prepare for future retransmissions */
 659                        skb_push(skb, 1);
 660                        return NETDEV_TX_BUSY;
 661                }
 662        }
 663
 664free_packet:
 665        dev_kfree_skb(skb);
 666
 667        return NETDEV_TX_OK;
 668}
 669
 670/* Get Ethernet-style interface statistics.
 671 * Return a pointer to struct net_device_stats */
 672static struct net_device_stats *cycx_netdevice_get_stats(struct net_device *dev)
 673{
 674        struct cycx_x25_channel *chan = netdev_priv(dev);
 675
 676        return chan ? &chan->ifstats : NULL;
 677}
 678
 679/* Interrupt Handlers */
 680/* X.25 Interrupt Service Routine. */
 681static void cycx_x25_irq_handler(struct cycx_device *card)
 682{
 683        struct cycx_x25_cmd cmd;
 684        u16 z = 0;
 685
 686        card->in_isr = 1;
 687        card->buff_int_mode_unbusy = 0;
 688        cycx_peek(&card->hw, X25_RXMBOX_OFFS, &cmd, sizeof(cmd));
 689
 690        switch (cmd.command) {
 691        case X25_DATA_INDICATION:
 692                cycx_x25_irq_rx(card, &cmd);
 693                break;
 694        case X25_ACK_FROM_VC:
 695                cycx_x25_irq_tx(card, &cmd);
 696                break;
 697        case X25_LOG:
 698                cycx_x25_irq_log(card, &cmd);
 699                break;
 700        case X25_STATISTIC:
 701                cycx_x25_irq_stat(card, &cmd);
 702                break;
 703        case X25_CONNECT_CONFIRM:
 704                cycx_x25_irq_connect_confirm(card, &cmd);
 705                break;
 706        case X25_CONNECT_INDICATION:
 707                cycx_x25_irq_connect(card, &cmd);
 708                break;
 709        case X25_DISCONNECT_INDICATION:
 710                cycx_x25_irq_disconnect(card, &cmd);
 711                break;
 712        case X25_DISCONNECT_CONFIRM:
 713                cycx_x25_irq_disconnect_confirm(card, &cmd);
 714                break;
 715        case X25_LINE_ON:
 716                cycx_set_state(card, WAN_CONNECTED);
 717                break;
 718        case X25_LINE_OFF:
 719                cycx_set_state(card, WAN_DISCONNECTED);
 720                break;
 721        default:
 722                cycx_x25_irq_spurious(card, &cmd);
 723                break;
 724        }
 725
 726        cycx_poke(&card->hw, 0, &z, sizeof(z));
 727        cycx_poke(&card->hw, X25_RXMBOX_OFFS, &z, sizeof(z));
 728        card->in_isr = 0;
 729}
 730
 731/* Transmit interrupt handler.
 732 *      o Release socket buffer
 733 *      o Clear 'tbusy' flag */
 734static void cycx_x25_irq_tx(struct cycx_device *card, struct cycx_x25_cmd *cmd)
 735{
 736        struct net_device *dev;
 737        struct wan_device *wandev = &card->wandev;
 738        u8 lcn;
 739
 740        cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
 741
 742        /* unbusy device and then dev_tint(); */
 743        dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
 744        if (dev) {
 745                card->buff_int_mode_unbusy = 1;
 746                netif_wake_queue(dev);
 747        } else
 748                printk(KERN_ERR "%s:ackvc for inexistent lcn %d\n",
 749                                 card->devname, lcn);
 750}
 751
 752/* Receive interrupt handler.
 753 * This routine handles fragmented IP packets using M-bit according to the
 754 * RFC1356.
 755 * o map logical channel number to network interface.
 756 * o allocate socket buffer or append received packet to the existing one.
 757 * o if M-bit is reset (i.e. it's the last packet in a sequence) then
 758 *   decapsulate packet and pass socket buffer to the protocol stack.
 759 *
 760 * Notes:
 761 * 1. When allocating a socket buffer, if M-bit is set then more data is
 762 *    coming and we have to allocate buffer for the maximum IP packet size
 763 *    expected on this channel.
 764 * 2. If something goes wrong and X.25 packet has to be dropped (e.g. no
 765 *    socket buffers available) the whole packet sequence must be discarded. */
 766static void cycx_x25_irq_rx(struct cycx_device *card, struct cycx_x25_cmd *cmd)
 767{
 768        struct wan_device *wandev = &card->wandev;
 769        struct net_device *dev;
 770        struct cycx_x25_channel *chan;
 771        struct sk_buff *skb;
 772        u8 bitm, lcn;
 773        int pktlen = cmd->len - 5;
 774
 775        cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
 776        cycx_peek(&card->hw, cmd->buf + 4, &bitm, sizeof(bitm));
 777        bitm &= 0x10;
 778
 779        dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
 780        if (!dev) {
 781                /* Invalid channel, discard packet */
 782                printk(KERN_INFO "%s: receiving on orphaned LCN %d!\n",
 783                                 card->devname, lcn);
 784                return;
 785        }
 786
 787        chan = netdev_priv(dev);
 788        reset_timer(dev);
 789
 790        if (chan->drop_sequence) {
 791                if (!bitm)
 792                        chan->drop_sequence = 0;
 793                else
 794                        return;
 795        }
 796
 797        if ((skb = chan->rx_skb) == NULL) {
 798                /* Allocate new socket buffer */
 799                int bufsize = bitm ? dev->mtu : pktlen;
 800
 801                if ((skb = dev_alloc_skb((chan->protocol == ETH_P_X25 ? 1 : 0) +
 802                                         bufsize +
 803                                         dev->hard_header_len)) == NULL) {
 804                        printk(KERN_INFO "%s: no socket buffers available!\n",
 805                                         card->devname);
 806                        chan->drop_sequence = 1;
 807                        ++chan->ifstats.rx_dropped;
 808                        return;
 809                }
 810
 811                if (chan->protocol == ETH_P_X25) /* X.25 socket layer control */
 812                        /* 0 = data packet (dev_alloc_skb zeroed skb->data) */
 813                        skb_put(skb, 1);
 814
 815                skb->dev = dev;
 816                skb->protocol = htons(chan->protocol);
 817                chan->rx_skb = skb;
 818        }
 819
 820        if (skb_tailroom(skb) < pktlen) {
 821                /* No room for the packet. Call off the whole thing! */
 822                dev_kfree_skb_irq(skb);
 823                chan->rx_skb = NULL;
 824
 825                if (bitm)
 826                        chan->drop_sequence = 1;
 827
 828                printk(KERN_INFO "%s: unexpectedly long packet sequence "
 829                        "on interface %s!\n", card->devname, dev->name);
 830                ++chan->ifstats.rx_length_errors;
 831                return;
 832        }
 833
 834        /* Append packet to the socket buffer  */
 835        cycx_peek(&card->hw, cmd->buf + 5, skb_put(skb, pktlen), pktlen);
 836
 837        if (bitm)
 838                return; /* more data is coming */
 839
 840        chan->rx_skb = NULL;            /* dequeue packet */
 841
 842        ++chan->ifstats.rx_packets;
 843        chan->ifstats.rx_bytes += pktlen;
 844
 845        skb_reset_mac_header(skb);
 846        netif_rx(skb);
 847}
 848
 849/* Connect interrupt handler. */
 850static void cycx_x25_irq_connect(struct cycx_device *card,
 851                                 struct cycx_x25_cmd *cmd)
 852{
 853        struct wan_device *wandev = &card->wandev;
 854        struct net_device *dev = NULL;
 855        struct cycx_x25_channel *chan;
 856        u8 d[32],
 857           loc[24],
 858           rem[24];
 859        u8 lcn, sizeloc, sizerem;
 860
 861        cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
 862        cycx_peek(&card->hw, cmd->buf + 5, &sizeloc, sizeof(sizeloc));
 863        cycx_peek(&card->hw, cmd->buf + 6, d, cmd->len - 6);
 864
 865        sizerem = sizeloc >> 4;
 866        sizeloc &= 0x0F;
 867
 868        loc[0] = rem[0] = '\0';
 869
 870        if (sizeloc)
 871                nibble_to_byte(d, loc, sizeloc, 0);
 872
 873        if (sizerem)
 874                nibble_to_byte(d + (sizeloc >> 1), rem, sizerem, sizeloc & 1);
 875
 876        dprintk(1, KERN_INFO "%s:lcn=%d, local=%s, remote=%s\n",
 877                          __func__, lcn, loc, rem);
 878
 879        dev = cycx_x25_get_dev_by_dte_addr(wandev, rem);
 880        if (!dev) {
 881                /* Invalid channel, discard packet */
 882                printk(KERN_INFO "%s: connect not expected: remote %s!\n",
 883                                 card->devname, rem);
 884                return;
 885        }
 886
 887        chan = netdev_priv(dev);
 888        chan->lcn = lcn;
 889        cycx_x25_connect_response(card, chan);
 890        cycx_x25_set_chan_state(dev, WAN_CONNECTED);
 891}
 892
 893/* Connect confirm interrupt handler. */
 894static void cycx_x25_irq_connect_confirm(struct cycx_device *card,
 895                                         struct cycx_x25_cmd *cmd)
 896{
 897        struct wan_device *wandev = &card->wandev;
 898        struct net_device *dev;
 899        struct cycx_x25_channel *chan;
 900        u8 lcn, key;
 901
 902        cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
 903        cycx_peek(&card->hw, cmd->buf + 1, &key, sizeof(key));
 904        dprintk(1, KERN_INFO "%s: %s:lcn=%d, key=%d\n",
 905                          card->devname, __func__, lcn, key);
 906
 907        dev = cycx_x25_get_dev_by_lcn(wandev, -key);
 908        if (!dev) {
 909                /* Invalid channel, discard packet */
 910                clear_bit(--key, (void*)&card->u.x.connection_keys);
 911                printk(KERN_INFO "%s: connect confirm not expected: lcn %d, "
 912                                 "key=%d!\n", card->devname, lcn, key);
 913                return;
 914        }
 915
 916        clear_bit(--key, (void*)&card->u.x.connection_keys);
 917        chan = netdev_priv(dev);
 918        chan->lcn = lcn;
 919        cycx_x25_set_chan_state(dev, WAN_CONNECTED);
 920}
 921
 922/* Disconnect confirm interrupt handler. */
 923static void cycx_x25_irq_disconnect_confirm(struct cycx_device *card,
 924                                            struct cycx_x25_cmd *cmd)
 925{
 926        struct wan_device *wandev = &card->wandev;
 927        struct net_device *dev;
 928        u8 lcn;
 929
 930        cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
 931        dprintk(1, KERN_INFO "%s: %s:lcn=%d\n",
 932                          card->devname, __func__, lcn);
 933        dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
 934        if (!dev) {
 935                /* Invalid channel, discard packet */
 936                printk(KERN_INFO "%s:disconnect confirm not expected!:lcn %d\n",
 937                                 card->devname, lcn);
 938                return;
 939        }
 940
 941        cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
 942}
 943
 944/* disconnect interrupt handler. */
 945static void cycx_x25_irq_disconnect(struct cycx_device *card,
 946                                    struct cycx_x25_cmd *cmd)
 947{
 948        struct wan_device *wandev = &card->wandev;
 949        struct net_device *dev;
 950        u8 lcn;
 951
 952        cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
 953        dprintk(1, KERN_INFO "%s:lcn=%d\n", __func__, lcn);
 954
 955        dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
 956        if (dev) {
 957                struct cycx_x25_channel *chan = netdev_priv(dev);
 958
 959                cycx_x25_disconnect_response(card, chan->link, lcn);
 960                cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
 961        } else
 962                cycx_x25_disconnect_response(card, 0, lcn);
 963}
 964
 965/* LOG interrupt handler. */
 966static void cycx_x25_irq_log(struct cycx_device *card, struct cycx_x25_cmd *cmd)
 967{
 968#if CYCLOMX_X25_DEBUG
 969        char bf[20];
 970        u16 size, toread, link, msg_code;
 971        u8 code, routine;
 972
 973        cycx_peek(&card->hw, cmd->buf, &msg_code, sizeof(msg_code));
 974        cycx_peek(&card->hw, cmd->buf + 2, &link, sizeof(link));
 975        cycx_peek(&card->hw, cmd->buf + 4, &size, sizeof(size));
 976        /* at most 20 bytes are available... thanks to Daniela :) */
 977        toread = size < 20 ? size : 20;
 978        cycx_peek(&card->hw, cmd->buf + 10, &bf, toread);
 979        cycx_peek(&card->hw, cmd->buf + 10 + toread, &code, 1);
 980        cycx_peek(&card->hw, cmd->buf + 10 + toread + 1, &routine, 1);
 981
 982        printk(KERN_INFO "cycx_x25_irq_handler: X25_LOG (0x4500) indic.:\n");
 983        printk(KERN_INFO "cmd->buf=0x%X\n", cmd->buf);
 984        printk(KERN_INFO "Log message code=0x%X\n", msg_code);
 985        printk(KERN_INFO "Link=%d\n", link);
 986        printk(KERN_INFO "log code=0x%X\n", code);
 987        printk(KERN_INFO "log routine=0x%X\n", routine);
 988        printk(KERN_INFO "Message size=%d\n", size);
 989        hex_dump("Message", bf, toread);
 990#endif
 991}
 992
 993/* STATISTIC interrupt handler. */
 994static void cycx_x25_irq_stat(struct cycx_device *card,
 995                              struct cycx_x25_cmd *cmd)
 996{
 997        cycx_peek(&card->hw, cmd->buf, &card->u.x.stats,
 998                  sizeof(card->u.x.stats));
 999        hex_dump("cycx_x25_irq_stat", (unsigned char*)&card->u.x.stats,
1000                 sizeof(card->u.x.stats));
1001        cycx_x25_dump_stats(&card->u.x.stats);
1002        wake_up_interruptible(&card->wait_stats);
1003}
1004
1005/* Spurious interrupt handler.
1006 * o print a warning
1007 * If number of spurious interrupts exceeded some limit, then ??? */
1008static void cycx_x25_irq_spurious(struct cycx_device *card,
1009                                  struct cycx_x25_cmd *cmd)
1010{
1011        printk(KERN_INFO "%s: spurious interrupt (0x%X)!\n",
1012                         card->devname, cmd->command);
1013}
1014#ifdef CYCLOMX_X25_DEBUG
1015static void hex_dump(char *msg, unsigned char *p, int len)
1016{
1017        unsigned char hex[1024],
1018                * phex = hex;
1019
1020        if (len >= (sizeof(hex) / 2))
1021                len = (sizeof(hex) / 2) - 1;
1022
1023        while (len--) {
1024                sprintf(phex, "%02x", *p++);
1025                phex += 2;
1026        }
1027
1028        printk(KERN_INFO "%s: %s\n", msg, hex);
1029}
1030#endif
1031
1032/* Cyclom 2X Firmware-Specific Functions */
1033/* Exec X.25 command. */
1034static int x25_exec(struct cycx_device *card, int command, int link,
1035                    void *d1, int len1, void *d2, int len2)
1036{
1037        struct cycx_x25_cmd c;
1038        unsigned long flags;
1039        u32 addr = 0x1200 + 0x2E0 * link + 0x1E2;
1040        u8 retry = CYCX_X25_MAX_CMD_RETRY;
1041        int err = 0;
1042
1043        c.command = command;
1044        c.link = link;
1045        c.len = len1 + len2;
1046
1047        spin_lock_irqsave(&card->u.x.lock, flags);
1048
1049        /* write command */
1050        cycx_poke(&card->hw, X25_MBOX_OFFS, &c, sizeof(c) - sizeof(c.buf));
1051
1052        /* write X.25 data */
1053        if (d1) {
1054                cycx_poke(&card->hw, addr, d1, len1);
1055
1056                if (d2) {
1057                        if (len2 > 254) {
1058                                u32 addr1 = 0xA00 + 0x400 * link;
1059
1060                                cycx_poke(&card->hw, addr + len1, d2, 249);
1061                                cycx_poke(&card->hw, addr1, ((u8*)d2) + 249,
1062                                          len2 - 249);
1063                        } else
1064                                cycx_poke(&card->hw, addr + len1, d2, len2);
1065                }
1066        }
1067
1068        /* generate interruption, executing command */
1069        cycx_intr(&card->hw);
1070
1071        /* wait till card->mbox == 0 */
1072        do {
1073                err = cycx_exec(card->mbox);
1074        } while (retry-- && err);
1075
1076        spin_unlock_irqrestore(&card->u.x.lock, flags);
1077
1078        return err;
1079}
1080
1081/* Configure adapter. */
1082static int cycx_x25_configure(struct cycx_device *card,
1083                              struct cycx_x25_config *conf)
1084{
1085        struct {
1086                u16 nlinks;
1087                struct cycx_x25_config conf[2];
1088        } x25_cmd_conf;
1089
1090        memset(&x25_cmd_conf, 0, sizeof(x25_cmd_conf));
1091        x25_cmd_conf.nlinks = 2;
1092        x25_cmd_conf.conf[0] = *conf;
1093        /* FIXME: we need to find a way in the wanrouter framework
1094                  to configure the second link, for now lets use it
1095                  with the same config from the first link, fixing
1096                  the interface type to RS232, the speed in 38400 and
1097                  the clock to external */
1098        x25_cmd_conf.conf[1] = *conf;
1099        x25_cmd_conf.conf[1].link = 1;
1100        x25_cmd_conf.conf[1].speed = 5; /* 38400 */
1101        x25_cmd_conf.conf[1].clock = 8;
1102        x25_cmd_conf.conf[1].flags = 0; /* default = RS232 */
1103
1104        cycx_x25_dump_config(&x25_cmd_conf.conf[0]);
1105        cycx_x25_dump_config(&x25_cmd_conf.conf[1]);
1106
1107        return x25_exec(card, X25_CONFIG, 0,
1108                        &x25_cmd_conf, sizeof(x25_cmd_conf), NULL, 0);
1109}
1110
1111/* Get protocol statistics. */
1112static int cycx_x25_get_stats(struct cycx_device *card)
1113{
1114        /* the firmware expects 20 in the size field!!!
1115           thanks to Daniela */
1116        int err = x25_exec(card, X25_STATISTIC, 0, NULL, 20, NULL, 0);
1117
1118        if (err)
1119                return err;
1120
1121        interruptible_sleep_on(&card->wait_stats);
1122
1123        if (signal_pending(current))
1124                return -EINTR;
1125
1126        card->wandev.stats.rx_packets = card->u.x.stats.n2_rx_frames;
1127        card->wandev.stats.rx_over_errors = card->u.x.stats.rx_over_errors;
1128        card->wandev.stats.rx_crc_errors = card->u.x.stats.rx_crc_errors;
1129        card->wandev.stats.rx_length_errors = 0; /* not available from fw */
1130        card->wandev.stats.rx_frame_errors = 0; /* not available from fw */
1131        card->wandev.stats.rx_missed_errors = card->u.x.stats.rx_aborts;
1132        card->wandev.stats.rx_dropped = 0; /* not available from fw */
1133        card->wandev.stats.rx_errors = 0; /* not available from fw */
1134        card->wandev.stats.tx_packets = card->u.x.stats.n2_tx_frames;
1135        card->wandev.stats.tx_aborted_errors = card->u.x.stats.tx_aborts;
1136        card->wandev.stats.tx_dropped = 0; /* not available from fw */
1137        card->wandev.stats.collisions = 0; /* not available from fw */
1138        card->wandev.stats.tx_errors = 0; /* not available from fw */
1139
1140        cycx_x25_dump_devs(&card->wandev);
1141
1142        return 0;
1143}
1144
1145/* return the number of nibbles */
1146static int byte_to_nibble(u8 *s, u8 *d, char *nibble)
1147{
1148        int i = 0;
1149
1150        if (*nibble && *s) {
1151                d[i] |= *s++ - '0';
1152                *nibble = 0;
1153                ++i;
1154        }
1155
1156        while (*s) {
1157                d[i] = (*s - '0') << 4;
1158                if (*(s + 1))
1159                        d[i] |= *(s + 1) - '0';
1160                else {
1161                        *nibble = 1;
1162                        break;
1163                }
1164                ++i;
1165                s += 2;
1166        }
1167
1168        return i;
1169}
1170
1171static void nibble_to_byte(u8 *s, u8 *d, u8 len, u8 nibble)
1172{
1173        if (nibble) {
1174                *d++ = '0' + (*s++ & 0x0F);
1175                --len;
1176        }
1177
1178        while (len) {
1179                *d++ = '0' + (*s >> 4);
1180
1181                if (--len) {
1182                        *d++ = '0' + (*s & 0x0F);
1183                        --len;
1184                } else break;
1185
1186                ++s;
1187        }
1188
1189        *d = '\0';
1190}
1191
1192/* Place X.25 call. */
1193static int x25_place_call(struct cycx_device *card,
1194                          struct cycx_x25_channel *chan)
1195{
1196        int err = 0,
1197            len;
1198        char d[64],
1199             nibble = 0,
1200             mylen = chan->local_addr ? strlen(chan->local_addr) : 0,
1201             remotelen = strlen(chan->addr);
1202        u8 key;
1203
1204        if (card->u.x.connection_keys == ~0U) {
1205                printk(KERN_INFO "%s: too many simultaneous connection "
1206                                 "requests!\n", card->devname);
1207                return -EAGAIN;
1208        }
1209
1210        key = ffz(card->u.x.connection_keys);
1211        set_bit(key, (void*)&card->u.x.connection_keys);
1212        ++key;
1213        dprintk(1, KERN_INFO "%s:x25_place_call:key=%d\n", card->devname, key);
1214        memset(d, 0, sizeof(d));
1215        d[1] = key; /* user key */
1216        d[2] = 0x10;
1217        d[4] = 0x0B;
1218
1219        len = byte_to_nibble(chan->addr, d + 6, &nibble);
1220
1221        if (chan->local_addr)
1222                len += byte_to_nibble(chan->local_addr, d + 6 + len, &nibble);
1223
1224        if (nibble)
1225                ++len;
1226
1227        d[5] = mylen << 4 | remotelen;
1228        d[6 + len + 1] = 0xCC; /* TCP/IP over X.25, thanks to Daniela :) */
1229
1230        if ((err = x25_exec(card, X25_CONNECT_REQUEST, chan->link,
1231                            &d, 7 + len + 1, NULL, 0)) != 0)
1232                clear_bit(--key, (void*)&card->u.x.connection_keys);
1233        else
1234                chan->lcn = -key;
1235
1236        return err;
1237}
1238
1239/* Place X.25 CONNECT RESPONSE. */
1240static int cycx_x25_connect_response(struct cycx_device *card,
1241                                     struct cycx_x25_channel *chan)
1242{
1243        u8 d[8];
1244
1245        memset(d, 0, sizeof(d));
1246        d[0] = d[3] = chan->lcn;
1247        d[2] = 0x10;
1248        d[4] = 0x0F;
1249        d[7] = 0xCC; /* TCP/IP over X.25, thanks Daniela */
1250
1251        return x25_exec(card, X25_CONNECT_RESPONSE, chan->link, &d, 8, NULL, 0);
1252}
1253
1254/* Place X.25 DISCONNECT RESPONSE.  */
1255static int cycx_x25_disconnect_response(struct cycx_device *card, u8 link,
1256                                        u8 lcn)
1257{
1258        char d[5];
1259
1260        memset(d, 0, sizeof(d));
1261        d[0] = d[3] = lcn;
1262        d[2] = 0x10;
1263        d[4] = 0x17;
1264
1265        return x25_exec(card, X25_DISCONNECT_RESPONSE, link, &d, 5, NULL, 0);
1266}
1267
1268/* Clear X.25 call.  */
1269static int x25_clear_call(struct cycx_device *card, u8 link, u8 lcn, u8 cause,
1270                          u8 diagn)
1271{
1272        u8 d[7];
1273
1274        memset(d, 0, sizeof(d));
1275        d[0] = d[3] = lcn;
1276        d[2] = 0x10;
1277        d[4] = 0x13;
1278        d[5] = cause;
1279        d[6] = diagn;
1280
1281        return x25_exec(card, X25_DISCONNECT_REQUEST, link, d, 7, NULL, 0);
1282}
1283
1284/* Send X.25 data packet. */
1285static int cycx_x25_send(struct cycx_device *card, u8 link, u8 lcn, u8 bitm,
1286                         int len, void *buf)
1287{
1288        u8 d[] = "?\xFF\x10??";
1289
1290        d[0] = d[3] = lcn;
1291        d[4] = bitm;
1292
1293        return x25_exec(card, X25_DATA_REQUEST, link, &d, 5, buf, len);
1294}
1295
1296/* Miscellaneous */
1297/* Find network device by its channel number.  */
1298static struct net_device *cycx_x25_get_dev_by_lcn(struct wan_device *wandev,
1299                                                  s16 lcn)
1300{
1301        struct net_device *dev = wandev->dev;
1302        struct cycx_x25_channel *chan;
1303
1304        while (dev) {
1305                chan = netdev_priv(dev);
1306
1307                if (chan->lcn == lcn)
1308                        break;
1309                dev = chan->slave;
1310        }
1311        return dev;
1312}
1313
1314/* Find network device by its remote dte address. */
1315static struct net_device *
1316        cycx_x25_get_dev_by_dte_addr(struct wan_device *wandev, char *dte)
1317{
1318        struct net_device *dev = wandev->dev;
1319        struct cycx_x25_channel *chan;
1320
1321        while (dev) {
1322                chan = netdev_priv(dev);
1323
1324                if (!strcmp(chan->addr, dte))
1325                        break;
1326                dev = chan->slave;
1327        }
1328        return dev;
1329}
1330
1331/* Initiate connection on the logical channel.
1332 * o for PVC we just get channel configuration
1333 * o for SVCs place an X.25 call
1334 *
1335 * Return:      0       connected
1336 *              >0      connection in progress
1337 *              <0      failure */
1338static int cycx_x25_chan_connect(struct net_device *dev)
1339{
1340        struct cycx_x25_channel *chan = netdev_priv(dev);
1341        struct cycx_device *card = chan->card;
1342
1343        if (chan->svc) {
1344                if (!chan->addr[0])
1345                        return -EINVAL; /* no destination address */
1346
1347                dprintk(1, KERN_INFO "%s: placing X.25 call to %s...\n",
1348                                  card->devname, chan->addr);
1349
1350                if (x25_place_call(card, chan))
1351                        return -EIO;
1352
1353                cycx_x25_set_chan_state(dev, WAN_CONNECTING);
1354                return 1;
1355        } else
1356                cycx_x25_set_chan_state(dev, WAN_CONNECTED);
1357
1358        return 0;
1359}
1360
1361/* Disconnect logical channel.
1362 * o if SVC then clear X.25 call */
1363static void cycx_x25_chan_disconnect(struct net_device *dev)
1364{
1365        struct cycx_x25_channel *chan = netdev_priv(dev);
1366
1367        if (chan->svc) {
1368                x25_clear_call(chan->card, chan->link, chan->lcn, 0, 0);
1369                cycx_x25_set_chan_state(dev, WAN_DISCONNECTING);
1370        } else
1371                cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
1372}
1373
1374/* Called by kernel timer */
1375static void cycx_x25_chan_timer(unsigned long d)
1376{
1377        struct net_device *dev = (struct net_device *)d;
1378        struct cycx_x25_channel *chan = netdev_priv(dev);
1379
1380        if (chan->state == WAN_CONNECTED)
1381                cycx_x25_chan_disconnect(dev);
1382        else
1383                printk(KERN_ERR "%s: %s for svc (%s) not connected!\n",
1384                                chan->card->devname, __func__, dev->name);
1385}
1386
1387/* Set logical channel state. */
1388static void cycx_x25_set_chan_state(struct net_device *dev, u8 state)
1389{
1390        struct cycx_x25_channel *chan = netdev_priv(dev);
1391        struct cycx_device *card = chan->card;
1392        unsigned long flags;
1393        char *string_state = NULL;
1394
1395        spin_lock_irqsave(&card->lock, flags);
1396
1397        if (chan->state != state) {
1398                if (chan->svc && chan->state == WAN_CONNECTED)
1399                        del_timer(&chan->timer);
1400
1401                switch (state) {
1402                case WAN_CONNECTED:
1403                        string_state = "connected!";
1404                        *(__be16*)dev->dev_addr = htons(chan->lcn);
1405                        netif_wake_queue(dev);
1406                        reset_timer(dev);
1407
1408                        if (chan->protocol == ETH_P_X25)
1409                                cycx_x25_chan_send_event(dev, 1);
1410
1411                        break;
1412                case WAN_CONNECTING:
1413                        string_state = "connecting...";
1414                        break;
1415                case WAN_DISCONNECTING:
1416                        string_state = "disconnecting...";
1417                        break;
1418                case WAN_DISCONNECTED:
1419                        string_state = "disconnected!";
1420
1421                        if (chan->svc) {
1422                                *(unsigned short*)dev->dev_addr = 0;
1423                                chan->lcn = 0;
1424                        }
1425
1426                        if (chan->protocol == ETH_P_X25)
1427                                cycx_x25_chan_send_event(dev, 2);
1428
1429                        netif_wake_queue(dev);
1430                        break;
1431                }
1432
1433                printk(KERN_INFO "%s: interface %s %s\n", card->devname,
1434                                  dev->name, string_state);
1435                chan->state = state;
1436        }
1437
1438        spin_unlock_irqrestore(&card->lock, flags);
1439}
1440
1441/* Send packet on a logical channel.
1442 *      When this function is called, tx_skb field of the channel data space
1443 *      points to the transmit socket buffer.  When transmission is complete,
1444 *      release socket buffer and reset 'tbusy' flag.
1445 *
1446 * Return:      0       - transmission complete
1447 *              1       - busy
1448 *
1449 * Notes:
1450 * 1. If packet length is greater than MTU for this channel, we'll fragment
1451 *    the packet into 'complete sequence' using M-bit.
1452 * 2. When transmission is complete, an event notification should be issued
1453 *    to the router.  */
1454static int cycx_x25_chan_send(struct net_device *dev, struct sk_buff *skb)
1455{
1456        struct cycx_x25_channel *chan = netdev_priv(dev);
1457        struct cycx_device *card = chan->card;
1458        int bitm = 0;           /* final packet */
1459        unsigned len = skb->len;
1460
1461        if (skb->len > card->wandev.mtu) {
1462                len = card->wandev.mtu;
1463                bitm = 0x10;            /* set M-bit (more data) */
1464        }
1465
1466        if (cycx_x25_send(card, chan->link, chan->lcn, bitm, len, skb->data))
1467                return 1;
1468
1469        if (bitm) {
1470                skb_pull(skb, len);
1471                return 1;
1472        }
1473
1474        ++chan->ifstats.tx_packets;
1475        chan->ifstats.tx_bytes += len;
1476
1477        return 0;
1478}
1479
1480/* Send event (connection, disconnection, etc) to X.25 socket layer */
1481
1482static void cycx_x25_chan_send_event(struct net_device *dev, u8 event)
1483{
1484        struct sk_buff *skb;
1485        unsigned char *ptr;
1486
1487        if ((skb = dev_alloc_skb(1)) == NULL) {
1488                printk(KERN_ERR "%s: out of memory\n", __func__);
1489                return;
1490        }
1491
1492        ptr  = skb_put(skb, 1);
1493        *ptr = event;
1494
1495        skb->protocol = x25_type_trans(skb, dev);
1496        netif_rx(skb);
1497}
1498
1499/* Convert line speed in bps to a number used by cyclom 2x code. */
1500static u8 bps_to_speed_code(u32 bps)
1501{
1502        u8 number = 0; /* defaults to the lowest (1200) speed ;> */
1503
1504             if (bps >= 512000) number = 8;
1505        else if (bps >= 256000) number = 7;
1506        else if (bps >= 64000)  number = 6;
1507        else if (bps >= 38400)  number = 5;
1508        else if (bps >= 19200)  number = 4;
1509        else if (bps >= 9600)   number = 3;
1510        else if (bps >= 4800)   number = 2;
1511        else if (bps >= 2400)   number = 1;
1512
1513        return number;
1514}
1515
1516/* log base 2 */
1517static u8 cycx_log2(u32 n)
1518{
1519        u8 log = 0;
1520
1521        if (!n)
1522                return 0;
1523
1524        while (n > 1) {
1525                n >>= 1;
1526                ++log;
1527        }
1528
1529        return log;
1530}
1531
1532/* Convert decimal string to unsigned integer.
1533 * If len != 0 then only 'len' characters of the string are converted. */
1534static unsigned dec_to_uint(u8 *str, int len)
1535{
1536        unsigned val = 0;
1537
1538        if (!len)
1539                len = strlen(str);
1540
1541        for (; len && isdigit(*str); ++str, --len)
1542                val = (val * 10) + (*str - (unsigned) '0');
1543
1544        return val;
1545}
1546
1547static void reset_timer(struct net_device *dev)
1548{
1549        struct cycx_x25_channel *chan = netdev_priv(dev);
1550
1551        if (chan->svc)
1552                mod_timer(&chan->timer, jiffies+chan->idle_tmout*HZ);
1553}
1554#ifdef CYCLOMX_X25_DEBUG
1555static void cycx_x25_dump_config(struct cycx_x25_config *conf)
1556{
1557        printk(KERN_INFO "X.25 configuration\n");
1558        printk(KERN_INFO "-----------------\n");
1559        printk(KERN_INFO "link number=%d\n", conf->link);
1560        printk(KERN_INFO "line speed=%d\n", conf->speed);
1561        printk(KERN_INFO "clock=%sternal\n", conf->clock == 8 ? "Ex" : "In");
1562        printk(KERN_INFO "# level 2 retransm.=%d\n", conf->n2);
1563        printk(KERN_INFO "level 2 window=%d\n", conf->n2win);
1564        printk(KERN_INFO "level 3 window=%d\n", conf->n3win);
1565        printk(KERN_INFO "# logical channels=%d\n", conf->nvc);
1566        printk(KERN_INFO "level 3 pkt len=%d\n", conf->pktlen);
1567        printk(KERN_INFO "my address=%d\n", conf->locaddr);
1568        printk(KERN_INFO "remote address=%d\n", conf->remaddr);
1569        printk(KERN_INFO "t1=%d seconds\n", conf->t1);
1570        printk(KERN_INFO "t2=%d seconds\n", conf->t2);
1571        printk(KERN_INFO "t21=%d seconds\n", conf->t21);
1572        printk(KERN_INFO "# PVCs=%d\n", conf->npvc);
1573        printk(KERN_INFO "t23=%d seconds\n", conf->t23);
1574        printk(KERN_INFO "flags=0x%x\n", conf->flags);
1575}
1576
1577static void cycx_x25_dump_stats(struct cycx_x25_stats *stats)
1578{
1579        printk(KERN_INFO "X.25 statistics\n");
1580        printk(KERN_INFO "--------------\n");
1581        printk(KERN_INFO "rx_crc_errors=%d\n", stats->rx_crc_errors);
1582        printk(KERN_INFO "rx_over_errors=%d\n", stats->rx_over_errors);
1583        printk(KERN_INFO "n2_tx_frames=%d\n", stats->n2_tx_frames);
1584        printk(KERN_INFO "n2_rx_frames=%d\n", stats->n2_rx_frames);
1585        printk(KERN_INFO "tx_timeouts=%d\n", stats->tx_timeouts);
1586        printk(KERN_INFO "rx_timeouts=%d\n", stats->rx_timeouts);
1587        printk(KERN_INFO "n3_tx_packets=%d\n", stats->n3_tx_packets);
1588        printk(KERN_INFO "n3_rx_packets=%d\n", stats->n3_rx_packets);
1589        printk(KERN_INFO "tx_aborts=%d\n", stats->tx_aborts);
1590        printk(KERN_INFO "rx_aborts=%d\n", stats->rx_aborts);
1591}
1592
1593static void cycx_x25_dump_devs(struct wan_device *wandev)
1594{
1595        struct net_device *dev = wandev->dev;
1596
1597        printk(KERN_INFO "X.25 dev states\n");
1598        printk(KERN_INFO "name: addr:           txoff:  protocol:\n");
1599        printk(KERN_INFO "---------------------------------------\n");
1600
1601        while(dev) {
1602                struct cycx_x25_channel *chan = netdev_priv(dev);
1603
1604                printk(KERN_INFO "%-5.5s %-15.15s   %d     ETH_P_%s\n",
1605                                 chan->name, chan->addr, netif_queue_stopped(dev),
1606                                 chan->protocol == ETH_P_IP ? "IP" : "X25");
1607                dev = chan->slave;
1608        }
1609}
1610
1611#endif /* CYCLOMX_X25_DEBUG */
1612/* End */
1613