linux-bk/drivers/net/3c515.c
<<
>>
Prefs
   1/*
   2        Written 1997-1998 by Donald Becker.
   3
   4        This software may be used and distributed according to the terms
   5        of the GNU General Public License, incorporated herein by reference.
   6
   7        This driver is for the 3Com ISA EtherLink XL "Corkscrew" 3c515 ethercard.
   8
   9        The author may be reached as becker@scyld.com, or C/O
  10        Scyld Computing Corporation
  11        410 Severn Ave., Suite 210
  12        Annapolis MD 21403
  13
  14
  15        2000/2/2- Added support for kernel-level ISAPnP 
  16                by Stephen Frost <sfrost@snowman.net> and Alessandro Zummo
  17        Cleaned up for 2.3.x/softnet by Jeff Garzik and Alan Cox.
  18        
  19        2001/11/17 - Added ethtool support (jgarzik)
  20        
  21        2002/10/28 - Locking updates for 2.5 (alan@redhat.com)
  22
  23*/
  24
  25#define DRV_NAME                "3c515"
  26#define DRV_VERSION             "0.99t-ac"
  27#define DRV_RELDATE             "28-Oct-2002"
  28
  29static char *version =
  30DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " becker@scyld.com and others\n";
  31
  32#define CORKSCREW 1
  33
  34/* "Knobs" that adjust features and parameters. */
  35/* Set the copy breakpoint for the copy-only-tiny-frames scheme.
  36   Setting to > 1512 effectively disables this feature. */
  37static const int rx_copybreak = 200;
  38
  39/* Allow setting MTU to a larger size, bypassing the normal ethernet setup. */
  40static const int mtu = 1500;
  41
  42/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
  43static int max_interrupt_work = 20;
  44
  45/* Enable the automatic media selection code -- usually set. */
  46#define AUTOMEDIA 1
  47
  48/* Allow the use of fragment bus master transfers instead of only
  49   programmed-I/O for Vortex cards.  Full-bus-master transfers are always
  50   enabled by default on Boomerang cards.  If VORTEX_BUS_MASTER is defined,
  51   the feature may be turned on using 'options'. */
  52#define VORTEX_BUS_MASTER
  53
  54/* A few values that may be tweaked. */
  55/* Keep the ring sizes a power of two for efficiency. */
  56#define TX_RING_SIZE    16
  57#define RX_RING_SIZE    16
  58#define PKT_BUF_SZ              1536    /* Size of each temporary Rx buffer. */
  59
  60#include <linux/config.h>
  61#include <linux/module.h>
  62#include <linux/isapnp.h>
  63#include <linux/kernel.h>
  64#include <linux/netdevice.h>
  65#include <linux/string.h>
  66#include <linux/errno.h>
  67#include <linux/in.h>
  68#include <linux/ioport.h>
  69#include <linux/slab.h>
  70#include <linux/skbuff.h>
  71#include <linux/etherdevice.h>
  72#include <linux/interrupt.h>
  73#include <linux/timer.h>
  74#include <linux/ethtool.h>
  75
  76#include <asm/uaccess.h>
  77#include <asm/bitops.h>
  78#include <asm/io.h>
  79#include <asm/dma.h>
  80
  81#define NEW_MULTICAST
  82#include <linux/delay.h>
  83
  84#define MAX_UNITS 8
  85
  86MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
  87MODULE_DESCRIPTION("3Com 3c515 Corkscrew driver");
  88MODULE_LICENSE("GPL");
  89
  90MODULE_PARM(debug, "i");
  91MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
  92MODULE_PARM(rx_copybreak, "i");
  93MODULE_PARM(max_interrupt_work, "i");
  94MODULE_PARM_DESC(debug, "3c515 debug level (0-6)");
  95MODULE_PARM_DESC(options, "3c515: Bits 0-2: media type, bit 3: full duplex, bit 4: bus mastering");
  96MODULE_PARM_DESC(rx_copybreak, "3c515 copy breakpoint for copy-only-tiny-frames");
  97MODULE_PARM_DESC(max_interrupt_work, "3c515 maximum events handled per interrupt");
  98
  99/* "Knobs" for adjusting internal parameters. */
 100/* Put out somewhat more debugging messages. (0 - no msg, 1 minimal msgs). */
 101#define DRIVER_DEBUG 1
 102/* Some values here only for performance evaluation and path-coverage
 103   debugging. */
 104static int rx_nocopy, rx_copy, queued_packet;
 105
 106/* Number of times to check to see if the Tx FIFO has space, used in some
 107   limited cases. */
 108#define WAIT_TX_AVAIL 200
 109
 110/* Operational parameter that usually are not changed. */
 111#define TX_TIMEOUT  40          /* Time in jiffies before concluding Tx hung */
 112
 113/* The size here is somewhat misleading: the Corkscrew also uses the ISA
 114   aliased registers at <base>+0x400.
 115   */
 116#define CORKSCREW_TOTAL_SIZE 0x20
 117
 118#ifdef DRIVER_DEBUG
 119static int corkscrew_debug = DRIVER_DEBUG;
 120#else
 121static int corkscrew_debug = 1;
 122#endif
 123
 124#define CORKSCREW_ID 10
 125
 126/*
 127                                Theory of Operation
 128
 129I. Board Compatibility
 130
 131This device driver is designed for the 3Com 3c515 ISA Fast EtherLink XL,
 1323Com's ISA bus adapter for Fast Ethernet.  Due to the unique I/O port layout,
 133it's not practical to integrate this driver with the other EtherLink drivers.
 134
 135II. Board-specific settings
 136
 137The Corkscrew has an EEPROM for configuration, but no special settings are
 138needed for Linux.
 139
 140III. Driver operation
 141
 142The 3c515 series use an interface that's very similar to the 3c900 "Boomerang"
 143PCI cards, with the bus master interface extensively modified to work with
 144the ISA bus.
 145
 146The card is capable of full-bus-master transfers with separate
 147lists of transmit and receive descriptors, similar to the AMD LANCE/PCnet,
 148DEC Tulip and Intel Speedo3.
 149
 150This driver uses a "RX_COPYBREAK" scheme rather than a fixed intermediate
 151receive buffer.  This scheme allocates full-sized skbuffs as receive
 152buffers.  The value RX_COPYBREAK is used as the copying breakpoint: it is
 153chosen to trade-off the memory wasted by passing the full-sized skbuff to
 154the queue layer for all frames vs. the copying cost of copying a frame to a
 155correctly-sized skbuff.
 156
 157
 158IIIC. Synchronization
 159The driver runs as two independent, single-threaded flows of control.  One
 160is the send-packet routine, which enforces single-threaded use by the netif
 161layer.  The other thread is the interrupt handler, which is single
 162threaded by the hardware and other software.
 163
 164IV. Notes
 165
 166Thanks to Terry Murphy of 3Com for providing documentation and a development
 167board.
 168
 169The names "Vortex", "Boomerang" and "Corkscrew" are the internal 3Com
 170project names.  I use these names to eliminate confusion -- 3Com product
 171numbers and names are very similar and often confused.
 172
 173The new chips support both ethernet (1.5K) and FDDI (4.5K) frame sizes!
 174This driver only supports ethernet frames because of the recent MTU limit
 175of 1.5K, but the changes to support 4.5K are minimal.
 176*/
 177
 178/* Operational definitions.
 179   These are not used by other compilation units and thus are not
 180   exported in a ".h" file.
 181
 182   First the windows.  There are eight register windows, with the command
 183   and status registers available in each.
 184   */
 185#define EL3WINDOW(win_num) outw(SelectWindow + (win_num), ioaddr + EL3_CMD)
 186#define EL3_CMD 0x0e
 187#define EL3_STATUS 0x0e
 188
 189/* The top five bits written to EL3_CMD are a command, the lower
 190   11 bits are the parameter, if applicable.
 191   Note that 11 parameters bits was fine for ethernet, but the new chips
 192   can handle FDDI length frames (~4500 octets) and now parameters count
 193   32-bit 'Dwords' rather than octets. */
 194
 195enum corkscrew_cmd {
 196        TotalReset = 0 << 11, SelectWindow = 1 << 11, StartCoax = 2 << 11,
 197        RxDisable = 3 << 11, RxEnable = 4 << 11, RxReset = 5 << 11,
 198        UpStall = 6 << 11, UpUnstall = (6 << 11) + 1, DownStall = (6 << 11) + 2,
 199        DownUnstall = (6 << 11) + 3, RxDiscard = 8 << 11, TxEnable = 9 << 11, 
 200        TxDisable = 10 << 11, TxReset = 11 << 11, FakeIntr = 12 << 11, 
 201        AckIntr = 13 << 11, SetIntrEnb = 14 << 11, SetStatusEnb = 15 << 11, 
 202        SetRxFilter = 16 << 11, SetRxThreshold = 17 << 11,
 203        SetTxThreshold = 18 << 11, SetTxStart = 19 << 11, StartDMAUp = 20 << 11,
 204        StartDMADown = (20 << 11) + 1, StatsEnable = 21 << 11,
 205        StatsDisable = 22 << 11, StopCoax = 23 << 11,
 206};
 207
 208/* The SetRxFilter command accepts the following classes: */
 209enum RxFilter {
 210        RxStation = 1, RxMulticast = 2, RxBroadcast = 4, RxProm = 8
 211};
 212
 213/* Bits in the general status register. */
 214enum corkscrew_status {
 215        IntLatch = 0x0001, AdapterFailure = 0x0002, TxComplete = 0x0004,
 216        TxAvailable = 0x0008, RxComplete = 0x0010, RxEarly = 0x0020,
 217        IntReq = 0x0040, StatsFull = 0x0080,
 218        DMADone = 1 << 8, DownComplete = 1 << 9, UpComplete = 1 << 10,
 219        DMAInProgress = 1 << 11,        /* DMA controller is still busy. */
 220        CmdInProgress = 1 << 12,        /* EL3_CMD is still busy. */
 221};
 222
 223/* Register window 1 offsets, the window used in normal operation.
 224   On the Corkscrew this window is always mapped at offsets 0x10-0x1f. */
 225enum Window1 {
 226        TX_FIFO = 0x10, RX_FIFO = 0x10, RxErrors = 0x14,
 227        RxStatus = 0x18, Timer = 0x1A, TxStatus = 0x1B,
 228        TxFree = 0x1C,          /* Remaining free bytes in Tx buffer. */
 229};
 230enum Window0 {
 231        Wn0IRQ = 0x08,
 232#if defined(CORKSCREW)
 233        Wn0EepromCmd = 0x200A,  /* Corkscrew EEPROM command register. */
 234        Wn0EepromData = 0x200C, /* Corkscrew EEPROM results register. */
 235#else
 236        Wn0EepromCmd = 10,      /* Window 0: EEPROM command register. */
 237        Wn0EepromData = 12,     /* Window 0: EEPROM results register. */
 238#endif
 239};
 240enum Win0_EEPROM_bits {
 241        EEPROM_Read = 0x80, EEPROM_WRITE = 0x40, EEPROM_ERASE = 0xC0,
 242        EEPROM_EWENB = 0x30,    /* Enable erasing/writing for 10 msec. */
 243        EEPROM_EWDIS = 0x00,    /* Disable EWENB before 10 msec timeout. */
 244};
 245
 246/* EEPROM locations. */
 247enum eeprom_offset {
 248        PhysAddr01 = 0, PhysAddr23 = 1, PhysAddr45 = 2, ModelID = 3,
 249        EtherLink3ID = 7,
 250};
 251
 252enum Window3 {                  /* Window 3: MAC/config bits. */
 253        Wn3_Config = 0, Wn3_MAC_Ctrl = 6, Wn3_Options = 8,
 254};
 255union wn3_config {
 256        int i;
 257        struct w3_config_fields {
 258                unsigned int ram_size:3, ram_width:1, ram_speed:2, rom_size:2;
 259                int pad8:8;
 260                unsigned int ram_split:2, pad18:2, xcvr:3, pad21:1, autoselect:1;
 261                int pad24:7;
 262        } u;
 263};
 264
 265enum Window4 {
 266        Wn4_NetDiag = 6, Wn4_Media = 10,        /* Window 4: Xcvr/media bits. */
 267};
 268enum Win4_Media_bits {
 269        Media_SQE = 0x0008,     /* Enable SQE error counting for AUI. */
 270        Media_10TP = 0x00C0,    /* Enable link beat and jabber for 10baseT. */
 271        Media_Lnk = 0x0080,     /* Enable just link beat for 100TX/100FX. */
 272        Media_LnkBeat = 0x0800,
 273};
 274enum Window7 {                  /* Window 7: Bus Master control. */
 275        Wn7_MasterAddr = 0, Wn7_MasterLen = 6, Wn7_MasterStatus = 12,
 276};
 277
 278/* Boomerang-style bus master control registers.  Note ISA aliases! */
 279enum MasterCtrl {
 280        PktStatus = 0x400, DownListPtr = 0x404, FragAddr = 0x408, FragLen =
 281            0x40c,
 282        TxFreeThreshold = 0x40f, UpPktStatus = 0x410, UpListPtr = 0x418,
 283};
 284
 285/* The Rx and Tx descriptor lists.
 286   Caution Alpha hackers: these types are 32 bits!  Note also the 8 byte
 287   alignment contraint on tx_ring[] and rx_ring[]. */
 288struct boom_rx_desc {
 289        u32 next;
 290        s32 status;
 291        u32 addr;
 292        s32 length;
 293};
 294
 295/* Values for the Rx status entry. */
 296enum rx_desc_status {
 297        RxDComplete = 0x00008000, RxDError = 0x4000,
 298        /* See boomerang_rx() for actual error bits */
 299};
 300
 301struct boom_tx_desc {
 302        u32 next;
 303        s32 status;
 304        u32 addr;
 305        s32 length;
 306};
 307
 308struct corkscrew_private {
 309        const char *product_name;
 310        struct net_device *next_module;
 311        /* The Rx and Tx rings are here to keep them quad-word-aligned. */
 312        struct boom_rx_desc rx_ring[RX_RING_SIZE];
 313        struct boom_tx_desc tx_ring[TX_RING_SIZE];
 314        /* The addresses of transmit- and receive-in-place skbuffs. */
 315        struct sk_buff *rx_skbuff[RX_RING_SIZE];
 316        struct sk_buff *tx_skbuff[TX_RING_SIZE];
 317        unsigned int cur_rx, cur_tx;    /* The next free ring entry */
 318        unsigned int dirty_rx, dirty_tx;/* The ring entries to be free()ed. */
 319        struct net_device_stats stats;
 320        struct sk_buff *tx_skb; /* Packet being eaten by bus master ctrl.  */
 321        struct timer_list timer;        /* Media selection timer. */
 322        int capabilities        ;       /* Adapter capabilities word. */
 323        int options;                    /* User-settable misc. driver options. */
 324        int last_rx_packets;            /* For media autoselection. */
 325        unsigned int available_media:8, /* From Wn3_Options */
 326                media_override:3,       /* Passed-in media type. */
 327                default_media:3,        /* Read from the EEPROM. */
 328                full_duplex:1, autoselect:1, bus_master:1,      /* Vortex can only do a fragment bus-m. */
 329                full_bus_master_tx:1, full_bus_master_rx:1,     /* Boomerang  */
 330                tx_full:1;
 331        spinlock_t lock;
 332};
 333
 334/* The action to take with a media selection timer tick.
 335   Note that we deviate from the 3Com order by checking 10base2 before AUI.
 336 */
 337enum xcvr_types {
 338        XCVR_10baseT = 0, XCVR_AUI, XCVR_10baseTOnly, XCVR_10base2, XCVR_100baseTx,
 339        XCVR_100baseFx, XCVR_MII = 6, XCVR_Default = 8,
 340};
 341
 342static struct media_table {
 343        char *name;
 344        unsigned int media_bits:16,     /* Bits to set in Wn4_Media register. */
 345                mask:8,                 /* The transceiver-present bit in Wn3_Config. */
 346                next:8;                 /* The media type to try next. */
 347        short wait;                     /* Time before we check media status. */
 348} media_tbl[] = {       
 349        { "10baseT", Media_10TP, 0x08, XCVR_10base2, (14 * HZ) / 10 }, 
 350        { "10Mbs AUI", Media_SQE, 0x20, XCVR_Default, (1 * HZ) / 10}, 
 351        { "undefined", 0, 0x80, XCVR_10baseT, 10000}, 
 352        { "10base2", 0, 0x10, XCVR_AUI, (1 * HZ) / 10}, 
 353        { "100baseTX", Media_Lnk, 0x02, XCVR_100baseFx, (14 * HZ) / 10}, 
 354        { "100baseFX", Media_Lnk, 0x04, XCVR_MII, (14 * HZ) / 10}, 
 355        { "MII", 0, 0x40, XCVR_10baseT, 3 * HZ}, 
 356        { "undefined", 0, 0x01, XCVR_10baseT, 10000}, 
 357        { "Default", 0, 0xFF, XCVR_10baseT, 10000},
 358};
 359
 360#ifdef __ISAPNP__
 361static struct isapnp_device_id corkscrew_isapnp_adapters[] = {
 362        {       ISAPNP_ANY_ID, ISAPNP_ANY_ID,
 363                ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5051),
 364                (long) "3Com Fast EtherLink ISA" },
 365        { }     /* terminate list */
 366};
 367
 368MODULE_DEVICE_TABLE(isapnp, corkscrew_isapnp_adapters);
 369
 370static int corkscrew_isapnp_phys_addr[3];
 371
 372static int nopnp;
 373#endif /* __ISAPNP__ */
 374
 375static int corkscrew_scan(struct net_device *dev);
 376static struct net_device *corkscrew_found_device(struct net_device *dev,
 377                                                 int ioaddr, int irq,
 378                                                 int product_index,
 379                                                 int options);
 380static int corkscrew_probe1(struct net_device *dev);
 381static int corkscrew_open(struct net_device *dev);
 382static void corkscrew_timer(unsigned long arg);
 383static int corkscrew_start_xmit(struct sk_buff *skb,
 384                                struct net_device *dev);
 385static int corkscrew_rx(struct net_device *dev);
 386static void corkscrew_timeout(struct net_device *dev);
 387static int boomerang_rx(struct net_device *dev);
 388static irqreturn_t corkscrew_interrupt(int irq, void *dev_id,
 389                                    struct pt_regs *regs);
 390static int corkscrew_close(struct net_device *dev);
 391static void update_stats(int addr, struct net_device *dev);
 392static struct net_device_stats *corkscrew_get_stats(struct net_device *dev);
 393static void set_rx_mode(struct net_device *dev);
 394static struct ethtool_ops netdev_ethtool_ops;
 395
 396
 397/* 
 398   Unfortunately maximizing the shared code between the integrated and
 399   module version of the driver results in a complicated set of initialization
 400   procedures.
 401   init_module() -- modules /  tc59x_init()  -- built-in
 402                The wrappers for corkscrew_scan()
 403   corkscrew_scan()              The common routine that scans for PCI and EISA cards
 404   corkscrew_found_device() Allocate a device structure when we find a card.
 405                                        Different versions exist for modules and built-in.
 406   corkscrew_probe1()           Fill in the device structure -- this is separated
 407                                        so that the modules code can put it in dev->init.
 408*/
 409/* This driver uses 'options' to pass the media type, full-duplex flag, etc. */
 410/* Note: this is the only limit on the number of cards supported!! */
 411static int options[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1, };
 412
 413#ifdef MODULE
 414static int debug = -1;
 415/* A list of all installed Vortex devices, for removing the driver module. */
 416static struct net_device *root_corkscrew_dev;
 417
 418int init_module(void)
 419{
 420        int cards_found;
 421
 422        if (debug >= 0)
 423                corkscrew_debug = debug;
 424        if (corkscrew_debug)
 425                printk(version);
 426
 427        root_corkscrew_dev = NULL;
 428        cards_found = corkscrew_scan(NULL);
 429        return cards_found ? 0 : -ENODEV;
 430}
 431
 432#else
 433int tc515_probe(struct net_device *dev)
 434{
 435        int cards_found = 0;
 436
 437        SET_MODULE_OWNER(dev);
 438
 439        cards_found = corkscrew_scan(dev);
 440
 441        if (corkscrew_debug > 0 && cards_found)
 442                printk(version);
 443
 444        return cards_found ? 0 : -ENODEV;
 445}
 446#endif                          /* not MODULE */
 447
 448static int corkscrew_scan(struct net_device *dev)
 449{
 450        int cards_found = 0;
 451        static int ioaddr;
 452#ifdef __ISAPNP__
 453        short i;
 454        static int pnp_cards;
 455#endif
 456
 457#ifdef __ISAPNP__
 458        if(nopnp == 1)
 459                goto no_pnp;
 460        for(i=0; corkscrew_isapnp_adapters[i].vendor != 0; i++) {
 461                struct pnp_dev *idev = NULL;
 462                int irq;
 463                while((idev = pnp_find_dev(NULL,
 464                                           corkscrew_isapnp_adapters[i].vendor,
 465                                           corkscrew_isapnp_adapters[i].function,
 466                                           idev))) {
 467
 468                        if (pnp_device_attach(idev) < 0)
 469                                continue;
 470                        if (pnp_activate_dev(idev) < 0) {
 471                                printk("pnp activate failed (out of resources?)\n");
 472                                pnp_device_detach(idev);
 473                                return -ENOMEM;
 474                        }
 475                        if (!pnp_port_valid(idev, 0) || !pnp_irq_valid(idev, 0)) {
 476                                pnp_device_detach(idev);
 477                                continue;
 478                        }
 479                        ioaddr = pnp_port_start(idev, 0);
 480                        irq = pnp_irq(idev, 0);
 481                        if(corkscrew_debug)
 482                                printk ("ISAPNP reports %s at i/o 0x%x, irq %d\n",
 483                                        (char*) corkscrew_isapnp_adapters[i].driver_data, ioaddr, irq);
 484                                        
 485                        if ((inw(ioaddr + 0x2002) & 0x1f0) != (ioaddr & 0x1f0)) {
 486                                pnp_device_detach(idev);
 487                                continue;
 488                        }
 489                        /* Verify by reading the device ID from the EEPROM. */
 490                        {
 491                                int timer;
 492                                outw(EEPROM_Read + 7, ioaddr + Wn0EepromCmd);
 493                                /* Pause for at least 162 us. for the read to take place. */
 494                                for (timer = 4; timer >= 0; timer--) {
 495                                        udelay(162);
 496                                        if ((inw(ioaddr + Wn0EepromCmd) & 0x0200)
 497                                                == 0)
 498                                                        break;
 499                                }
 500                                if (inw(ioaddr + Wn0EepromData) != 0x6d50) {
 501                                        pnp_device_detach(idev);
 502                                        continue;
 503                                }
 504                        }
 505                        printk(KERN_INFO "3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
 506                                inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
 507                        /* irq = inw(ioaddr + 0x2002) & 15; */ /* Use the irq from isapnp */
 508                        corkscrew_isapnp_phys_addr[pnp_cards] = ioaddr;
 509                        corkscrew_found_device(dev, ioaddr, irq, CORKSCREW_ID, dev
 510                                        && dev->mem_start ? dev->
 511                                        mem_start : options[cards_found]);
 512                        dev = 0;
 513                        pnp_cards++;
 514                        cards_found++;
 515                }
 516        }
 517no_pnp:
 518#endif /* __ISAPNP__ */
 519
 520        /* Check all locations on the ISA bus -- evil! */
 521        for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x20) {
 522                int irq;
 523#ifdef __ISAPNP__
 524                /* Make sure this was not already picked up by isapnp */
 525                if(ioaddr == corkscrew_isapnp_phys_addr[0]) continue;
 526                if(ioaddr == corkscrew_isapnp_phys_addr[1]) continue;
 527                if(ioaddr == corkscrew_isapnp_phys_addr[2]) continue;
 528#endif /* __ISAPNP__ */
 529                if (check_region(ioaddr, CORKSCREW_TOTAL_SIZE))
 530                        continue;
 531                /* Check the resource configuration for a matching ioaddr. */
 532                if ((inw(ioaddr + 0x2002) & 0x1f0) != (ioaddr & 0x1f0))
 533                        continue;
 534                /* Verify by reading the device ID from the EEPROM. */
 535                {
 536                        int timer;
 537                        outw(EEPROM_Read + 7, ioaddr + Wn0EepromCmd);
 538                        /* Pause for at least 162 us. for the read to take place. */
 539                        for (timer = 4; timer >= 0; timer--) {
 540                                udelay(162);
 541                                if ((inw(ioaddr + Wn0EepromCmd) & 0x0200)
 542                                    == 0)
 543                                        break;
 544                        }
 545                        if (inw(ioaddr + Wn0EepromData) != 0x6d50)
 546                                continue;
 547                }
 548                printk(KERN_INFO "3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
 549                     inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
 550                irq = inw(ioaddr + 0x2002) & 15;
 551                corkscrew_found_device(dev, ioaddr, irq, CORKSCREW_ID,
 552                                       dev && dev->mem_start ?  dev->mem_start :
 553                                         (cards_found >= MAX_UNITS ? -1 :
 554                                                options[cards_found]));
 555                dev = 0;
 556                cards_found++;
 557        }
 558        if (corkscrew_debug)
 559                printk(KERN_INFO "%d 3c515 cards found.\n", cards_found);
 560        return cards_found;
 561}
 562
 563static struct net_device *corkscrew_found_device(struct net_device *dev,
 564                                                 int ioaddr, int irq,
 565                                                 int product_index,
 566                                                 int options)
 567{
 568        struct corkscrew_private *vp;
 569
 570#ifdef MODULE
 571        /* Allocate and fill new device structure. */
 572        int dev_size = sizeof(struct net_device) + sizeof(struct corkscrew_private) + 15;       /* Pad for alignment */
 573
 574        dev = (struct net_device *) kmalloc(dev_size, GFP_KERNEL);
 575        if (!dev)
 576                return NULL;
 577        memset(dev, 0, dev_size);
 578        /* Align the Rx and Tx ring entries.  */
 579        dev->priv = (void *) (((long) dev + sizeof(struct net_device) + 15) & ~15);
 580        vp = (struct corkscrew_private *) dev->priv;
 581        dev->base_addr = ioaddr;
 582        dev->irq = irq;
 583        dev->dma = (product_index == CORKSCREW_ID ? inw(ioaddr + 0x2000) & 7 : 0);
 584        dev->init = corkscrew_probe1;
 585        vp->product_name = "3c515";
 586        vp->options = options;
 587        if (options >= 0) {
 588                vp->media_override = ((options & 7) == 2) ? 0 : options & 7;
 589                vp->full_duplex = (options & 8) ? 1 : 0;
 590                vp->bus_master = (options & 16) ? 1 : 0;
 591        } else {
 592                vp->media_override = 7;
 593                vp->full_duplex = 0;
 594                vp->bus_master = 0;
 595        }
 596        ether_setup(dev);
 597        vp->next_module = root_corkscrew_dev;
 598        root_corkscrew_dev = dev;
 599        SET_MODULE_OWNER(dev);
 600        if (register_netdev(dev) != 0) {
 601                kfree(dev);
 602                return NULL;
 603        }
 604#else                           /* not a MODULE */
 605        /* Caution: quad-word alignment required for rings! */
 606        dev->priv = kmalloc(sizeof(struct corkscrew_private), GFP_KERNEL);
 607        if (!dev->priv)
 608                return NULL;
 609        memset(dev->priv, 0, sizeof(struct corkscrew_private));
 610        dev = init_etherdev(dev, sizeof(struct corkscrew_private));
 611        dev->base_addr = ioaddr;
 612        dev->irq = irq;
 613        dev->dma = (product_index == CORKSCREW_ID ? inw(ioaddr + 0x2000) & 7 : 0);
 614        vp = (struct corkscrew_private *) dev->priv;
 615        vp->product_name = "3c515";
 616        vp->options = options;
 617        if (options >= 0) {
 618                vp->media_override = ((options & 7) == 2) ? 0 : options & 7;
 619                vp->full_duplex = (options & 8) ? 1 : 0;
 620                vp->bus_master = (options & 16) ? 1 : 0;
 621        } else {
 622                vp->media_override = 7;
 623                vp->full_duplex = 0;
 624                vp->bus_master = 0;
 625        }
 626
 627        corkscrew_probe1(dev);
 628#endif                          /* MODULE */
 629        return dev;
 630}
 631
 632static int corkscrew_probe1(struct net_device *dev)
 633{
 634        int ioaddr = dev->base_addr;
 635        struct corkscrew_private *vp = (struct corkscrew_private *) dev->priv;
 636        unsigned int eeprom[0x40], checksum = 0;        /* EEPROM contents */
 637        int i;
 638
 639        printk(KERN_INFO "%s: 3Com %s at %#3x,", dev->name, vp->product_name, ioaddr);
 640
 641        spin_lock_init(&vp->lock);
 642        
 643        /* Read the station address from the EEPROM. */
 644        EL3WINDOW(0);
 645        for (i = 0; i < 0x18; i++) {
 646                short *phys_addr = (short *) dev->dev_addr;
 647                int timer;
 648                outw(EEPROM_Read + i, ioaddr + Wn0EepromCmd);
 649                /* Pause for at least 162 us. for the read to take place. */
 650                for (timer = 4; timer >= 0; timer--) {
 651                        udelay(162);
 652                        if ((inw(ioaddr + Wn0EepromCmd) & 0x0200) == 0)
 653                                break;
 654                }
 655                eeprom[i] = inw(ioaddr + Wn0EepromData);
 656                checksum ^= eeprom[i];
 657                if (i < 3)
 658                        phys_addr[i] = htons(eeprom[i]);
 659        }
 660        checksum = (checksum ^ (checksum >> 8)) & 0xff;
 661        if (checksum != 0x00)
 662                printk(" ***INVALID CHECKSUM %4.4x*** ", checksum);
 663        for (i = 0; i < 6; i++)
 664                printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i]);
 665        if (eeprom[16] == 0x11c7) {     /* Corkscrew */
 666                if (request_dma(dev->dma, "3c515")) {
 667                        printk(", DMA %d allocation failed", dev->dma);
 668                        dev->dma = 0;
 669                } else
 670                        printk(", DMA %d", dev->dma);
 671        }
 672        printk(", IRQ %d\n", dev->irq);
 673        /* Tell them about an invalid IRQ. */
 674        if (corkscrew_debug && (dev->irq <= 0 || dev->irq > 15))
 675                printk(KERN_WARNING " *** Warning: this IRQ is unlikely to work! ***\n");
 676
 677        {
 678                char *ram_split[] = { "5:3", "3:1", "1:1", "3:5" };
 679                union wn3_config config;
 680                EL3WINDOW(3);
 681                vp->available_media = inw(ioaddr + Wn3_Options);
 682                config.i = inl(ioaddr + Wn3_Config);
 683                if (corkscrew_debug > 1)
 684                        printk(KERN_INFO "  Internal config register is %4.4x, transceivers %#x.\n",
 685                                config.i, inw(ioaddr + Wn3_Options));
 686                printk(KERN_INFO "  %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
 687                        8 << config.u.ram_size,
 688                        config.u.ram_width ? "word" : "byte",
 689                        ram_split[config.u.ram_split],
 690                        config.u.autoselect ? "autoselect/" : "",
 691                        media_tbl[config.u.xcvr].name);
 692                dev->if_port = config.u.xcvr;
 693                vp->default_media = config.u.xcvr;
 694                vp->autoselect = config.u.autoselect;
 695        }
 696        if (vp->media_override != 7) {
 697                printk(KERN_INFO "  Media override to transceiver type %d (%s).\n",
 698                       vp->media_override,
 699                       media_tbl[vp->media_override].name);
 700                dev->if_port = vp->media_override;
 701        }
 702
 703        vp->capabilities = eeprom[16];
 704        vp->full_bus_master_tx = (vp->capabilities & 0x20) ? 1 : 0;
 705        /* Rx is broken at 10mbps, so we always disable it. */
 706        /* vp->full_bus_master_rx = 0; */
 707        vp->full_bus_master_rx = (vp->capabilities & 0x20) ? 1 : 0;
 708
 709        /* We do a request_region() to register /proc/ioports info. */
 710        request_region(ioaddr, CORKSCREW_TOTAL_SIZE, vp->product_name);
 711
 712        /* The 3c51x-specific entries in the device structure. */
 713        dev->open = &corkscrew_open;
 714        dev->hard_start_xmit = &corkscrew_start_xmit;
 715        dev->tx_timeout = &corkscrew_timeout;
 716        dev->watchdog_timeo = (400 * HZ) / 1000;
 717        dev->stop = &corkscrew_close;
 718        dev->get_stats = &corkscrew_get_stats;
 719        dev->set_multicast_list = &set_rx_mode;
 720        dev->ethtool_ops = &netdev_ethtool_ops;
 721
 722        return 0;
 723}
 724
 725
 726static int corkscrew_open(struct net_device *dev)
 727{
 728        int ioaddr = dev->base_addr;
 729        struct corkscrew_private *vp =
 730            (struct corkscrew_private *) dev->priv;
 731        union wn3_config config;
 732        int i;
 733
 734        /* Before initializing select the active media port. */
 735        EL3WINDOW(3);
 736        if (vp->full_duplex)
 737                outb(0x20, ioaddr + Wn3_MAC_Ctrl);      /* Set the full-duplex bit. */
 738        config.i = inl(ioaddr + Wn3_Config);
 739
 740        if (vp->media_override != 7) {
 741                if (corkscrew_debug > 1)
 742                        printk(KERN_INFO "%s: Media override to transceiver %d (%s).\n",
 743                                dev->name, vp->media_override,
 744                                media_tbl[vp->media_override].name);
 745                dev->if_port = vp->media_override;
 746        } else if (vp->autoselect) {
 747                /* Find first available media type, starting with 100baseTx. */
 748                dev->if_port = 4;
 749                while (!(vp->available_media & media_tbl[dev->if_port].mask)) 
 750                        dev->if_port = media_tbl[dev->if_port].next;
 751
 752                if (corkscrew_debug > 1)
 753                        printk("%s: Initial media type %s.\n",
 754                               dev->name, media_tbl[dev->if_port].name);
 755
 756                init_timer(&vp->timer);
 757                vp->timer.expires = jiffies + media_tbl[dev->if_port].wait;
 758                vp->timer.data = (unsigned long) dev;
 759                vp->timer.function = &corkscrew_timer;  /* timer handler */
 760                add_timer(&vp->timer);
 761        } else
 762                dev->if_port = vp->default_media;
 763
 764        config.u.xcvr = dev->if_port;
 765        outl(config.i, ioaddr + Wn3_Config);
 766
 767        if (corkscrew_debug > 1) {
 768                printk("%s: corkscrew_open() InternalConfig %8.8x.\n",
 769                       dev->name, config.i);
 770        }
 771
 772        outw(TxReset, ioaddr + EL3_CMD);
 773        for (i = 20; i >= 0; i--)
 774                if (!(inw(ioaddr + EL3_STATUS) & CmdInProgress))
 775                        break;
 776
 777        outw(RxReset, ioaddr + EL3_CMD);
 778        /* Wait a few ticks for the RxReset command to complete. */
 779        for (i = 20; i >= 0; i--)
 780                if (!(inw(ioaddr + EL3_STATUS) & CmdInProgress))
 781                        break;
 782
 783        outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
 784
 785        /* Use the now-standard shared IRQ implementation. */
 786        if (vp->capabilities == 0x11c7) {
 787                /* Corkscrew: Cannot share ISA resources. */
 788                if (dev->irq == 0
 789                    || dev->dma == 0
 790                    || request_irq(dev->irq, &corkscrew_interrupt, 0,
 791                                   vp->product_name, dev)) return -EAGAIN;
 792                enable_dma(dev->dma);
 793                set_dma_mode(dev->dma, DMA_MODE_CASCADE);
 794        } else if (request_irq(dev->irq, &corkscrew_interrupt, SA_SHIRQ,
 795                               vp->product_name, dev)) {
 796                return -EAGAIN;
 797        }
 798
 799        if (corkscrew_debug > 1) {
 800                EL3WINDOW(4);
 801                printk("%s: corkscrew_open() irq %d media status %4.4x.\n",
 802                       dev->name, dev->irq, inw(ioaddr + Wn4_Media));
 803        }
 804
 805        /* Set the station address and mask in window 2 each time opened. */
 806        EL3WINDOW(2);
 807        for (i = 0; i < 6; i++)
 808                outb(dev->dev_addr[i], ioaddr + i);
 809        for (; i < 12; i += 2)
 810                outw(0, ioaddr + i);
 811
 812        if (dev->if_port == 3)
 813                /* Start the thinnet transceiver. We should really wait 50ms... */
 814                outw(StartCoax, ioaddr + EL3_CMD);
 815        EL3WINDOW(4);
 816        outw((inw(ioaddr + Wn4_Media) & ~(Media_10TP | Media_SQE)) |
 817             media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media);
 818
 819        /* Switch to the stats window, and clear all stats by reading. */
 820        outw(StatsDisable, ioaddr + EL3_CMD);
 821        EL3WINDOW(6);
 822        for (i = 0; i < 10; i++)
 823                inb(ioaddr + i);
 824        inw(ioaddr + 10);
 825        inw(ioaddr + 12);
 826        /* New: On the Vortex we must also clear the BadSSD counter. */
 827        EL3WINDOW(4);
 828        inb(ioaddr + 12);
 829        /* ..and on the Boomerang we enable the extra statistics bits. */
 830        outw(0x0040, ioaddr + Wn4_NetDiag);
 831
 832        /* Switch to register set 7 for normal use. */
 833        EL3WINDOW(7);
 834
 835        if (vp->full_bus_master_rx) {   /* Boomerang bus master. */
 836                vp->cur_rx = vp->dirty_rx = 0;
 837                if (corkscrew_debug > 2)
 838                        printk("%s:  Filling in the Rx ring.\n",
 839                               dev->name);
 840                for (i = 0; i < RX_RING_SIZE; i++) {
 841                        struct sk_buff *skb;
 842                        if (i < (RX_RING_SIZE - 1))
 843                                vp->rx_ring[i].next =
 844                                    isa_virt_to_bus(&vp->rx_ring[i + 1]);
 845                        else
 846                                vp->rx_ring[i].next = 0;
 847                        vp->rx_ring[i].status = 0;      /* Clear complete bit. */
 848                        vp->rx_ring[i].length = PKT_BUF_SZ | 0x80000000;
 849                        skb = dev_alloc_skb(PKT_BUF_SZ);
 850                        vp->rx_skbuff[i] = skb;
 851                        if (skb == NULL)
 852                                break;  /* Bad news!  */
 853                        skb->dev = dev; /* Mark as being used by this device. */
 854                        skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */
 855                        vp->rx_ring[i].addr = isa_virt_to_bus(skb->tail);
 856                }
 857                vp->rx_ring[i - 1].next = isa_virt_to_bus(&vp->rx_ring[0]);     /* Wrap the ring. */
 858                outl(isa_virt_to_bus(&vp->rx_ring[0]), ioaddr + UpListPtr);
 859        }
 860        if (vp->full_bus_master_tx) {   /* Boomerang bus master Tx. */
 861                vp->cur_tx = vp->dirty_tx = 0;
 862                outb(PKT_BUF_SZ >> 8, ioaddr + TxFreeThreshold);        /* Room for a packet. */
 863                /* Clear the Tx ring. */
 864                for (i = 0; i < TX_RING_SIZE; i++)
 865                        vp->tx_skbuff[i] = 0;
 866                outl(0, ioaddr + DownListPtr);
 867        }
 868        /* Set receiver mode: presumably accept b-case and phys addr only. */
 869        set_rx_mode(dev);
 870        outw(StatsEnable, ioaddr + EL3_CMD);    /* Turn on statistics. */
 871
 872        netif_start_queue(dev);
 873
 874        outw(RxEnable, ioaddr + EL3_CMD);       /* Enable the receiver. */
 875        outw(TxEnable, ioaddr + EL3_CMD);       /* Enable transmitter. */
 876        /* Allow status bits to be seen. */
 877        outw(SetStatusEnb | AdapterFailure | IntReq | StatsFull |
 878             (vp->full_bus_master_tx ? DownComplete : TxAvailable) |
 879             (vp->full_bus_master_rx ? UpComplete : RxComplete) |
 880             (vp->bus_master ? DMADone : 0), ioaddr + EL3_CMD);
 881        /* Ack all pending events, and set active indicator mask. */
 882        outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
 883             ioaddr + EL3_CMD);
 884        outw(SetIntrEnb | IntLatch | TxAvailable | RxComplete | StatsFull
 885             | (vp->bus_master ? DMADone : 0) | UpComplete | DownComplete,
 886             ioaddr + EL3_CMD);
 887
 888        return 0;
 889}
 890
 891static void corkscrew_timer(unsigned long data)
 892{
 893#ifdef AUTOMEDIA
 894        struct net_device *dev = (struct net_device *) data;
 895        struct corkscrew_private *vp = (struct corkscrew_private *) dev->priv;
 896        int ioaddr = dev->base_addr;
 897        unsigned long flags;
 898        int ok = 0;
 899
 900        if (corkscrew_debug > 1)
 901                printk("%s: Media selection timer tick happened, %s.\n",
 902                       dev->name, media_tbl[dev->if_port].name);
 903
 904        spin_lock_irqsave(&vp->lock, flags);
 905        
 906        {
 907                int old_window = inw(ioaddr + EL3_CMD) >> 13;
 908                int media_status;
 909                EL3WINDOW(4);
 910                media_status = inw(ioaddr + Wn4_Media);
 911                switch (dev->if_port) {
 912                case 0:
 913                case 4:
 914                case 5: /* 10baseT, 100baseTX, 100baseFX  */
 915                        if (media_status & Media_LnkBeat) {
 916                                ok = 1;
 917                                if (corkscrew_debug > 1)
 918                                        printk("%s: Media %s has link beat, %x.\n",
 919                                                dev->name,
 920                                                media_tbl[dev->if_port].name,
 921                                                media_status);
 922                        } else if (corkscrew_debug > 1)
 923                                printk("%s: Media %s is has no link beat, %x.\n",
 924                                        dev->name,
 925                                        media_tbl[dev->if_port].name,
 926                                        media_status);
 927
 928                        break;
 929                default:        /* Other media types handled by Tx timeouts. */
 930                        if (corkscrew_debug > 1)
 931                                printk("%s: Media %s is has no indication, %x.\n",
 932                                        dev->name,
 933                                        media_tbl[dev->if_port].name,
 934                                        media_status);
 935                        ok = 1;
 936                }
 937                if (!ok) {
 938                        union wn3_config config;
 939
 940                        do {
 941                                dev->if_port =
 942                                    media_tbl[dev->if_port].next;
 943                        }
 944                        while (!(vp->available_media & media_tbl[dev->if_port].mask));
 945                        
 946                        if (dev->if_port == 8) {        /* Go back to default. */
 947                                dev->if_port = vp->default_media;
 948                                if (corkscrew_debug > 1)
 949                                        printk("%s: Media selection failing, using default %s port.\n",
 950                                                dev->name,
 951                                                media_tbl[dev->if_port].name);
 952                        } else {
 953                                if (corkscrew_debug > 1)
 954                                        printk("%s: Media selection failed, now trying %s port.\n",
 955                                                dev->name,
 956                                                media_tbl[dev->if_port].name);
 957                                vp->timer.expires = jiffies + media_tbl[dev->if_port].wait;
 958                                add_timer(&vp->timer);
 959                        }
 960                        outw((media_status & ~(Media_10TP | Media_SQE)) |
 961                             media_tbl[dev->if_port].media_bits,
 962                             ioaddr + Wn4_Media);
 963
 964                        EL3WINDOW(3);
 965                        config.i = inl(ioaddr + Wn3_Config);
 966                        config.u.xcvr = dev->if_port;
 967                        outl(config.i, ioaddr + Wn3_Config);
 968
 969                        outw(dev->if_port == 3 ? StartCoax : StopCoax,
 970                             ioaddr + EL3_CMD);
 971                }
 972                EL3WINDOW(old_window);
 973        }
 974        
 975        spin_unlock_irqrestore(&vp->lock, flags);
 976        if (corkscrew_debug > 1)
 977                printk("%s: Media selection timer finished, %s.\n",
 978                       dev->name, media_tbl[dev->if_port].name);
 979
 980#endif                          /* AUTOMEDIA */
 981        return;
 982}
 983
 984static void corkscrew_timeout(struct net_device *dev)
 985{
 986        int i;
 987        struct corkscrew_private *vp =
 988            (struct corkscrew_private *) dev->priv;
 989        int ioaddr = dev->base_addr;
 990
 991        printk(KERN_WARNING
 992               "%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
 993               dev->name, inb(ioaddr + TxStatus),
 994               inw(ioaddr + EL3_STATUS));
 995        /* Slight code bloat to be user friendly. */
 996        if ((inb(ioaddr + TxStatus) & 0x88) == 0x88)
 997                printk(KERN_WARNING
 998                       "%s: Transmitter encountered 16 collisions -- network"
 999                       " network cable problem?\n", dev->name);
1000#ifndef final_version
1001        printk("  Flags; bus-master %d, full %d; dirty %d current %d.\n",
1002               vp->full_bus_master_tx, vp->tx_full, vp->dirty_tx,
1003               vp->cur_tx);
1004        printk("  Down list %8.8x vs. %p.\n", inl(ioaddr + DownListPtr),
1005               &vp->tx_ring[0]);
1006        for (i = 0; i < TX_RING_SIZE; i++) {
1007                printk("  %d: %p  length %8.8x status %8.8x\n", i,
1008                       &vp->tx_ring[i],
1009                       vp->tx_ring[i].length, vp->tx_ring[i].status);
1010        }
1011#endif
1012        /* Issue TX_RESET and TX_START commands. */
1013        outw(TxReset, ioaddr + EL3_CMD);
1014        for (i = 20; i >= 0; i--)
1015                if (!(inw(ioaddr + EL3_STATUS) & CmdInProgress))
1016                        break;
1017        outw(TxEnable, ioaddr + EL3_CMD);
1018        dev->trans_start = jiffies;
1019        vp->stats.tx_errors++;
1020        vp->stats.tx_dropped++;
1021        netif_wake_queue(dev);
1022}
1023
1024static int corkscrew_start_xmit(struct sk_buff *skb,
1025                                struct net_device *dev)
1026{
1027        struct corkscrew_private *vp =
1028            (struct corkscrew_private *) dev->priv;
1029        int ioaddr = dev->base_addr;
1030
1031        /* Block a timer-based transmit from overlapping. */
1032
1033        netif_stop_queue(dev);
1034
1035        if (vp->full_bus_master_tx) {   /* BOOMERANG bus-master */
1036                /* Calculate the next Tx descriptor entry. */
1037                int entry = vp->cur_tx % TX_RING_SIZE;
1038                struct boom_tx_desc *prev_entry;
1039                unsigned long flags, i;
1040
1041                if (vp->tx_full)        /* No room to transmit with */
1042                        return 1;
1043                if (vp->cur_tx != 0)
1044                        prev_entry = &vp->tx_ring[(vp->cur_tx - 1) % TX_RING_SIZE];
1045                else
1046                        prev_entry = NULL;
1047                if (corkscrew_debug > 3)
1048                        printk("%s: Trying to send a packet, Tx index %d.\n",
1049                                dev->name, vp->cur_tx);
1050                /* vp->tx_full = 1; */
1051                vp->tx_skbuff[entry] = skb;
1052                vp->tx_ring[entry].next = 0;
1053                vp->tx_ring[entry].addr = isa_virt_to_bus(skb->data);
1054                vp->tx_ring[entry].length = skb->len | 0x80000000;
1055                vp->tx_ring[entry].status = skb->len | 0x80000000;
1056
1057                spin_lock_irqsave(&vp->lock, flags);
1058                outw(DownStall, ioaddr + EL3_CMD);
1059                /* Wait for the stall to complete. */
1060                for (i = 20; i >= 0; i--)
1061                        if ((inw(ioaddr + EL3_STATUS) & CmdInProgress) == 0) 
1062                                break;
1063                if (prev_entry)
1064                        prev_entry->next = isa_virt_to_bus(&vp->tx_ring[entry]);
1065                if (inl(ioaddr + DownListPtr) == 0) {
1066                        outl(isa_virt_to_bus(&vp->tx_ring[entry]),
1067                             ioaddr + DownListPtr);
1068                        queued_packet++;
1069                }
1070                outw(DownUnstall, ioaddr + EL3_CMD);
1071                spin_unlock_irqrestore(&vp->lock, flags);
1072
1073                vp->cur_tx++;
1074                if (vp->cur_tx - vp->dirty_tx > TX_RING_SIZE - 1)
1075                        vp->tx_full = 1;
1076                else {          /* Clear previous interrupt enable. */
1077                        if (prev_entry)
1078                                prev_entry->status &= ~0x80000000;
1079                        netif_wake_queue(dev);
1080                }
1081                dev->trans_start = jiffies;
1082                return 0;
1083        }
1084        /* Put out the doubleword header... */
1085        outl(skb->len, ioaddr + TX_FIFO);
1086        vp->stats.tx_bytes += skb->len;
1087#ifdef VORTEX_BUS_MASTER
1088        if (vp->bus_master) {
1089                /* Set the bus-master controller to transfer the packet. */
1090                outl((int) (skb->data), ioaddr + Wn7_MasterAddr);
1091                outw((skb->len + 3) & ~3, ioaddr + Wn7_MasterLen);
1092                vp->tx_skb = skb;
1093                outw(StartDMADown, ioaddr + EL3_CMD);
1094                /* queue will be woken at the DMADone interrupt. */
1095        } else {
1096                /* ... and the packet rounded to a doubleword. */
1097                outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
1098                dev_kfree_skb(skb);
1099                if (inw(ioaddr + TxFree) > 1536) {
1100                        netif_wake_queue(dev);
1101                } else
1102                        /* Interrupt us when the FIFO has room for max-sized packet. */
1103                        outw(SetTxThreshold + (1536 >> 2),
1104                             ioaddr + EL3_CMD);
1105        }
1106#else
1107        /* ... and the packet rounded to a doubleword. */
1108        outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
1109        dev_kfree_skb(skb);
1110        if (inw(ioaddr + TxFree) > 1536) {
1111                netif_wake_queue(dev);
1112        } else
1113                /* Interrupt us when the FIFO has room for max-sized packet. */
1114                outw(SetTxThreshold + (1536 >> 2), ioaddr + EL3_CMD);
1115#endif                          /* bus master */
1116
1117        dev->trans_start = jiffies;
1118
1119        /* Clear the Tx status stack. */
1120        {
1121                short tx_status;
1122                int i = 4;
1123
1124                while (--i > 0 && (tx_status = inb(ioaddr + TxStatus)) > 0) {
1125                        if (tx_status & 0x3C) { /* A Tx-disabling error occurred.  */
1126                                if (corkscrew_debug > 2)
1127                                        printk("%s: Tx error, status %2.2x.\n",
1128                                                dev->name, tx_status);
1129                                if (tx_status & 0x04)
1130                                        vp->stats.tx_fifo_errors++;
1131                                if (tx_status & 0x38)
1132                                        vp->stats.tx_aborted_errors++;
1133                                if (tx_status & 0x30) {
1134                                        int j;
1135                                        outw(TxReset, ioaddr + EL3_CMD);
1136                                        for (j = 20; j >= 0; j--)
1137                                                if (!(inw(ioaddr + EL3_STATUS) & CmdInProgress)) 
1138                                                        break;
1139                                }
1140                                outw(TxEnable, ioaddr + EL3_CMD);
1141                        }
1142                        outb(0x00, ioaddr + TxStatus);  /* Pop the status stack. */
1143                }
1144        }
1145        return 0;
1146}
1147
1148/* The interrupt handler does all of the Rx thread work and cleans up
1149   after the Tx thread. */
1150
1151static irqreturn_t corkscrew_interrupt(int irq, void *dev_id,
1152                                    struct pt_regs *regs)
1153{
1154        /* Use the now-standard shared IRQ implementation. */
1155        struct net_device *dev = dev_id;
1156        struct corkscrew_private *lp;
1157        int ioaddr, status;
1158        int latency;
1159        int i = max_interrupt_work;
1160
1161        ioaddr = dev->base_addr;
1162        latency = inb(ioaddr + Timer);
1163        lp = (struct corkscrew_private *) dev->priv;
1164
1165        spin_lock(&lp->lock);
1166        
1167        status = inw(ioaddr + EL3_STATUS);
1168
1169        if (corkscrew_debug > 4)
1170                printk("%s: interrupt, status %4.4x, timer %d.\n",
1171                        dev->name, status, latency);
1172        if ((status & 0xE000) != 0xE000) {
1173                static int donedidthis;
1174                /* Some interrupt controllers store a bogus interrupt from boot-time.
1175                   Ignore a single early interrupt, but don't hang the machine for
1176                   other interrupt problems. */
1177                if (donedidthis++ > 100) {
1178                        printk(KERN_ERR "%s: Bogus interrupt, bailing. Status %4.4x, start=%d.\n",
1179                                   dev->name, status, netif_running(dev));
1180                        free_irq(dev->irq, dev);
1181                        dev->irq = -1;
1182                }
1183        }
1184
1185        do {
1186                if (corkscrew_debug > 5)
1187                        printk("%s: In interrupt loop, status %4.4x.\n",
1188                               dev->name, status);
1189                if (status & RxComplete)
1190                        corkscrew_rx(dev);
1191
1192                if (status & TxAvailable) {
1193                        if (corkscrew_debug > 5)
1194                                printk("        TX room bit was handled.\n");
1195                        /* There's room in the FIFO for a full-sized packet. */
1196                        outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
1197                        netif_wake_queue(dev);
1198                }
1199                if (status & DownComplete) {
1200                        unsigned int dirty_tx = lp->dirty_tx;
1201
1202                        while (lp->cur_tx - dirty_tx > 0) {
1203                                int entry = dirty_tx % TX_RING_SIZE;
1204                                if (inl(ioaddr + DownListPtr) == isa_virt_to_bus(&lp->tx_ring[entry]))
1205                                        break;  /* It still hasn't been processed. */
1206                                if (lp->tx_skbuff[entry]) {
1207                                        dev_kfree_skb_irq(lp->tx_skbuff[entry]);
1208                                        lp->tx_skbuff[entry] = 0;
1209                                }
1210                                dirty_tx++;
1211                        }
1212                        lp->dirty_tx = dirty_tx;
1213                        outw(AckIntr | DownComplete, ioaddr + EL3_CMD);
1214                        if (lp->tx_full && (lp->cur_tx - dirty_tx <= TX_RING_SIZE - 1)) {
1215                                lp->tx_full = 0;
1216                                netif_wake_queue(dev);
1217                        }
1218                }
1219#ifdef VORTEX_BUS_MASTER
1220                if (status & DMADone) {
1221                        outw(0x1000, ioaddr + Wn7_MasterStatus);        /* Ack the event. */
1222                        dev_kfree_skb_irq(lp->tx_skb);  /* Release the transferred buffer */
1223                        netif_wake_queue(dev);
1224                }
1225#endif
1226                if (status & UpComplete) {
1227                        boomerang_rx(dev);
1228                        outw(AckIntr | UpComplete, ioaddr + EL3_CMD);
1229                }
1230                if (status & (AdapterFailure | RxEarly | StatsFull)) {
1231                        /* Handle all uncommon interrupts at once. */
1232                        if (status & RxEarly) { /* Rx early is unused. */
1233                                corkscrew_rx(dev);
1234                                outw(AckIntr | RxEarly, ioaddr + EL3_CMD);
1235                        }
1236                        if (status & StatsFull) {       /* Empty statistics. */
1237                                static int DoneDidThat;
1238                                if (corkscrew_debug > 4)
1239                                        printk("%s: Updating stats.\n", dev->name);
1240                                update_stats(ioaddr, dev);
1241                                /* DEBUG HACK: Disable statistics as an interrupt source. */
1242                                /* This occurs when we have the wrong media type! */
1243                                if (DoneDidThat == 0 && inw(ioaddr + EL3_STATUS) & StatsFull) {
1244                                        int win, reg;
1245                                        printk("%s: Updating stats failed, disabling stats as an"
1246                                             " interrupt source.\n", dev->name);
1247                                        for (win = 0; win < 8; win++) {
1248                                                EL3WINDOW(win);
1249                                                printk("\n Vortex window %d:", win);
1250                                                for (reg = 0; reg < 16; reg++)
1251                                                        printk(" %2.2x", inb(ioaddr + reg));
1252                                        }
1253                                        EL3WINDOW(7);
1254                                        outw(SetIntrEnb | TxAvailable |
1255                                             RxComplete | AdapterFailure |
1256                                             UpComplete | DownComplete |
1257                                             TxComplete, ioaddr + EL3_CMD);
1258                                        DoneDidThat++;
1259                                }
1260                        }
1261                        if (status & AdapterFailure) {
1262                                /* Adapter failure requires Rx reset and reinit. */
1263                                outw(RxReset, ioaddr + EL3_CMD);
1264                                /* Set the Rx filter to the current state. */
1265                                set_rx_mode(dev);
1266                                outw(RxEnable, ioaddr + EL3_CMD);       /* Re-enable the receiver. */
1267                                outw(AckIntr | AdapterFailure,
1268                                     ioaddr + EL3_CMD);
1269                        }
1270                }
1271
1272                if (--i < 0) {
1273                        printk(KERN_ERR "%s: Too much work in interrupt, status %4.4x.  "
1274                             "Disabling functions (%4.4x).\n", dev->name,
1275                             status, SetStatusEnb | ((~status) & 0x7FE));
1276                        /* Disable all pending interrupts. */
1277                        outw(SetStatusEnb | ((~status) & 0x7FE), ioaddr + EL3_CMD);
1278                        outw(AckIntr | 0x7FF, ioaddr + EL3_CMD);
1279                        break;
1280                }
1281                /* Acknowledge the IRQ. */
1282                outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
1283
1284        } while ((status = inw(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));
1285        
1286        spin_unlock(&lp->lock);
1287
1288        if (corkscrew_debug > 4)
1289                printk("%s: exiting interrupt, status %4.4x.\n", dev->name, status);
1290        return IRQ_HANDLED;
1291}
1292
1293static int corkscrew_rx(struct net_device *dev)
1294{
1295        struct corkscrew_private *vp = (struct corkscrew_private *) dev->priv;
1296        int ioaddr = dev->base_addr;
1297        int i;
1298        short rx_status;
1299
1300        if (corkscrew_debug > 5)
1301                printk("   In rx_packet(), status %4.4x, rx_status %4.4x.\n",
1302                     inw(ioaddr + EL3_STATUS), inw(ioaddr + RxStatus));
1303        while ((rx_status = inw(ioaddr + RxStatus)) > 0) {
1304                if (rx_status & 0x4000) {       /* Error, update stats. */
1305                        unsigned char rx_error = inb(ioaddr + RxErrors);
1306                        if (corkscrew_debug > 2)
1307                                printk(" Rx error: status %2.2x.\n",
1308                                       rx_error);
1309                        vp->stats.rx_errors++;
1310                        if (rx_error & 0x01)
1311                                vp->stats.rx_over_errors++;
1312                        if (rx_error & 0x02)
1313                                vp->stats.rx_length_errors++;
1314                        if (rx_error & 0x04)
1315                                vp->stats.rx_frame_errors++;
1316                        if (rx_error & 0x08)
1317                                vp->stats.rx_crc_errors++;
1318                        if (rx_error & 0x10)
1319                                vp->stats.rx_length_errors++;
1320                } else {
1321                        /* The packet length: up to 4.5K!. */
1322                        short pkt_len = rx_status & 0x1fff;
1323                        struct sk_buff *skb;
1324
1325                        skb = dev_alloc_skb(pkt_len + 5 + 2);
1326                        if (corkscrew_debug > 4)
1327                                printk("Receiving packet size %d status %4.4x.\n",
1328                                     pkt_len, rx_status);
1329                        if (skb != NULL) {
1330                                skb->dev = dev;
1331                                skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */
1332                                /* 'skb_put()' points to the start of sk_buff data area. */
1333                                insl(ioaddr + RX_FIFO,
1334                                     skb_put(skb, pkt_len),
1335                                     (pkt_len + 3) >> 2);
1336                                outw(RxDiscard, ioaddr + EL3_CMD);      /* Pop top Rx packet. */
1337                                skb->protocol = eth_type_trans(skb, dev);
1338                                netif_rx(skb);
1339                                dev->last_rx = jiffies;
1340                                vp->stats.rx_packets++;
1341                                vp->stats.rx_bytes += pkt_len;
1342                                /* Wait a limited time to go to next packet. */
1343                                for (i = 200; i >= 0; i--)
1344                                        if (! (inw(ioaddr + EL3_STATUS) & CmdInProgress)) 
1345                                                break;
1346                                continue;
1347                        } else if (corkscrew_debug)
1348                                printk("%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, pkt_len);
1349                }
1350                outw(RxDiscard, ioaddr + EL3_CMD);
1351                vp->stats.rx_dropped++;
1352                /* Wait a limited time to skip this packet. */
1353                for (i = 200; i >= 0; i--)
1354                        if (!(inw(ioaddr + EL3_STATUS) & CmdInProgress))
1355                                break;
1356        }
1357        return 0;
1358}
1359
1360static int boomerang_rx(struct net_device *dev)
1361{
1362        struct corkscrew_private *vp =
1363            (struct corkscrew_private *) dev->priv;
1364        int entry = vp->cur_rx % RX_RING_SIZE;
1365        int ioaddr = dev->base_addr;
1366        int rx_status;
1367
1368        if (corkscrew_debug > 5)
1369                printk("   In boomerang_rx(), status %4.4x, rx_status %4.4x.\n",
1370                        inw(ioaddr + EL3_STATUS), inw(ioaddr + RxStatus));
1371        while ((rx_status = vp->rx_ring[entry].status) & RxDComplete) {
1372                if (rx_status & RxDError) {     /* Error, update stats. */
1373                        unsigned char rx_error = rx_status >> 16;
1374                        if (corkscrew_debug > 2)
1375                                printk(" Rx error: status %2.2x.\n",
1376                                       rx_error);
1377                        vp->stats.rx_errors++;
1378                        if (rx_error & 0x01)
1379                                vp->stats.rx_over_errors++;
1380                        if (rx_error & 0x02)
1381                                vp->stats.rx_length_errors++;
1382                        if (rx_error & 0x04)
1383                                vp->stats.rx_frame_errors++;
1384                        if (rx_error & 0x08)
1385                                vp->stats.rx_crc_errors++;
1386                        if (rx_error & 0x10)
1387                                vp->stats.rx_length_errors++;
1388                } else {
1389                        /* The packet length: up to 4.5K!. */
1390                        short pkt_len = rx_status & 0x1fff;
1391                        struct sk_buff *skb;
1392
1393                        vp->stats.rx_bytes += pkt_len;
1394                        if (corkscrew_debug > 4)
1395                                printk("Receiving packet size %d status %4.4x.\n",
1396                                     pkt_len, rx_status);
1397
1398                        /* Check if the packet is long enough to just accept without
1399                           copying to a properly sized skbuff. */
1400                        if (pkt_len < rx_copybreak
1401                            && (skb = dev_alloc_skb(pkt_len + 4)) != 0) {
1402                                skb->dev = dev;
1403                                skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */
1404                                /* 'skb_put()' points to the start of sk_buff data area. */
1405                                memcpy(skb_put(skb, pkt_len),
1406                                       isa_bus_to_virt(vp->rx_ring[entry].
1407                                                   addr), pkt_len);
1408                                rx_copy++;
1409                        } else {
1410                                void *temp;
1411                                /* Pass up the skbuff already on the Rx ring. */
1412                                skb = vp->rx_skbuff[entry];
1413                                vp->rx_skbuff[entry] = NULL;
1414                                temp = skb_put(skb, pkt_len);
1415                                /* Remove this checking code for final release. */
1416                                if (isa_bus_to_virt(vp->rx_ring[entry].addr) != temp)
1417                                            printk("%s: Warning -- the skbuff addresses do not match"
1418                                             " in boomerang_rx: %p vs. %p / %p.\n",
1419                                             dev->name,
1420                                             isa_bus_to_virt(vp->
1421                                                         rx_ring[entry].
1422                                                         addr), skb->head,
1423                                             temp);
1424                                rx_nocopy++;
1425                        }
1426                        skb->protocol = eth_type_trans(skb, dev);
1427                        netif_rx(skb);
1428                        dev->last_rx = jiffies;
1429                        vp->stats.rx_packets++;
1430                }
1431                entry = (++vp->cur_rx) % RX_RING_SIZE;
1432        }
1433        /* Refill the Rx ring buffers. */
1434        for (; vp->cur_rx - vp->dirty_rx > 0; vp->dirty_rx++) {
1435                struct sk_buff *skb;
1436                entry = vp->dirty_rx % RX_RING_SIZE;
1437                if (vp->rx_skbuff[entry] == NULL) {
1438                        skb = dev_alloc_skb(PKT_BUF_SZ);
1439                        if (skb == NULL)
1440                                break;  /* Bad news!  */
1441                        skb->dev = dev; /* Mark as being used by this device. */
1442                        skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */
1443                        vp->rx_ring[entry].addr = isa_virt_to_bus(skb->tail);
1444                        vp->rx_skbuff[entry] = skb;
1445                }
1446                vp->rx_ring[entry].status = 0;  /* Clear complete bit. */
1447        }
1448        return 0;
1449}
1450
1451static int corkscrew_close(struct net_device *dev)
1452{
1453        struct corkscrew_private *vp =
1454            (struct corkscrew_private *) dev->priv;
1455        int ioaddr = dev->base_addr;
1456        int i;
1457
1458        netif_stop_queue(dev);
1459
1460        if (corkscrew_debug > 1) {
1461                printk("%s: corkscrew_close() status %4.4x, Tx status %2.2x.\n",
1462                     dev->name, inw(ioaddr + EL3_STATUS),
1463                     inb(ioaddr + TxStatus));
1464                printk("%s: corkscrew close stats: rx_nocopy %d rx_copy %d"
1465                       " tx_queued %d.\n", dev->name, rx_nocopy, rx_copy,
1466                       queued_packet);
1467        }
1468
1469        del_timer(&vp->timer);
1470
1471        /* Turn off statistics ASAP.  We update lp->stats below. */
1472        outw(StatsDisable, ioaddr + EL3_CMD);
1473
1474        /* Disable the receiver and transmitter. */
1475        outw(RxDisable, ioaddr + EL3_CMD);
1476        outw(TxDisable, ioaddr + EL3_CMD);
1477
1478        if (dev->if_port == XCVR_10base2)
1479                /* Turn off thinnet power.  Green! */
1480                outw(StopCoax, ioaddr + EL3_CMD);
1481
1482        free_irq(dev->irq, dev);
1483
1484        outw(SetIntrEnb | 0x0000, ioaddr + EL3_CMD);
1485
1486        update_stats(ioaddr, dev);
1487        if (vp->full_bus_master_rx) {   /* Free Boomerang bus master Rx buffers. */
1488                outl(0, ioaddr + UpListPtr);
1489                for (i = 0; i < RX_RING_SIZE; i++)
1490                        if (vp->rx_skbuff[i]) {
1491                                dev_kfree_skb(vp->rx_skbuff[i]);
1492                                vp->rx_skbuff[i] = 0;
1493                        }
1494        }
1495        if (vp->full_bus_master_tx) {   /* Free Boomerang bus master Tx buffers. */
1496                outl(0, ioaddr + DownListPtr);
1497                for (i = 0; i < TX_RING_SIZE; i++)
1498                        if (vp->tx_skbuff[i]) {
1499                                dev_kfree_skb(vp->tx_skbuff[i]);
1500                                vp->tx_skbuff[i] = 0;
1501                        }
1502        }
1503
1504        return 0;
1505}
1506
1507static struct net_device_stats *corkscrew_get_stats(struct net_device *dev)
1508{
1509        struct corkscrew_private *vp = (struct corkscrew_private *) dev->priv;
1510        unsigned long flags;
1511
1512        if (netif_running(dev)) {
1513                spin_lock_irqsave(&vp->lock, flags);
1514                update_stats(dev->base_addr, dev);
1515                spin_unlock_irqrestore(&vp->lock, flags);
1516        }
1517        return &vp->stats;
1518}
1519
1520/*  Update statistics.
1521        Unlike with the EL3 we need not worry about interrupts changing
1522        the window setting from underneath us, but we must still guard
1523        against a race condition with a StatsUpdate interrupt updating the
1524        table.  This is done by checking that the ASM (!) code generated uses
1525        atomic updates with '+='.
1526        */
1527static void update_stats(int ioaddr, struct net_device *dev)
1528{
1529        struct corkscrew_private *vp =
1530            (struct corkscrew_private *) dev->priv;
1531
1532        /* Unlike the 3c5x9 we need not turn off stats updates while reading. */
1533        /* Switch to the stats window, and read everything. */
1534        EL3WINDOW(6);
1535        vp->stats.tx_carrier_errors += inb(ioaddr + 0);
1536        vp->stats.tx_heartbeat_errors += inb(ioaddr + 1);
1537        /* Multiple collisions. */ inb(ioaddr + 2);
1538        vp->stats.collisions += inb(ioaddr + 3);
1539        vp->stats.tx_window_errors += inb(ioaddr + 4);
1540        vp->stats.rx_fifo_errors += inb(ioaddr + 5);
1541        vp->stats.tx_packets += inb(ioaddr + 6);
1542        vp->stats.tx_packets += (inb(ioaddr + 9) & 0x30) << 4;
1543                                                /* Rx packets   */ inb(ioaddr + 7);
1544                                                /* Must read to clear */
1545        /* Tx deferrals */ inb(ioaddr + 8);
1546        /* Don't bother with register 9, an extension of registers 6&7.
1547           If we do use the 6&7 values the atomic update assumption above
1548           is invalid. */
1549        inw(ioaddr + 10);       /* Total Rx and Tx octets. */
1550        inw(ioaddr + 12);
1551        /* New: On the Vortex we must also clear the BadSSD counter. */
1552        EL3WINDOW(4);
1553        inb(ioaddr + 12);
1554
1555        /* We change back to window 7 (not 1) with the Vortex. */
1556        EL3WINDOW(7);
1557        return;
1558}
1559
1560/* This new version of set_rx_mode() supports v1.4 kernels.
1561   The Vortex chip has no documented multicast filter, so the only
1562   multicast setting is to receive all multicast frames.  At least
1563   the chip has a very clean way to set the mode, unlike many others. */
1564static void set_rx_mode(struct net_device *dev)
1565{
1566        int ioaddr = dev->base_addr;
1567        short new_mode;
1568
1569        if (dev->flags & IFF_PROMISC) {
1570                if (corkscrew_debug > 3)
1571                        printk("%s: Setting promiscuous mode.\n",
1572                               dev->name);
1573                new_mode = SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm;
1574        } else if ((dev->mc_list) || (dev->flags & IFF_ALLMULTI)) {
1575                new_mode = SetRxFilter | RxStation | RxMulticast | RxBroadcast;
1576        } else
1577                new_mode = SetRxFilter | RxStation | RxBroadcast;
1578
1579        outw(new_mode, ioaddr + EL3_CMD);
1580}
1581
1582static void netdev_get_drvinfo(struct net_device *dev,
1583                               struct ethtool_drvinfo *info)
1584{
1585        strcpy(info->driver, DRV_NAME);
1586        strcpy(info->version, DRV_VERSION);
1587        sprintf(info->bus_info, "ISA 0x%lx", dev->base_addr);
1588}
1589
1590static u32 netdev_get_msglevel(struct net_device *dev)
1591{
1592        return corkscrew_debug;
1593}
1594
1595static void netdev_set_msglevel(struct net_device *dev, u32 level)
1596{
1597        corkscrew_debug = level;
1598}
1599
1600static struct ethtool_ops netdev_ethtool_ops = {
1601        .get_drvinfo            = netdev_get_drvinfo,
1602        .get_msglevel           = netdev_get_msglevel,
1603        .set_msglevel           = netdev_set_msglevel,
1604};
1605
1606
1607#ifdef MODULE
1608void cleanup_module(void)
1609{
1610        struct net_device *next_dev;
1611
1612        while (root_corkscrew_dev) {
1613                next_dev =
1614                    ((struct corkscrew_private *) root_corkscrew_dev->
1615                     priv)->next_module;
1616                if (root_corkscrew_dev->dma)
1617                        free_dma(root_corkscrew_dev->dma);
1618                unregister_netdev(root_corkscrew_dev);
1619                outw(TotalReset, root_corkscrew_dev->base_addr + EL3_CMD);
1620                release_region(root_corkscrew_dev->base_addr,
1621                               CORKSCREW_TOTAL_SIZE);
1622                free_netdev(root_corkscrew_dev);
1623                root_corkscrew_dev = next_dev;
1624        }
1625}
1626#endif                          /* MODULE */
1627
1628/*
1629 * Local variables:
1630 *  compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c 3c515.c"
1631 *  c-indent-level: 4
1632 *  tab-width: 4
1633 * End:
1634 */
1635
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.