Annotation of Gnu-Mach/linux/src/drivers/net/3c507.c, revision 1.1.1.3

1.1       root        1: /* 3c507.c: An EtherLink16 device driver for Linux. */
                      2: /*
                      3:        Written 1993,1994 by Donald Becker.
                      4: 
                      5:        Copyright 1993 United States Government as represented by the
                      6:        Director, National Security Agency.
                      7: 
                      8:        This software may be used and distributed according to the terms
                      9:        of the GNU Public License, incorporated herein by reference.
                     10: 
                     11:        The author may be reached as [email protected], or C/O
                     12:        Center of Excellence in Space Data and Information Sciences
                     13:           Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
                     14: 
                     15:        Thanks go to [email protected] ( Patrick Jennings)
                     16:        and [email protected] (Rick Sladkey) for testing and bugfixes.
                     17:        Mark Salazar <[email protected]> made the changes for cards with
                     18:        only 16K packet buffers.
                     19: 
                     20:        Things remaining to do:
                     21:        Verify that the tx and rx buffers don't have fencepost errors.
                     22:        Move the theory of operation and memory map documentation.
                     23:        The statistics need to be updated correctly.
                     24: */
                     25: 
                     26: static const char *version =
                     27:        "3c507.c:v1.10 9/23/94 Donald Becker ([email protected])\n";
                     28: 
                     29: 
                     30: #include <linux/module.h>
                     31: 
                     32: /*
                     33:   Sources:
                     34:        This driver wouldn't have been written with the availability of the
                     35:        Crynwr driver source code.      It provided a known-working implementation
                     36:        that filled in the gaping holes of the Intel documentation.  Three cheers
                     37:        for Russ Nelson.
                     38: 
                     39:        Intel Microcommunications Databook, Vol. 1, 1990.  It provides just enough
                     40:        info that the casual reader might think that it documents the i82586 :-<.
                     41: */
                     42: 
                     43: #include <linux/kernel.h>
                     44: #include <linux/sched.h>
                     45: #include <linux/types.h>
                     46: #include <linux/fcntl.h>
                     47: #include <linux/interrupt.h>
                     48: #include <linux/ptrace.h>
                     49: #include <linux/ioport.h>
                     50: #include <linux/in.h>
                     51: #include <linux/string.h>
                     52: #include <asm/system.h>
                     53: #include <asm/bitops.h>
                     54: #include <asm/io.h>
                     55: #include <asm/dma.h>
                     56: #include <linux/errno.h>
                     57: 
                     58: #include <linux/netdevice.h>
                     59: #include <linux/etherdevice.h>
                     60: #include <linux/skbuff.h>
                     61: #include <linux/malloc.h>
                     62: 
                     63: 
                     64: /* use 0 for production, 1 for verification, 2..7 for debug */
                     65: #ifndef NET_DEBUG
                     66: #define NET_DEBUG 1
                     67: #endif
                     68: static unsigned int net_debug = NET_DEBUG;
                     69: 
                     70: /* A zero-terminated list of common I/O addresses to be probed. */
                     71: static unsigned int netcard_portlist[] =
                     72:        { 0x300, 0x320, 0x340, 0x280, 0};
                     73: 
1.1.1.2   root       74: static void init_rx_bufs(struct device *dev);
                     75: 
1.1       root       76: /*
                     77:                        Details of the i82586.
                     78: 
                     79:    You'll really need the databook to understand the details of this part,
                     80:    but the outline is that the i82586 has two separate processing units.
                     81:    Both are started from a list of three configuration tables, of which only
                     82:    the last, the System Control Block (SCB), is used after reset-time.  The SCB
                     83:    has the following fields:
                     84:                Status word
                     85:                Command word
                     86:                Tx/Command block addr.
                     87:                Rx block addr.
                     88:    The command word accepts the following controls for the Tx and Rx units:
                     89:   */
                     90: 
                     91: #define         CUC_START       0x0100
                     92: #define         CUC_RESUME      0x0200
                     93: #define         CUC_SUSPEND 0x0300
                     94: #define         RX_START        0x0010
                     95: #define         RX_RESUME       0x0020
                     96: #define         RX_SUSPEND      0x0030
                     97: 
                     98: /* The Rx unit uses a list of frame descriptors and a list of data buffer
                     99:    descriptors.  We use full-sized (1518 byte) data buffers, so there is
                    100:    a one-to-one pairing of frame descriptors to buffer descriptors.
                    101: 
                    102:    The Tx ("command") unit executes a list of commands that look like:
                    103:                Status word             Written by the 82586 when the command is done.
                    104:                Command word    Command in lower 3 bits, post-command action in upper 3
                    105:                Link word               The address of the next command.
                    106:                Parameters              (as needed).
                    107: 
                    108:        Some definitions related to the Command Word are:
                    109:  */
                    110: #define CMD_EOL                0x8000                  /* The last command of the list, stop. */
                    111: #define CMD_SUSP       0x4000                  /* Suspend after doing cmd. */
                    112: #define CMD_INTR       0x2000                  /* Interrupt after doing cmd. */
                    113: 
                    114: enum commands {
                    115:        CmdNOp = 0, CmdSASetup = 1, CmdConfigure = 2, CmdMulticastList = 3,
                    116:        CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7};
                    117: 
                    118: /* Information that need to be kept for each board. */
                    119: struct net_local {
                    120:        struct enet_statistics stats;
                    121:        int last_restart;
                    122:        ushort rx_head;
                    123:        ushort rx_tail;
                    124:        ushort tx_head;
                    125:        ushort tx_cmd_link;
                    126:        ushort tx_reap;
                    127: };
                    128: 
                    129: /*
                    130:                Details of the EtherLink16 Implementation
                    131:   The 3c507 is a generic shared-memory i82586 implementation.
                    132:   The host can map 16K, 32K, 48K, or 64K of the 64K memory into
                    133:   0x0[CD][08]0000, or all 64K into 0xF[02468]0000.
                    134:   */
                    135: 
                    136: /* Offsets from the base I/O address. */
                    137: #define        SA_DATA         0       /* Station address data, or 3Com signature. */
                    138: #define MISC_CTRL      6       /* Switch the SA_DATA banks, and bus config bits. */
                    139: #define RESET_IRQ      10      /* Reset the latched IRQ line. */
                    140: #define SIGNAL_CA      11      /* Frob the 82586 Channel Attention line. */
                    141: #define ROM_CONFIG     13
                    142: #define MEM_CONFIG     14
                    143: #define IRQ_CONFIG     15
                    144: #define EL16_IO_EXTENT 16
                    145: 
                    146: /* The ID port is used at boot-time to locate the ethercard. */
                    147: #define ID_PORT                0x100
                    148: 
                    149: /* Offsets to registers in the mailbox (SCB). */
                    150: #define iSCB_STATUS    0x8
                    151: #define iSCB_CMD               0xA
                    152: #define iSCB_CBL               0xC     /* Command BLock offset. */
                    153: #define iSCB_RFA               0xE     /* Rx Frame Area offset. */
                    154: 
                    155: /*  Since the 3c507 maps the shared memory window so that the last byte is
                    156:        at 82586 address FFFF, the first byte is at 82586 address 0, 16K, 32K, or
                    157:        48K corresponding to window sizes of 64K, 48K, 32K and 16K respectively. 
                    158:        We can account for this be setting the 'SBC Base' entry in the ISCP table
                    159:        below for all the 16 bit offset addresses, and also adding the 'SCB Base'
                    160:        value to all 24 bit physical addresses (in the SCP table and the TX and RX
                    161:        Buffer Descriptors).
                    162:                                        -Mark   
                    163:        */
                    164: #define SCB_BASE               ((unsigned)64*1024 - (dev->mem_end - dev->mem_start))
                    165:  
                    166: /*
                    167:   What follows in 'init_words[]' is the "program" that is downloaded to the
                    168:   82586 memory.         It's mostly tables and command blocks, and starts at the
                    169:   reset address 0xfffff6.  This is designed to be similar to the EtherExpress,
                    170:   thus the unusual location of the SCB at 0x0008.
                    171: 
                    172:   Even with the additional "don't care" values, doing it this way takes less
                    173:   program space than initializing the individual tables, and I feel it's much
                    174:   cleaner.
                    175: 
                    176:   The databook is particularly useless for the first two structures, I had
                    177:   to use the Crynwr driver as an example.
                    178: 
                    179:    The memory setup is as follows:
                    180:    */
                    181: 
                    182: #define CONFIG_CMD     0x0018
                    183: #define SET_SA_CMD     0x0024
                    184: #define SA_OFFSET      0x002A
                    185: #define IDLELOOP       0x30
                    186: #define TDR_CMD                0x38
                    187: #define TDR_TIME       0x3C
                    188: #define DUMP_CMD       0x40
                    189: #define DIAG_CMD       0x48
                    190: #define SET_MC_CMD     0x4E
                    191: #define DUMP_DATA      0x56    /* A 170 byte buffer for dump and Set-MC into. */
                    192: 
                    193: #define TX_BUF_START   0x0100
                    194: #define NUM_TX_BUFS    4
                    195: #define TX_BUF_SIZE    (1518+14+20+16) /* packet+header+TBD */
                    196: 
                    197: #define RX_BUF_START   0x2000
                    198: #define RX_BUF_SIZE    (1518+14+18)    /* packet+header+RBD */
                    199: #define RX_BUF_END             (dev->mem_end - dev->mem_start)
                    200: 
                    201: /*
                    202:   That's it: only 86 bytes to set up the beast, including every extra
                    203:   command available.  The 170 byte buffer at DUMP_DATA is shared between the
                    204:   Dump command (called only by the diagnostic program) and the SetMulticastList
                    205:   command. 
                    206: 
                    207:   To complete the memory setup you only have to write the station address at
                    208:   SA_OFFSET and create the Tx & Rx buffer lists.
                    209: 
                    210:   The Tx command chain and buffer list is setup as follows:
                    211:   A Tx command table, with the data buffer pointing to...
                    212:   A Tx data buffer descriptor.  The packet is in a single buffer, rather than
                    213:        chaining together several smaller buffers.
                    214:   A NoOp command, which initially points to itself,
                    215:   And the packet data.
                    216: 
                    217:   A transmit is done by filling in the Tx command table and data buffer,
                    218:   re-writing the NoOp command, and finally changing the offset of the last
                    219:   command to point to the current Tx command.  When the Tx command is finished,
                    220:   it jumps to the NoOp, when it loops until the next Tx command changes the
                    221:   "link offset" in the NoOp.  This way the 82586 never has to go through the
                    222:   slow restart sequence.
                    223: 
                    224:   The Rx buffer list is set up in the obvious ring structure.  We have enough
                    225:   memory (and low enough interrupt latency) that we can avoid the complicated
                    226:   Rx buffer linked lists by alway associating a full-size Rx data buffer with
                    227:   each Rx data frame.
                    228: 
                    229:   I current use four transmit buffers starting at TX_BUF_START (0x0100), and
                    230:   use the rest of memory, from RX_BUF_START to RX_BUF_END, for Rx buffers.
                    231: 
                    232:   */
                    233: 
                    234: unsigned short init_words[] = {
                    235:        /*      System Configuration Pointer (SCP). */
                    236:        0x0000,                                 /* Set bus size to 16 bits. */
                    237:        0,0,                                    /* pad words. */
                    238:        0x0000,0x0000,                  /* ISCP phys addr, set in init_82586_mem(). */
                    239: 
                    240:        /*      Intermediate System Configuration Pointer (ISCP). */
                    241:        0x0001,                                 /* Status word that's cleared when init is done. */
                    242:        0x0008,0,0,                             /* SCB offset, (skip, skip) */
                    243: 
                    244:        /* System Control Block (SCB). */
                    245:        0,0xf000|RX_START|CUC_START,    /* SCB status and cmd. */
                    246:        CONFIG_CMD,                             /* Command list pointer, points to Configure. */
                    247:        RX_BUF_START,                           /* Rx block list. */
                    248:        0,0,0,0,                                /* Error count: CRC, align, buffer, overrun. */
                    249: 
                    250:        /* 0x0018: Configure command.  Change to put MAC data with packet. */
                    251:        0, CmdConfigure,                /* Status, command.             */
                    252:        SET_SA_CMD,                             /* Next command is Set Station Addr. */
                    253:        0x0804,                                 /* "4" bytes of config data, 8 byte FIFO. */
                    254:        0x2e40,                                 /* Magic values, including MAC data location. */
                    255:        0,                                              /* Unused pad word. */
                    256: 
                    257:        /* 0x0024: Setup station address command. */
                    258:        0, CmdSASetup,
                    259:        SET_MC_CMD,                             /* Next command. */
                    260:        0xaa00,0xb000,0x0bad,   /* Station address (to be filled in) */
                    261: 
                    262:        /* 0x0030: NOP, looping back to itself.  Point to first Tx buffer to Tx. */
                    263:        0, CmdNOp, IDLELOOP, 0 /* pad */,
                    264: 
                    265:        /* 0x0038: A unused Time-Domain Reflectometer command. */
                    266:        0, CmdTDR, IDLELOOP, 0,
                    267: 
                    268:        /* 0x0040: An unused Dump State command. */
                    269:        0, CmdDump, IDLELOOP, DUMP_DATA,
                    270: 
                    271:        /* 0x0048: An unused Diagnose command. */
                    272:        0, CmdDiagnose, IDLELOOP,
                    273: 
                    274:        /* 0x004E: An empty set-multicast-list command. */
                    275:        0, CmdMulticastList, IDLELOOP, 0,
                    276: };
                    277: 
                    278: /* Index to functions, as function prototypes. */
                    279: 
                    280: extern int el16_probe(struct device *dev);     /* Called from Space.c */
                    281: 
                    282: static int     el16_probe1(struct device *dev, int ioaddr);
                    283: static int     el16_open(struct device *dev);
                    284: static int     el16_send_packet(struct sk_buff *skb, struct device *dev);
                    285: static void    el16_interrupt(int irq, void *dev_id, struct pt_regs *regs);
                    286: static void el16_rx(struct device *dev);
                    287: static int     el16_close(struct device *dev);
                    288: static struct enet_statistics *el16_get_stats(struct device *dev);
                    289: 
                    290: static void hardware_send_packet(struct device *dev, void *buf, short length);
                    291: void init_82586_mem(struct device *dev);
                    292: 
                    293: 
                    294: #ifdef HAVE_DEVLIST
                    295: struct netdev_entry netcard_drv =
                    296: {"3c507", el16_probe1, EL16_IO_EXTENT, netcard_portlist};
                    297: #endif
                    298: 
                    299: /* Check for a network adaptor of this type, and return '0' iff one exists.
                    300:        If dev->base_addr == 0, probe all likely locations.
                    301:        If dev->base_addr == 1, always return failure.
                    302:        If dev->base_addr == 2, (detachable devices only) allocate space for the
                    303:        device and return success.
                    304:        */
                    305: int
                    306: el16_probe(struct device *dev)
                    307: {
                    308:        int base_addr = dev ? dev->base_addr : 0;
                    309:        int i;
                    310: 
                    311:        if (base_addr > 0x1ff)  /* Check a single specified location. */
                    312:                return el16_probe1(dev, base_addr);
                    313:        else if (base_addr != 0)
                    314:                return ENXIO;           /* Don't probe at all. */
                    315: 
                    316:        for (i = 0; netcard_portlist[i]; i++) {
                    317:                int ioaddr = netcard_portlist[i];
                    318:                if (check_region(ioaddr, EL16_IO_EXTENT))
                    319:                        continue;
                    320:                if (el16_probe1(dev, ioaddr) == 0)
                    321:                        return 0;
                    322:        }
                    323: 
                    324:        return ENODEV;
                    325: }
                    326: 
                    327: int el16_probe1(struct device *dev, int ioaddr)
                    328: {
                    329:        static unsigned char init_ID_done = 0, version_printed = 0;
                    330:        int i, irq, irqval;
                    331: 
                    332:        if (init_ID_done == 0) {
                    333:                ushort lrs_state = 0xff;
                    334:                /* Send the ID sequence to the ID_PORT to enable the board(s). */
                    335:                outb(0x00, ID_PORT);
                    336:                for(i = 0; i < 255; i++) {
                    337:                        outb(lrs_state, ID_PORT);
                    338:                        lrs_state <<= 1;
                    339:                        if (lrs_state & 0x100)
                    340:                                lrs_state ^= 0xe7;
                    341:                }
                    342:                outb(0x00, ID_PORT);
                    343:                init_ID_done = 1;
                    344:        }
                    345: 
                    346:        if (inb(ioaddr) == '*' && inb(ioaddr+1) == '3'
                    347:                && inb(ioaddr+2) == 'C' && inb(ioaddr+3) == 'O')
                    348:                ;
                    349:        else
                    350:                return ENODEV;
                    351: 
                    352:        /* Allocate a new 'dev' if needed. */
                    353:        if (dev == NULL)
                    354:                dev = init_etherdev(0, sizeof(struct net_local));
                    355: 
                    356:        if (net_debug  &&  version_printed++ == 0)
1.1.1.3 ! root      357:                printk("%s", version);
1.1       root      358: 
                    359:        printk("%s: 3c507 at %#x,", dev->name, ioaddr);
                    360: 
                    361:        /* We should make a few more checks here, like the first three octets of
                    362:           the S.A. for the manufacturer's code. */ 
                    363: 
                    364:        irq = inb(ioaddr + IRQ_CONFIG) & 0x0f;
                    365: 
                    366:        irqval = request_irq(irq, &el16_interrupt, 0, "3c507", NULL);
                    367:        if (irqval) {
                    368:                printk ("unable to get IRQ %d (irqval=%d).\n", irq, irqval);
                    369:                return EAGAIN;
                    370:        }
                    371:        
                    372:        /* We've committed to using the board, and can start filling in *dev. */
                    373:        request_region(ioaddr, EL16_IO_EXTENT, "3c507");
                    374:        dev->base_addr = ioaddr;
                    375: 
                    376:        outb(0x01, ioaddr + MISC_CTRL);
                    377:        for (i = 0; i < 6; i++) {
                    378:                dev->dev_addr[i] = inb(ioaddr + i);
                    379:                printk(" %02x", dev->dev_addr[i]);
                    380:        }
                    381: 
                    382:        if ((dev->mem_start & 0xf) > 0)
                    383:                net_debug = dev->mem_start & 7;
                    384: 
                    385: #ifdef MEM_BASE
                    386:        dev->mem_start = MEM_BASE;
                    387:        dev->mem_end = dev->mem_start + 0x10000;
                    388: #else
                    389:        {
                    390:                int base;
                    391:                int size;
                    392:                char mem_config = inb(ioaddr + MEM_CONFIG);
                    393:                if (mem_config & 0x20) {
                    394:                        size = 64*1024;
                    395:                        base = 0xf00000 + (mem_config & 0x08 ? 0x080000
                    396:                                                           : ((mem_config & 3) << 17));
                    397:                } else {
                    398:                        size = ((mem_config & 3) + 1) << 14;
                    399:                        base = 0x0c0000 + ( (mem_config & 0x18) << 12);
                    400:                }
                    401:                dev->mem_start = base;
                    402:                dev->mem_end = base + size;
                    403:        }
                    404: #endif
                    405: 
                    406:        dev->if_port = (inb(ioaddr + ROM_CONFIG) & 0x80) ? 1 : 0;
                    407:        dev->irq = inb(ioaddr + IRQ_CONFIG) & 0x0f;
                    408: 
                    409:        printk(", IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev->irq,
                    410:                   dev->if_port ? "ex" : "in", dev->mem_start, dev->mem_end-1);
                    411: 
                    412:        if (net_debug)
1.1.1.3 ! root      413:                printk("%s", version);
1.1       root      414: 
                    415:        /* Initialize the device structure. */
                    416:        dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
                    417:        if (dev->priv == NULL)
                    418:                return -ENOMEM;
                    419:        memset(dev->priv, 0, sizeof(struct net_local));
                    420: 
                    421:        dev->open               = el16_open;
                    422:        dev->stop               = el16_close;
                    423:        dev->hard_start_xmit = el16_send_packet;
                    424:        dev->get_stats  = el16_get_stats;
                    425: 
                    426:        ether_setup(dev);       /* Generic ethernet behaviour */
                    427:        
                    428:        dev->flags&=~IFF_MULTICAST;     /* Multicast doesn't work */
                    429: 
                    430:        return 0;
                    431: }
                    432: 
                    433: 
                    434: 
                    435: static int
                    436: el16_open(struct device *dev)
                    437: {
                    438:        irq2dev_map[dev->irq] = dev;
                    439: 
                    440:        /* Initialize the 82586 memory and start it. */
                    441:        init_82586_mem(dev);
                    442: 
                    443:        dev->tbusy = 0;
                    444:        dev->interrupt = 0;
                    445:        dev->start = 1;
                    446: 
                    447:        MOD_INC_USE_COUNT;
                    448: 
                    449:        return 0;
                    450: }
                    451: 
                    452: static int
                    453: el16_send_packet(struct sk_buff *skb, struct device *dev)
                    454: {
                    455:        struct net_local *lp = (struct net_local *)dev->priv;
                    456:        int ioaddr = dev->base_addr;
                    457:        short *shmem = (short*)dev->mem_start;
                    458: 
                    459:        if (dev->tbusy) {
                    460:                /* If we get here, some higher level has decided we are broken.
                    461:                   There should really be a "kick me" function call instead. */
                    462:                int tickssofar = jiffies - dev->trans_start;
                    463:                if (tickssofar < 5)
                    464:                        return 1;
                    465:                if (net_debug > 1)
                    466:                        printk("%s: transmit timed out, %s?  ", dev->name,
                    467:                                   shmem[iSCB_STATUS>>1] & 0x8000 ? "IRQ conflict" :
                    468:                                   "network cable problem");
                    469:                /* Try to restart the adaptor. */
                    470:                if (lp->last_restart == lp->stats.tx_packets) {
                    471:                        if (net_debug > 1) printk("Resetting board.\n");
                    472:                        /* Completely reset the adaptor. */
                    473:                        init_82586_mem(dev);
                    474:                } else {
                    475:                        /* Issue the channel attention signal and hope it "gets better". */
                    476:                        if (net_debug > 1) printk("Kicking board.\n");
                    477:                        shmem[iSCB_CMD>>1] = 0xf000|CUC_START|RX_START;
                    478:                        outb(0, ioaddr + SIGNAL_CA);                    /* Issue channel-attn. */
                    479:                        lp->last_restart = lp->stats.tx_packets;
                    480:                }
                    481:                dev->tbusy=0;
                    482:                dev->trans_start = jiffies;
                    483:        }
                    484: 
                    485:        /* If some higher layer thinks we've missed an tx-done interrupt
                    486:           we are passed NULL. Caution: dev_tint() handles the cli()/sti()
                    487:           itself. */
                    488:        if (skb == NULL) {
                    489:                dev_tint(dev);
                    490:                return 0;
                    491:        }
                    492: 
                    493:        /* Block a timer-based transmit from overlapping. */
                    494:        if (set_bit(0, (void*)&dev->tbusy) != 0)
                    495:                printk("%s: Transmitter access conflict.\n", dev->name);
                    496:        else {
                    497:                short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
                    498:                unsigned char *buf = skb->data;
                    499: 
                    500:                /* Disable the 82586's input to the interrupt line. */
                    501:                outb(0x80, ioaddr + MISC_CTRL);
                    502:                hardware_send_packet(dev, buf, length);
                    503:                dev->trans_start = jiffies;
                    504:                /* Enable the 82586 interrupt input. */
                    505:                outb(0x84, ioaddr + MISC_CTRL);
                    506:        }
                    507: 
                    508:        dev_kfree_skb (skb, FREE_WRITE);
                    509: 
                    510:        /* You might need to clean up and record Tx statistics here. */
                    511: 
                    512:        return 0;
                    513: }
                    514: 
                    515: /*     The typical workload of the driver:
                    516:        Handle the network interface interrupts. */
                    517: static void
                    518: el16_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                    519: {
                    520:        struct device *dev = (struct device *)(irq2dev_map[irq]);
                    521:        struct net_local *lp;
                    522:        int ioaddr, status, boguscount = 0;
                    523:        ushort ack_cmd = 0;
                    524:        ushort *shmem;
                    525:        
                    526:        if (dev == NULL) {
                    527:                printk ("net_interrupt(): irq %d for unknown device.\n", irq);
                    528:                return;
                    529:        }
                    530:        dev->interrupt = 1;
                    531:        
                    532:        ioaddr = dev->base_addr;
                    533:        lp = (struct net_local *)dev->priv;
                    534:        shmem = ((ushort*)dev->mem_start);
                    535:        
                    536:        status = shmem[iSCB_STATUS>>1];
                    537:        
                    538:        if (net_debug > 4) {
                    539:                printk("%s: 3c507 interrupt, status %4.4x.\n", dev->name, status);
                    540:        }
                    541: 
                    542:        /* Disable the 82586's input to the interrupt line. */
                    543:        outb(0x80, ioaddr + MISC_CTRL);
                    544: 
                    545:        /* Reap the Tx packet buffers. */
                    546:        while (lp->tx_reap != lp->tx_head) {
                    547:          unsigned short tx_status = shmem[lp->tx_reap>>1];
                    548: 
                    549:          if (tx_status == 0) {
                    550:                if (net_debug > 5)  printk("Couldn't reap %#x.\n", lp->tx_reap);
                    551:                break;
                    552:          }
                    553:          if (tx_status & 0x2000) {
                    554:                lp->stats.tx_packets++;
                    555:                lp->stats.collisions += tx_status & 0xf;
                    556:                dev->tbusy = 0;
                    557:                mark_bh(NET_BH);                /* Inform upper layers. */
                    558:          } else {
                    559:                lp->stats.tx_errors++;
                    560:                if (tx_status & 0x0600)  lp->stats.tx_carrier_errors++;
                    561:                if (tx_status & 0x0100)  lp->stats.tx_fifo_errors++;
                    562:                if (!(tx_status & 0x0040))  lp->stats.tx_heartbeat_errors++;
                    563:                if (tx_status & 0x0020)  lp->stats.tx_aborted_errors++;
                    564:          }
                    565:          if (net_debug > 5)
                    566:                  printk("Reaped %x, Tx status %04x.\n" , lp->tx_reap, tx_status);
                    567:          lp->tx_reap += TX_BUF_SIZE;
                    568:          if (lp->tx_reap > RX_BUF_START - TX_BUF_SIZE)
                    569:                lp->tx_reap = TX_BUF_START;
                    570:          if (++boguscount > 4)
                    571:                break;
                    572:        }
                    573: 
                    574:        if (status & 0x4000) { /* Packet received. */
                    575:                if (net_debug > 5)
                    576:                        printk("Received packet, rx_head %04x.\n", lp->rx_head);
                    577:                el16_rx(dev);
                    578:        }
                    579: 
                    580:        /* Acknowledge the interrupt sources. */
                    581:        ack_cmd = status & 0xf000;
                    582: 
                    583:        if ((status & 0x0700) != 0x0200 && dev->start) {
                    584:                if (net_debug)
                    585:                        printk("%s: Command unit stopped, status %04x, restarting.\n",
                    586:                                   dev->name, status);
                    587:                /* If this ever occurs we should really re-write the idle loop, reset
                    588:                   the Tx list, and do a complete restart of the command unit.
                    589:                   For now we rely on the Tx timeout if the resume doesn't work. */
                    590:                ack_cmd |= CUC_RESUME;
                    591:        }
                    592: 
                    593:        if ((status & 0x0070) != 0x0040  &&  dev->start) {
                    594:                /* The Rx unit is not ready, it must be hung.  Restart the receiver by
                    595:                   initializing the rx buffers, and issuing an Rx start command. */
                    596:                if (net_debug)
                    597:                        printk("%s: Rx unit stopped, status %04x, restarting.\n",
                    598:                                   dev->name, status);
                    599:                init_rx_bufs(dev);
                    600:                shmem[iSCB_RFA >> 1] = RX_BUF_START;
                    601:                ack_cmd |= RX_START;
                    602:        }
                    603: 
                    604:        shmem[iSCB_CMD>>1] = ack_cmd;
                    605:        outb(0, ioaddr + SIGNAL_CA);                    /* Issue channel-attn. */
                    606: 
                    607:        /* Clear the latched interrupt. */
                    608:        outb(0, ioaddr + RESET_IRQ);
                    609: 
                    610:        /* Enable the 82586's interrupt input. */
                    611:        outb(0x84, ioaddr + MISC_CTRL);
                    612: 
                    613:        return;
                    614: }
                    615: 
                    616: static int
                    617: el16_close(struct device *dev)
                    618: {
                    619:        int ioaddr = dev->base_addr;
                    620:        ushort *shmem = (short*)dev->mem_start;
                    621: 
                    622:        dev->tbusy = 1;
                    623:        dev->start = 0;
                    624: 
                    625:        /* Flush the Tx and disable Rx. */
                    626:        shmem[iSCB_CMD >> 1] = RX_SUSPEND | CUC_SUSPEND;
                    627:        outb(0, ioaddr + SIGNAL_CA);
                    628: 
                    629:        /* Disable the 82586's input to the interrupt line. */
                    630:        outb(0x80, ioaddr + MISC_CTRL);
                    631: 
                    632:        /* We always physically use the IRQ line, so we don't do free_irq().
                    633:           We do remove ourselves from the map. */
                    634: 
                    635:        irq2dev_map[dev->irq] = 0;
                    636: 
                    637:        /* Update the statistics here. */
                    638: 
                    639:        MOD_DEC_USE_COUNT;
                    640: 
                    641:        return 0;
                    642: }
                    643: 
                    644: /* Get the current statistics. This may be called with the card open or
                    645:    closed. */
                    646: static struct enet_statistics *
                    647: el16_get_stats(struct device *dev)
                    648: {
                    649:        struct net_local *lp = (struct net_local *)dev->priv;
                    650: 
                    651:        /* ToDo: decide if there are any useful statistics from the SCB. */
                    652: 
                    653:        return &lp->stats;
                    654: }
                    655: 
                    656: /* Initialize the Rx-block list. */
                    657: static void
                    658: init_rx_bufs(struct device *dev)
                    659: {
                    660:        struct net_local *lp = (struct net_local *)dev->priv;
                    661:        unsigned short *write_ptr;
                    662:        unsigned short SCB_base = SCB_BASE;
                    663: 
                    664:        int cur_rxbuf = lp->rx_head = RX_BUF_START;
                    665:        
                    666:        /* Initialize each Rx frame + data buffer. */
                    667:        do {    /* While there is room for one more. */
                    668: 
                    669:          write_ptr = (unsigned short *)(dev->mem_start + cur_rxbuf);
                    670: 
                    671:                *write_ptr++ = 0x0000;                          /* Status */
                    672:                *write_ptr++ = 0x0000;                          /* Command */
                    673:                *write_ptr++ = cur_rxbuf + RX_BUF_SIZE; /* Link */
                    674:                *write_ptr++ = cur_rxbuf + 22;          /* Buffer offset */
                    675:                *write_ptr++ = 0x0000;                          /* Pad for dest addr. */
                    676:                *write_ptr++ = 0x0000;
                    677:                *write_ptr++ = 0x0000;
                    678:                *write_ptr++ = 0x0000;                          /* Pad for source addr. */
                    679:                *write_ptr++ = 0x0000;
                    680:                *write_ptr++ = 0x0000;
                    681:                *write_ptr++ = 0x0000;                          /* Pad for protocol. */
                    682:                
                    683:                *write_ptr++ = 0x0000;                          /* Buffer: Actual count */
                    684:                *write_ptr++ = -1;                                      /* Buffer: Next (none). */
                    685:                *write_ptr++ = cur_rxbuf + 0x20 + SCB_base;     /* Buffer: Address low */
                    686:                *write_ptr++ = 0x0000;
                    687:                /* Finally, the number of bytes in the buffer. */
                    688:                *write_ptr++ = 0x8000 + RX_BUF_SIZE-0x20;
                    689:                
                    690:                lp->rx_tail = cur_rxbuf;
                    691:                cur_rxbuf += RX_BUF_SIZE;
                    692:        } while (cur_rxbuf <= RX_BUF_END - RX_BUF_SIZE);
                    693:        
                    694:        /* Terminate the list by setting the EOL bit, and wrap the pointer to make
                    695:           the list a ring. */
                    696:        write_ptr = (unsigned short *)
                    697:          (dev->mem_start + lp->rx_tail + 2);
                    698:        *write_ptr++ = 0xC000;                                  /* Command, mark as last. */
                    699:        *write_ptr++ = lp->rx_head;                             /* Link */
                    700: 
                    701: }
                    702: 
                    703: void
                    704: init_82586_mem(struct device *dev)
                    705: {
                    706:        struct net_local *lp = (struct net_local *)dev->priv;
                    707:        short ioaddr = dev->base_addr;
                    708:        ushort *shmem = (short*)dev->mem_start;
                    709: 
                    710:        /* Enable loopback to protect the wire while starting up,
                    711:           and hold the 586 in reset during the memory initialization. */
                    712:        outb(0x20, ioaddr + MISC_CTRL);
                    713: 
                    714:        /* Fix the ISCP address and base. */
                    715:        init_words[3] = SCB_BASE;
                    716:        init_words[7] = SCB_BASE;
                    717: 
                    718:        /* Write the words at 0xfff6 (address-aliased to 0xfffff6). */
                    719:        memcpy((void*)dev->mem_end-10, init_words, 10);
                    720: 
                    721:        /* Write the words at 0x0000. */
                    722:        memcpy((char*)dev->mem_start, init_words + 5, sizeof(init_words) - 10);
                    723: 
                    724:        /* Fill in the station address. */
                    725:        memcpy((char*)dev->mem_start+SA_OFFSET, dev->dev_addr,
                    726:                   sizeof(dev->dev_addr));
                    727: 
                    728:        /* The Tx-block list is written as needed.  We just set up the values. */
                    729:        lp->tx_cmd_link = IDLELOOP + 4;
                    730:        lp->tx_head = lp->tx_reap = TX_BUF_START;
                    731: 
                    732:        init_rx_bufs(dev);
                    733: 
                    734:        /* Start the 586 by releasing the reset line, but leave loopback. */
                    735:        outb(0xA0, ioaddr + MISC_CTRL);
                    736: 
                    737:        /* This was time consuming to track down: you need to give two channel
                    738:           attention signals to reliably start up the i82586. */
                    739:        outb(0, ioaddr + SIGNAL_CA);
                    740: 
                    741:        {
                    742:                int boguscnt = 50;
                    743:                while (shmem[iSCB_STATUS>>1] == 0)
                    744:                        if (--boguscnt == 0) {
                    745:                                printk("%s: i82586 initialization timed out with status %04x,"
                    746:                                           "cmd %04x.\n", dev->name,
                    747:                                           shmem[iSCB_STATUS>>1], shmem[iSCB_CMD>>1]);
                    748:                                break;
                    749:                        }
                    750:                /* Issue channel-attn -- the 82586 won't start. */
                    751:                outb(0, ioaddr + SIGNAL_CA);
                    752:        }
                    753: 
                    754:        /* Disable loopback and enable interrupts. */
                    755:        outb(0x84, ioaddr + MISC_CTRL);
                    756:        if (net_debug > 4)
                    757:                printk("%s: Initialized 82586, status %04x.\n", dev->name,
                    758:                           shmem[iSCB_STATUS>>1]);
                    759:        return;
                    760: }
                    761: 
                    762: static void
                    763: hardware_send_packet(struct device *dev, void *buf, short length)
                    764: {
                    765:        struct net_local *lp = (struct net_local *)dev->priv;
                    766:        short ioaddr = dev->base_addr;
                    767:        ushort tx_block = lp->tx_head;
                    768:        ushort *write_ptr =       (ushort *)(dev->mem_start + tx_block);
                    769: 
                    770:        /* Set the write pointer to the Tx block, and put out the header. */
                    771:        *write_ptr++ = 0x0000;                          /* Tx status */
                    772:        *write_ptr++ = CMD_INTR|CmdTx;          /* Tx command */
                    773:        *write_ptr++ = tx_block+16;                     /* Next command is a NoOp. */
                    774:        *write_ptr++ = tx_block+8;                      /* Data Buffer offset. */
                    775: 
                    776:        /* Output the data buffer descriptor. */
                    777:        *write_ptr++ = length | 0x8000;         /* Byte count parameter. */
                    778:        *write_ptr++ = -1;                                      /* No next data buffer. */
                    779:        *write_ptr++ = tx_block+22+SCB_BASE;/* Buffer follows the NoOp command. */
                    780:        *write_ptr++ = 0x0000;                          /* Buffer address high bits (always zero). */
                    781: 
                    782:        /* Output the Loop-back NoOp command. */
                    783:        *write_ptr++ = 0x0000;                          /* Tx status */
                    784:        *write_ptr++ = CmdNOp;                          /* Tx command */
                    785:        *write_ptr++ = tx_block+16;                     /* Next is myself. */
                    786: 
                    787:        /* Output the packet at the write pointer. */
                    788:        memcpy(write_ptr, buf, length);
                    789: 
                    790:        /* Set the old command link pointing to this send packet. */
                    791:        *(ushort*)(dev->mem_start + lp->tx_cmd_link) = tx_block;
                    792:        lp->tx_cmd_link = tx_block + 20;
                    793: 
                    794:        /* Set the next free tx region. */
                    795:        lp->tx_head = tx_block + TX_BUF_SIZE;
                    796:        if (lp->tx_head > RX_BUF_START - TX_BUF_SIZE)
                    797:                lp->tx_head = TX_BUF_START;
                    798: 
                    799:        if (net_debug > 4) {
                    800:                printk("%s: 3c507 @%x send length = %d, tx_block %3x, next %3x.\n",
                    801:                           dev->name, ioaddr, length, tx_block, lp->tx_head);
                    802:        }
                    803: 
                    804:        if (lp->tx_head != lp->tx_reap)
                    805:                dev->tbusy = 0;
                    806: }
                    807: 
                    808: static void
                    809: el16_rx(struct device *dev)
                    810: {
                    811:        struct net_local *lp = (struct net_local *)dev->priv;
                    812:        short *shmem = (short*)dev->mem_start;
                    813:        ushort rx_head = lp->rx_head;
                    814:        ushort rx_tail = lp->rx_tail;
                    815:        ushort boguscount = 10;
                    816:        short frame_status;
                    817: 
                    818:        while ((frame_status = shmem[rx_head>>1]) < 0) {   /* Command complete */
                    819:                ushort *read_frame =  (short *)(dev->mem_start + rx_head);
                    820:                ushort rfd_cmd = read_frame[1];
                    821:                ushort next_rx_frame = read_frame[2];
                    822:                ushort data_buffer_addr = read_frame[3];
                    823:                ushort *data_frame = (short *)(dev->mem_start + data_buffer_addr);
                    824:                ushort pkt_len = data_frame[0];
                    825: 
                    826:                if (rfd_cmd != 0 || data_buffer_addr != rx_head + 22
                    827:                        || (pkt_len & 0xC000) != 0xC000) {
                    828:                        printk("%s: Rx frame at %#x corrupted, status %04x cmd %04x"
                    829:                                   "next %04x data-buf @%04x %04x.\n", dev->name, rx_head,
                    830:                                   frame_status, rfd_cmd, next_rx_frame, data_buffer_addr,
                    831:                                   pkt_len);
                    832:                } else if ((frame_status & 0x2000) == 0) {
                    833:                        /* Frame Rxed, but with error. */
                    834:                        lp->stats.rx_errors++;
                    835:                        if (frame_status & 0x0800) lp->stats.rx_crc_errors++;
                    836:                        if (frame_status & 0x0400) lp->stats.rx_frame_errors++;
                    837:                        if (frame_status & 0x0200) lp->stats.rx_fifo_errors++;
                    838:                        if (frame_status & 0x0100) lp->stats.rx_over_errors++;
                    839:                        if (frame_status & 0x0080) lp->stats.rx_length_errors++;
                    840:                } else {
                    841:                        /* Malloc up new buffer. */
                    842:                        struct sk_buff *skb;
                    843: 
                    844:                        pkt_len &= 0x3fff;
                    845:                        skb = dev_alloc_skb(pkt_len+2);
                    846:                        if (skb == NULL) {
                    847:                                printk("%s: Memory squeeze, dropping packet.\n", dev->name);
                    848:                                lp->stats.rx_dropped++;
                    849:                                break;
                    850:                        }
                    851:                        
                    852:                        skb_reserve(skb,2);
                    853:                        skb->dev = dev;
                    854: 
                    855:                        /* 'skb->data' points to the start of sk_buff data area. */
                    856:                        memcpy(skb_put(skb,pkt_len), data_frame + 5, pkt_len);
                    857:                
                    858:                        skb->protocol=eth_type_trans(skb,dev);
                    859:                        netif_rx(skb);
                    860:                        lp->stats.rx_packets++;
                    861:                }
                    862: 
                    863:                /* Clear the status word and set End-of-List on the rx frame. */
                    864:                read_frame[0] = 0;
                    865:                read_frame[1] = 0xC000;
                    866:                /* Clear the end-of-list on the prev. RFD. */
                    867:                *(short*)(dev->mem_start + rx_tail + 2) = 0x0000;
                    868: 
                    869:                rx_tail = rx_head;
                    870:                rx_head = next_rx_frame;
                    871:                if (--boguscount == 0)
                    872:                        break;
                    873:        }
                    874: 
                    875:        lp->rx_head = rx_head;
                    876:        lp->rx_tail = rx_tail;
                    877: }
                    878: #ifdef MODULE
                    879: static char devicename[9] = { 0, };
                    880: static struct device dev_3c507 = {
                    881:        devicename, /* device name is inserted by linux/drivers/net/net_init.c */
                    882:        0, 0, 0, 0,
                    883:        0, 0,
                    884:        0, 0, 0, NULL, el16_probe
                    885: };
                    886: 
                    887: static int io = 0x300;
                    888: static int irq = 0;
                    889: 
                    890: int init_module(void)
                    891: {
                    892:        if (io == 0)
                    893:                printk("3c507: You should not use auto-probing with insmod!\n");
                    894:        dev_3c507.base_addr = io;
                    895:        dev_3c507.irq       = irq;
                    896:        if (register_netdev(&dev_3c507) != 0) {
                    897:                printk("3c507: register_netdev() returned non-zero.\n");
                    898:                return -EIO;
                    899:        }
                    900:        return 0;
                    901: }
                    902: 
                    903: void
                    904: cleanup_module(void)
                    905: {
                    906:        unregister_netdev(&dev_3c507);
                    907:        kfree(dev_3c507.priv);
                    908:        dev_3c507.priv = NULL;
                    909: 
                    910:        /* If we don't do this, we can't re-insmod it later. */
                    911:        free_irq(dev_3c507.irq, NULL);
                    912:        release_region(dev_3c507.base_addr, EL16_IO_EXTENT);
                    913: }
                    914: #endif /* MODULE */
                    915: 
                    916: /*
                    917:  * Local variables:
                    918:  *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -I/usr/src/linux/drivers/net -Wall -Wstrict-prototypes -O6 -m486 -c 3c507.c"
                    919:  *  version-control: t
                    920:  *  kept-new-versions: 5
                    921:  *  tab-width: 4
                    922:  *  c-indent-level: 4
                    923:  * End:
                    924:  */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.