Annotation of Gnu-Mach/i386/i386at/gpl/linux/net/3c505.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Linux ethernet device driver for the 3Com Etherlink Plus (3C505)
        !             3:  *     By Craig Southeren and Juha Laiho
        !             4:  *
        !             5:  * 3c505.c     This module implements an interface to the 3Com
        !             6:  *             Etherlink Plus (3c505) ethernet card. Linux device 
        !             7:  *             driver interface reverse engineered from the Linux 3C509
        !             8:  *             device drivers. Some 3C505 information gleaned from
        !             9:  *             the Crynwr packet driver. Still this driver would not
        !            10:  *             be here without 3C505 technical reference provided by
        !            11:  *             3Com.
        !            12:  *
        !            13:  * Version:    @(#)3c505.c     0.8.4   17-Dec-95
        !            14:  *
        !            15:  * Authors:    Linux 3c505 device driver by
        !            16:  *                     Craig Southeren, <[email protected]>
        !            17:  *              Final debugging by
        !            18:  *                     Andrew Tridgell, <[email protected]>
        !            19:  *             Auto irq/address, tuning, cleanup and v1.1.4+ kernel mods by
        !            20:  *                     Juha Laiho, <[email protected]>
        !            21:  *              Linux 3C509 driver by
        !            22:  *                             Donald Becker, <[email protected]>
        !            23:  *             Crynwr packet driver by
        !            24:  *                     Krishnan Gopalan and Gregg Stefancik,
        !            25:  *                        Clemson University Engineering Computer Operations.
        !            26:  *                     Portions of the code have been adapted from the 3c505
        !            27:  *                        driver for NCSA Telnet by Bruce Orchard and later
        !            28:  *                        modified by Warren Van Houten and [email protected].
        !            29:  *              3C505 technical information provided by
        !            30:  *                      Terry Murphy, of 3Com Network Adapter Division
        !            31:  *             Linux 1.3.0 changes by
        !            32:  *                     Alan Cox <[email protected]>
        !            33:  *                     
        !            34:  */
        !            35: 
        !            36: #include <linux/module.h>
        !            37: 
        !            38: #include <linux/kernel.h>
        !            39: #include <linux/sched.h>
        !            40: #include <linux/string.h>
        !            41: #include <linux/interrupt.h>
        !            42: #include <linux/ptrace.h>
        !            43: #include <linux/errno.h>
        !            44: #include <linux/in.h>
        !            45: #include <linux/malloc.h>
        !            46: #include <linux/ioport.h>
        !            47: #include <asm/bitops.h>
        !            48: #include <asm/io.h>
        !            49: 
        !            50: #include <linux/netdevice.h>
        !            51: #include <linux/etherdevice.h>
        !            52: #include <linux/skbuff.h>
        !            53: 
        !            54: #include "3c505.h"
        !            55: 
        !            56: /*********************************************************
        !            57:  *
        !            58:  *  define debug messages here as common strings to reduce space
        !            59:  *
        !            60:  *********************************************************/
        !            61: 
        !            62: static const char * filename = __FILE__;
        !            63: 
        !            64: static const char * null_msg = "*** NULL at %s:%s (line %d) ***\n";
        !            65: #define CHECK_NULL(p) \
        !            66:        if (!p) printk(null_msg, filename,__FUNCTION__,__LINE__)
        !            67: 
        !            68: static const char * timeout_msg = "*** timeout at %s:%s (line %d) ***\n";
        !            69: #define TIMEOUT_MSG(lineno) \
        !            70:        printk(timeout_msg, filename,__FUNCTION__,(lineno))
        !            71: 
        !            72: static const char * invalid_pcb_msg =
        !            73:        "*** invalid pcb length %d at %s:%s (line %d) ***\n";
        !            74: #define INVALID_PCB_MSG(len) \
        !            75:        printk(invalid_pcb_msg, (len),filename,__FUNCTION__,__LINE__)
        !            76: 
        !            77: static const char * search_msg = "%s: Looking for 3c505 adapter at address %#x...";
        !            78: 
        !            79: static const char * stilllooking_msg = "still looking...";
        !            80: 
        !            81: static const char * found_msg = "found.\n";
        !            82: 
        !            83: static const char * notfound_msg = "not found (reason = %d)\n";
        !            84: 
        !            85: static const char * couldnot_msg = "%s: 3c505 not found\n";
        !            86: 
        !            87: /*********************************************************
        !            88:  *
        !            89:  *  various other debug stuff
        !            90:  *
        !            91:  *********************************************************/
        !            92: 
        !            93: #ifdef ELP_DEBUG
        !            94: static int elp_debug = ELP_DEBUG;
        !            95: #else
        !            96: static int elp_debug = 0;
        !            97: #endif
        !            98: 
        !            99: /*
        !           100:  *  0 = no messages (well, some)
        !           101:  *  1 = messages when high level commands performed
        !           102:  *  2 = messages when low level commands performed
        !           103:  *  3 = messages when interrupts received
        !           104:  */
        !           105: 
        !           106: #define        ELP_VERSION     "0.8.4"
        !           107: 
        !           108: #ifdef MACH
        !           109: #define ELP_NEED_HARD_RESET 0
        !           110: #endif
        !           111: 
        !           112: /*****************************************************************
        !           113:  *
        !           114:  * useful macros
        !           115:  *
        !           116:  *****************************************************************/
        !           117: 
        !           118: #ifndef        TRUE
        !           119: #define        TRUE    1
        !           120: #endif
        !           121: 
        !           122: #ifndef        FALSE
        !           123: #define        FALSE   0
        !           124: #endif
        !           125: 
        !           126: 
        !           127: /*****************************************************************
        !           128:  *
        !           129:  * List of I/O-addresses we try to auto-sense
        !           130:  * Last element MUST BE 0!
        !           131:  *****************************************************************/
        !           132: 
        !           133: const int addr_list[]={0x300,0x280,0x310,0}; 
        !           134: 
        !           135: /*****************************************************************
        !           136:  *
        !           137:  * Functions for I/O (note the inline !)
        !           138:  *
        !           139:  *****************************************************************/
        !           140: 
        !           141: static inline unsigned char
        !           142: inb_status (unsigned int base_addr)
        !           143: {
        !           144:        return inb(base_addr+PORT_STATUS);
        !           145: }
        !           146: 
        !           147: static inline unsigned char
        !           148: inb_control (unsigned int base_addr)
        !           149: {
        !           150:        return inb(base_addr+PORT_CONTROL);
        !           151: }
        !           152: 
        !           153: static inline int
        !           154: inb_command (unsigned int base_addr)
        !           155: {
        !           156:        return inb(base_addr+PORT_COMMAND);
        !           157: }
        !           158: 
        !           159: static inline void
        !           160: outb_control (unsigned char val, unsigned int base_addr)
        !           161: {
        !           162:        outb(val, base_addr+PORT_CONTROL);
        !           163: }
        !           164: 
        !           165: static inline void
        !           166: outb_command (unsigned char val, unsigned int base_addr)
        !           167: {
        !           168:        outb(val, base_addr+PORT_COMMAND);
        !           169: }
        !           170: 
        !           171: static inline unsigned int
        !           172: inw_data (unsigned int base_addr)
        !           173: {
        !           174:        return inw(base_addr+PORT_DATA);
        !           175: }
        !           176: 
        !           177: static inline void
        !           178: outw_data (unsigned int val, unsigned int base_addr)
        !           179: {
        !           180:        outw(val, base_addr+PORT_DATA);
        !           181: }
        !           182: 
        !           183: 
        !           184: /*****************************************************************
        !           185:  *
        !           186:  *  structure to hold context information for adapter
        !           187:  *
        !           188:  *****************************************************************/
        !           189: 
        !           190: typedef struct {
        !           191:        volatile short got[NUM_TRANSMIT_CMDS];  /* flags for command completion */
        !           192:        pcb_struct tx_pcb;      /* PCB for foreground sending */
        !           193:        pcb_struct rx_pcb;      /* PCB for foreground receiving */
        !           194:        pcb_struct itx_pcb;     /* PCB for background sending */
        !           195:        pcb_struct irx_pcb;     /* PCB for background receiving */
        !           196:        struct enet_statistics stats;
        !           197: } elp_device;
        !           198: 
        !           199: static int reset_count=0;
        !           200: 
        !           201: /*****************************************************************
        !           202:  *
        !           203:  *  useful functions for accessing the adapter
        !           204:  *
        !           205:  *****************************************************************/
        !           206: 
        !           207: /*
        !           208:  * use this routine when accessing the ASF bits as they are
        !           209:  * changed asynchronously by the adapter
        !           210:  */
        !           211: 
        !           212: /* get adapter PCB status */
        !           213: #define        GET_ASF(addr) \
        !           214:        (get_status(addr)&ASF_PCB_MASK)
        !           215: 
        !           216: static inline int
        !           217: get_status (unsigned int base_addr)
        !           218: {
        !           219:        int timeout = jiffies + 10;
        !           220:        register int stat1;
        !           221:        do {
        !           222:                stat1 = inb_status(base_addr);
        !           223:        } while (stat1 != inb_status(base_addr) && jiffies < timeout);
        !           224:        if (jiffies >= timeout)
        !           225:                TIMEOUT_MSG(__LINE__);
        !           226:        return stat1;
        !           227: }
        !           228: 
        !           229: static inline void
        !           230: set_hsf (unsigned int base_addr, int hsf)
        !           231: {
        !           232:        cli();
        !           233:        outb_control((inb_control(base_addr)&~HSF_PCB_MASK)|hsf, base_addr);
        !           234:        sti(); 
        !           235: }
        !           236: 
        !           237: #define WAIT_HCRE(addr,toval) wait_hcre((addr),(toval),__LINE__)
        !           238: static inline int
        !           239: wait_hcre (unsigned int base_addr, int toval, int lineno)
        !           240: {
        !           241:        int timeout = jiffies + toval;
        !           242:        while (((inb_status(base_addr)&HCRE)==0) && (jiffies <= timeout))
        !           243:                ;
        !           244:        if (jiffies >= timeout) {
        !           245:                TIMEOUT_MSG(lineno);
        !           246:                return FALSE;
        !           247:        }
        !           248:        return TRUE;
        !           249: }
        !           250: 
        !           251: static inline int
        !           252: wait_fast_hcre (unsigned int base_addr, int toval, int lineno)
        !           253: {
        !           254:        int timeout = 0;
        !           255:        while (((inb_status(base_addr)&HCRE)==0) && (timeout++ < toval))
        !           256:                ;
        !           257:        if (timeout >= toval) {
        !           258:                sti();
        !           259:                TIMEOUT_MSG(lineno);
        !           260:                return FALSE;
        !           261:        }
        !           262:        return TRUE;
        !           263: }
        !           264: 
        !           265: static int start_receive (struct device *, pcb_struct *);
        !           266: static void adapter_hard_reset (struct device *);
        !           267: 
        !           268: inline static void
        !           269: adapter_reset (struct device * dev)
        !           270: {
        !           271:        int timeout;
        !           272:        unsigned char orig_hcr=inb_control(dev->base_addr);
        !           273: 
        !           274:        elp_device * adapter=dev->priv;
        !           275: 
        !           276:        outb_control(0,dev->base_addr);
        !           277: 
        !           278:        if (inb_status(dev->base_addr)&ACRF) {
        !           279:                do {
        !           280:                        inb_command(dev->base_addr);
        !           281:                        timeout=jiffies+2;
        !           282:                        while ((jiffies<=timeout) && !(inb_status(dev->base_addr)&ACRF))
        !           283:                                ;
        !           284:                } while (inb_status(dev->base_addr)&ACRF);
        !           285:                set_hsf(dev->base_addr,HSF_PCB_NAK);
        !           286:        }
        !           287: 
        !           288:        outb_control(inb_control(dev->base_addr)|ATTN|DIR,dev->base_addr);
        !           289:        timeout=jiffies+1;
        !           290:        while (jiffies<=timeout)
        !           291:                ;
        !           292:        outb_control(inb_control(dev->base_addr)&~ATTN,dev->base_addr);
        !           293:        timeout=jiffies+1;
        !           294:        while (jiffies<=timeout)
        !           295:                ;
        !           296:        outb_control(inb_control(dev->base_addr)|FLSH,dev->base_addr);
        !           297:        timeout=jiffies+1;
        !           298:        while (jiffies<=timeout)
        !           299:                ;
        !           300:        outb_control(inb_control(dev->base_addr)&~FLSH,dev->base_addr);
        !           301:        timeout=jiffies+1;
        !           302:        while (jiffies<=timeout)
        !           303:                ;
        !           304: 
        !           305:        outb_control(orig_hcr, dev->base_addr);
        !           306:        if (!start_receive(dev, &adapter->tx_pcb))
        !           307:                printk("%s: start receive command failed \n", dev->name);
        !           308: }
        !           309: 
        !           310: /*****************************************************************
        !           311:  *
        !           312:  * send_pcb
        !           313:  *   Send a PCB to the adapter. 
        !           314:  *
        !           315:  *     output byte to command reg  --<--+
        !           316:  *     wait until HCRE is non zero      |
        !           317:  *     loop until all bytes sent   -->--+
        !           318:  *     set HSF1 and HSF2 to 1
        !           319:  *     output pcb length
        !           320:  *     wait until ASF give ACK or NAK
        !           321:  *     set HSF1 and HSF2 to 0
        !           322:  *
        !           323:  *****************************************************************/
        !           324: 
        !           325: static int
        !           326: send_pcb (struct device * dev, pcb_struct * pcb)
        !           327: {
        !           328:        int i;
        !           329:        int timeout;
        !           330:        int cont;
        !           331: 
        !           332:        /*
        !           333:         * load each byte into the command register and
        !           334:         * wait for the HCRE bit to indicate the adapter
        !           335:         * had read the byte
        !           336:         */
        !           337:        set_hsf(dev->base_addr,0); 
        !           338:        if ((cont = WAIT_HCRE(dev->base_addr,5))) {
        !           339:                cli();
        !           340:                if (pcb->command==CMD_TRANSMIT_PACKET)
        !           341:                        outb_control(inb_control(dev->base_addr)&~DIR,dev->base_addr);
        !           342:                outb_command(pcb->command, dev->base_addr);
        !           343:                sti();
        !           344:                cont = WAIT_HCRE(dev->base_addr,5);
        !           345:        }
        !           346: 
        !           347:        if (cont) {
        !           348:                outb_command(pcb->length, dev->base_addr);
        !           349:                cont = WAIT_HCRE(dev->base_addr,5);
        !           350:        }
        !           351: 
        !           352:        cli();
        !           353:        for (i = 0; cont && (i < pcb->length); i++) {
        !           354:                outb_command(pcb->data.raw[i], dev->base_addr);
        !           355:                cont = wait_fast_hcre(dev->base_addr,20000,__LINE__);
        !           356:        } /* if wait_fast_hcre() failed, has already done sti() */
        !           357: 
        !           358:        /* set the host status bits to indicate end of PCB */
        !           359:        /* send the total packet length as well */
        !           360:        /* wait for the adapter to indicate that it has read the PCB */
        !           361:        if (cont) {
        !           362:                set_hsf(dev->base_addr,HSF_PCB_END);
        !           363:                outb_command(2+pcb->length, dev->base_addr);
        !           364:                sti();
        !           365:                timeout = jiffies + 7;
        !           366:                while (jiffies < timeout) {
        !           367:                        i = GET_ASF(dev->base_addr);
        !           368:                        if ((i == ASF_PCB_ACK) || (i == ASF_PCB_NAK))
        !           369:                                break;
        !           370:                }
        !           371: 
        !           372:                if (i == ASF_PCB_ACK) {
        !           373:                        reset_count=0;
        !           374:                        return TRUE;
        !           375:                }
        !           376:                else if (i == ASF_PCB_NAK) {
        !           377:                        printk("%s: PCB send was NAKed\n", dev->name);
        !           378:                } else {
        !           379:                        printk("%s: timeout after sending PCB\n", dev->name);
        !           380:                }
        !           381:        } else {
        !           382:                sti();
        !           383:                printk("%s: timeout in middle of sending PCB\n", dev->name);
        !           384:        }
        !           385: 
        !           386:        adapter_reset(dev);
        !           387:        return FALSE;
        !           388: }
        !           389: 
        !           390: /*****************************************************************
        !           391:  *
        !           392:  * receive_pcb
        !           393:  *   Read a PCB to the adapter
        !           394:  *
        !           395:  *     wait for ACRF to be non-zero        ---<---+
        !           396:  *     input a byte                               |
        !           397:  *     if ASF1 and ASF2 were not both one         |
        !           398:  *             before byte was read, loop      --->---+
        !           399:  *     set HSF1 and HSF2 for ack
        !           400:  *
        !           401:  *****************************************************************/
        !           402: 
        !           403: static int
        !           404: receive_pcb (struct device * dev, pcb_struct * pcb)
        !           405: {
        !           406:        int i, j;
        !           407:        int total_length;
        !           408:        int stat;
        !           409:        int timeout;
        !           410: 
        !           411:        CHECK_NULL(pcb);
        !           412:        CHECK_NULL(dev);
        !           413: 
        !           414:        set_hsf(dev->base_addr,0);
        !           415: 
        !           416:        /* get the command code */
        !           417:        timeout = jiffies + 2;
        !           418:        while (((stat = get_status(dev->base_addr))&ACRF) == 0 && jiffies < timeout)
        !           419:                ;
        !           420:        if (jiffies >= timeout) {
        !           421:                TIMEOUT_MSG(__LINE__);
        !           422:                return FALSE;
        !           423:        }
        !           424: 
        !           425:        pcb->command = inb_command(dev->base_addr);
        !           426: 
        !           427:        /* read the data length */
        !           428:        timeout = jiffies + 3;
        !           429:        while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && jiffies < timeout)
        !           430:                ;
        !           431:        if (jiffies >= timeout) {
        !           432:                TIMEOUT_MSG(__LINE__);
        !           433:                return FALSE;
        !           434:        }
        !           435:        pcb->length = inb_command(dev->base_addr);
        !           436: 
        !           437:        if (pcb->length > MAX_PCB_DATA) {
        !           438:                INVALID_PCB_MSG(pcb->length);
        !           439:                adapter_reset(dev);
        !           440:                return FALSE;
        !           441:        }
        !           442: 
        !           443:        /* read the data */
        !           444:        cli();
        !           445:        i = 0;
        !           446:        do {
        !           447:                j = 0;
        !           448:                while (((stat = get_status(dev->base_addr))&ACRF) == 0 && j++ < 20000)
        !           449:                        ;
        !           450:                pcb->data.raw[i++] = inb_command(dev->base_addr);
        !           451:                if (i > MAX_PCB_DATA)
        !           452:                        INVALID_PCB_MSG(i);
        !           453:        } while ((stat & ASF_PCB_MASK) != ASF_PCB_END && j < 20000);
        !           454:        sti();
        !           455:        if (j >= 20000) {
        !           456:                TIMEOUT_MSG(__LINE__);
        !           457:                return FALSE;
        !           458:        }
        !           459: 
        !           460:        /* woops, the last "data" byte was really the length! */
        !           461:        total_length = pcb->data.raw[--i];
        !           462: 
        !           463:        /* safety check total length vs data length */
        !           464:        if (total_length != (pcb->length + 2)) {
        !           465:                if (elp_debug >= 2)
        !           466:                        printk("%s: mangled PCB received\n", dev->name);
        !           467:                set_hsf(dev->base_addr,HSF_PCB_NAK);
        !           468:                return FALSE;
        !           469:        }
        !           470: 
        !           471:        set_hsf(dev->base_addr,HSF_PCB_ACK);
        !           472:        reset_count=0;
        !           473:        return TRUE;
        !           474: }
        !           475: 
        !           476: static void
        !           477: adapter_hard_reset (struct device * dev)
        !           478: {
        !           479:        int timeout;
        !           480:        long flags;
        !           481: 
        !           482:        CHECK_NULL(dev);
        !           483: 
        !           484:        save_flags(flags);
        !           485:        sti();
        !           486: 
        !           487:        if (elp_debug > 0)
        !           488:                printk("%s: Resetting the adapter, please wait (approx 20 s)\n",
        !           489:                        dev->name);
        !           490:        /*
        !           491:         * take FLSH and ATTN high
        !           492:         */
        !           493:        outb_control(ATTN|FLSH, dev->base_addr);
        !           494: 
        !           495:        /*
        !           496:         * wait for a little bit
        !           497:         */
        !           498:        for (timeout = jiffies + 20; jiffies <= timeout; )
        !           499:                ;
        !           500: 
        !           501:        /*
        !           502:         * now take them low
        !           503:         */
        !           504:        outb_control(0, dev->base_addr);
        !           505: 
        !           506:        /*
        !           507:         * wait for a little bit
        !           508:         */
        !           509:        for (timeout = jiffies + 20; jiffies <= timeout; )
        !           510:                ;
        !           511: 
        !           512:        /*
        !           513:         * now hang around until the board gets it's act together
        !           514:         */
        !           515:        for (timeout = jiffies + (100 * 15); jiffies <= timeout; ) 
        !           516:                if (GET_ASF(dev->base_addr) != ASF_PCB_END)
        !           517:                        break;
        !           518:        restore_flags(flags);
        !           519: }
        !           520: 
        !           521: /******************************************************
        !           522:  *
        !           523:  *  queue a receive command on the adapter so we will get an
        !           524:  *  interrupt when a packet is received.
        !           525:  *
        !           526:  ******************************************************/
        !           527: 
        !           528: static int
        !           529: start_receive (struct device * dev, pcb_struct * tx_pcb)
        !           530: {
        !           531:        CHECK_NULL(dev);
        !           532:        CHECK_NULL(tx_pcb);
        !           533: 
        !           534:        if (elp_debug >= 3)
        !           535:                printk("%s: restarting receiver\n", dev->name);
        !           536:        tx_pcb->command = CMD_RECEIVE_PACKET;
        !           537:        tx_pcb->length = sizeof(struct Rcv_pkt);
        !           538:        tx_pcb->data.rcv_pkt.buf_seg
        !           539:                = tx_pcb->data.rcv_pkt.buf_ofs = 0; /* Unused */
        !           540:        tx_pcb->data.rcv_pkt.buf_len = 1600;
        !           541:        tx_pcb->data.rcv_pkt.timeout = 0;       /* set timeout to zero */
        !           542:        return send_pcb(dev, tx_pcb); 
        !           543: }
        !           544: 
        !           545: /******************************************************
        !           546:  *
        !           547:  * extract a packet from the adapter
        !           548:  * this routine is only called from within the interrupt
        !           549:  * service routine, so no cli/sti calls are needed
        !           550:  * note that the length is always assumed to be even
        !           551:  *
        !           552:  ******************************************************/
        !           553: 
        !           554: static void
        !           555: receive_packet (struct device * dev, int len)
        !           556: {
        !           557:        register int i;
        !           558:        unsigned short * ptr;
        !           559:        int timeout;
        !           560:        int rlen;
        !           561:        struct sk_buff *skb;
        !           562:        elp_device * adapter;
        !           563: 
        !           564:        CHECK_NULL(dev);
        !           565:        adapter=dev->priv;
        !           566: 
        !           567:        if (len <= 0 || ((len & ~1) != len))
        !           568:                if (elp_debug >= 3) {
        !           569:                        sti();
        !           570:                        printk("*** bad packet len %d at %s(%d)\n",len,filename,__LINE__);
        !           571:                        cli();
        !           572:                }
        !           573: 
        !           574:        rlen = (len+1) & ~1;
        !           575: 
        !           576:        skb = dev_alloc_skb(rlen+2);
        !           577: 
        !           578:        /*
        !           579:         * make sure the data register is going the right way
        !           580:         */
        !           581: 
        !           582:        outb_control(inb_control(dev->base_addr)|DIR, dev->base_addr);
        !           583: 
        !           584:        /*
        !           585:         * if buffer could not be allocated, swallow it
        !           586:         */
        !           587:        if (skb == NULL) {
        !           588:                for (i = 0; i < (rlen/2); i++) {
        !           589:                        timeout = 0;
        !           590:                        while ((inb_status(dev->base_addr)&HRDY) == 0 && timeout++ < 20000)
        !           591:                                ;
        !           592:                        if (timeout >= 20000) {
        !           593:                                sti();
        !           594:                                TIMEOUT_MSG(__LINE__);
        !           595:                                break;
        !           596:                        }
        !           597: 
        !           598:                        inw_data(dev->base_addr);
        !           599:                }
        !           600:                adapter->stats.rx_dropped++;
        !           601: 
        !           602:        } else {
        !           603:                skb_reserve(skb,2);     /* 16 byte alignment */
        !           604:                skb->dev = dev;
        !           605: 
        !           606:                /*
        !           607:                 * now read the data from the adapter
        !           608:                 */
        !           609:                ptr = (unsigned short *)skb_put(skb,len);
        !           610:                for (i = 0; i < (rlen/2); i++) { 
        !           611:                        timeout = 0;
        !           612:                        while ((inb_status(dev->base_addr)&HRDY) == 0 && timeout++ < 20000) 
        !           613:                                ;
        !           614:                        if (timeout >= 20000) {
        !           615:                                sti();
        !           616:                                printk("*** timeout at %s(%d) reading word %d of %d ***\n",
        !           617:                                        filename,__LINE__, i, rlen/2);  
        !           618:                                kfree_skb(skb, FREE_WRITE);
        !           619:                                return;
        !           620:                        }
        !           621: 
        !           622:                        *ptr = inw_data(dev->base_addr); 
        !           623:                        ptr++; 
        !           624:                }
        !           625: 
        !           626:                sti();
        !           627:                skb->protocol=eth_type_trans(skb,dev);
        !           628:                netif_rx(skb);
        !           629:        }
        !           630: 
        !           631:        outb_control(inb_control(dev->base_addr)&~DIR, dev->base_addr);
        !           632: }
        !           633: 
        !           634: 
        !           635: /******************************************************
        !           636:  *
        !           637:  * interrupt handler
        !           638:  *
        !           639:  ******************************************************/
        !           640: 
        !           641: static void
        !           642: elp_interrupt (int irq, struct pt_regs *reg_ptr)
        !           643: {
        !           644:        int len;
        !           645:        int dlen;
        !           646:        struct device *dev;
        !           647:        elp_device * adapter;
        !           648:        int timeout;
        !           649: 
        !           650:        if (irq < 0 || irq > 15) {
        !           651:                printk ("elp_interrupt(): illegal IRQ number found in interrupt routine (%i)\n", irq);
        !           652:                return;
        !           653:        }
        !           654: 
        !           655:        dev = irq2dev_map[irq];
        !           656: 
        !           657:        if (dev == NULL) {
        !           658:                printk ("elp_interrupt(): irq %d for unknown device.\n", irq);
        !           659:                return;
        !           660:        }
        !           661: 
        !           662:        adapter = (elp_device *) dev->priv;
        !           663: 
        !           664:        CHECK_NULL(adapter);
        !           665: 
        !           666:        if (dev->interrupt)
        !           667:                if (elp_debug >= 2)
        !           668:                        printk("%s: Re-entering the interrupt handler.\n", dev->name);
        !           669:        dev->interrupt = 1;
        !           670: 
        !           671:        /*
        !           672:         * allow interrupts (we need timers!)
        !           673:         */
        !           674:        sti();
        !           675: 
        !           676:        /*
        !           677:         * receive a PCB from the adapter
        !           678:         */
        !           679:        timeout = jiffies + 3;
        !           680:        while ((inb_status(dev->base_addr)&ACRF) != 0 && jiffies < timeout) {
        !           681: 
        !           682:                if (receive_pcb(dev, &adapter->irx_pcb)) {
        !           683: 
        !           684:                        switch (adapter->irx_pcb.command) {
        !           685: 
        !           686:                                /*
        !           687:                                 * received a packet - this must be handled fast
        !           688:                                 */
        !           689:                                case CMD_RECEIVE_PACKET_COMPLETE:
        !           690:                                        /* if the device isn't open, don't pass packets up the stack */
        !           691:                                        if (dev->start == 0)
        !           692:                                                break;
        !           693:                                        cli();
        !           694:                                        /* Set direction of adapter FIFO */
        !           695:                                        outb_control(inb_control(dev->base_addr)|DIR,
        !           696:                                                     dev->base_addr);
        !           697:                                        len = adapter->irx_pcb.data.rcv_resp.pkt_len;
        !           698:                                        dlen = adapter->irx_pcb.data.rcv_resp.buf_len;
        !           699:                                        if (adapter->irx_pcb.data.rcv_resp.timeout != 0) {
        !           700:                                                printk("%s: interrupt - packet not received correctly\n", dev->name);
        !           701:                                                sti();
        !           702:                                        } else {
        !           703:                                                if (elp_debug >= 3) {
        !           704:                                                        sti();
        !           705:                                                        printk("%s: interrupt - packet received of length %i (%i)\n", dev->name, len, dlen);
        !           706:                                                        cli();
        !           707:                                                }
        !           708:                                                receive_packet(dev, dlen);
        !           709:                                                sti();
        !           710:                                                if (elp_debug >= 3)
        !           711:                                                        printk("%s: packet received\n", dev->name);
        !           712:                                        }
        !           713:                                        if (dev->start && !start_receive(dev, &adapter->itx_pcb)) 
        !           714:                                                if (elp_debug >= 2)
        !           715:                                                        printk("%s: interrupt - failed to send receive start PCB\n", dev->name);
        !           716:                                        if (elp_debug >= 3)
        !           717:                                        printk("%s: receive procedure complete\n", dev->name);
        !           718: 
        !           719:                                        break;
        !           720: 
        !           721:                                /*
        !           722:                                 * 82586 configured correctly
        !           723:                                 */
        !           724:                                case CMD_CONFIGURE_82586_RESPONSE:
        !           725:                                        adapter->got[CMD_CONFIGURE_82586] = 1;
        !           726:                                        if (elp_debug >= 3)
        !           727:                                                printk("%s: interrupt - configure response received\n", dev->name);
        !           728:                                        break;
        !           729: 
        !           730:                                /*
        !           731:                                 * Adapter memory configuration
        !           732:                                 */
        !           733:                                case CMD_CONFIGURE_ADAPTER_RESPONSE:
        !           734:                                        adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 1;
        !           735:                                        if (elp_debug >= 3)
        !           736:                                                printk("%s: Adapter memory configuration %s.\n",dev->name,
        !           737:                                                        adapter->irx_pcb.data.failed?"failed":"succeeded");
        !           738:                                        break;
        !           739: 
        !           740:                                /*
        !           741:                                 * Multicast list loading
        !           742:                                 */
        !           743:                                case CMD_LOAD_MULTICAST_RESPONSE:
        !           744:                                        adapter->got[CMD_LOAD_MULTICAST_LIST] = 1;
        !           745:                                        if (elp_debug >= 3)
        !           746:                                                printk("%s: Multicast address list loading %s.\n",dev->name,
        !           747:                                                        adapter->irx_pcb.data.failed?"failed":"succeeded");
        !           748:                                        break;
        !           749: 
        !           750:                                /*
        !           751:                                 * Station address setting
        !           752:                                 */
        !           753:                                case CMD_SET_ADDRESS_RESPONSE:
        !           754:                                        adapter->got[CMD_SET_STATION_ADDRESS] = 1;
        !           755:                                        if (elp_debug >= 3)
        !           756:                                                printk("%s: Ethernet address setting %s.\n",dev->name,
        !           757:                                                        adapter->irx_pcb.data.failed?"failed":"succeeded");
        !           758:                                        break;
        !           759: 
        !           760: 
        !           761:                                /*
        !           762:                                 * received board statistics
        !           763:                                 */
        !           764:                                case CMD_NETWORK_STATISTICS_RESPONSE:
        !           765:                                        adapter->stats.rx_packets += adapter->irx_pcb.data.netstat.tot_recv;
        !           766:                                        adapter->stats.tx_packets += adapter->irx_pcb.data.netstat.tot_xmit;
        !           767:                                        adapter->stats.rx_crc_errors += adapter->irx_pcb.data.netstat.err_CRC;
        !           768:                                        adapter->stats.rx_frame_errors += adapter->irx_pcb.data.netstat.err_align;
        !           769:                                        adapter->stats.rx_fifo_errors += adapter->irx_pcb.data.netstat.err_ovrrun;
        !           770:                                        adapter->got[CMD_NETWORK_STATISTICS] = 1;
        !           771:                                        if (elp_debug >= 3)
        !           772:                                                printk("%s: interrupt - statistics response received\n", dev->name);
        !           773:                                        break;
        !           774: 
        !           775:                                /*
        !           776:                                 * sent a packet
        !           777:                                 */
        !           778:                                case CMD_TRANSMIT_PACKET_COMPLETE:
        !           779:                                        if (elp_debug >= 3) 
        !           780:                                        printk("%s: interrupt - packet sent\n", dev->name);
        !           781:                                        if (dev->start == 0)
        !           782:                                                break;
        !           783:                                        if (adapter->irx_pcb.data.xmit_resp.c_stat != 0)
        !           784:                                                if (elp_debug >= 2)
        !           785:                                                        printk("%s: interrupt - error sending packet %4.4x\n",
        !           786:                                                                dev->name, adapter->irx_pcb.data.xmit_resp.c_stat);
        !           787:                                        dev->tbusy = 0;
        !           788:                                        mark_bh(NET_BH);
        !           789:                                        break;
        !           790: 
        !           791:                                /*
        !           792:                                 * some unknown PCB
        !           793:                                 */
        !           794:                                default:
        !           795:                                        printk("%s: unknown PCB received - %2.2x\n", dev->name, adapter->irx_pcb.command);
        !           796:                                        break;
        !           797:                        }
        !           798:                } else {
        !           799:                        printk("%s: failed to read PCB on interrupt\n", dev->name);
        !           800:                        adapter_reset(dev);
        !           801:                }
        !           802:        }
        !           803: 
        !           804:        /*
        !           805:         * indicate no longer in interrupt routine
        !           806:         */
        !           807:        dev->interrupt = 0;
        !           808: }
        !           809: 
        !           810: 
        !           811: /******************************************************
        !           812:  *
        !           813:  * open the board
        !           814:  *
        !           815:  ******************************************************/
        !           816: 
        !           817: static int
        !           818: elp_open (struct device *dev)
        !           819: {
        !           820:        elp_device * adapter;
        !           821: 
        !           822:        CHECK_NULL(dev);
        !           823: 
        !           824:        adapter = dev->priv;
        !           825: 
        !           826:        if (elp_debug >= 3)  
        !           827:                printk("%s: request to open device\n", dev->name);
        !           828: 
        !           829:        /*
        !           830:         * make sure we actually found the device
        !           831:         */
        !           832:        if (adapter == NULL) {
        !           833:                printk("%s: Opening a non-existent physical device\n", dev->name);
        !           834:                return -EAGAIN;
        !           835:        }
        !           836: 
        !           837:        /*
        !           838:         * disable interrupts on the board
        !           839:         */
        !           840:        outb_control(0x00, dev->base_addr);
        !           841: 
        !           842:        /*
        !           843:         * clear any pending interrupts
        !           844:         */
        !           845:        inb_command(dev->base_addr);
        !           846:        adapter_reset(dev);
        !           847: 
        !           848:        /*
        !           849:         * interrupt routine not entered
        !           850:         */
        !           851:        dev->interrupt = 0;
        !           852: 
        !           853:        /*
        !           854:         *  transmitter not busy 
        !           855:         */
        !           856:        dev->tbusy = 0;
        !           857: 
        !           858:        /*
        !           859:         * make sure we can find the device header given the interrupt number
        !           860:         */
        !           861:        irq2dev_map[dev->irq] = dev;
        !           862: 
        !           863:        /*
        !           864:         * install our interrupt service routine
        !           865:         */
        !           866:        if (request_irq(dev->irq, &elp_interrupt, 0, "3c505")) {
        !           867:                irq2dev_map[dev->irq] = NULL;
        !           868:                return -EAGAIN;
        !           869:        }
        !           870: 
        !           871:        /*
        !           872:         * enable interrupts on the board
        !           873:         */
        !           874:        outb_control(CMDE, dev->base_addr);
        !           875: 
        !           876:        /*
        !           877:         * device is now officially open!
        !           878:         */
        !           879:        dev->start = 1;
        !           880: 
        !           881:        /*
        !           882:         * configure adapter memory: we need 10 multicast addresses, default==0
        !           883:         */
        !           884:        if (elp_debug >= 3)
        !           885:                printk("%s: sending 3c505 memory configuration command\n", dev->name);
        !           886:        adapter->tx_pcb.command = CMD_CONFIGURE_ADAPTER_MEMORY;
        !           887:        adapter->tx_pcb.data.memconf.cmd_q = 10;
        !           888:        adapter->tx_pcb.data.memconf.rcv_q = 20;
        !           889:        adapter->tx_pcb.data.memconf.mcast = 10;
        !           890:        adapter->tx_pcb.data.memconf.frame = 20;
        !           891:        adapter->tx_pcb.data.memconf.rcv_b = 20;
        !           892:        adapter->tx_pcb.data.memconf.progs = 0;
        !           893:        adapter->tx_pcb.length = sizeof(struct Memconf);
        !           894:        adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 0;
        !           895:        if (!send_pcb(dev, &adapter->tx_pcb))
        !           896:                printk("%s: couldn't send memory configuration command\n", dev->name);
        !           897:        else {
        !           898:                int timeout = jiffies + TIMEOUT;
        !           899:                while (adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] == 0 && jiffies < timeout)
        !           900:                        ;
        !           901:                if (jiffies >= timeout)
        !           902:                        TIMEOUT_MSG(__LINE__);
        !           903:        }
        !           904: 
        !           905: 
        !           906:        /*
        !           907:         * configure adapter to receive broadcast messages and wait for response
        !           908:         */
        !           909:        if (elp_debug >= 3)
        !           910:                printk("%s: sending 82586 configure command\n", dev->name);
        !           911:        adapter->tx_pcb.command = CMD_CONFIGURE_82586;
        !           912:        adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD;
        !           913:        adapter->tx_pcb.length  = 2;
        !           914:        adapter->got[CMD_CONFIGURE_82586] = 0;
        !           915:        if (!send_pcb(dev, &adapter->tx_pcb))
        !           916:                printk("%s: couldn't send 82586 configure command\n", dev->name);
        !           917:        else {
        !           918:                int timeout = jiffies + TIMEOUT;
        !           919:                while (adapter->got[CMD_CONFIGURE_82586] == 0 && jiffies < timeout)
        !           920:                        ;
        !           921:                if (jiffies >= timeout)
        !           922:                        TIMEOUT_MSG(__LINE__);
        !           923:        }
        !           924: 
        !           925:        /*
        !           926:         * queue receive commands to provide buffering
        !           927:         */
        !           928:        if (!start_receive(dev, &adapter->tx_pcb))
        !           929:                printk("%s: start receive command failed \n", dev->name);
        !           930:        if (elp_debug >= 3)
        !           931:                printk("%s: start receive command sent\n", dev->name);
        !           932: 
        !           933:        MOD_INC_USE_COUNT;
        !           934: 
        !           935:        return 0;                       /* Always succeed */
        !           936: }
        !           937: 
        !           938: 
        !           939: /******************************************************
        !           940:  *
        !           941:  * send a packet to the adapter
        !           942:  *
        !           943:  ******************************************************/
        !           944: 
        !           945: static int
        !           946: send_packet (struct device * dev, unsigned char * ptr, int len)
        !           947: {
        !           948:        int i;
        !           949:        int timeout = 0;
        !           950:        elp_device * adapter;
        !           951: 
        !           952:        /*
        !           953:         * make sure the length is even and no shorter than 60 bytes
        !           954:         */
        !           955:        unsigned int nlen = (((len < 60) ? 60 : len) + 1) & (~1);
        !           956: 
        !           957:        CHECK_NULL(dev);
        !           958:        CHECK_NULL(ptr);
        !           959: 
        !           960:        adapter = dev->priv;
        !           961: 
        !           962:        if (nlen < len)
        !           963:                printk("Warning, bad length nlen=%d len=%d %s(%d)\n",nlen,len,filename,__LINE__);
        !           964: 
        !           965:        /*
        !           966:         * send the adapter a transmit packet command. Ignore segment and offset
        !           967:         * and make sure the length is even
        !           968:         */
        !           969:        adapter->tx_pcb.command = CMD_TRANSMIT_PACKET;
        !           970:        adapter->tx_pcb.length = sizeof(struct Xmit_pkt);
        !           971:        adapter->tx_pcb.data.xmit_pkt.buf_ofs
        !           972:                = adapter->tx_pcb.data.xmit_pkt.buf_seg = 0; /* Unused */
        !           973:        adapter->tx_pcb.data.xmit_pkt.pkt_len = nlen;
        !           974:        if (!send_pcb(dev, &adapter->tx_pcb)) {
        !           975:                return FALSE;
        !           976:        }
        !           977: 
        !           978:        /*
        !           979:         * write data to the adapter
        !           980:         */
        !           981:        cli();
        !           982:        for (i = 0; i < (nlen/2);i++) {
        !           983:                while (((inb_status(dev->base_addr)&HRDY) == 0)
        !           984:                       && (timeout++ < 20000))
        !           985:                        ;
        !           986:                if (timeout >= 20000) {
        !           987:                        sti();
        !           988:                        printk("%s: timeout at %s(%d) writing word %d of %d ***\n",
        !           989:                                dev->name,filename,__LINE__, i, nlen/2);
        !           990:                        return FALSE;
        !           991:                }
        !           992: 
        !           993:                outw_data(*(short *)ptr, dev->base_addr);
        !           994:                ptr +=2;
        !           995:        }
        !           996:        sti();
        !           997: 
        !           998:        return TRUE;
        !           999: }
        !          1000: 
        !          1001: /******************************************************
        !          1002:  *
        !          1003:  * start the transmitter
        !          1004:  *    return 0 if sent OK, else return 1
        !          1005:  *
        !          1006:  ******************************************************/
        !          1007: 
        !          1008: static int
        !          1009: elp_start_xmit (struct sk_buff *skb, struct device *dev)
        !          1010: {
        !          1011:        CHECK_NULL(dev);
        !          1012: 
        !          1013:        /*
        !          1014:         * not sure what this does, but the 3c509 driver does it, so...
        !          1015:         */
        !          1016:        if (skb == NULL) {
        !          1017:                dev_tint(dev);
        !          1018:                return 0;
        !          1019:        }
        !          1020: 
        !          1021:        /*
        !          1022:         * if we ended up with a munged length, don't send it
        !          1023:         */
        !          1024:        if (skb->len <= 0)
        !          1025:                return 0;
        !          1026: 
        !          1027:        if (elp_debug >= 3)
        !          1028:                printk("%s: request to send packet of length %d\n", dev->name, (int)skb->len);
        !          1029: 
        !          1030:        /*
        !          1031:         * if the transmitter is still busy, we have a transmit timeout...
        !          1032:         */
        !          1033:        if (dev->tbusy) {
        !          1034:                int tickssofar = jiffies - dev->trans_start;
        !          1035:                int stat;
        !          1036:                if (tickssofar < 50) /* was 500, AJT */
        !          1037:                        return 1;
        !          1038:                printk("%s: transmit timed out, not resetting adapter\n", dev->name);
        !          1039:                if (((stat=inb_status(dev->base_addr))&ACRF) != 0) 
        !          1040:                        printk("%s: hmmm...seemed to have missed an interrupt!\n", dev->name);
        !          1041:                printk("%s: status %#02x\n", dev->name, stat);
        !          1042:                dev->trans_start = jiffies;
        !          1043:                dev->tbusy = 0;
        !          1044:        }
        !          1045: 
        !          1046:        /*
        !          1047:         * send the packet at skb->data for skb->len
        !          1048:         */
        !          1049:        if (!send_packet(dev, skb->data, skb->len)) {
        !          1050:                printk("%s: send packet PCB failed\n", dev->name);
        !          1051:                return 1;
        !          1052:        }
        !          1053: 
        !          1054:        if (elp_debug >= 3)
        !          1055:                printk("%s: packet of length %d sent\n", dev->name, (int)skb->len);
        !          1056: 
        !          1057: 
        !          1058:        /*
        !          1059:         * start the transmit timeout
        !          1060:         */
        !          1061:        dev->trans_start = jiffies;
        !          1062: 
        !          1063:        /*
        !          1064:         * the transmitter is now busy
        !          1065:         */
        !          1066:        dev->tbusy = 1;
        !          1067: 
        !          1068:        /*
        !          1069:         * free the buffer
        !          1070:         */
        !          1071:        dev_kfree_skb(skb, FREE_WRITE);
        !          1072: 
        !          1073:        return 0;
        !          1074: }
        !          1075: 
        !          1076: /******************************************************
        !          1077:  *
        !          1078:  * return statistics on the board
        !          1079:  *
        !          1080:  ******************************************************/
        !          1081: 
        !          1082: static struct enet_statistics *
        !          1083: elp_get_stats (struct device *dev)
        !          1084: {
        !          1085:        elp_device *adapter = (elp_device *) dev->priv;
        !          1086: 
        !          1087:        if (elp_debug >= 3)
        !          1088:                printk("%s: request for stats\n", dev->name);
        !          1089: 
        !          1090:        /* If the device is closed, just return the latest stats we have,
        !          1091:           - we cannot ask from the adapter without interrupts */
        !          1092:        if (!dev->start)
        !          1093:                return &adapter->stats;
        !          1094: 
        !          1095:        /* send a get statistics command to the board */
        !          1096:        adapter->tx_pcb.command = CMD_NETWORK_STATISTICS;
        !          1097:        adapter->tx_pcb.length  = 0;
        !          1098:        adapter->got[CMD_NETWORK_STATISTICS] = 0;
        !          1099:        if (!send_pcb(dev, &adapter->tx_pcb))
        !          1100:                printk("%s: couldn't send get statistics command\n", dev->name);
        !          1101:        else {
        !          1102:                int timeout = jiffies + TIMEOUT;
        !          1103:                while (adapter->got[CMD_NETWORK_STATISTICS] == 0 && jiffies < timeout)
        !          1104:                        ;
        !          1105:                if (jiffies >= timeout) {
        !          1106:                        TIMEOUT_MSG(__LINE__);
        !          1107:                        return &adapter->stats;
        !          1108:                }
        !          1109:        }
        !          1110: 
        !          1111:        /* statistics are now up to date */
        !          1112:        return &adapter->stats;
        !          1113: }
        !          1114: 
        !          1115: /******************************************************
        !          1116:  *
        !          1117:  * close the board
        !          1118:  *
        !          1119:  ******************************************************/
        !          1120: 
        !          1121: static int
        !          1122: elp_close (struct device *dev)
        !          1123: {
        !          1124:        elp_device * adapter;
        !          1125: 
        !          1126:        CHECK_NULL(dev);
        !          1127:        adapter = dev->priv;
        !          1128:        CHECK_NULL(adapter);
        !          1129: 
        !          1130:        if (elp_debug >= 3)
        !          1131:                printk("%s: request to close device\n", dev->name);
        !          1132: 
        !          1133:        /* Someone may request the device statistic information even when
        !          1134:         * the interface is closed. The following will update the statistics
        !          1135:         * structure in the driver, so we'll be able to give current statistics.
        !          1136:         */
        !          1137:        (void) elp_get_stats(dev);
        !          1138: 
        !          1139:        /*
        !          1140:         * disable interrupts on the board
        !          1141:         */
        !          1142:        outb_control(0x00, dev->base_addr);
        !          1143: 
        !          1144:        /*
        !          1145:         *  flag transmitter as busy (i.e. not available)
        !          1146:         */
        !          1147:        dev->tbusy = 1;
        !          1148: 
        !          1149:        /*
        !          1150:         *  indicate device is closed
        !          1151:         */
        !          1152:        dev->start = 0;
        !          1153: 
        !          1154:        /*
        !          1155:         * release the IRQ
        !          1156:         */
        !          1157:        free_irq(dev->irq);
        !          1158: 
        !          1159:        /*
        !          1160:         * and we no longer have to map irq to dev either
        !          1161:         */
        !          1162:        irq2dev_map[dev->irq] = 0;
        !          1163: 
        !          1164:        MOD_DEC_USE_COUNT;
        !          1165: 
        !          1166:        return 0;
        !          1167: }
        !          1168: 
        !          1169: 
        !          1170: /************************************************************
        !          1171:  *
        !          1172:  * Set multicast list
        !          1173:  * num_addrs==0: clear mc_list
        !          1174:  * num_addrs==-1: set promiscuous mode
        !          1175:  * num_addrs>0: set mc_list
        !          1176:  *
        !          1177:  ************************************************************/
        !          1178: 
        !          1179: static void
        !          1180: elp_set_mc_list (struct device *dev)
        !          1181: {
        !          1182:        elp_device *adapter = (elp_device *) dev->priv;
        !          1183:        struct dev_mc_list *dmi=dev->mc_list;
        !          1184:        int i;
        !          1185: 
        !          1186:        if (elp_debug >= 3)
        !          1187:                printk("%s: request to set multicast list\n", dev->name);
        !          1188: 
        !          1189:        if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI)))
        !          1190:        {
        !          1191:                /* send a "load multicast list" command to the board, max 10 addrs/cmd */
        !          1192:                /* if num_addrs==0 the list will be cleared */
        !          1193:                adapter->tx_pcb.command = CMD_LOAD_MULTICAST_LIST;
        !          1194:                adapter->tx_pcb.length  = 6*dev->mc_count;
        !          1195:                for (i=0;i<dev->mc_count;i++)
        !          1196:                {
        !          1197:                        memcpy(adapter->tx_pcb.data.multicast[i], dmi->dmi_addr,6);
        !          1198:                        dmi=dmi->next;
        !          1199:                }
        !          1200:                adapter->got[CMD_LOAD_MULTICAST_LIST] = 0;
        !          1201:                if (!send_pcb(dev, &adapter->tx_pcb))
        !          1202:                        printk("%s: couldn't send set_multicast command\n", dev->name);
        !          1203:                else {
        !          1204:                        int timeout = jiffies + TIMEOUT;
        !          1205:                        while (adapter->got[CMD_LOAD_MULTICAST_LIST] == 0 && jiffies < timeout)
        !          1206:                                ;
        !          1207:                        if (jiffies >= timeout) {
        !          1208:                                TIMEOUT_MSG(__LINE__);
        !          1209:                        }
        !          1210:                }
        !          1211:                if (dev->mc_count)
        !          1212:                        adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD | RECV_MULTI;
        !          1213:                else /* num_addrs == 0 */
        !          1214:                        adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD;
        !          1215:        } 
        !          1216:        else
        !          1217:                adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_PROMISC;
        !          1218:        /*
        !          1219:         * configure adapter to receive messages (as specified above)
        !          1220:         * and wait for response
        !          1221:         */
        !          1222:        if (elp_debug >= 3)
        !          1223:                printk("%s: sending 82586 configure command\n", dev->name);
        !          1224:        adapter->tx_pcb.command = CMD_CONFIGURE_82586;
        !          1225:        adapter->tx_pcb.length  = 2;
        !          1226:        adapter->got[CMD_CONFIGURE_82586]  = 0;
        !          1227:        if (!send_pcb(dev, &adapter->tx_pcb))
        !          1228:                printk("%s: couldn't send 82586 configure command\n", dev->name);
        !          1229:        else {
        !          1230:                int timeout = jiffies + TIMEOUT;
        !          1231:                while (adapter->got[CMD_CONFIGURE_82586] == 0 && jiffies < timeout)
        !          1232:                        ;
        !          1233:                if (jiffies >= timeout)
        !          1234:                        TIMEOUT_MSG(__LINE__);
        !          1235:        }
        !          1236: }
        !          1237: 
        !          1238: /******************************************************
        !          1239:  *
        !          1240:  * initialise Etherlink Plus board
        !          1241:  *
        !          1242:  ******************************************************/
        !          1243: 
        !          1244: static void
        !          1245: elp_init (struct device *dev)
        !          1246: {
        !          1247:        elp_device * adapter;
        !          1248: 
        !          1249:        CHECK_NULL(dev);
        !          1250: 
        !          1251:        /*
        !          1252:         * set ptrs to various functions
        !          1253:         */
        !          1254:        dev->open = elp_open;   /* local */
        !          1255:        dev->stop = elp_close;  /* local */
        !          1256:        dev->get_stats = elp_get_stats; /* local */
        !          1257:        dev->hard_start_xmit = elp_start_xmit;  /* local */
        !          1258:        dev->set_multicast_list = elp_set_mc_list;      /* local */
        !          1259: 
        !          1260:        /* Setup the generic properties */
        !          1261:        ether_setup(dev);
        !          1262: 
        !          1263:        /*
        !          1264:         * setup ptr to adapter specific information
        !          1265:         */
        !          1266:        adapter = (elp_device *)(dev->priv = kmalloc(sizeof(elp_device), GFP_KERNEL));
        !          1267:        CHECK_NULL(adapter);
        !          1268:        if (adapter == NULL)
        !          1269:                return;
        !          1270:        memset(&(adapter->stats), 0, sizeof(struct enet_statistics));
        !          1271: 
        !          1272:        /*
        !          1273:         * memory information
        !          1274:         */
        !          1275:        dev->mem_start = dev->mem_end = dev->rmem_end = dev->rmem_start = 0;
        !          1276: }
        !          1277: 
        !          1278: /************************************************************
        !          1279:  *
        !          1280:  * A couple of tests to see if there's 3C505 or not
        !          1281:  * Called only by elp_autodetect
        !          1282:  ************************************************************/
        !          1283: 
        !          1284: static int
        !          1285: elp_sense (struct device * dev)
        !          1286: {
        !          1287:        int timeout;
        !          1288:        int addr=dev->base_addr;
        !          1289:        const char *name=dev->name;
        !          1290:        long flags;
        !          1291:        byte orig_HCR, orig_HSR;
        !          1292: 
        !          1293:        if (check_region(addr, 0xf)) 
        !          1294:          return -1;  
        !          1295: 
        !          1296:        orig_HCR=inb_control(addr);
        !          1297:        orig_HSR=inb_status(addr);
        !          1298: 
        !          1299:        if (elp_debug > 0)
        !          1300:                printk(search_msg, name, addr);
        !          1301: 
        !          1302:        if (((orig_HCR==0xff) && (orig_HSR==0xff)) ||
        !          1303:            ((orig_HCR & DIR) != (orig_HSR & DIR))) {
        !          1304:                if (elp_debug > 0)
        !          1305:                        printk(notfound_msg, 1);
        !          1306:                return -1; /* It can't be 3c505 if HCR.DIR != HSR.DIR */
        !          1307:        }
        !          1308: 
        !          1309:        /* Enable interrupts - we need timers! */
        !          1310:        save_flags(flags);
        !          1311:        sti();
        !          1312: 
        !          1313:        /* Wait for a while; the adapter may still be booting up */
        !          1314:        if (elp_debug > 0)
        !          1315:                printk(stilllooking_msg);
        !          1316:        for (timeout = jiffies + (100 * 15); jiffies <= timeout; ) 
        !          1317:                if (GET_ASF(addr) != ASF_PCB_END)
        !          1318:                        break;
        !          1319: 
        !          1320:        if (orig_HCR & DIR) {
        !          1321:                /* If HCR.DIR is up, we pull it down. HSR.DIR should follow. */
        !          1322:                outb_control(orig_HCR & ~DIR,addr);
        !          1323:                timeout = jiffies+30;
        !          1324:                while (jiffies < timeout)
        !          1325:                        ;
        !          1326:                restore_flags(flags);
        !          1327:                if (inb_status(addr) & DIR) {
        !          1328:                        outb_control(orig_HCR,addr);
        !          1329:                        if (elp_debug > 0)
        !          1330:                                printk(notfound_msg, 2);
        !          1331:                        return -1;
        !          1332:                }
        !          1333:        } else {
        !          1334:                /* If HCR.DIR is down, we pull it up. HSR.DIR should follow. */
        !          1335:                outb_control(orig_HCR | DIR,addr);
        !          1336:                timeout = jiffies+300;
        !          1337:                while (jiffies < timeout)
        !          1338:                        ;
        !          1339:                restore_flags(flags);
        !          1340:                if (!(inb_status(addr) & DIR)) {
        !          1341:                        outb_control(orig_HCR,addr);
        !          1342:                        if (elp_debug > 0)
        !          1343:                                printk(notfound_msg, 3);
        !          1344:                        return -1;
        !          1345:                }
        !          1346:        }
        !          1347:        /*
        !          1348:         * It certainly looks like a 3c505. If it has DMA enabled, it needs
        !          1349:         * a hard reset. Also, do a hard reset if selected at the compile time.
        !          1350:         */
        !          1351:        if (elp_debug > 0)
        !          1352:                        printk(found_msg);
        !          1353: 
        !          1354:        if (((orig_HCR==0x35) && (orig_HSR==0x5b)) || ELP_NEED_HARD_RESET)
        !          1355:                adapter_hard_reset(dev);
        !          1356:        return 0;
        !          1357: }
        !          1358: 
        !          1359: /*************************************************************
        !          1360:  *
        !          1361:  * Search through addr_list[] and try to find a 3C505
        !          1362:  * Called only by eplus_probe
        !          1363:  *************************************************************/
        !          1364: 
        !          1365: static int
        !          1366: elp_autodetect (struct device * dev)
        !          1367: {
        !          1368:        int idx=0;
        !          1369: 
        !          1370:        /* if base address set, then only check that address
        !          1371:        otherwise, run through the table */
        !          1372:        if (dev->base_addr != 0) { /* dev->base_addr == 0 ==> plain autodetect */
        !          1373:                if (elp_sense(dev) == 0)
        !          1374:                        return dev->base_addr;
        !          1375:        } else while ( (dev->base_addr=addr_list[idx++]) ) {
        !          1376:                if (elp_sense(dev) == 0)
        !          1377:                        return dev->base_addr;
        !          1378:        }
        !          1379: 
        !          1380:        /* could not find an adapter */
        !          1381:        if (elp_debug > 0)
        !          1382:                printk(couldnot_msg, dev->name);
        !          1383: 
        !          1384:        return 0; /* Because of this, the layer above will return -ENODEV */
        !          1385: }
        !          1386: 
        !          1387: /******************************************************
        !          1388:  *
        !          1389:  * probe for an Etherlink Plus board at the specified address
        !          1390:  *
        !          1391:  ******************************************************/
        !          1392: 
        !          1393: int
        !          1394: elplus_probe (struct device *dev)
        !          1395: {
        !          1396:        elp_device adapter;
        !          1397:        int i;
        !          1398: 
        !          1399:        CHECK_NULL(dev);
        !          1400: 
        !          1401:        /*
        !          1402:         *  setup adapter structure
        !          1403:         */
        !          1404: 
        !          1405:        dev->base_addr = elp_autodetect(dev);
        !          1406:        if ( !(dev->base_addr) )
        !          1407:                return -ENODEV;
        !          1408: 
        !          1409:        /*
        !          1410:         *  As we enter here from bootup, the adapter should have IRQs enabled,
        !          1411:         *  but we can as well enable them anyway.
        !          1412:         */
        !          1413:        outb_control(inb_control(dev->base_addr) | CMDE, dev->base_addr);
        !          1414:        autoirq_setup(0);
        !          1415: 
        !          1416:        /*
        !          1417:         * use ethernet address command to probe for board in polled mode
        !          1418:         * (this also makes us the IRQ that we need for automatic detection)
        !          1419:         */
        !          1420:        adapter.tx_pcb.command = CMD_STATION_ADDRESS;
        !          1421:        adapter.tx_pcb.length  = 0;
        !          1422:        if (!send_pcb   (dev, &adapter.tx_pcb) ||
        !          1423:            !receive_pcb(dev, &adapter.rx_pcb) ||
        !          1424:            (adapter.rx_pcb.command != CMD_ADDRESS_RESPONSE) ||
        !          1425:            (adapter.rx_pcb.length != 6)) {
        !          1426:                printk("%s: not responding to first PCB\n", dev->name);
        !          1427:                return -ENODEV;
        !          1428:        }
        !          1429: 
        !          1430:        if (dev->irq) { /* Is there a preset IRQ? */
        !          1431:                if (dev->irq != autoirq_report(0)) {
        !          1432:                        printk("%s: Detected IRQ doesn't match user-defined one.\n",dev->name);
        !          1433:                        return -ENODEV;
        !          1434:                }
        !          1435:                /* if dev->irq == autoirq_report(0), all is well */
        !          1436:        } else /* No preset IRQ; just use what we can detect */
        !          1437:                dev->irq=autoirq_report(0);
        !          1438:        switch (dev->irq) { /* Legal, sane? */
        !          1439:                case 0:
        !          1440:                        printk("%s: No IRQ reported by autoirq_report().\n",dev->name);
        !          1441:                        printk("%s: Check the jumpers of your 3c505 board.\n",dev->name);
        !          1442:                        return -ENODEV;
        !          1443:                case 1:
        !          1444:                case 6:
        !          1445:                case 8:
        !          1446:                case 13: 
        !          1447:                        printk("%s: Impossible IRQ %d reported by autoirq_report().\n",
        !          1448:                               dev->name, dev->irq);
        !          1449:                        return -ENODEV;
        !          1450:        }
        !          1451:        /*
        !          1452:         *  Now we have the IRQ number so we can disable the interrupts from
        !          1453:         *  the board until the board is opened.
        !          1454:         */
        !          1455:        outb_control(inb_control(dev->base_addr) & ~CMDE, dev->base_addr);
        !          1456: 
        !          1457:        /*
        !          1458:         * copy ethernet address into structure
        !          1459:         */
        !          1460:        for (i = 0; i < 6; i++) 
        !          1461:                dev->dev_addr[i] = adapter.rx_pcb.data.eth_addr[i];
        !          1462: 
        !          1463:        /*
        !          1464:         * print remainder of startup message
        !          1465:         */
        !          1466:        printk("%s: 3c505 card found at I/O %#lx using IRQ%d"
        !          1467:               " has address %02x:%02x:%02x:%02x:%02x:%02x\n",
        !          1468:               dev->name, dev->base_addr, dev->irq,
        !          1469:               dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
        !          1470:               dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
        !          1471: 
        !          1472:        /*
        !          1473:         * and reserve the address region
        !          1474:         */
        !          1475:        request_region(dev->base_addr, ELP_IO_EXTENT, "3c505");
        !          1476: 
        !          1477:        /*
        !          1478:         * initialise the device
        !          1479:         */
        !          1480:        elp_init(dev);
        !          1481:        return 0;
        !          1482: }
        !          1483: 
        !          1484: #ifdef MODULE
        !          1485: static char devicename[9] = { 0, };
        !          1486: static struct device dev_3c505 = {
        !          1487:        devicename, /* device name is inserted by linux/drivers/net/net_init.c */
        !          1488:        0, 0, 0, 0,
        !          1489:        0, 0,
        !          1490:        0, 0, 0, NULL, elplus_probe };
        !          1491: 
        !          1492: int io = 0x300;
        !          1493: int irq = 0;
        !          1494: 
        !          1495: int init_module(void)
        !          1496: {
        !          1497:        if (io == 0)
        !          1498:                printk("3c505: You should not use auto-probing with insmod!\n");
        !          1499:        dev_3c505.base_addr = io;
        !          1500:        dev_3c505.irq       = irq;
        !          1501:        if (register_netdev(&dev_3c505) != 0) {
        !          1502:                printk("3c505: register_netdev() returned non-zero.\n");
        !          1503:                return -EIO;
        !          1504:        }
        !          1505:        return 0;
        !          1506: }
        !          1507: 
        !          1508: void
        !          1509: cleanup_module(void)
        !          1510: {
        !          1511:        unregister_netdev(&dev_3c505);
        !          1512:        kfree(dev_3c505.priv);
        !          1513:        dev_3c505.priv = NULL;
        !          1514: 
        !          1515:        /* If we don't do this, we can't re-insmod it later. */
        !          1516:        release_region(dev_3c505.base_addr, ELP_IO_EXTENT);
        !          1517: }
        !          1518: #endif /* MODULE */

unix.superglobalmegacorp.com

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