linux/drivers/net/wan/sbni.c
<<
>>
Prefs
   1/* sbni.c:  Granch SBNI12 leased line adapters driver for linux
   2 *
   3 *      Written 2001 by Denis I.Timofeev (timofeev@granch.ru)
   4 *
   5 *      Previous versions were written by Yaroslav Polyakov,
   6 *      Alexey Zverev and Max Khon.
   7 *
   8 *      Driver supports SBNI12-02,-04,-05,-10,-11 cards, single and
   9 *      double-channel, PCI and ISA modifications.
  10 *      More info and useful utilities to work with SBNI12 cards you can find
  11 *      at http://www.granch.com (English) or http://www.granch.ru (Russian)
  12 *
  13 *      This software may be used and distributed according to the terms
  14 *      of the GNU General Public License.
  15 *
  16 *
  17 *  5.0.1       Jun 22 2001
  18 *        - Fixed bug in probe
  19 *  5.0.0       Jun 06 2001
  20 *        - Driver was completely redesigned by Denis I.Timofeev,
  21 *        - now PCI/Dual, ISA/Dual (with single interrupt line) models are
  22 *        - supported
  23 *  3.3.0       Thu Feb 24 21:30:28 NOVT 2000 
  24 *        - PCI cards support
  25 *  3.2.0       Mon Dec 13 22:26:53 NOVT 1999
  26 *        - Completely rebuilt all the packet storage system
  27 *        -    to work in Ethernet-like style.
  28 *  3.1.1       just fixed some bugs (5 aug 1999)
  29 *  3.1.0       added balancing feature (26 apr 1999)
  30 *  3.0.1       just fixed some bugs (14 apr 1999).
  31 *  3.0.0       Initial Revision, Yaroslav Polyakov (24 Feb 1999)
  32 *        - added pre-calculation for CRC, fixed bug with "len-2" frames, 
  33 *        - removed outbound fragmentation (MTU=1000), written CRC-calculation 
  34 *        - on asm, added work with hard_headers and now we have our own cache 
  35 *        - for them, optionally supported word-interchange on some chipsets,
  36 * 
  37 *      Known problem: this driver wasn't tested on multiprocessor machine.
  38 */
  39
  40#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  41
  42#include <linux/module.h>
  43#include <linux/kernel.h>
  44#include <linux/ptrace.h>
  45#include <linux/fcntl.h>
  46#include <linux/ioport.h>
  47#include <linux/interrupt.h>
  48#include <linux/string.h>
  49#include <linux/errno.h>
  50#include <linux/netdevice.h>
  51#include <linux/etherdevice.h>
  52#include <linux/pci.h>
  53#include <linux/skbuff.h>
  54#include <linux/timer.h>
  55#include <linux/init.h>
  56#include <linux/delay.h>
  57
  58#include <net/net_namespace.h>
  59#include <net/arp.h>
  60
  61#include <asm/io.h>
  62#include <asm/types.h>
  63#include <asm/byteorder.h>
  64#include <asm/irq.h>
  65#include <asm/uaccess.h>
  66
  67#include "sbni.h"
  68
  69/* device private data */
  70
  71struct net_local {
  72        struct timer_list       watchdog;
  73
  74        spinlock_t      lock;
  75        struct sk_buff  *rx_buf_p;              /* receive buffer ptr */
  76        struct sk_buff  *tx_buf_p;              /* transmit buffer ptr */
  77        
  78        unsigned int    framelen;               /* current frame length */
  79        unsigned int    maxframe;               /* maximum valid frame length */
  80        unsigned int    state;
  81        unsigned int    inppos, outpos;         /* positions in rx/tx buffers */
  82
  83        /* transmitting frame number - from frames qty to 1 */
  84        unsigned int    tx_frameno;
  85
  86        /* expected number of next receiving frame */
  87        unsigned int    wait_frameno;
  88
  89        /* count of failed attempts to frame send - 32 attempts do before
  90           error - while receiver tunes on opposite side of wire */
  91        unsigned int    trans_errors;
  92
  93        /* idle time; send pong when limit exceeded */
  94        unsigned int    timer_ticks;
  95
  96        /* fields used for receive level autoselection */
  97        int     delta_rxl;
  98        unsigned int    cur_rxl_index, timeout_rxl;
  99        unsigned long   cur_rxl_rcvd, prev_rxl_rcvd;
 100
 101        struct sbni_csr1        csr1;           /* current value of CSR1 */
 102        struct sbni_in_stats    in_stats;       /* internal statistics */ 
 103
 104        struct net_device               *second;        /* for ISA/dual cards */
 105
 106#ifdef CONFIG_SBNI_MULTILINE
 107        struct net_device               *master;
 108        struct net_device               *link;
 109#endif
 110};
 111
 112
 113static int  sbni_card_probe( unsigned long );
 114static int  sbni_pci_probe( struct net_device  * );
 115static struct net_device  *sbni_probe1(struct net_device *, unsigned long, int);
 116static int  sbni_open( struct net_device * );
 117static int  sbni_close( struct net_device * );
 118static netdev_tx_t sbni_start_xmit(struct sk_buff *,
 119                                         struct net_device * );
 120static int  sbni_ioctl( struct net_device *, struct ifreq *, int );
 121static void  set_multicast_list( struct net_device * );
 122
 123static irqreturn_t sbni_interrupt( int, void * );
 124static void  handle_channel( struct net_device * );
 125static int   recv_frame( struct net_device * );
 126static void  send_frame( struct net_device * );
 127static int   upload_data( struct net_device *,
 128                          unsigned, unsigned, unsigned, u32 );
 129static void  download_data( struct net_device *, u32 * );
 130static void  sbni_watchdog( unsigned long );
 131static void  interpret_ack( struct net_device *, unsigned );
 132static int   append_frame_to_pkt( struct net_device *, unsigned, u32 );
 133static void  indicate_pkt( struct net_device * );
 134static void  card_start( struct net_device * );
 135static void  prepare_to_send( struct sk_buff *, struct net_device * );
 136static void  drop_xmit_queue( struct net_device * );
 137static void  send_frame_header( struct net_device *, u32 * );
 138static int   skip_tail( unsigned int, unsigned int, u32 );
 139static int   check_fhdr( u32, u32 *, u32 *, u32 *, u32 *, u32 * );
 140static void  change_level( struct net_device * );
 141static void  timeout_change_level( struct net_device * );
 142static u32   calc_crc32( u32, u8 *, u32 );
 143static struct sk_buff *  get_rx_buf( struct net_device * );
 144static int  sbni_init( struct net_device * );
 145
 146#ifdef CONFIG_SBNI_MULTILINE
 147static int  enslave( struct net_device *, struct net_device * );
 148static int  emancipate( struct net_device * );
 149#endif
 150
 151#ifdef __i386__
 152#define ASM_CRC 1
 153#endif
 154
 155static const char  version[] =
 156        "Granch SBNI12 driver ver 5.0.1  Jun 22 2001  Denis I.Timofeev.\n";
 157
 158static bool skip_pci_probe      __initdata = false;
 159static int  scandone    __initdata = 0;
 160static int  num         __initdata = 0;
 161
 162static unsigned char  rxl_tab[];
 163static u32  crc32tab[];
 164
 165/* A list of all installed devices, for removing the driver module. */
 166static struct net_device  *sbni_cards[ SBNI_MAX_NUM_CARDS ];
 167
 168/* Lists of device's parameters */
 169static u32      io[   SBNI_MAX_NUM_CARDS ] __initdata =
 170        { [0 ... SBNI_MAX_NUM_CARDS-1] = -1 };
 171static u32      irq[  SBNI_MAX_NUM_CARDS ] __initdata;
 172static u32      baud[ SBNI_MAX_NUM_CARDS ] __initdata;
 173static u32      rxl[  SBNI_MAX_NUM_CARDS ] __initdata =
 174        { [0 ... SBNI_MAX_NUM_CARDS-1] = -1 };
 175static u32      mac[  SBNI_MAX_NUM_CARDS ] __initdata;
 176
 177#ifndef MODULE
 178typedef u32  iarr[];
 179static iarr __initdata *dest[5] = { &io, &irq, &baud, &rxl, &mac };
 180#endif
 181
 182/* A zero-terminated list of I/O addresses to be probed on ISA bus */
 183static unsigned int  netcard_portlist[ ] __initdata = { 
 184        0x210, 0x214, 0x220, 0x224, 0x230, 0x234, 0x240, 0x244, 0x250, 0x254,
 185        0x260, 0x264, 0x270, 0x274, 0x280, 0x284, 0x290, 0x294, 0x2a0, 0x2a4,
 186        0x2b0, 0x2b4, 0x2c0, 0x2c4, 0x2d0, 0x2d4, 0x2e0, 0x2e4, 0x2f0, 0x2f4,
 187        0 };
 188
 189#define NET_LOCAL_LOCK(dev) (((struct net_local *)netdev_priv(dev))->lock)
 190
 191/*
 192 * Look for SBNI card which addr stored in dev->base_addr, if nonzero.
 193 * Otherwise, look through PCI bus. If none PCI-card was found, scan ISA.
 194 */
 195
 196static inline int __init
 197sbni_isa_probe( struct net_device  *dev )
 198{
 199        if( dev->base_addr > 0x1ff &&
 200            request_region( dev->base_addr, SBNI_IO_EXTENT, dev->name ) &&
 201            sbni_probe1( dev, dev->base_addr, dev->irq ) )
 202
 203                return  0;
 204        else {
 205                pr_err("base address 0x%lx is busy, or adapter is malfunctional!\n",
 206                       dev->base_addr);
 207                return  -ENODEV;
 208        }
 209}
 210
 211static const struct net_device_ops sbni_netdev_ops = {
 212        .ndo_open               = sbni_open,
 213        .ndo_stop               = sbni_close,
 214        .ndo_start_xmit         = sbni_start_xmit,
 215        .ndo_set_rx_mode        = set_multicast_list,
 216        .ndo_do_ioctl           = sbni_ioctl,
 217        .ndo_change_mtu         = eth_change_mtu,
 218        .ndo_set_mac_address    = eth_mac_addr,
 219        .ndo_validate_addr      = eth_validate_addr,
 220};
 221
 222static void __init sbni_devsetup(struct net_device *dev)
 223{
 224        ether_setup( dev );
 225        dev->netdev_ops = &sbni_netdev_ops;
 226}
 227
 228int __init sbni_probe(int unit)
 229{
 230        struct net_device *dev;
 231        int err;
 232
 233        dev = alloc_netdev(sizeof(struct net_local), "sbni", sbni_devsetup);
 234        if (!dev)
 235                return -ENOMEM;
 236
 237        dev->netdev_ops = &sbni_netdev_ops;
 238
 239        sprintf(dev->name, "sbni%d", unit);
 240        netdev_boot_setup_check(dev);
 241
 242        err = sbni_init(dev);
 243        if (err) {
 244                free_netdev(dev);
 245                return err;
 246        }
 247
 248        err = register_netdev(dev);
 249        if (err) {
 250                release_region( dev->base_addr, SBNI_IO_EXTENT );
 251                free_netdev(dev);
 252                return err;
 253        }
 254        pr_info_once("%s", version);
 255        return 0;
 256}
 257
 258static int __init sbni_init(struct net_device *dev)
 259{
 260        int  i;
 261        if( dev->base_addr )
 262                return  sbni_isa_probe( dev );
 263        /* otherwise we have to perform search our adapter */
 264
 265        if( io[ num ] != -1 )
 266                dev->base_addr  = io[ num ],
 267                dev->irq        = irq[ num ];
 268        else if( scandone  ||  io[ 0 ] != -1 )
 269                return  -ENODEV;
 270
 271        /* if io[ num ] contains non-zero address, then that is on ISA bus */
 272        if( dev->base_addr )
 273                return  sbni_isa_probe( dev );
 274
 275        /* ...otherwise - scan PCI first */
 276        if( !skip_pci_probe  &&  !sbni_pci_probe( dev ) )
 277                return  0;
 278
 279        if( io[ num ] == -1 ) {
 280                /* Auto-scan will be stopped when first ISA card were found */
 281                scandone = 1;
 282                if( num > 0 )
 283                        return  -ENODEV;
 284        }
 285
 286        for( i = 0;  netcard_portlist[ i ];  ++i ) {
 287                int  ioaddr = netcard_portlist[ i ];
 288                if( request_region( ioaddr, SBNI_IO_EXTENT, dev->name ) &&
 289                    sbni_probe1( dev, ioaddr, 0 ))
 290                        return 0;
 291        }
 292
 293        return  -ENODEV;
 294}
 295
 296
 297static int __init
 298sbni_pci_probe( struct net_device  *dev )
 299{
 300        struct pci_dev  *pdev = NULL;
 301
 302        while( (pdev = pci_get_class( PCI_CLASS_NETWORK_OTHER << 8, pdev ))
 303               != NULL ) {
 304                int  pci_irq_line;
 305                unsigned long  pci_ioaddr;
 306
 307                if( pdev->vendor != SBNI_PCI_VENDOR &&
 308                    pdev->device != SBNI_PCI_DEVICE )
 309                        continue;
 310
 311                pci_ioaddr = pci_resource_start( pdev, 0 );
 312                pci_irq_line = pdev->irq;
 313
 314                /* Avoid already found cards from previous calls */
 315                if( !request_region( pci_ioaddr, SBNI_IO_EXTENT, dev->name ) ) {
 316                        if (pdev->subsystem_device != 2)
 317                                continue;
 318
 319                        /* Dual adapter is present */
 320                        if (!request_region(pci_ioaddr += 4, SBNI_IO_EXTENT,
 321                                                        dev->name ) )
 322                                continue;
 323                }
 324
 325                if (pci_irq_line <= 0 || pci_irq_line >= nr_irqs)
 326                        pr_warn(
 327"WARNING: The PCI BIOS assigned this PCI card to IRQ %d, which is unlikely to work!.\n"
 328"You should use the PCI BIOS setup to assign a valid IRQ line.\n",
 329                                pci_irq_line );
 330
 331                /* avoiding re-enable dual adapters */
 332                if( (pci_ioaddr & 7) == 0  &&  pci_enable_device( pdev ) ) {
 333                        release_region( pci_ioaddr, SBNI_IO_EXTENT );
 334                        pci_dev_put( pdev );
 335                        return  -EIO;
 336                }
 337                if( sbni_probe1( dev, pci_ioaddr, pci_irq_line ) ) {
 338                        SET_NETDEV_DEV(dev, &pdev->dev);
 339                        /* not the best thing to do, but this is all messed up 
 340                           for hotplug systems anyway... */
 341                        pci_dev_put( pdev );
 342                        return  0;
 343                }
 344        }
 345        return  -ENODEV;
 346}
 347
 348
 349static struct net_device * __init
 350sbni_probe1( struct net_device  *dev,  unsigned long  ioaddr,  int  irq )
 351{
 352        struct net_local  *nl;
 353
 354        if( sbni_card_probe( ioaddr ) ) {
 355                release_region( ioaddr, SBNI_IO_EXTENT );
 356                return NULL;
 357        }
 358
 359        outb( 0, ioaddr + CSR0 );
 360
 361        if( irq < 2 ) {
 362                unsigned long irq_mask;
 363
 364                irq_mask = probe_irq_on();
 365                outb( EN_INT | TR_REQ, ioaddr + CSR0 );
 366                outb( PR_RES, ioaddr + CSR1 );
 367                mdelay(50);
 368                irq = probe_irq_off(irq_mask);
 369                outb( 0, ioaddr + CSR0 );
 370
 371                if( !irq ) {
 372                        pr_err("%s: can't detect device irq!\n", dev->name);
 373                        release_region( ioaddr, SBNI_IO_EXTENT );
 374                        return NULL;
 375                }
 376        } else if( irq == 2 )
 377                irq = 9;
 378
 379        dev->irq = irq;
 380        dev->base_addr = ioaddr;
 381
 382        /* Fill in sbni-specific dev fields. */
 383        nl = netdev_priv(dev);
 384        if( !nl ) {
 385                pr_err("%s: unable to get memory!\n", dev->name);
 386                release_region( ioaddr, SBNI_IO_EXTENT );
 387                return NULL;
 388        }
 389
 390        memset( nl, 0, sizeof(struct net_local) );
 391        spin_lock_init( &nl->lock );
 392
 393        /* store MAC address (generate if that isn't known) */
 394        *(__be16 *)dev->dev_addr = htons( 0x00ff );
 395        *(__be32 *)(dev->dev_addr + 2) = htonl( 0x01000000 |
 396                ((mac[num] ?
 397                mac[num] :
 398                (u32)((long)netdev_priv(dev))) & 0x00ffffff));
 399
 400        /* store link settings (speed, receive level ) */
 401        nl->maxframe  = DEFAULT_FRAME_LEN;
 402        nl->csr1.rate = baud[ num ];
 403
 404        if( (nl->cur_rxl_index = rxl[ num ]) == -1 )
 405                /* autotune rxl */
 406                nl->cur_rxl_index = DEF_RXL,
 407                nl->delta_rxl = DEF_RXL_DELTA;
 408        else
 409                nl->delta_rxl = 0;
 410        nl->csr1.rxl  = rxl_tab[ nl->cur_rxl_index ];
 411        if( inb( ioaddr + CSR0 ) & 0x01 )
 412                nl->state |= FL_SLOW_MODE;
 413
 414        pr_notice("%s: ioaddr %#lx, irq %d, MAC: 00:ff:01:%02x:%02x:%02x\n",
 415                  dev->name, dev->base_addr, dev->irq,
 416                  ((u8 *)dev->dev_addr)[3],
 417                  ((u8 *)dev->dev_addr)[4],
 418                  ((u8 *)dev->dev_addr)[5]);
 419
 420        pr_notice("%s: speed %d",
 421                  dev->name,
 422                  ((nl->state & FL_SLOW_MODE) ? 500000 : 2000000)
 423                  / (1 << nl->csr1.rate));
 424
 425        if( nl->delta_rxl == 0 )
 426                pr_cont(", receive level 0x%x (fixed)\n", nl->cur_rxl_index);
 427        else
 428                pr_cont(", receive level (auto)\n");
 429
 430#ifdef CONFIG_SBNI_MULTILINE
 431        nl->master = dev;
 432        nl->link   = NULL;
 433#endif
 434   
 435        sbni_cards[ num++ ] = dev;
 436        return  dev;
 437}
 438
 439/* -------------------------------------------------------------------------- */
 440
 441#ifdef CONFIG_SBNI_MULTILINE
 442
 443static netdev_tx_t
 444sbni_start_xmit( struct sk_buff  *skb,  struct net_device  *dev )
 445{
 446        struct net_device  *p;
 447
 448        netif_stop_queue( dev );
 449
 450        /* Looking for idle device in the list */
 451        for( p = dev;  p; ) {
 452                struct net_local  *nl = netdev_priv(p);
 453                spin_lock( &nl->lock );
 454                if( nl->tx_buf_p  ||  (nl->state & FL_LINE_DOWN) ) {
 455                        p = nl->link;
 456                        spin_unlock( &nl->lock );
 457                } else {
 458                        /* Idle dev is found */
 459                        prepare_to_send( skb, p );
 460                        spin_unlock( &nl->lock );
 461                        netif_start_queue( dev );
 462                        return NETDEV_TX_OK;
 463                }
 464        }
 465
 466        return NETDEV_TX_BUSY;
 467}
 468
 469#else   /* CONFIG_SBNI_MULTILINE */
 470
 471static netdev_tx_t
 472sbni_start_xmit( struct sk_buff  *skb,  struct net_device  *dev )
 473{
 474        struct net_local  *nl  = netdev_priv(dev);
 475
 476        netif_stop_queue( dev );
 477        spin_lock( &nl->lock );
 478
 479        prepare_to_send( skb, dev );
 480
 481        spin_unlock( &nl->lock );
 482        return NETDEV_TX_OK;
 483}
 484
 485#endif  /* CONFIG_SBNI_MULTILINE */
 486
 487/* -------------------------------------------------------------------------- */
 488
 489/* interrupt handler */
 490
 491/*
 492 *      SBNI12D-10, -11/ISA boards within "common interrupt" mode could not
 493 * be looked as two independent single-channel devices. Every channel seems
 494 * as Ethernet interface but interrupt handler must be common. Really, first
 495 * channel ("master") driver only registers the handler. In its struct net_local
 496 * it has got pointer to "slave" channel's struct net_local and handles that's
 497 * interrupts too.
 498 *      dev of successfully attached ISA SBNI boards is linked to list.
 499 * While next board driver is initialized, it scans this list. If one
 500 * has found dev with same irq and ioaddr different by 4 then it assumes
 501 * this board to be "master".
 502 */ 
 503
 504static irqreturn_t
 505sbni_interrupt( int  irq,  void  *dev_id )
 506{
 507        struct net_device         *dev = dev_id;
 508        struct net_local  *nl  = netdev_priv(dev);
 509        int     repeat;
 510
 511        spin_lock( &nl->lock );
 512        if( nl->second )
 513                spin_lock(&NET_LOCAL_LOCK(nl->second));
 514
 515        do {
 516                repeat = 0;
 517                if( inb( dev->base_addr + CSR0 ) & (RC_RDY | TR_RDY) )
 518                        handle_channel( dev ),
 519                        repeat = 1;
 520                if( nl->second  &&      /* second channel present */
 521                    (inb( nl->second->base_addr+CSR0 ) & (RC_RDY | TR_RDY)) )
 522                        handle_channel( nl->second ),
 523                        repeat = 1;
 524        } while( repeat );
 525
 526        if( nl->second )
 527                spin_unlock(&NET_LOCAL_LOCK(nl->second));
 528        spin_unlock( &nl->lock );
 529        return IRQ_HANDLED;
 530}
 531
 532
 533static void
 534handle_channel( struct net_device  *dev )
 535{
 536        struct net_local        *nl    = netdev_priv(dev);
 537        unsigned long           ioaddr = dev->base_addr;
 538
 539        int  req_ans;
 540        unsigned char  csr0;
 541
 542#ifdef CONFIG_SBNI_MULTILINE
 543        /* Lock the master device because we going to change its local data */
 544        if( nl->state & FL_SLAVE )
 545                spin_lock(&NET_LOCAL_LOCK(nl->master));
 546#endif
 547
 548        outb( (inb( ioaddr + CSR0 ) & ~EN_INT) | TR_REQ, ioaddr + CSR0 );
 549
 550        nl->timer_ticks = CHANGE_LEVEL_START_TICKS;
 551        for(;;) {
 552                csr0 = inb( ioaddr + CSR0 );
 553                if( ( csr0 & (RC_RDY | TR_RDY) ) == 0 )
 554                        break;
 555
 556                req_ans = !(nl->state & FL_PREV_OK);
 557
 558                if( csr0 & RC_RDY )
 559                        req_ans = recv_frame( dev );
 560
 561                /*
 562                 * TR_RDY always equals 1 here because we have owned the marker,
 563                 * and we set TR_REQ when disabled interrupts
 564                 */
 565                csr0 = inb( ioaddr + CSR0 );
 566                if( !(csr0 & TR_RDY)  ||  (csr0 & RC_RDY) )
 567                        netdev_err(dev, "internal error!\n");
 568
 569                /* if state & FL_NEED_RESEND != 0 then tx_frameno != 0 */
 570                if( req_ans  ||  nl->tx_frameno != 0 )
 571                        send_frame( dev );
 572                else
 573                        /* send marker without any data */
 574                        outb( inb( ioaddr + CSR0 ) & ~TR_REQ, ioaddr + CSR0 );
 575        }
 576
 577        outb( inb( ioaddr + CSR0 ) | EN_INT, ioaddr + CSR0 );
 578
 579#ifdef CONFIG_SBNI_MULTILINE
 580        if( nl->state & FL_SLAVE )
 581                spin_unlock(&NET_LOCAL_LOCK(nl->master));
 582#endif
 583}
 584
 585
 586/*
 587 * Routine returns 1 if it need to acknoweledge received frame.
 588 * Empty frame received without errors won't be acknoweledged.
 589 */
 590
 591static int
 592recv_frame( struct net_device  *dev )
 593{
 594        struct net_local  *nl   = netdev_priv(dev);
 595        unsigned long  ioaddr   = dev->base_addr;
 596
 597        u32  crc = CRC32_INITIAL;
 598
 599        unsigned  framelen = 0, frameno, ack;
 600        unsigned  is_first, frame_ok = 0;
 601
 602        if( check_fhdr( ioaddr, &framelen, &frameno, &ack, &is_first, &crc ) ) {
 603                frame_ok = framelen > 4
 604                        ?  upload_data( dev, framelen, frameno, is_first, crc )
 605                        :  skip_tail( ioaddr, framelen, crc );
 606                if( frame_ok )
 607                        interpret_ack( dev, ack );
 608        }
 609
 610        outb( inb( ioaddr + CSR0 ) ^ CT_ZER, ioaddr + CSR0 );
 611        if( frame_ok ) {
 612                nl->state |= FL_PREV_OK;
 613                if( framelen > 4 )
 614                        nl->in_stats.all_rx_number++;
 615        } else
 616                nl->state &= ~FL_PREV_OK,
 617                change_level( dev ),
 618                nl->in_stats.all_rx_number++,
 619                nl->in_stats.bad_rx_number++;
 620
 621        return  !frame_ok  ||  framelen > 4;
 622}
 623
 624
 625static void
 626send_frame( struct net_device  *dev )
 627{
 628        struct net_local  *nl    = netdev_priv(dev);
 629
 630        u32  crc = CRC32_INITIAL;
 631
 632        if( nl->state & FL_NEED_RESEND ) {
 633
 634                /* if frame was sended but not ACK'ed - resend it */
 635                if( nl->trans_errors ) {
 636                        --nl->trans_errors;
 637                        if( nl->framelen != 0 )
 638                                nl->in_stats.resend_tx_number++;
 639                } else {
 640                        /* cannot xmit with many attempts */
 641#ifdef CONFIG_SBNI_MULTILINE
 642                        if( (nl->state & FL_SLAVE)  ||  nl->link )
 643#endif
 644                        nl->state |= FL_LINE_DOWN;
 645                        drop_xmit_queue( dev );
 646                        goto  do_send;
 647                }
 648        } else
 649                nl->trans_errors = TR_ERROR_COUNT;
 650
 651        send_frame_header( dev, &crc );
 652        nl->state |= FL_NEED_RESEND;
 653        /*
 654         * FL_NEED_RESEND will be cleared after ACK, but if empty
 655         * frame sended then in prepare_to_send next frame
 656         */
 657
 658
 659        if( nl->framelen ) {
 660                download_data( dev, &crc );
 661                nl->in_stats.all_tx_number++;
 662                nl->state |= FL_WAIT_ACK;
 663        }
 664
 665        outsb( dev->base_addr + DAT, (u8 *)&crc, sizeof crc );
 666
 667do_send:
 668        outb( inb( dev->base_addr + CSR0 ) & ~TR_REQ, dev->base_addr + CSR0 );
 669
 670        if( nl->tx_frameno )
 671                /* next frame exists - we request card to send it */
 672                outb( inb( dev->base_addr + CSR0 ) | TR_REQ,
 673                      dev->base_addr + CSR0 );
 674}
 675
 676
 677/*
 678 * Write the frame data into adapter's buffer memory, and calculate CRC.
 679 * Do padding if necessary.
 680 */
 681
 682static void
 683download_data( struct net_device  *dev,  u32  *crc_p )
 684{
 685        struct net_local  *nl    = netdev_priv(dev);
 686        struct sk_buff    *skb   = nl->tx_buf_p;
 687
 688        unsigned  len = min_t(unsigned int, skb->len - nl->outpos, nl->framelen);
 689
 690        outsb( dev->base_addr + DAT, skb->data + nl->outpos, len );
 691        *crc_p = calc_crc32( *crc_p, skb->data + nl->outpos, len );
 692
 693        /* if packet too short we should write some more bytes to pad */
 694        for( len = nl->framelen - len;  len--; )
 695                outb( 0, dev->base_addr + DAT ),
 696                *crc_p = CRC32( 0, *crc_p );
 697}
 698
 699
 700static int
 701upload_data( struct net_device  *dev,  unsigned  framelen,  unsigned  frameno,
 702             unsigned  is_first,  u32  crc )
 703{
 704        struct net_local  *nl = netdev_priv(dev);
 705
 706        int  frame_ok;
 707
 708        if( is_first )
 709                nl->wait_frameno = frameno,
 710                nl->inppos = 0;
 711
 712        if( nl->wait_frameno == frameno ) {
 713
 714                if( nl->inppos + framelen  <=  ETHER_MAX_LEN )
 715                        frame_ok = append_frame_to_pkt( dev, framelen, crc );
 716
 717                /*
 718                 * if CRC is right but framelen incorrect then transmitter
 719                 * error was occurred... drop entire packet
 720                 */
 721                else if( (frame_ok = skip_tail( dev->base_addr, framelen, crc ))
 722                         != 0 )
 723                        nl->wait_frameno = 0,
 724                        nl->inppos = 0,
 725#ifdef CONFIG_SBNI_MULTILINE
 726                        nl->master->stats.rx_errors++,
 727                        nl->master->stats.rx_missed_errors++;
 728#else
 729                        dev->stats.rx_errors++,
 730                        dev->stats.rx_missed_errors++;
 731#endif
 732                        /* now skip all frames until is_first != 0 */
 733        } else
 734                frame_ok = skip_tail( dev->base_addr, framelen, crc );
 735
 736        if( is_first  &&  !frame_ok )
 737                /*
 738                 * Frame has been broken, but we had already stored
 739                 * is_first... Drop entire packet.
 740                 */
 741                nl->wait_frameno = 0,
 742#ifdef CONFIG_SBNI_MULTILINE
 743                nl->master->stats.rx_errors++,
 744                nl->master->stats.rx_crc_errors++;
 745#else
 746                dev->stats.rx_errors++,
 747                dev->stats.rx_crc_errors++;
 748#endif
 749
 750        return  frame_ok;
 751}
 752
 753
 754static inline void
 755send_complete( struct net_device *dev )
 756{
 757        struct net_local  *nl = netdev_priv(dev);
 758
 759#ifdef CONFIG_SBNI_MULTILINE
 760        nl->master->stats.tx_packets++;
 761        nl->master->stats.tx_bytes += nl->tx_buf_p->len;
 762#else
 763        dev->stats.tx_packets++;
 764        dev->stats.tx_bytes += nl->tx_buf_p->len;
 765#endif
 766        dev_kfree_skb_irq( nl->tx_buf_p );
 767
 768        nl->tx_buf_p = NULL;
 769
 770        nl->outpos = 0;
 771        nl->state &= ~(FL_WAIT_ACK | FL_NEED_RESEND);
 772        nl->framelen   = 0;
 773}
 774
 775
 776static void
 777interpret_ack( struct net_device  *dev,  unsigned  ack )
 778{
 779        struct net_local  *nl = netdev_priv(dev);
 780
 781        if( ack == FRAME_SENT_OK ) {
 782                nl->state &= ~FL_NEED_RESEND;
 783
 784                if( nl->state & FL_WAIT_ACK ) {
 785                        nl->outpos += nl->framelen;
 786
 787                        if( --nl->tx_frameno )
 788                                nl->framelen = min_t(unsigned int,
 789                                                   nl->maxframe,
 790                                                   nl->tx_buf_p->len - nl->outpos);
 791                        else
 792                                send_complete( dev ),
 793#ifdef CONFIG_SBNI_MULTILINE
 794                                netif_wake_queue( nl->master );
 795#else
 796                                netif_wake_queue( dev );
 797#endif
 798                }
 799        }
 800
 801        nl->state &= ~FL_WAIT_ACK;
 802}
 803
 804
 805/*
 806 * Glue received frame with previous fragments of packet.
 807 * Indicate packet when last frame would be accepted.
 808 */
 809
 810static int
 811append_frame_to_pkt( struct net_device  *dev,  unsigned  framelen,  u32  crc )
 812{
 813        struct net_local  *nl = netdev_priv(dev);
 814
 815        u8  *p;
 816
 817        if( nl->inppos + framelen  >  ETHER_MAX_LEN )
 818                return  0;
 819
 820        if( !nl->rx_buf_p  &&  !(nl->rx_buf_p = get_rx_buf( dev )) )
 821                return  0;
 822
 823        p = nl->rx_buf_p->data + nl->inppos;
 824        insb( dev->base_addr + DAT, p, framelen );
 825        if( calc_crc32( crc, p, framelen ) != CRC32_REMAINDER )
 826                return  0;
 827
 828        nl->inppos += framelen - 4;
 829        if( --nl->wait_frameno == 0 )           /* last frame received */
 830                indicate_pkt( dev );
 831
 832        return  1;
 833}
 834
 835
 836/*
 837 * Prepare to start output on adapter.
 838 * Transmitter will be actually activated when marker is accepted.
 839 */
 840
 841static void
 842prepare_to_send( struct sk_buff  *skb,  struct net_device  *dev )
 843{
 844        struct net_local  *nl = netdev_priv(dev);
 845
 846        unsigned int  len;
 847
 848        /* nl->tx_buf_p == NULL here! */
 849        if( nl->tx_buf_p )
 850                netdev_err(dev, "memory leak!\n");
 851
 852        nl->outpos = 0;
 853        nl->state &= ~(FL_WAIT_ACK | FL_NEED_RESEND);
 854
 855        len = skb->len;
 856        if( len < SBNI_MIN_LEN )
 857                len = SBNI_MIN_LEN;
 858
 859        nl->tx_buf_p    = skb;
 860        nl->tx_frameno  = DIV_ROUND_UP(len, nl->maxframe);
 861        nl->framelen    = len < nl->maxframe  ?  len  :  nl->maxframe;
 862
 863        outb( inb( dev->base_addr + CSR0 ) | TR_REQ,  dev->base_addr + CSR0 );
 864#ifdef CONFIG_SBNI_MULTILINE
 865        nl->master->trans_start = jiffies;
 866#else
 867        dev->trans_start = jiffies;
 868#endif
 869}
 870
 871
 872static void
 873drop_xmit_queue( struct net_device  *dev )
 874{
 875        struct net_local  *nl = netdev_priv(dev);
 876
 877        if( nl->tx_buf_p )
 878                dev_kfree_skb_any( nl->tx_buf_p ),
 879                nl->tx_buf_p = NULL,
 880#ifdef CONFIG_SBNI_MULTILINE
 881                nl->master->stats.tx_errors++,
 882                nl->master->stats.tx_carrier_errors++;
 883#else
 884                dev->stats.tx_errors++,
 885                dev->stats.tx_carrier_errors++;
 886#endif
 887
 888        nl->tx_frameno  = 0;
 889        nl->framelen    = 0;
 890        nl->outpos      = 0;
 891        nl->state &= ~(FL_WAIT_ACK | FL_NEED_RESEND);
 892#ifdef CONFIG_SBNI_MULTILINE
 893        netif_start_queue( nl->master );
 894        nl->master->trans_start = jiffies;
 895#else
 896        netif_start_queue( dev );
 897        dev->trans_start = jiffies;
 898#endif
 899}
 900
 901
 902static void
 903send_frame_header( struct net_device  *dev,  u32  *crc_p )
 904{
 905        struct net_local  *nl  = netdev_priv(dev);
 906
 907        u32  crc = *crc_p;
 908        u32  len_field = nl->framelen + 6;      /* CRC + frameno + reserved */
 909        u8   value;
 910
 911        if( nl->state & FL_NEED_RESEND )
 912                len_field |= FRAME_RETRY;       /* non-first attempt... */
 913
 914        if( nl->outpos == 0 )
 915                len_field |= FRAME_FIRST;
 916
 917        len_field |= (nl->state & FL_PREV_OK) ? FRAME_SENT_OK : FRAME_SENT_BAD;
 918        outb( SBNI_SIG, dev->base_addr + DAT );
 919
 920        value = (u8) len_field;
 921        outb( value, dev->base_addr + DAT );
 922        crc = CRC32( value, crc );
 923        value = (u8) (len_field >> 8);
 924        outb( value, dev->base_addr + DAT );
 925        crc = CRC32( value, crc );
 926
 927        outb( nl->tx_frameno, dev->base_addr + DAT );
 928        crc = CRC32( nl->tx_frameno, crc );
 929        outb( 0, dev->base_addr + DAT );
 930        crc = CRC32( 0, crc );
 931        *crc_p = crc;
 932}
 933
 934
 935/*
 936 * if frame tail not needed (incorrect number or received twice),
 937 * it won't store, but CRC will be calculated
 938 */
 939
 940static int
 941skip_tail( unsigned int  ioaddr,  unsigned int  tail_len,  u32 crc )
 942{
 943        while( tail_len-- )
 944                crc = CRC32( inb( ioaddr + DAT ), crc );
 945
 946        return  crc == CRC32_REMAINDER;
 947}
 948
 949
 950/*
 951 * Preliminary checks if frame header is correct, calculates its CRC
 952 * and split it to simple fields
 953 */
 954
 955static int
 956check_fhdr( u32  ioaddr,  u32  *framelen,  u32  *frameno,  u32  *ack,
 957            u32  *is_first,  u32  *crc_p )
 958{
 959        u32  crc = *crc_p;
 960        u8   value;
 961
 962        if( inb( ioaddr + DAT ) != SBNI_SIG )
 963                return  0;
 964
 965        value = inb( ioaddr + DAT );
 966        *framelen = (u32)value;
 967        crc = CRC32( value, crc );
 968        value = inb( ioaddr + DAT );
 969        *framelen |= ((u32)value) << 8;
 970        crc = CRC32( value, crc );
 971
 972        *ack = *framelen & FRAME_ACK_MASK;
 973        *is_first = (*framelen & FRAME_FIRST) != 0;
 974
 975        if( (*framelen &= FRAME_LEN_MASK) < 6 ||
 976            *framelen > SBNI_MAX_FRAME - 3 )
 977                return  0;
 978
 979        value = inb( ioaddr + DAT );
 980        *frameno = (u32)value;
 981        crc = CRC32( value, crc );
 982
 983        crc = CRC32( inb( ioaddr + DAT ), crc );        /* reserved byte */
 984        *framelen -= 2;
 985
 986        *crc_p = crc;
 987        return  1;
 988}
 989
 990
 991static struct sk_buff *
 992get_rx_buf( struct net_device  *dev )
 993{
 994        /* +2 is to compensate for the alignment fixup below */
 995        struct sk_buff  *skb = dev_alloc_skb( ETHER_MAX_LEN + 2 );
 996        if( !skb )
 997                return  NULL;
 998
 999        skb_reserve( skb, 2 );          /* Align IP on longword boundaries */
1000        return  skb;
1001}
1002
1003
1004static void
1005indicate_pkt( struct net_device  *dev )
1006{
1007        struct net_local  *nl  = netdev_priv(dev);
1008        struct sk_buff    *skb = nl->rx_buf_p;
1009
1010        skb_put( skb, nl->inppos );
1011
1012#ifdef CONFIG_SBNI_MULTILINE
1013        skb->protocol = eth_type_trans( skb, nl->master );
1014        netif_rx( skb );
1015        ++nl->master->stats.rx_packets;
1016        nl->master->stats.rx_bytes += nl->inppos;
1017#else
1018        skb->protocol = eth_type_trans( skb, dev );
1019        netif_rx( skb );
1020        ++dev->stats.rx_packets;
1021        dev->stats.rx_bytes += nl->inppos;
1022#endif
1023        nl->rx_buf_p = NULL;    /* protocol driver will clear this sk_buff */
1024}
1025
1026
1027/* -------------------------------------------------------------------------- */
1028
1029/*
1030 * Routine checks periodically wire activity and regenerates marker if
1031 * connect was inactive for a long time.
1032 */
1033
1034static void
1035sbni_watchdog( unsigned long  arg )
1036{
1037        struct net_device  *dev = (struct net_device *) arg;
1038        struct net_local   *nl  = netdev_priv(dev);
1039        struct timer_list  *w   = &nl->watchdog; 
1040        unsigned long      flags;
1041        unsigned char      csr0;
1042
1043        spin_lock_irqsave( &nl->lock, flags );
1044
1045        csr0 = inb( dev->base_addr + CSR0 );
1046        if( csr0 & RC_CHK ) {
1047
1048                if( nl->timer_ticks ) {
1049                        if( csr0 & (RC_RDY | BU_EMP) )
1050                                /* receiving not active */
1051                                nl->timer_ticks--;
1052                } else {
1053                        nl->in_stats.timeout_number++;
1054                        if( nl->delta_rxl )
1055                                timeout_change_level( dev );
1056
1057                        outb( *(u_char *)&nl->csr1 | PR_RES,
1058                              dev->base_addr + CSR1 );
1059                        csr0 = inb( dev->base_addr + CSR0 );
1060                }
1061        } else
1062                nl->state &= ~FL_LINE_DOWN;
1063
1064        outb( csr0 | RC_CHK, dev->base_addr + CSR0 ); 
1065
1066        init_timer( w );
1067        w->expires      = jiffies + SBNI_TIMEOUT;
1068        w->data         = arg;
1069        w->function     = sbni_watchdog;
1070        add_timer( w );
1071
1072        spin_unlock_irqrestore( &nl->lock, flags );
1073}
1074
1075
1076static unsigned char  rxl_tab[] = {
1077        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08,
1078        0x0a, 0x0c, 0x0f, 0x16, 0x18, 0x1a, 0x1c, 0x1f
1079};
1080
1081#define SIZE_OF_TIMEOUT_RXL_TAB 4
1082static unsigned char  timeout_rxl_tab[] = {
1083        0x03, 0x05, 0x08, 0x0b
1084};
1085
1086/* -------------------------------------------------------------------------- */
1087
1088static void
1089card_start( struct net_device  *dev )
1090{
1091        struct net_local  *nl = netdev_priv(dev);
1092
1093        nl->timer_ticks = CHANGE_LEVEL_START_TICKS;
1094        nl->state &= ~(FL_WAIT_ACK | FL_NEED_RESEND);
1095        nl->state |= FL_PREV_OK;
1096
1097        nl->inppos = nl->outpos = 0;
1098        nl->wait_frameno = 0;
1099        nl->tx_frameno   = 0;
1100        nl->framelen     = 0;
1101
1102        outb( *(u_char *)&nl->csr1 | PR_RES, dev->base_addr + CSR1 );
1103        outb( EN_INT, dev->base_addr + CSR0 );
1104}
1105
1106/* -------------------------------------------------------------------------- */
1107
1108/* Receive level auto-selection */
1109
1110static void
1111change_level( struct net_device  *dev )
1112{
1113        struct net_local  *nl = netdev_priv(dev);
1114
1115        if( nl->delta_rxl == 0 )        /* do not auto-negotiate RxL */
1116                return;
1117
1118        if( nl->cur_rxl_index == 0 )
1119                nl->delta_rxl = 1;
1120        else if( nl->cur_rxl_index == 15 )
1121                nl->delta_rxl = -1;
1122        else if( nl->cur_rxl_rcvd < nl->prev_rxl_rcvd )
1123                nl->delta_rxl = -nl->delta_rxl;
1124
1125        nl->csr1.rxl = rxl_tab[ nl->cur_rxl_index += nl->delta_rxl ];
1126        inb( dev->base_addr + CSR0 );   /* needs for PCI cards */
1127        outb( *(u8 *)&nl->csr1, dev->base_addr + CSR1 );
1128
1129        nl->prev_rxl_rcvd = nl->cur_rxl_rcvd;
1130        nl->cur_rxl_rcvd  = 0;
1131}
1132
1133
1134static void
1135timeout_change_level( struct net_device  *dev )
1136{
1137        struct net_local  *nl = netdev_priv(dev);
1138
1139        nl->cur_rxl_index = timeout_rxl_tab[ nl->timeout_rxl ];
1140        if( ++nl->timeout_rxl >= 4 )
1141                nl->timeout_rxl = 0;
1142
1143        nl->csr1.rxl = rxl_tab[ nl->cur_rxl_index ];
1144        inb( dev->base_addr + CSR0 );
1145        outb( *(unsigned char *)&nl->csr1, dev->base_addr + CSR1 );
1146
1147        nl->prev_rxl_rcvd = nl->cur_rxl_rcvd;
1148        nl->cur_rxl_rcvd  = 0;
1149}
1150
1151/* -------------------------------------------------------------------------- */
1152
1153/*
1154 *      Open/initialize the board. 
1155 */
1156
1157static int
1158sbni_open( struct net_device  *dev )
1159{
1160        struct net_local        *nl = netdev_priv(dev);
1161        struct timer_list       *w  = &nl->watchdog;
1162
1163        /*
1164         * For double ISA adapters within "common irq" mode, we have to
1165         * determine whether primary or secondary channel is initialized,
1166         * and set the irq handler only in first case.
1167         */
1168        if( dev->base_addr < 0x400 ) {          /* ISA only */
1169                struct net_device  **p = sbni_cards;
1170                for( ;  *p  &&  p < sbni_cards + SBNI_MAX_NUM_CARDS;  ++p )
1171                        if( (*p)->irq == dev->irq &&
1172                            ((*p)->base_addr == dev->base_addr + 4 ||
1173                             (*p)->base_addr == dev->base_addr - 4) &&
1174                            (*p)->flags & IFF_UP ) {
1175
1176                                ((struct net_local *) (netdev_priv(*p)))
1177                                        ->second = dev;
1178                                netdev_notice(dev, "using shared irq with %s\n",
1179                                              (*p)->name);
1180                                nl->state |= FL_SECONDARY;
1181                                goto  handler_attached;
1182                        }
1183        }
1184
1185        if( request_irq(dev->irq, sbni_interrupt, IRQF_SHARED, dev->name, dev) ) {
1186                netdev_err(dev, "unable to get IRQ %d\n", dev->irq);
1187                return  -EAGAIN;
1188        }
1189
1190handler_attached:
1191
1192        spin_lock( &nl->lock );
1193        memset( &dev->stats, 0, sizeof(struct net_device_stats) );
1194        memset( &nl->in_stats, 0, sizeof(struct sbni_in_stats) );
1195
1196        card_start( dev );
1197
1198        netif_start_queue( dev );
1199
1200        /* set timer watchdog */
1201        init_timer( w );
1202        w->expires      = jiffies + SBNI_TIMEOUT;
1203        w->data         = (unsigned long) dev;
1204        w->function     = sbni_watchdog;
1205        add_timer( w );
1206   
1207        spin_unlock( &nl->lock );
1208        return 0;
1209}
1210
1211
1212static int
1213sbni_close( struct net_device  *dev )
1214{
1215        struct net_local  *nl = netdev_priv(dev);
1216
1217        if( nl->second  &&  nl->second->flags & IFF_UP ) {
1218                netdev_notice(dev, "Secondary channel (%s) is active!\n",
1219                              nl->second->name);
1220                return  -EBUSY;
1221        }
1222
1223#ifdef CONFIG_SBNI_MULTILINE
1224        if( nl->state & FL_SLAVE )
1225                emancipate( dev );
1226        else
1227                while( nl->link )       /* it's master device! */
1228                        emancipate( nl->link );
1229#endif
1230
1231        spin_lock( &nl->lock );
1232
1233        nl->second = NULL;
1234        drop_xmit_queue( dev ); 
1235        netif_stop_queue( dev );
1236   
1237        del_timer( &nl->watchdog );
1238
1239        outb( 0, dev->base_addr + CSR0 );
1240
1241        if( !(nl->state & FL_SECONDARY) )
1242                free_irq( dev->irq, dev );
1243        nl->state &= FL_SECONDARY;
1244
1245        spin_unlock( &nl->lock );
1246        return 0;
1247}
1248
1249
1250/*
1251        Valid combinations in CSR0 (for probing):
1252
1253        VALID_DECODER   0000,0011,1011,1010
1254
1255                                        ; 0   ; -
1256                                TR_REQ  ; 1   ; +
1257                        TR_RDY          ; 2   ; -
1258                        TR_RDY  TR_REQ  ; 3   ; +
1259                BU_EMP                  ; 4   ; +
1260                BU_EMP          TR_REQ  ; 5   ; +
1261                BU_EMP  TR_RDY          ; 6   ; -
1262                BU_EMP  TR_RDY  TR_REQ  ; 7   ; +
1263        RC_RDY                          ; 8   ; +
1264        RC_RDY                  TR_REQ  ; 9   ; +
1265        RC_RDY          TR_RDY          ; 10  ; -
1266        RC_RDY          TR_RDY  TR_REQ  ; 11  ; -
1267        RC_RDY  BU_EMP                  ; 12  ; -
1268        RC_RDY  BU_EMP          TR_REQ  ; 13  ; -
1269        RC_RDY  BU_EMP  TR_RDY          ; 14  ; -
1270        RC_RDY  BU_EMP  TR_RDY  TR_REQ  ; 15  ; -
1271*/
1272
1273#define VALID_DECODER (2 + 8 + 0x10 + 0x20 + 0x80 + 0x100 + 0x200)
1274
1275
1276static int
1277sbni_card_probe( unsigned long  ioaddr )
1278{
1279        unsigned char  csr0;
1280
1281        csr0 = inb( ioaddr + CSR0 );
1282        if( csr0 != 0xff  &&  csr0 != 0x00 ) {
1283                csr0 &= ~EN_INT;
1284                if( csr0 & BU_EMP )
1285                        csr0 |= EN_INT;
1286      
1287                if( VALID_DECODER & (1 << (csr0 >> 4)) )
1288                        return  0;
1289        }
1290   
1291        return  -ENODEV;
1292}
1293
1294/* -------------------------------------------------------------------------- */
1295
1296static int
1297sbni_ioctl( struct net_device  *dev,  struct ifreq  *ifr,  int  cmd )
1298{
1299        struct net_local  *nl = netdev_priv(dev);
1300        struct sbni_flags  flags;
1301        int  error = 0;
1302
1303#ifdef CONFIG_SBNI_MULTILINE
1304        struct net_device  *slave_dev;
1305        char  slave_name[ 8 ];
1306#endif
1307  
1308        switch( cmd ) {
1309        case  SIOCDEVGETINSTATS :
1310                if (copy_to_user( ifr->ifr_data, &nl->in_stats,
1311                                        sizeof(struct sbni_in_stats) ))
1312                        error = -EFAULT;
1313                break;
1314
1315        case  SIOCDEVRESINSTATS :
1316                if (!capable(CAP_NET_ADMIN))
1317                        return  -EPERM;
1318                memset( &nl->in_stats, 0, sizeof(struct sbni_in_stats) );
1319                break;
1320
1321        case  SIOCDEVGHWSTATE :
1322                flags.mac_addr  = *(u32 *)(dev->dev_addr + 3);
1323                flags.rate      = nl->csr1.rate;
1324                flags.slow_mode = (nl->state & FL_SLOW_MODE) != 0;
1325                flags.rxl       = nl->cur_rxl_index;
1326                flags.fixed_rxl = nl->delta_rxl == 0;
1327
1328                if (copy_to_user( ifr->ifr_data, &flags, sizeof flags ))
1329                        error = -EFAULT;
1330                break;
1331
1332        case  SIOCDEVSHWSTATE :
1333                if (!capable(CAP_NET_ADMIN))
1334                        return  -EPERM;
1335
1336                spin_lock( &nl->lock );
1337                flags = *(struct sbni_flags*) &ifr->ifr_ifru;
1338                if( flags.fixed_rxl )
1339                        nl->delta_rxl = 0,
1340                        nl->cur_rxl_index = flags.rxl;
1341                else
1342                        nl->delta_rxl = DEF_RXL_DELTA,
1343                        nl->cur_rxl_index = DEF_RXL;
1344
1345                nl->csr1.rxl = rxl_tab[ nl->cur_rxl_index ];
1346                nl->csr1.rate = flags.rate;
1347                outb( *(u8 *)&nl->csr1 | PR_RES, dev->base_addr + CSR1 );
1348                spin_unlock( &nl->lock );
1349                break;
1350
1351#ifdef CONFIG_SBNI_MULTILINE
1352
1353        case  SIOCDEVENSLAVE :
1354                if (!capable(CAP_NET_ADMIN))
1355                        return  -EPERM;
1356
1357                if (copy_from_user( slave_name, ifr->ifr_data, sizeof slave_name ))
1358                        return -EFAULT;
1359                slave_dev = dev_get_by_name(&init_net, slave_name );
1360                if( !slave_dev  ||  !(slave_dev->flags & IFF_UP) ) {
1361                        netdev_err(dev, "trying to enslave non-active device %s\n",
1362                                   slave_name);
1363                        return  -EPERM;
1364                }
1365
1366                return  enslave( dev, slave_dev );
1367
1368        case  SIOCDEVEMANSIPATE :
1369                if (!capable(CAP_NET_ADMIN))
1370                        return  -EPERM;
1371
1372                return  emancipate( dev );
1373
1374#endif  /* CONFIG_SBNI_MULTILINE */
1375
1376        default :
1377                return  -EOPNOTSUPP;
1378        }
1379
1380        return  error;
1381}
1382
1383
1384#ifdef CONFIG_SBNI_MULTILINE
1385
1386static int
1387enslave( struct net_device  *dev,  struct net_device  *slave_dev )
1388{
1389        struct net_local  *nl  = netdev_priv(dev);
1390        struct net_local  *snl = netdev_priv(slave_dev);
1391
1392        if( nl->state & FL_SLAVE )      /* This isn't master or free device */
1393                return  -EBUSY;
1394
1395        if( snl->state & FL_SLAVE )     /* That was already enslaved */
1396                return  -EBUSY;
1397
1398        spin_lock( &nl->lock );
1399        spin_lock( &snl->lock );
1400
1401        /* append to list */
1402        snl->link = nl->link;
1403        nl->link  = slave_dev;
1404        snl->master = dev;
1405        snl->state |= FL_SLAVE;
1406
1407        /* Summary statistics of MultiLine operation will be stored
1408           in master's counters */
1409        memset( &slave_dev->stats, 0, sizeof(struct net_device_stats) );
1410        netif_stop_queue( slave_dev );
1411        netif_wake_queue( dev );        /* Now we are able to transmit */
1412
1413        spin_unlock( &snl->lock );
1414        spin_unlock( &nl->lock );
1415        netdev_notice(dev, "slave device (%s) attached\n", slave_dev->name);
1416        return  0;
1417}
1418
1419
1420static int
1421emancipate( struct net_device  *dev )
1422{
1423        struct net_local   *snl = netdev_priv(dev);
1424        struct net_device  *p   = snl->master;
1425        struct net_local   *nl  = netdev_priv(p);
1426
1427        if( !(snl->state & FL_SLAVE) )
1428                return  -EINVAL;
1429
1430        spin_lock( &nl->lock );
1431        spin_lock( &snl->lock );
1432        drop_xmit_queue( dev );
1433
1434        /* exclude from list */
1435        for(;;) {       /* must be in list */
1436                struct net_local  *t = netdev_priv(p);
1437                if( t->link == dev ) {
1438                        t->link = snl->link;
1439                        break;
1440                }
1441                p = t->link;
1442        }
1443
1444        snl->link = NULL;
1445        snl->master = dev;
1446        snl->state &= ~FL_SLAVE;
1447
1448        netif_start_queue( dev );
1449
1450        spin_unlock( &snl->lock );
1451        spin_unlock( &nl->lock );
1452
1453        dev_put( dev );
1454        return  0;
1455}
1456
1457#endif
1458
1459static void
1460set_multicast_list( struct net_device  *dev )
1461{
1462        return;         /* sbni always operate in promiscuos mode */
1463}
1464
1465
1466#ifdef MODULE
1467module_param_array(io, int, NULL, 0);
1468module_param_array(irq, int, NULL, 0);
1469module_param_array(baud, int, NULL, 0);
1470module_param_array(rxl, int, NULL, 0);
1471module_param_array(mac, int, NULL, 0);
1472module_param(skip_pci_probe, bool, 0);
1473
1474MODULE_LICENSE("GPL");
1475
1476
1477int __init init_module( void )
1478{
1479        struct net_device  *dev;
1480        int err;
1481
1482        while( num < SBNI_MAX_NUM_CARDS ) {
1483                dev = alloc_netdev(sizeof(struct net_local), 
1484                                   "sbni%d", sbni_devsetup);
1485                if( !dev)
1486                        break;
1487
1488                sprintf( dev->name, "sbni%d", num );
1489
1490                err = sbni_init(dev);
1491                if (err) {
1492                        free_netdev(dev);
1493                        break;
1494                }
1495
1496                if( register_netdev( dev ) ) {
1497                        release_region( dev->base_addr, SBNI_IO_EXTENT );
1498                        free_netdev( dev );
1499                        break;
1500                }
1501        }
1502
1503        return  *sbni_cards  ?  0  :  -ENODEV;
1504}
1505
1506void
1507cleanup_module(void)
1508{
1509        int i;
1510
1511        for (i = 0;  i < SBNI_MAX_NUM_CARDS;  ++i) {
1512                struct net_device *dev = sbni_cards[i];
1513                if (dev != NULL) {
1514                        unregister_netdev(dev);
1515                        release_region(dev->base_addr, SBNI_IO_EXTENT);
1516                        free_netdev(dev);
1517                }
1518        }
1519}
1520
1521#else   /* MODULE */
1522
1523static int __init
1524sbni_setup( char  *p )
1525{
1526        int  n, parm;
1527
1528        if( *p++ != '(' )
1529                goto  bad_param;
1530
1531        for( n = 0, parm = 0;  *p  &&  n < 8; ) {
1532                (*dest[ parm ])[ n ] = simple_strtol( p, &p, 0 );
1533                if( !*p  ||  *p == ')' )
1534                        return 1;
1535                if( *p == ';' )
1536                        ++p, ++n, parm = 0;
1537                else if( *p++ != ',' )
1538                        break;
1539                else
1540                        if( ++parm >= 5 )
1541                                break;
1542        }
1543bad_param:
1544        pr_err("Error in sbni kernel parameter!\n");
1545        return 0;
1546}
1547
1548__setup( "sbni=", sbni_setup );
1549
1550#endif  /* MODULE */
1551
1552/* -------------------------------------------------------------------------- */
1553
1554#ifdef ASM_CRC
1555
1556static u32
1557calc_crc32( u32  crc,  u8  *p,  u32  len )
1558{
1559        register u32  _crc;
1560        _crc = crc;
1561        
1562        __asm__ __volatile__ (
1563                "xorl   %%ebx, %%ebx\n"
1564                "movl   %2, %%esi\n" 
1565                "movl   %3, %%ecx\n" 
1566                "movl   $crc32tab, %%edi\n"
1567                "shrl   $2, %%ecx\n"
1568                "jz     1f\n"
1569
1570                ".align 4\n"
1571        "0:\n"
1572                "movb   %%al, %%bl\n"
1573                "movl   (%%esi), %%edx\n"
1574                "shrl   $8, %%eax\n"
1575                "xorb   %%dl, %%bl\n"
1576                "shrl   $8, %%edx\n"
1577                "xorl   (%%edi,%%ebx,4), %%eax\n"
1578
1579                "movb   %%al, %%bl\n"
1580                "shrl   $8, %%eax\n"
1581                "xorb   %%dl, %%bl\n"
1582                "shrl   $8, %%edx\n"
1583                "xorl   (%%edi,%%ebx,4), %%eax\n"
1584
1585                "movb   %%al, %%bl\n"
1586                "shrl   $8, %%eax\n"
1587                "xorb   %%dl, %%bl\n"
1588                "movb   %%dh, %%dl\n" 
1589                "xorl   (%%edi,%%ebx,4), %%eax\n"
1590
1591                "movb   %%al, %%bl\n"
1592                "shrl   $8, %%eax\n"
1593                "xorb   %%dl, %%bl\n"
1594                "addl   $4, %%esi\n"
1595                "xorl   (%%edi,%%ebx,4), %%eax\n"
1596
1597                "decl   %%ecx\n"
1598                "jnz    0b\n"
1599
1600        "1:\n"
1601                "movl   %3, %%ecx\n"
1602                "andl   $3, %%ecx\n"
1603                "jz     2f\n"
1604
1605                "movb   %%al, %%bl\n"
1606                "shrl   $8, %%eax\n"
1607                "xorb   (%%esi), %%bl\n"
1608                "xorl   (%%edi,%%ebx,4), %%eax\n"
1609
1610                "decl   %%ecx\n"
1611                "jz     2f\n"
1612
1613                "movb   %%al, %%bl\n"
1614                "shrl   $8, %%eax\n"
1615                "xorb   1(%%esi), %%bl\n"
1616                "xorl   (%%edi,%%ebx,4), %%eax\n"
1617
1618                "decl   %%ecx\n"
1619                "jz     2f\n"
1620
1621                "movb   %%al, %%bl\n"
1622                "shrl   $8, %%eax\n"
1623                "xorb   2(%%esi), %%bl\n"
1624                "xorl   (%%edi,%%ebx,4), %%eax\n"
1625        "2:\n"
1626                : "=a" (_crc)
1627                : "0" (_crc), "g" (p), "g" (len)
1628                : "bx", "cx", "dx", "si", "di"
1629        );
1630
1631        return  _crc;
1632}
1633
1634#else   /* ASM_CRC */
1635
1636static u32
1637calc_crc32( u32  crc,  u8  *p,  u32  len )
1638{
1639        while( len-- )
1640                crc = CRC32( *p++, crc );
1641
1642        return  crc;
1643}
1644
1645#endif  /* ASM_CRC */
1646
1647
1648static u32  crc32tab[] __attribute__ ((aligned(8))) = {
1649        0xD202EF8D,  0xA505DF1B,  0x3C0C8EA1,  0x4B0BBE37,
1650        0xD56F2B94,  0xA2681B02,  0x3B614AB8,  0x4C667A2E,
1651        0xDCD967BF,  0xABDE5729,  0x32D70693,  0x45D03605,
1652        0xDBB4A3A6,  0xACB39330,  0x35BAC28A,  0x42BDF21C,
1653        0xCFB5FFE9,  0xB8B2CF7F,  0x21BB9EC5,  0x56BCAE53,
1654        0xC8D83BF0,  0xBFDF0B66,  0x26D65ADC,  0x51D16A4A,
1655        0xC16E77DB,  0xB669474D,  0x2F6016F7,  0x58672661,
1656        0xC603B3C2,  0xB1048354,  0x280DD2EE,  0x5F0AE278,
1657        0xE96CCF45,  0x9E6BFFD3,  0x0762AE69,  0x70659EFF,
1658        0xEE010B5C,  0x99063BCA,  0x000F6A70,  0x77085AE6,
1659        0xE7B74777,  0x90B077E1,  0x09B9265B,  0x7EBE16CD,
1660        0xE0DA836E,  0x97DDB3F8,  0x0ED4E242,  0x79D3D2D4,
1661        0xF4DBDF21,  0x83DCEFB7,  0x1AD5BE0D,  0x6DD28E9B,
1662        0xF3B61B38,  0x84B12BAE,  0x1DB87A14,  0x6ABF4A82,
1663        0xFA005713,  0x8D076785,  0x140E363F,  0x630906A9,
1664        0xFD6D930A,  0x8A6AA39C,  0x1363F226,  0x6464C2B0,
1665        0xA4DEAE1D,  0xD3D99E8B,  0x4AD0CF31,  0x3DD7FFA7,
1666        0xA3B36A04,  0xD4B45A92,  0x4DBD0B28,  0x3ABA3BBE,
1667        0xAA05262F,  0xDD0216B9,  0x440B4703,  0x330C7795,
1668        0xAD68E236,  0xDA6FD2A0,  0x4366831A,  0x3461B38C,
1669        0xB969BE79,  0xCE6E8EEF,  0x5767DF55,  0x2060EFC3,
1670        0xBE047A60,  0xC9034AF6,  0x500A1B4C,  0x270D2BDA,
1671        0xB7B2364B,  0xC0B506DD,  0x59BC5767,  0x2EBB67F1,
1672        0xB0DFF252,  0xC7D8C2C4,  0x5ED1937E,  0x29D6A3E8,
1673        0x9FB08ED5,  0xE8B7BE43,  0x71BEEFF9,  0x06B9DF6F,
1674        0x98DD4ACC,  0xEFDA7A5A,  0x76D32BE0,  0x01D41B76,
1675        0x916B06E7,  0xE66C3671,  0x7F6567CB,  0x0862575D,
1676        0x9606C2FE,  0xE101F268,  0x7808A3D2,  0x0F0F9344,
1677        0x82079EB1,  0xF500AE27,  0x6C09FF9D,  0x1B0ECF0B,
1678        0x856A5AA8,  0xF26D6A3E,  0x6B643B84,  0x1C630B12,
1679        0x8CDC1683,  0xFBDB2615,  0x62D277AF,  0x15D54739,
1680        0x8BB1D29A,  0xFCB6E20C,  0x65BFB3B6,  0x12B88320,
1681        0x3FBA6CAD,  0x48BD5C3B,  0xD1B40D81,  0xA6B33D17,
1682        0x38D7A8B4,  0x4FD09822,  0xD6D9C998,  0xA1DEF90E,
1683        0x3161E49F,  0x4666D409,  0xDF6F85B3,  0xA868B525,
1684        0x360C2086,  0x410B1010,  0xD80241AA,  0xAF05713C,
1685        0x220D7CC9,  0x550A4C5F,  0xCC031DE5,  0xBB042D73,
1686        0x2560B8D0,  0x52678846,  0xCB6ED9FC,  0xBC69E96A,
1687        0x2CD6F4FB,  0x5BD1C46D,  0xC2D895D7,  0xB5DFA541,
1688        0x2BBB30E2,  0x5CBC0074,  0xC5B551CE,  0xB2B26158,
1689        0x04D44C65,  0x73D37CF3,  0xEADA2D49,  0x9DDD1DDF,
1690        0x03B9887C,  0x74BEB8EA,  0xEDB7E950,  0x9AB0D9C6,
1691        0x0A0FC457,  0x7D08F4C1,  0xE401A57B,  0x930695ED,
1692        0x0D62004E,  0x7A6530D8,  0xE36C6162,  0x946B51F4,
1693        0x19635C01,  0x6E646C97,  0xF76D3D2D,  0x806A0DBB,
1694        0x1E0E9818,  0x6909A88E,  0xF000F934,  0x8707C9A2,
1695        0x17B8D433,  0x60BFE4A5,  0xF9B6B51F,  0x8EB18589,
1696        0x10D5102A,  0x67D220BC,  0xFEDB7106,  0x89DC4190,
1697        0x49662D3D,  0x3E611DAB,  0xA7684C11,  0xD06F7C87,
1698        0x4E0BE924,  0x390CD9B2,  0xA0058808,  0xD702B89E,
1699        0x47BDA50F,  0x30BA9599,  0xA9B3C423,  0xDEB4F4B5,
1700        0x40D06116,  0x37D75180,  0xAEDE003A,  0xD9D930AC,
1701        0x54D13D59,  0x23D60DCF,  0xBADF5C75,  0xCDD86CE3,
1702        0x53BCF940,  0x24BBC9D6,  0xBDB2986C,  0xCAB5A8FA,
1703        0x5A0AB56B,  0x2D0D85FD,  0xB404D447,  0xC303E4D1,
1704        0x5D677172,  0x2A6041E4,  0xB369105E,  0xC46E20C8,
1705        0x72080DF5,  0x050F3D63,  0x9C066CD9,  0xEB015C4F,
1706        0x7565C9EC,  0x0262F97A,  0x9B6BA8C0,  0xEC6C9856,
1707        0x7CD385C7,  0x0BD4B551,  0x92DDE4EB,  0xE5DAD47D,
1708        0x7BBE41DE,  0x0CB97148,  0x95B020F2,  0xE2B71064,
1709        0x6FBF1D91,  0x18B82D07,  0x81B17CBD,  0xF6B64C2B,
1710        0x68D2D988,  0x1FD5E91E,  0x86DCB8A4,  0xF1DB8832,
1711        0x616495A3,  0x1663A535,  0x8F6AF48F,  0xF86DC419,
1712        0x660951BA,  0x110E612C,  0x88073096,  0xFF000000
1713};
1714
1715