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

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

unix.superglobalmegacorp.com

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