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/slab.h>         /* kmalloc(), kfree() */
  88#include <linux/stddef.h>       /* offsetof(), etc. */
  89#include <linux/wanrouter.h>    /* WAN router definitions */
  90
  91#include <asm/byteorder.h>      /* htons(), etc. */
  92
  93#include <linux/cyclomx.h>      /* Cyclom 2X common user API definitions */
  94#include <linux/cycx_x25.h>     /* X.25 firmware API definitions */
  95
  96#include <net/x25device.h>
  97
  98/* Defines & Macros */
  99#define CYCX_X25_MAX_CMD_RETRY 5
 100#define CYCX_X25_CHAN_MTU 2048  /* unfragmented logical channel MTU */
 101
 102/* Data Structures */
 103/* This is an extension of the 'struct net_device' we create for each network
 104   interface to keep the rest of X.25 channel-specific data. */
 105struct cycx_x25_channel {
 106        /* This member must be first. */
 107        struct net_device *slave;       /* WAN slave */
 108
 109        char name[WAN_IFNAME_SZ+1];     /* interface name, ASCIIZ */
 110        char addr[WAN_ADDRESS_SZ+1];    /* media address, ASCIIZ */
 111        char *local_addr;               /* local media address, ASCIIZ -
 112                                           svc thru crossover cable */
 113        s16 lcn;                        /* logical channel number/conn.req.key*/
 114        u8 link;
 115        struct timer_list timer;        /* timer used for svc channel disc. */
 116        u16 protocol;                   /* ethertype, 0 - multiplexed */
 117        u8 svc;                         /* 0 - permanent, 1 - switched */
 118        u8 state;                       /* channel state */
 119        u8 drop_sequence;               /* mark sequence for dropping */
 120        u32 idle_tmout;                 /* sec, before disconnecting */
 121        struct sk_buff *rx_skb;         /* receive socket buffer */
 122        struct cycx_device *card;       /* -> owner */
 123        struct net_device_stats ifstats;/* interface statistics */
 124};
 125
 126/* Function Prototypes */
 127/* WAN link driver entry points. These are called by the WAN router module. */
 128static int cycx_wan_update(struct wan_device *wandev),
 129           cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev,
 130                           wanif_conf_t *conf),
 131           cycx_wan_del_if(struct wan_device *wandev, struct net_device *dev);
 132
 133/* Network device interface */
 134static int cycx_netdevice_init(struct net_device *dev);
 135static int cycx_netdevice_open(struct net_device *dev);
 136static int cycx_netdevice_stop(struct net_device *dev);
 137static int cycx_netdevice_hard_header(struct sk_buff *skb,
 138                                      struct net_device *dev, u16 type,
 139                                      const void *daddr, const void *saddr,
 140                                      unsigned len);
 141static int cycx_netdevice_rebuild_header(struct sk_buff *skb);
 142static int cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
 143                                          struct net_device *dev);
 144
 145static struct net_device_stats *
 146                        cycx_netdevice_get_stats(struct net_device *dev);
 147
 148/* Interrupt handlers */
 149static void cycx_x25_irq_handler(struct cycx_device *card),
 150            cycx_x25_irq_tx(struct cycx_device *card, struct cycx_x25_cmd *cmd),
 151            cycx_x25_irq_rx(struct cycx_device *card, struct cycx_x25_cmd *cmd),
 152            cycx_x25_irq_log(struct cycx_device *card,
 153                             struct cycx_x25_cmd *cmd),
 154            cycx_x25_irq_stat(struct cycx_device *card,
 155                              struct cycx_x25_cmd *cmd),
 156            cycx_x25_irq_connect_confirm(struct cycx_device *card,
 157                                         struct cycx_x25_cmd *cmd),
 158            cycx_x25_irq_disconnect_confirm(struct cycx_device *card,
 159                                            struct cycx_x25_cmd *cmd),
 160            cycx_x25_irq_connect(struct cycx_device *card,
 161                                 struct cycx_x25_cmd *cmd),
 162            cycx_x25_irq_disconnect(struct cycx_device *card,
 163                                    struct cycx_x25_cmd *cmd),
 164            cycx_x25_irq_spurious(struct cycx_device *card,
 165                                  struct cycx_x25_cmd *cmd);
 166
 167/* X.25 firmware interface functions */
 168static int cycx_x25_configure(struct cycx_device *card,
 169                              struct cycx_x25_config *conf),
 170           cycx_x25_get_stats(struct cycx_device *card),
 171           cycx_x25_send(struct cycx_device *card, u8 link, u8 lcn, u8 bitm,
 172                         int len, void *buf),
 173           cycx_x25_connect_response(struct cycx_device *card,
 174                                struct cycx_x25_channel *chan),
 175           cycx_x25_disconnect_response(struct cycx_device *card, u8 link,
 176                                        u8 lcn);
 177
 178/* channel functions */
 179static int cycx_x25_chan_connect(struct net_device *dev),
 180           cycx_x25_chan_send(struct net_device *dev, struct sk_buff *skb);
 181
 182static void cycx_x25_chan_disconnect(struct net_device *dev),
 183            cycx_x25_chan_send_event(struct net_device *dev, u8 event);
 184
 185/* Miscellaneous functions */
 186static void cycx_x25_set_chan_state(struct net_device *dev, u8 state),
 187            cycx_x25_chan_timer(unsigned long d);
 188
 189static void nibble_to_byte(u8 *s, u8 *d, u8 len, u8 nibble),
 190            reset_timer(struct net_device *dev);
 191
 192static u8 bps_to_speed_code(u32 bps);
 193static u8 cycx_log2(u32 n);
 194
 195static unsigned dec_to_uint(u8 *str, int len);
 196
 197static struct net_device *cycx_x25_get_dev_by_lcn(struct wan_device *wandev,
 198                                                  s16 lcn);
 199static struct net_device *
 200        cycx_x25_get_dev_by_dte_addr(struct wan_device *wandev, char *dte);
 201
 202#ifdef CYCLOMX_X25_DEBUG
 203static void hex_dump(char *msg, unsigned char *p, int len);
 204static void cycx_x25_dump_config(struct cycx_x25_config *conf);
 205static void cycx_x25_dump_stats(struct cycx_x25_stats *stats);
 206static void cycx_x25_dump_devs(struct wan_device *wandev);
 207#else
 208#define hex_dump(msg, p, len)
 209#define cycx_x25_dump_config(conf)
 210#define cycx_x25_dump_stats(stats)
 211#define cycx_x25_dump_devs(wandev)
 212#endif
 213/* Public Functions */
 214
 215/* X.25 Protocol Initialization routine.
 216 *
 217 * This routine is called by the main Cyclom 2X module during setup.  At this
 218 * point adapter is completely initialized and X.25 firmware is running.
 219 *  o configure adapter
 220 *  o initialize protocol-specific fields of the adapter data space.
 221 *
 222 * Return:      0       o.k.
 223 *              < 0     failure.  */
 224int cycx_x25_wan_init(struct cycx_device *card, wandev_conf_t *conf)
 225{
 226        struct cycx_x25_config cfg;
 227
 228        /* Verify configuration ID */
 229        if (conf->config_id != WANCONFIG_X25) {
 230                printk(KERN_INFO "%s: invalid configuration ID %u!\n",
 231                                 card->devname, conf->config_id);
 232                return -EINVAL;
 233        }
 234
 235        /* Initialize protocol-specific fields */
 236        card->mbox  = card->hw.dpmbase + X25_MBOX_OFFS;
 237        card->u.x.connection_keys = 0;
 238        spin_lock_init(&card->u.x.lock);
 239
 240        /* Configure adapter. Here we set reasonable defaults, then parse
 241         * device configuration structure and set configuration options.
 242         * Most configuration options are verified and corrected (if
 243         * necessary) since we can't rely on the adapter to do so and don't
 244         * want it to fail either. */
 245        memset(&cfg, 0, sizeof(cfg));
 246        cfg.link = 0;
 247        cfg.clock = conf->clocking == WANOPT_EXTERNAL ? 8 : 55;
 248        cfg.speed = bps_to_speed_code(conf->bps);
 249        cfg.n3win = 7;
 250        cfg.n2win = 2;
 251        cfg.n2 = 5;
 252        cfg.nvc = 1;
 253        cfg.npvc = 1;
 254        cfg.flags = 0x02; /* default = V35 */
 255        cfg.t1 = 10;   /* line carrier timeout */
 256        cfg.t2 = 29;   /* tx timeout */
 257        cfg.t21 = 180; /* CALL timeout */
 258        cfg.t23 = 180; /* CLEAR timeout */
 259
 260        /* adjust MTU */
 261        if (!conf->mtu || conf->mtu >= 512)
 262                card->wandev.mtu = 512;
 263        else if (conf->mtu >= 256)
 264                card->wandev.mtu = 256;
 265        else if (conf->mtu >= 128)
 266                card->wandev.mtu = 128;
 267        else
 268                card->wandev.mtu = 64;
 269
 270        cfg.pktlen = cycx_log2(card->wandev.mtu);
 271
 272        if (conf->station == WANOPT_DTE) {
 273                cfg.locaddr = 3; /* DTE */
 274                cfg.remaddr = 1; /* DCE */
 275        } else {
 276                cfg.locaddr = 1; /* DCE */
 277                cfg.remaddr = 3; /* DTE */
 278        }
 279
 280        if (conf->interface == WANOPT_RS232)
 281                cfg.flags = 0;      /* FIXME just reset the 2nd bit */
 282
 283        if (conf->u.x25.hi_pvc) {
 284                card->u.x.hi_pvc = min_t(unsigned int, conf->u.x25.hi_pvc, 4095);
 285                card->u.x.lo_pvc = min_t(unsigned int, conf->u.x25.lo_pvc, card->u.x.hi_pvc);
 286        }
 287
 288        if (conf->u.x25.hi_svc) {
 289                card->u.x.hi_svc = min_t(unsigned int, conf->u.x25.hi_svc, 4095);
 290                card->u.x.lo_svc = min_t(unsigned int, conf->u.x25.lo_svc, card->u.x.hi_svc);
 291        }
 292
 293        if (card->u.x.lo_pvc == 255)
 294                cfg.npvc = 0;
 295        else
 296                cfg.npvc = card->u.x.hi_pvc - card->u.x.lo_pvc + 1;
 297
 298        cfg.nvc = card->u.x.hi_svc - card->u.x.lo_svc + 1 + cfg.npvc;
 299
 300        if (conf->u.x25.hdlc_window)
 301                cfg.n2win = min_t(unsigned int, conf->u.x25.hdlc_window, 7);
 302
 303        if (conf->u.x25.pkt_window)
 304                cfg.n3win = min_t(unsigned int, conf->u.x25.pkt_window, 7);
 305
 306        if (conf->u.x25.t1)
 307                cfg.t1 = min_t(unsigned int, conf->u.x25.t1, 30);
 308
 309        if (conf->u.x25.t2)
 310                cfg.t2 = min_t(unsigned int, conf->u.x25.t2, 30);
 311
 312        if (conf->u.x25.t11_t21)
 313                cfg.t21 = min_t(unsigned int, conf->u.x25.t11_t21, 30);
 314
 315        if (conf->u.x25.t13_t23)
 316                cfg.t23 = min_t(unsigned int, conf->u.x25.t13_t23, 30);
 317
 318        if (conf->u.x25.n2)
 319                cfg.n2 = min_t(unsigned int, conf->u.x25.n2, 30);
 320
 321        /* initialize adapter */
 322        if (cycx_x25_configure(card, &cfg))
 323                return -EIO;
 324
 325        /* Initialize protocol-specific fields of adapter data space */
 326        card->wandev.bps        = conf->bps;
 327        card->wandev.interface  = conf->interface;
 328        card->wandev.clocking   = conf->clocking;
 329        card->wandev.station    = conf->station;
 330        card->isr               = cycx_x25_irq_handler;
 331        card->exec              = NULL;
 332        card->wandev.update     = cycx_wan_update;
 333        card->wandev.new_if     = cycx_wan_new_if;
 334        card->wandev.del_if     = cycx_wan_del_if;
 335        card->wandev.state      = WAN_DISCONNECTED;
 336
 337        return 0;
 338}
 339
 340/* WAN Device Driver Entry Points */
 341/* Update device status & statistics. */
 342static int cycx_wan_update(struct wan_device *wandev)
 343{
 344        /* sanity checks */
 345        if (!wandev || !wandev->private)
 346                return -EFAULT;
 347
 348        if (wandev->state == WAN_UNCONFIGURED)
 349                return -ENODEV;
 350
 351        cycx_x25_get_stats(wandev->private);
 352
 353        return 0;
 354}
 355
 356/* Create new logical channel.
 357 * This routine is called by the router when ROUTER_IFNEW IOCTL is being
 358 * handled.
 359 * o parse media- and hardware-specific configuration
 360 * o make sure that a new channel can be created
 361 * o allocate resources, if necessary
 362 * o prepare network device structure for registration.
 363 *
 364 * Return:      0       o.k.
 365 *              < 0     failure (channel will not be created) */
 366static int cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev,
 367                           wanif_conf_t *conf)
 368{
 369        struct cycx_device *card = wandev->private;
 370        struct cycx_x25_channel *chan;
 371        int err = 0;
 372
 373        if (!conf->name[0] || strlen(conf->name) > WAN_IFNAME_SZ) {
 374                printk(KERN_INFO "%s: invalid interface name!\n",
 375                       card->devname);
 376                return -EINVAL;
 377        }
 378
 379        /* allocate and initialize private data */
 380        chan = kzalloc(sizeof(struct cycx_x25_channel), GFP_KERNEL);
 381        if (!chan)
 382                return -ENOMEM;
 383
 384        strcpy(chan->name, conf->name);
 385        chan->card = card;
 386        chan->link = conf->port;
 387        chan->protocol = conf->protocol ? ETH_P_X25 : ETH_P_IP;
 388        chan->rx_skb = NULL;
 389        /* only used in svc connected thru crossover cable */
 390        chan->local_addr = NULL;
 391
 392        if (conf->addr[0] == '@') {     /* SVC */
 393                int len = strlen(conf->local_addr);
 394
 395                if (len) {
 396                        if (len > WAN_ADDRESS_SZ) {
 397                                printk(KERN_ERR "%s: %s local addr too long!\n",
 398                                                wandev->name, chan->name);
 399                                kfree(chan);
 400                                return -EINVAL;
 401                        } else {
 402                                chan->local_addr = kmalloc(len + 1, GFP_KERNEL);
 403
 404                                if (!chan->local_addr) {
 405                                        kfree(chan);
 406                                        return -ENOMEM;
 407                                }
 408                        }
 409
 410                        strncpy(chan->local_addr, conf->local_addr,
 411                                WAN_ADDRESS_SZ);
 412                }
 413
 414                chan->svc = 1;
 415                strncpy(chan->addr, &conf->addr[1], WAN_ADDRESS_SZ);
 416                init_timer(&chan->timer);
 417                chan->timer.function    = cycx_x25_chan_timer;
 418                chan->timer.data        = (unsigned long)dev;
 419
 420                /* Set channel timeouts (default if not specified) */
 421                chan->idle_tmout = conf->idle_timeout ? conf->idle_timeout : 90;
 422        } else if (isdigit(conf->addr[0])) {    /* PVC */
 423                s16 lcn = dec_to_uint(conf->addr, 0);
 424
 425                if (lcn >= card->u.x.lo_pvc && lcn <= card->u.x.hi_pvc)
 426                        chan->lcn = lcn;
 427                else {
 428                        printk(KERN_ERR
 429                                "%s: PVC %u is out of range on interface %s!\n",
 430                                wandev->name, lcn, chan->name);
 431                        err = -EINVAL;
 432                }
 433        } else {
 434                printk(KERN_ERR "%s: invalid media address on interface %s!\n",
 435                                wandev->name, chan->name);
 436                err = -EINVAL;
 437        }
 438
 439        if (err) {
 440                kfree(chan->local_addr);
 441                kfree(chan);
 442                return err;
 443        }
 444
 445        /* prepare network device data space for registration */
 446        strcpy(dev->name, chan->name);
 447        dev->init = cycx_netdevice_init;
 448        dev->priv = chan;
 449
 450        return 0;
 451}
 452
 453/* Delete logical channel. */
 454static int cycx_wan_del_if(struct wan_device *wandev, struct net_device *dev)
 455{
 456        if (dev->priv) {
 457                struct cycx_x25_channel *chan = dev->priv;
 458
 459                if (chan->svc) {
 460                        kfree(chan->local_addr);
 461                        if (chan->state == WAN_CONNECTED)
 462                                del_timer(&chan->timer);
 463                }
 464
 465                kfree(chan);
 466                dev->priv = NULL;
 467        }
 468
 469        return 0;
 470}
 471
 472
 473/* Network Device Interface */
 474
 475static const struct header_ops cycx_header_ops = {
 476        .create = cycx_netdevice_hard_header,
 477        .rebuild = cycx_netdevice_rebuild_header,
 478};
 479
 480/* Initialize Linux network interface.
 481 *
 482 * This routine is called only once for each interface, during Linux network
 483 * interface registration.  Returning anything but zero will fail interface
 484 * registration. */
 485static int cycx_netdevice_init(struct net_device *dev)
 486{
 487        struct cycx_x25_channel *chan = dev->priv;
 488        struct cycx_device *card = chan->card;
 489        struct wan_device *wandev = &card->wandev;
 490
 491        /* Initialize device driver entry points */
 492        dev->open               = cycx_netdevice_open;
 493        dev->stop               = cycx_netdevice_stop;
 494        dev->header_ops         = &cycx_header_ops;
 495
 496        dev->hard_start_xmit    = cycx_netdevice_hard_start_xmit;
 497        dev->get_stats          = cycx_netdevice_get_stats;
 498
 499        /* Initialize media-specific parameters */
 500        dev->mtu                = CYCX_X25_CHAN_MTU;
 501        dev->type               = ARPHRD_HWX25; /* ARP h/w type */
 502        dev->hard_header_len    = 0;            /* media header length */
 503        dev->addr_len           = 0;            /* hardware address length */
 504
 505        if (!chan->svc)
 506                *(__be16*)dev->dev_addr = htons(chan->lcn);
 507
 508        /* Initialize hardware parameters (just for reference) */
 509        dev->irq                = wandev->irq;
 510        dev->dma                = wandev->dma;
 511        dev->base_addr          = wandev->ioport;
 512        dev->mem_start          = (unsigned long)wandev->maddr;
 513        dev->mem_end            = (unsigned long)(wandev->maddr +
 514                                                  wandev->msize - 1);
 515        dev->flags              |= IFF_NOARP;
 516
 517        /* Set transmit buffer queue length */
 518        dev->tx_queue_len       = 10;
 519
 520        /* Initialize socket buffers */
 521        cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
 522
 523        return 0;
 524}
 525
 526/* Open network interface.
 527 * o prevent module from unloading by incrementing use count
 528 * o if link is disconnected then initiate connection
 529 *
 530 * Return 0 if O.k. or errno.  */
 531static int cycx_netdevice_open(struct net_device *dev)
 532{
 533        if (netif_running(dev))
 534                return -EBUSY; /* only one open is allowed */
 535
 536        netif_start_queue(dev);
 537        return 0;
 538}
 539
 540/* Close network interface.
 541 * o reset flags.
 542 * o if there's no more open channels then disconnect physical link. */
 543static int cycx_netdevice_stop(struct net_device *dev)
 544{
 545        struct cycx_x25_channel *chan = dev->priv;
 546
 547        netif_stop_queue(dev);
 548
 549        if (chan->state == WAN_CONNECTED || chan->state == WAN_CONNECTING)
 550                cycx_x25_chan_disconnect(dev);
 551
 552        return 0;
 553}
 554
 555/* Build media header.
 556 * o encapsulate packet according to encapsulation type.
 557 *
 558 * The trick here is to put packet type (Ethertype) into 'protocol' field of
 559 * the socket buffer, so that we don't forget it.  If encapsulation fails,
 560 * set skb->protocol to 0 and discard packet later.
 561 *
 562 * Return:      media header length. */
 563static int cycx_netdevice_hard_header(struct sk_buff *skb,
 564                                      struct net_device *dev, u16 type,
 565                                      const void *daddr, const void *saddr,
 566                                      unsigned len)
 567{
 568        skb->protocol = htons(type);
 569
 570        return dev->hard_header_len;
 571}
 572
 573/* * Re-build media header.
 574 * Return:      1       physical address resolved.
 575 *              0       physical address not resolved */
 576static int cycx_netdevice_rebuild_header(struct sk_buff *skb)
 577{
 578        return 1;
 579}
 580
 581/* Send a packet on a network interface.
 582 * o set busy flag (marks start of the transmission).
 583 * o check link state. If link is not up, then drop the packet.
 584 * o check channel status. If it's down then initiate a call.
 585 * o pass a packet to corresponding WAN device.
 586 * o free socket buffer
 587 *
 588 * Return:      0       complete (socket buffer must be freed)
 589 *              non-0   packet may be re-transmitted (tbusy must be set)
 590 *
 591 * Notes:
 592 * 1. This routine is called either by the protocol stack or by the "net
 593 *    bottom half" (with interrupts enabled).
 594 * 2. Setting tbusy flag will inhibit further transmit requests from the
 595 *    protocol stack and can be used for flow control with protocol layer. */
 596static int cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
 597                                          struct net_device *dev)
 598{
 599        struct cycx_x25_channel *chan = dev->priv;
 600        struct cycx_device *card = chan->card;
 601
 602        if (!chan->svc)
 603                chan->protocol = ntohs(skb->protocol);
 604
 605        if (card->wandev.state != WAN_CONNECTED)
 606                ++chan->ifstats.tx_dropped;
 607        else if (chan->svc && chan->protocol &&
 608                 chan->protocol != ntohs(skb->protocol)) {
 609                printk(KERN_INFO
 610                       "%s: unsupported Ethertype 0x%04X on interface %s!\n",
 611                       card->devname, ntohs(skb->protocol), dev->name);
 612                ++chan->ifstats.tx_errors;
 613        } else if (chan->protocol == ETH_P_IP) {
 614                switch (chan->state) {
 615                case WAN_DISCONNECTED:
 616                        if (cycx_x25_chan_connect(dev)) {
 617                                netif_stop_queue(dev);
 618                                return -EBUSY;
 619                        }
 620                        /* fall thru */
 621                case WAN_CONNECTED:
 622                        reset_timer(dev);
 623                        dev->trans_start = jiffies;
 624                        netif_stop_queue(dev);
 625
 626                        if (cycx_x25_chan_send(dev, skb))
 627                                return -EBUSY;
 628
 629                        break;
 630                default:
 631                        ++chan->ifstats.tx_dropped;
 632                        ++card->wandev.stats.tx_dropped;
 633        }
 634        } else { /* chan->protocol == ETH_P_X25 */
 635                switch (skb->data[0]) {
 636                case 0: break;
 637                case 1: /* Connect request */
 638                        cycx_x25_chan_connect(dev);
 639                        goto free_packet;
 640                case 2: /* Disconnect request */
 641                        cycx_x25_chan_disconnect(dev);
 642                        goto free_packet;
 643                default:
 644                        printk(KERN_INFO
 645                               "%s: unknown %d x25-iface request on %s!\n",
 646                               card->devname, skb->data[0], dev->name);
 647                        ++chan->ifstats.tx_errors;
 648                        goto free_packet;
 649                }
 650
 651                skb_pull(skb, 1); /* Remove control byte */
 652                reset_timer(dev);
 653                dev->trans_start = jiffies;
 654                netif_stop_queue(dev);
 655
 656                if (cycx_x25_chan_send(dev, skb)) {
 657                        /* prepare for future retransmissions */
 658                        skb_push(skb, 1);
 659                        return -EBUSY;
 660                }
 661        }
 662
 663free_packet:
 664        dev_kfree_skb(skb);
 665
 666        return 0;
 667}
 668
 669/* Get Ethernet-style interface statistics.
 670 * Return a pointer to struct net_device_stats */
 671static struct net_device_stats *cycx_netdevice_get_stats(struct net_device *dev)
 672{
 673        struct cycx_x25_channel *chan = dev->priv;
 674
 675        return chan ? &chan->ifstats : NULL;
 676}
 677
 678/* Interrupt Handlers */
 679/* X.25 Interrupt Service Routine. */
 680static void cycx_x25_irq_handler(struct cycx_device *card)
 681{
 682        struct cycx_x25_cmd cmd;
 683        u16 z = 0;
 684
 685        card->in_isr = 1;
 686        card->buff_int_mode_unbusy = 0;
 687        cycx_peek(&card->hw, X25_RXMBOX_OFFS, &cmd, sizeof(cmd));
 688
 689        switch (cmd.command) {
 690        case X25_DATA_INDICATION:
 691                cycx_x25_irq_rx(card, &cmd);
 692                break;
 693        case X25_ACK_FROM_VC:
 694                cycx_x25_irq_tx(card, &cmd);
 695                break;
 696        case X25_LOG:
 697                cycx_x25_irq_log(card, &cmd);
 698                break;
 699        case X25_STATISTIC:
 700                cycx_x25_irq_stat(card, &cmd);
 701                break;
 702        case X25_CONNECT_CONFIRM:
 703                cycx_x25_irq_connect_confirm(card, &cmd);
 704                break;
 705        case X25_CONNECT_INDICATION:
 706                cycx_x25_irq_connect(card, &cmd);
 707                break;
 708        case X25_DISCONNECT_INDICATION:
 709                cycx_x25_irq_disconnect(card, &cmd);
 710                break;
 711        case X25_DISCONNECT_CONFIRM:
 712                cycx_x25_irq_disconnect_confirm(card, &cmd);
 713                break;
 714        case X25_LINE_ON:
 715                cycx_set_state(card, WAN_CONNECTED);
 716                break;
 717        case X25_LINE_OFF:
 718                cycx_set_state(card, WAN_DISCONNECTED);
 719                break;
 720        default:
 721                cycx_x25_irq_spurious(card, &cmd);
 722                break;
 723        }
 724
 725        cycx_poke(&card->hw, 0, &z, sizeof(z));
 726        cycx_poke(&card->hw, X25_RXMBOX_OFFS, &z, sizeof(z));
 727        card->in_isr = 0;
 728}
 729
 730/* Transmit interrupt handler.
 731 *      o Release socket buffer
 732 *      o Clear 'tbusy' flag */
 733static void cycx_x25_irq_tx(struct cycx_device *card, struct cycx_x25_cmd *cmd)
 734{
 735        struct net_device *dev;
 736        struct wan_device *wandev = &card->wandev;
 737        u8 lcn;
 738
 739        cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
 740
 741        /* unbusy device and then dev_tint(); */
 742        dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
 743        if (dev) {
 744                card->buff_int_mode_unbusy = 1;
 745                netif_wake_queue(dev);
 746        } else
 747                printk(KERN_ERR "%s:ackvc for inexistent lcn %d\n",
 748                                 card->devname, lcn);
 749}
 750
 751/* Receive interrupt handler.
 752 * This routine handles fragmented IP packets using M-bit according to the
 753 * RFC1356.
 754 * o map logical channel number to network interface.
 755 * o allocate socket buffer or append received packet to the existing one.
 756 * o if M-bit is reset (i.e. it's the last packet in a sequence) then
 757 *   decapsulate packet and pass socket buffer to the protocol stack.
 758 *
 759 * Notes:
 760 * 1. When allocating a socket buffer, if M-bit is set then more data is
 761 *    coming and we have to allocate buffer for the maximum IP packet size
 762 *    expected on this channel.
 763 * 2. If something goes wrong and X.25 packet has to be dropped (e.g. no
 764 *    socket buffers available) the whole packet sequence must be discarded. */
 765static void cycx_x25_irq_rx(struct cycx_device *card, struct cycx_x25_cmd *cmd)
 766{
 767        struct wan_device *wandev = &card->wandev;
 768        struct net_device *dev;
 769        struct cycx_x25_channel *chan;
 770        struct sk_buff *skb;
 771        u8 bitm, lcn;
 772        int pktlen = cmd->len - 5;
 773
 774        cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
 775        cycx_peek(&card->hw, cmd->buf + 4, &bitm, sizeof(bitm));
 776        bitm &= 0x10;
 777
 778        dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
 779        if (!dev) {
 780                /* Invalid channel, discard packet */
 781                printk(KERN_INFO "%s: receiving on orphaned LCN %d!\n",
 782                                 card->devname, lcn);
 783                return;
 784        }
 785
 786        chan = dev->priv;
 787        reset_timer(dev);
 788
 789        if (chan->drop_sequence) {
 790                if (!bitm)
 791                        chan->drop_sequence = 0;
 792                else
 793                        return;
 794        }
 795
 796        if ((skb = chan->rx_skb) == NULL) {
 797                /* Allocate new socket buffer */
 798                int bufsize = bitm ? dev->mtu : pktlen;
 799
 800                if ((skb = dev_alloc_skb((chan->protocol == ETH_P_X25 ? 1 : 0) +
 801                                         bufsize +
 802                                         dev->hard_header_len)) == NULL) {
 803                        printk(KERN_INFO "%s: no socket buffers available!\n",
 804                                         card->devname);
 805                        chan->drop_sequence = 1;
 806                        ++chan->ifstats.rx_dropped;
 807                        return;
 808                }
 809
 810                if (chan->protocol == ETH_P_X25) /* X.25 socket layer control */
 811                        /* 0 = data packet (dev_alloc_skb zeroed skb->data) */
 812                        skb_put(skb, 1);
 813
 814                skb->dev = dev;
 815                skb->protocol = htons(chan->protocol);
 816                chan->rx_skb = skb;
 817        }
 818
 819        if (skb_tailroom(skb) < pktlen) {
 820                /* No room for the packet. Call off the whole thing! */
 821                dev_kfree_skb_irq(skb);
 822                chan->rx_skb = NULL;
 823
 824                if (bitm)
 825                        chan->drop_sequence = 1;
 826
 827                printk(KERN_INFO "%s: unexpectedly long packet sequence "
 828                        "on interface %s!\n", card->devname, dev->name);
 829                ++chan->ifstats.rx_length_errors;
 830                return;
 831        }
 832
 833        /* Append packet to the socket buffer  */
 834        cycx_peek(&card->hw, cmd->buf + 5, skb_put(skb, pktlen), pktlen);
 835
 836        if (bitm)
 837                return; /* more data is coming */
 838
 839        chan->rx_skb = NULL;            /* dequeue packet */
 840
 841        ++chan->ifstats.rx_packets;
 842        chan->ifstats.rx_bytes += pktlen;
 843
 844        skb_reset_mac_header(skb);
 845        netif_rx(skb);
 846        dev->last_rx = jiffies;         /* timestamp */
 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 = dev->priv;
 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 = dev->priv;
 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 = dev->priv;
 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 = (struct cycx_x25_channel*)dev->priv;
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 = (struct cycx_x25_channel*)dev->priv;
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 = dev->priv;
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 = dev->priv;
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 = dev->priv;
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 = dev->priv;
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 = dev->priv;
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        dev->last_rx = jiffies;         /* timestamp */
1498}
1499
1500/* Convert line speed in bps to a number used by cyclom 2x code. */
1501static u8 bps_to_speed_code(u32 bps)
1502{
1503        u8 number = 0; /* defaults to the lowest (1200) speed ;> */
1504
1505             if (bps >= 512000) number = 8;
1506        else if (bps >= 256000) number = 7;
1507        else if (bps >= 64000)  number = 6;
1508        else if (bps >= 38400)  number = 5;
1509        else if (bps >= 19200)  number = 4;
1510        else if (bps >= 9600)   number = 3;
1511        else if (bps >= 4800)   number = 2;
1512        else if (bps >= 2400)   number = 1;
1513
1514        return number;
1515}
1516
1517/* log base 2 */
1518static u8 cycx_log2(u32 n)
1519{
1520        u8 log = 0;
1521
1522        if (!n)
1523                return 0;
1524
1525        while (n > 1) {
1526                n >>= 1;
1527                ++log;
1528        }
1529
1530        return log;
1531}
1532
1533/* Convert decimal string to unsigned integer.
1534 * If len != 0 then only 'len' characters of the string are converted. */
1535static unsigned dec_to_uint(u8 *str, int len)
1536{
1537        unsigned val = 0;
1538
1539        if (!len)
1540                len = strlen(str);
1541
1542        for (; len && isdigit(*str); ++str, --len)
1543                val = (val * 10) + (*str - (unsigned) '0');
1544
1545        return val;
1546}
1547
1548static void reset_timer(struct net_device *dev)
1549{
1550        struct cycx_x25_channel *chan = dev->priv;
1551
1552        if (chan->svc)
1553                mod_timer(&chan->timer, jiffies+chan->idle_tmout*HZ);
1554}
1555#ifdef CYCLOMX_X25_DEBUG
1556static void cycx_x25_dump_config(struct cycx_x25_config *conf)
1557{
1558        printk(KERN_INFO "X.25 configuration\n");
1559        printk(KERN_INFO "-----------------\n");
1560        printk(KERN_INFO "link number=%d\n", conf->link);
1561        printk(KERN_INFO "line speed=%d\n", conf->speed);
1562        printk(KERN_INFO "clock=%sternal\n", conf->clock == 8 ? "Ex" : "In");
1563        printk(KERN_INFO "# level 2 retransm.=%d\n", conf->n2);
1564        printk(KERN_INFO "level 2 window=%d\n", conf->n2win);
1565        printk(KERN_INFO "level 3 window=%d\n", conf->n3win);
1566        printk(KERN_INFO "# logical channels=%d\n", conf->nvc);
1567        printk(KERN_INFO "level 3 pkt len=%d\n", conf->pktlen);
1568        printk(KERN_INFO "my address=%d\n", conf->locaddr);
1569        printk(KERN_INFO "remote address=%d\n", conf->remaddr);
1570        printk(KERN_INFO "t1=%d seconds\n", conf->t1);
1571        printk(KERN_INFO "t2=%d seconds\n", conf->t2);
1572        printk(KERN_INFO "t21=%d seconds\n", conf->t21);
1573        printk(KERN_INFO "# PVCs=%d\n", conf->npvc);
1574        printk(KERN_INFO "t23=%d seconds\n", conf->t23);
1575        printk(KERN_INFO "flags=0x%x\n", conf->flags);
1576}
1577
1578static void cycx_x25_dump_stats(struct cycx_x25_stats *stats)
1579{
1580        printk(KERN_INFO "X.25 statistics\n");
1581        printk(KERN_INFO "--------------\n");
1582        printk(KERN_INFO "rx_crc_errors=%d\n", stats->rx_crc_errors);
1583        printk(KERN_INFO "rx_over_errors=%d\n", stats->rx_over_errors);
1584        printk(KERN_INFO "n2_tx_frames=%d\n", stats->n2_tx_frames);
1585        printk(KERN_INFO "n2_rx_frames=%d\n", stats->n2_rx_frames);
1586        printk(KERN_INFO "tx_timeouts=%d\n", stats->tx_timeouts);
1587        printk(KERN_INFO "rx_timeouts=%d\n", stats->rx_timeouts);
1588        printk(KERN_INFO "n3_tx_packets=%d\n", stats->n3_tx_packets);
1589        printk(KERN_INFO "n3_rx_packets=%d\n", stats->n3_rx_packets);
1590        printk(KERN_INFO "tx_aborts=%d\n", stats->tx_aborts);
1591        printk(KERN_INFO "rx_aborts=%d\n", stats->rx_aborts);
1592}
1593
1594static void cycx_x25_dump_devs(struct wan_device *wandev)
1595{
1596        struct net_device *dev = wandev->dev;
1597
1598        printk(KERN_INFO "X.25 dev states\n");
1599        printk(KERN_INFO "name: addr:           txoff:  protocol:\n");
1600        printk(KERN_INFO "---------------------------------------\n");
1601
1602        while(dev) {
1603                struct cycx_x25_channel *chan = dev->priv;
1604
1605                printk(KERN_INFO "%-5.5s %-15.15s   %d     ETH_P_%s\n",
1606                                 chan->name, chan->addr, netif_queue_stopped(dev),
1607                                 chan->protocol == ETH_P_IP ? "IP" : "X25");
1608                dev = chan->slave;
1609        }
1610}
1611
1612#endif /* CYCLOMX_X25_DEBUG */
1613/* End */
1614
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.