Annotation of qemu/roms/ipxe/src/drivers/net/ns8390.c, revision 1.1.1.1

1.1       root        1: /**************************************************************************
                      2: ETHERBOOT -  BOOTP/TFTP Bootstrap Program
                      3: 
                      4: Author: Martin Renters
                      5:   Date: May/94
                      6: 
                      7:  This code is based heavily on David Greenman's if_ed.c driver
                      8: 
                      9:  Copyright (C) 1993-1994, David Greenman, Martin Renters.
                     10:   This software may be used, modified, copied, distributed, and sold, in
                     11:   both source and binary form provided that the above copyright and these
                     12:   terms are retained. Under no circumstances are the authors responsible for
                     13:   the proper functioning of this software, nor do the authors assume any
                     14:   responsibility for damages incurred with its use.
                     15: 
                     16: Multicast support added by Timothy Legge ([email protected]) 09/28/2003
                     17: Relocation support added by Ken Yap ([email protected]) 28/12/02
                     18: 3c503 support added by Bill Paul ([email protected]) on 11/15/94
                     19: SMC8416 support added by Bill Paul ([email protected]) on 12/25/94
                     20: 3c503 PIO support added by Jim Hague ([email protected]) on 2/17/98
                     21: RX overrun by Klaus Espenlaub ([email protected]) on 3/10/99
                     22:   parts taken from the Linux 8390 driver (by Donald Becker and Paul Gortmaker)
                     23: SMC8416 PIO support added by Andrew Bettison ([email protected]) on 4/3/02
                     24:   based on the Linux 8390 driver (by Donald Becker and Paul Gortmaker)
                     25: 
                     26: **************************************************************************/
                     27: 
                     28: FILE_LICENCE ( BSD2 );
                     29: 
                     30: /* #warning "ns8390.c: FIXME: split ISA and PCI, clean up" */
                     31: 
                     32: #if 1
                     33: 
                     34: #if !defined(INCLUDE_NS8390) && !defined(INCLUDE_WD) && \
                     35:     !defined(INCLUDE_NE) && !defined(INCLUDE_3C503)
                     36:   /* The driver named ns8390 is the PCI driver, often called
                     37:      "PCI ne2000 clones". */
                     38: # define INCLUDE_NS8390 1
                     39: #endif
                     40: 
                     41: #include "etherboot.h"
                     42: #include "nic.h"
                     43: #include "ns8390.h"
                     44: #include <ipxe/ethernet.h>
                     45: #ifdef INCLUDE_NS8390
                     46: #include <ipxe/pci.h>
                     47: #else
                     48: #include <ipxe/isa.h>
                     49: #endif
                     50: 
                     51: static unsigned char   eth_vendor, eth_flags;
                     52: #ifdef INCLUDE_WD
                     53: static unsigned char   eth_laar;
                     54: #endif
                     55: static unsigned short  eth_nic_base, eth_asic_base;
                     56: static unsigned char   eth_memsize, eth_rx_start, eth_tx_start;
                     57: static Address         eth_bmem, eth_rmem;
                     58: static unsigned char   eth_drain_receiver;
                     59: 
                     60: #ifdef INCLUDE_WD
                     61: static struct wd_board {
                     62:        const char *name;
                     63:        char id;
                     64:        char flags;
                     65:        char memsize;
                     66: } wd_boards[] = {
                     67:        {"WD8003S",     TYPE_WD8003S,   0,                      MEM_8192},
                     68:        {"WD8003E",     TYPE_WD8003E,   0,                      MEM_8192},
                     69:        {"WD8013EBT",   TYPE_WD8013EBT, FLAG_16BIT,             MEM_16384},
                     70:        {"WD8003W",     TYPE_WD8003W,   0,                      MEM_8192},
                     71:        {"WD8003EB",    TYPE_WD8003EB,  0,                      MEM_8192},
                     72:        {"WD8013W",     TYPE_WD8013W,   FLAG_16BIT,             MEM_16384},
                     73:        {"WD8003EP/WD8013EP",
                     74:                        TYPE_WD8013EP,  0,                      MEM_8192},
                     75:        {"WD8013WC",    TYPE_WD8013WC,  FLAG_16BIT,             MEM_16384},
                     76:        {"WD8013EPC",   TYPE_WD8013EPC, FLAG_16BIT,             MEM_16384},
                     77:        {"SMC8216T",    TYPE_SMC8216T,  FLAG_16BIT | FLAG_790,  MEM_16384},
                     78:        {"SMC8216C",    TYPE_SMC8216C,  FLAG_16BIT | FLAG_790,  MEM_16384},
                     79:        {"SMC8416T",    TYPE_SMC8416T,  FLAG_16BIT | FLAG_790,  MEM_8192},
                     80:        {"SMC8416C/BT", TYPE_SMC8416C,  FLAG_16BIT | FLAG_790,  MEM_8192},
                     81:        {"SMC8013EBP",  TYPE_SMC8013EBP,FLAG_16BIT,             MEM_16384},
                     82:        {NULL,          0,              0,                      0}
                     83: };
                     84: #endif
                     85: 
                     86: #ifdef INCLUDE_3C503
                     87: static unsigned char   t503_output;    /* AUI or internal xcvr (Thinnet) */
                     88: #endif
                     89: 
                     90: #if    defined(INCLUDE_WD)
                     91: #define        ASIC_PIO        WD_IAR
                     92: #define        eth_probe       wd_probe
                     93: #if    defined(INCLUDE_3C503) || defined(INCLUDE_NE) || defined(INCLUDE_NS8390)
                     94: Error you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE, INCLUDE_NS8390
                     95: #endif
                     96: #endif
                     97: 
                     98: #if    defined(INCLUDE_3C503)
                     99: #define        eth_probe       t503_probe
                    100: #if    defined(INCLUDE_NE) || defined(INCLUDE_NS8390) || defined(INCLUDE_WD)
                    101: Error you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE, INCLUDE_NS8390
                    102: #endif
                    103: #endif
                    104: 
                    105: #if    defined(INCLUDE_NE)
                    106: #define        eth_probe       ne_probe
                    107: #if    defined(INCLUDE_NS8390) || defined(INCLUDE_3C503) || defined(INCLUDE_WD)
                    108: Error you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE, INCLUDE_NS8390
                    109: #endif
                    110: #endif
                    111: 
                    112: #if    defined(INCLUDE_NS8390)
                    113: #define        eth_probe       nepci_probe
                    114: #if    defined(INCLUDE_NE) || defined(INCLUDE_3C503) || defined(INCLUDE_WD)
                    115: Error you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE, INCLUDE_NS8390
                    116: #endif
                    117: #endif
                    118: 
                    119: #if    defined(INCLUDE_3C503)
                    120: #define        ASIC_PIO        _3COM_RFMSB
                    121: #else
                    122: #if    defined(INCLUDE_NE) || defined(INCLUDE_NS8390)
                    123: #define        ASIC_PIO        NE_DATA
                    124: #endif
                    125: #endif
                    126: 
                    127: #if    defined(INCLUDE_NE) || defined(INCLUDE_NS8390) || (defined(INCLUDE_3C503) && !defined(T503_SHMEM)) || (defined(INCLUDE_WD) && defined(WD_790_PIO))
                    128: /**************************************************************************
                    129: ETH_PIO_READ - Read a frame via Programmed I/O
                    130: **************************************************************************/
                    131: static void eth_pio_read(unsigned int src, unsigned char *dst, unsigned int cnt)
                    132: {
                    133: #ifdef INCLUDE_WD
                    134:        outb(src & 0xff, eth_asic_base + WD_GP2);
                    135:        outb(src >> 8, eth_asic_base + WD_GP2);
                    136: #else
                    137:        outb(D8390_COMMAND_RD2 |
                    138:                D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND);
                    139:        outb(cnt, eth_nic_base + D8390_P0_RBCR0);
                    140:        outb(cnt>>8, eth_nic_base + D8390_P0_RBCR1);
                    141:        outb(src, eth_nic_base + D8390_P0_RSAR0);
                    142:        outb(src>>8, eth_nic_base + D8390_P0_RSAR1);
                    143:        outb(D8390_COMMAND_RD0 |
                    144:                D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND);
                    145: 
                    146: #ifdef INCLUDE_3C503
                    147:        outb(src & 0xff, eth_asic_base + _3COM_DALSB);
                    148:        outb(src >> 8, eth_asic_base + _3COM_DAMSB);
                    149:        outb(t503_output | _3COM_CR_START, eth_asic_base + _3COM_CR);
                    150: #endif
                    151: #endif
                    152: 
                    153:        if (eth_flags & FLAG_16BIT)
                    154:                cnt = (cnt + 1) >> 1;
                    155: 
                    156:        while(cnt--) {
                    157: #ifdef INCLUDE_3C503
                    158:                while((inb(eth_asic_base + _3COM_STREG) & _3COM_STREG_DPRDY) == 0)
                    159:                        ;
                    160: #endif
                    161: 
                    162:                if (eth_flags & FLAG_16BIT) {
                    163:                        *((unsigned short *)dst) = inw(eth_asic_base + ASIC_PIO);
                    164:                        dst += 2;
                    165:                }
                    166:                else
                    167:                        *(dst++) = inb(eth_asic_base + ASIC_PIO);
                    168:        }
                    169: 
                    170: #ifdef INCLUDE_3C503
                    171:        outb(t503_output, eth_asic_base + _3COM_CR);
                    172: #endif
                    173: }
                    174: 
                    175: /**************************************************************************
                    176: ETH_PIO_WRITE - Write a frame via Programmed I/O
                    177: **************************************************************************/
                    178: static void eth_pio_write(const unsigned char *src, unsigned int dst, unsigned int cnt)
                    179: {
                    180: #ifdef COMPEX_RL2000_FIX
                    181:        unsigned int x;
                    182: #endif /* COMPEX_RL2000_FIX */
                    183: #ifdef INCLUDE_WD
                    184:        outb(dst & 0xff, eth_asic_base + WD_GP2);
                    185:        outb(dst >> 8, eth_asic_base + WD_GP2);
                    186: #else
                    187:        outb(D8390_COMMAND_RD2 |
                    188:                D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND);
                    189:        outb(D8390_ISR_RDC, eth_nic_base + D8390_P0_ISR);
                    190:        outb(cnt, eth_nic_base + D8390_P0_RBCR0);
                    191:        outb(cnt>>8, eth_nic_base + D8390_P0_RBCR1);
                    192:        outb(dst, eth_nic_base + D8390_P0_RSAR0);
                    193:        outb(dst>>8, eth_nic_base + D8390_P0_RSAR1);
                    194:        outb(D8390_COMMAND_RD1 |
                    195:                D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND);
                    196: 
                    197: #ifdef INCLUDE_3C503
                    198:        outb(dst & 0xff, eth_asic_base + _3COM_DALSB);
                    199:        outb(dst >> 8, eth_asic_base + _3COM_DAMSB);
                    200: 
                    201:        outb(t503_output | _3COM_CR_DDIR | _3COM_CR_START, eth_asic_base + _3COM_CR);
                    202: #endif
                    203: #endif
                    204: 
                    205:        if (eth_flags & FLAG_16BIT)
                    206:                cnt = (cnt + 1) >> 1;
                    207: 
                    208:        while(cnt--)
                    209:        {
                    210: #ifdef INCLUDE_3C503
                    211:                while((inb(eth_asic_base + _3COM_STREG) & _3COM_STREG_DPRDY) == 0)
                    212:                        ;
                    213: #endif
                    214: 
                    215:                if (eth_flags & FLAG_16BIT) {
                    216:                        outw(*((unsigned short *)src), eth_asic_base + ASIC_PIO);
                    217:                        src += 2;
                    218:                }
                    219:                else
                    220:                        outb(*(src++), eth_asic_base + ASIC_PIO);
                    221:        }
                    222: 
                    223: #ifdef INCLUDE_3C503
                    224:        outb(t503_output, eth_asic_base + _3COM_CR);
                    225: #else
                    226: #ifdef COMPEX_RL2000_FIX
                    227:        for (x = 0;
                    228:                x < COMPEX_RL2000_TRIES &&
                    229:                (inb(eth_nic_base + D8390_P0_ISR) & D8390_ISR_RDC)
                    230:                != D8390_ISR_RDC;
                    231:                ++x);
                    232:        if (x >= COMPEX_RL2000_TRIES)
                    233:                printf("Warning: Compex RL2000 aborted wait!\n");
                    234: #endif /* COMPEX_RL2000_FIX */
                    235: #ifndef        INCLUDE_WD
                    236:        while((inb(eth_nic_base + D8390_P0_ISR) & D8390_ISR_RDC)
                    237:                != D8390_ISR_RDC);
                    238: #endif
                    239: #endif
                    240: }
                    241: #else
                    242: /**************************************************************************
                    243: ETH_PIO_READ - Dummy routine when NE2000 not compiled in
                    244: **************************************************************************/
                    245: static void eth_pio_read(unsigned int src __unused, unsigned char *dst  __unused, unsigned int cnt __unused) {}
                    246: #endif
                    247: 
                    248: 
                    249: /**************************************************************************
                    250: enable_multycast - Enable Multicast
                    251: **************************************************************************/
                    252: static void enable_multicast(unsigned short eth_nic_base) 
                    253: {
                    254:        unsigned char mcfilter[8];
                    255:        int i;
                    256:        memset(mcfilter, 0xFF, 8);
                    257:        outb(4, eth_nic_base+D8390_P0_RCR);     
                    258:        outb(D8390_COMMAND_RD2 + D8390_COMMAND_PS1, eth_nic_base + D8390_P0_COMMAND);
                    259:        for(i=0;i<8;i++)
                    260:        {
                    261:                outb(mcfilter[i], eth_nic_base + 8 + i);
                    262:                if(inb(eth_nic_base + 8 + i)!=mcfilter[i])
                    263:                        printf("Error SMC 83C690 Multicast filter read/write mishap %d\n",i);
                    264:        }
                    265:        outb(D8390_COMMAND_RD2 + D8390_COMMAND_PS0, eth_nic_base + D8390_P0_COMMAND);
                    266:        outb(4 | 0x08, eth_nic_base+D8390_P0_RCR);
                    267: }
                    268: 
                    269: /**************************************************************************
                    270: NS8390_RESET - Reset adapter
                    271: **************************************************************************/
                    272: static void ns8390_reset(struct nic *nic)
                    273: {
                    274:        int i;
                    275: 
                    276:        eth_drain_receiver = 0;
                    277: #ifdef INCLUDE_WD
                    278:        if (eth_flags & FLAG_790)
                    279:                outb(D8390_COMMAND_PS0 | D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
                    280:        else
                    281: #endif
                    282:                outb(D8390_COMMAND_PS0 | D8390_COMMAND_RD2 |
                    283:                        D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
                    284:        if (eth_flags & FLAG_16BIT)
                    285:                outb(0x49, eth_nic_base+D8390_P0_DCR);
                    286:        else
                    287:                outb(0x48, eth_nic_base+D8390_P0_DCR);
                    288:        outb(0, eth_nic_base+D8390_P0_RBCR0);
                    289:        outb(0, eth_nic_base+D8390_P0_RBCR1);
                    290:        outb(0x20, eth_nic_base+D8390_P0_RCR);  /* monitor mode */
                    291:        outb(2, eth_nic_base+D8390_P0_TCR);
                    292:        outb(eth_tx_start, eth_nic_base+D8390_P0_TPSR);
                    293:        outb(eth_rx_start, eth_nic_base+D8390_P0_PSTART);
                    294: #ifdef INCLUDE_WD
                    295:        if (eth_flags & FLAG_790) {
                    296: #ifdef WD_790_PIO
                    297:                outb(0x10, eth_asic_base + 0x06); /* disable interrupts, enable PIO */
                    298:                outb(0x01, eth_nic_base + 0x09); /* enable ring read auto-wrap */
                    299: #else
                    300:                outb(0, eth_nic_base + 0x09);
                    301: #endif
                    302:        }
                    303: #endif
                    304:        outb(eth_memsize, eth_nic_base+D8390_P0_PSTOP);
                    305:        outb(eth_memsize - 1, eth_nic_base+D8390_P0_BOUND);
                    306:        outb(0xFF, eth_nic_base+D8390_P0_ISR);
                    307:        outb(0, eth_nic_base+D8390_P0_IMR);
                    308: #ifdef INCLUDE_WD
                    309:        if (eth_flags & FLAG_790)
                    310:                outb(D8390_COMMAND_PS1 |
                    311:                        D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
                    312:        else
                    313: #endif
                    314:                outb(D8390_COMMAND_PS1 |
                    315:                        D8390_COMMAND_RD2 | D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
                    316:        for (i=0; i<ETH_ALEN; i++)
                    317:                outb(nic->node_addr[i], eth_nic_base+D8390_P1_PAR0+i);
                    318:        for (i=0; i<ETH_ALEN; i++)
                    319:                outb(0xFF, eth_nic_base+D8390_P1_MAR0+i);
                    320:        outb(eth_rx_start, eth_nic_base+D8390_P1_CURR);
                    321: #ifdef INCLUDE_WD
                    322:        if (eth_flags & FLAG_790)
                    323:                outb(D8390_COMMAND_PS0 |
                    324:                        D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
                    325:        else
                    326: #endif
                    327:                outb(D8390_COMMAND_PS0 |
                    328:                        D8390_COMMAND_RD2 | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
                    329:        outb(0xFF, eth_nic_base+D8390_P0_ISR);
                    330:        outb(0, eth_nic_base+D8390_P0_TCR);     /* transmitter on */
                    331:        outb(4, eth_nic_base+D8390_P0_RCR);     /* allow rx broadcast frames */
                    332: 
                    333:        enable_multicast(eth_nic_base);
                    334: 
                    335: #ifdef INCLUDE_3C503
                    336:         /*
                    337:          * No way to tell whether or not we're supposed to use
                    338:          * the 3Com's transceiver unless the user tells us.
                    339:          * 'flags' should have some compile time default value
                    340:          * which can be changed from the command menu.
                    341:          */
                    342:        t503_output = (nic->flags) ? 0 : _3COM_CR_XSEL;
                    343:        outb(t503_output, eth_asic_base + _3COM_CR);
                    344: #endif
                    345: }
                    346: 
                    347: static int ns8390_poll(struct nic *nic, int retrieve);
                    348: 
                    349: #ifndef        INCLUDE_3C503
                    350: /**************************************************************************
                    351: ETH_RX_OVERRUN - Bring adapter back to work after an RX overrun
                    352: **************************************************************************/
                    353: static void eth_rx_overrun(struct nic *nic)
                    354: {
                    355:        int start_time;
                    356: 
                    357: #ifdef INCLUDE_WD
                    358:        if (eth_flags & FLAG_790)
                    359:                outb(D8390_COMMAND_PS0 | D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
                    360:        else
                    361: #endif
                    362:                outb(D8390_COMMAND_PS0 | D8390_COMMAND_RD2 |
                    363:                        D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
                    364: 
                    365:        /* wait for at least 1.6ms - we wait one timer tick */
                    366:        start_time = currticks();
                    367:        while (currticks() - start_time <= 1)
                    368:                /* Nothing */;
                    369: 
                    370:        outb(0, eth_nic_base+D8390_P0_RBCR0);   /* reset byte counter */
                    371:        outb(0, eth_nic_base+D8390_P0_RBCR1);
                    372: 
                    373:        /*
                    374:         * Linux driver checks for interrupted TX here. This is not necessary,
                    375:         * because the transmit routine waits until the frame is sent.
                    376:         */
                    377: 
                    378:        /* enter loopback mode and restart NIC */
                    379:        outb(2, eth_nic_base+D8390_P0_TCR);
                    380: #ifdef INCLUDE_WD
                    381:        if (eth_flags & FLAG_790)
                    382:                outb(D8390_COMMAND_PS0 | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
                    383:        else
                    384: #endif
                    385:                outb(D8390_COMMAND_PS0 | D8390_COMMAND_RD2 |
                    386:                        D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
                    387: 
                    388:        /* clear the RX ring, acknowledge overrun interrupt */
                    389:        eth_drain_receiver = 1;
                    390:        while (ns8390_poll(nic, 1))
                    391:                /* Nothing */;
                    392:        eth_drain_receiver = 0;
                    393:        outb(D8390_ISR_OVW, eth_nic_base+D8390_P0_ISR);
                    394: 
                    395:        /* leave loopback mode - no packets to be resent (see Linux driver) */
                    396:        outb(0, eth_nic_base+D8390_P0_TCR);
                    397: }
                    398: #endif /* INCLUDE_3C503 */
                    399: 
                    400: /**************************************************************************
                    401: NS8390_TRANSMIT - Transmit a frame
                    402: **************************************************************************/
                    403: static void ns8390_transmit(
                    404:        struct nic *nic,
                    405:        const char *d,                  /* Destination */
                    406:        unsigned int t,                 /* Type */
                    407:        unsigned int s,                 /* size */
                    408:        const char *p)                  /* Packet */
                    409: {
                    410: #if defined(INCLUDE_3C503) || (defined(INCLUDE_WD) && ! defined(WD_790_PIO))
                    411:        Address         eth_vmem = bus_to_virt(eth_bmem);
                    412: #endif
                    413: #ifdef INCLUDE_3C503
                    414:         if (!(eth_flags & FLAG_PIO)) {
                    415:                 memcpy((char *)eth_vmem, d, ETH_ALEN); /* dst */
                    416:                 memcpy((char *)eth_vmem+ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */
                    417:                 *((char *)eth_vmem+12) = t>>8;         /* type */
                    418:                 *((char *)eth_vmem+13) = t;
                    419:                 memcpy((char *)eth_vmem+ETH_HLEN, p, s);
                    420:                 s += ETH_HLEN;
                    421:                 while (s < ETH_ZLEN) *((char *)eth_vmem+(s++)) = 0;
                    422:         }
                    423: #endif
                    424: 
                    425: #ifdef INCLUDE_WD
                    426:        if (eth_flags & FLAG_16BIT) {
                    427:                outb(eth_laar | WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
                    428:                inb(0x84);
                    429:        }
                    430: #ifndef        WD_790_PIO
                    431:        /* Memory interface */
                    432:        if (eth_flags & FLAG_790) {
                    433:                outb(WD_MSR_MENB, eth_asic_base + WD_MSR);
                    434:                inb(0x84);
                    435:        }
                    436:        inb(0x84);
                    437:        memcpy((char *)eth_vmem, d, ETH_ALEN);  /* dst */
                    438:        memcpy((char *)eth_vmem+ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */
                    439:        *((char *)eth_vmem+12) = t>>8;          /* type */
                    440:        *((char *)eth_vmem+13) = t;
                    441:        memcpy((char *)eth_vmem+ETH_HLEN, p, s);
                    442:        s += ETH_HLEN;
                    443:        while (s < ETH_ZLEN) *((char *)eth_vmem+(s++)) = 0;
                    444:        if (eth_flags & FLAG_790) {
                    445:                outb(0, eth_asic_base + WD_MSR);
                    446:                inb(0x84);
                    447:        }
                    448: #else
                    449:        inb(0x84);
                    450: #endif
                    451: #endif
                    452: 
                    453: #if    defined(INCLUDE_3C503)
                    454:        if (eth_flags & FLAG_PIO)
                    455: #endif
                    456: #if    defined(INCLUDE_NE) || defined(INCLUDE_NS8390) || (defined(INCLUDE_3C503) && !defined(T503_SHMEM)) || (defined(INCLUDE_WD) && defined(WD_790_PIO))
                    457:        {
                    458:                /* Programmed I/O */
                    459:                unsigned short type;
                    460:                type = (t >> 8) | (t << 8);
                    461:                eth_pio_write( (unsigned char *) d, eth_tx_start<<8, ETH_ALEN);
                    462:                eth_pio_write(nic->node_addr, (eth_tx_start<<8)+ETH_ALEN, ETH_ALEN);
                    463:                /* bcc generates worse code without (const+const) below */
                    464:                eth_pio_write((unsigned char *)&type, (eth_tx_start<<8)+(ETH_ALEN+ETH_ALEN), 2);
                    465:                eth_pio_write( (unsigned char *) p, (eth_tx_start<<8)+ETH_HLEN, s);
                    466:                s += ETH_HLEN;
                    467:                if (s < ETH_ZLEN) s = ETH_ZLEN;
                    468:        }
                    469: #endif
                    470: #if    defined(INCLUDE_3C503)
                    471: #endif
                    472: 
                    473: #ifdef INCLUDE_WD
                    474:        if (eth_flags & FLAG_16BIT) {
                    475:                outb(eth_laar & ~WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
                    476:                inb(0x84);
                    477:        }
                    478:        if (eth_flags & FLAG_790)
                    479:                outb(D8390_COMMAND_PS0 |
                    480:                        D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
                    481:        else
                    482: #endif
                    483:                outb(D8390_COMMAND_PS0 |
                    484:                        D8390_COMMAND_RD2 | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
                    485:        outb(eth_tx_start, eth_nic_base+D8390_P0_TPSR);
                    486:        outb(s, eth_nic_base+D8390_P0_TBCR0);
                    487:        outb(s>>8, eth_nic_base+D8390_P0_TBCR1);
                    488: #ifdef INCLUDE_WD
                    489:        if (eth_flags & FLAG_790)
                    490:                outb(D8390_COMMAND_PS0 |
                    491:                        D8390_COMMAND_TXP | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
                    492:        else
                    493: #endif
                    494:                outb(D8390_COMMAND_PS0 |
                    495:                        D8390_COMMAND_TXP | D8390_COMMAND_RD2 |
                    496:                        D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
                    497: }
                    498: 
                    499: /**************************************************************************
                    500: NS8390_POLL - Wait for a frame
                    501: **************************************************************************/
                    502: static int ns8390_poll(struct nic *nic, int retrieve)
                    503: {
                    504:        int ret = 0;
                    505:        unsigned char rstat, curr, next;
                    506:        unsigned short len, frag;
                    507:        unsigned short pktoff;
                    508:        unsigned char *p;
                    509:        struct ringbuffer pkthdr;
                    510: 
                    511: #ifndef        INCLUDE_3C503
                    512:        /* avoid infinite recursion: see eth_rx_overrun() */
                    513:        if (!eth_drain_receiver && (inb(eth_nic_base+D8390_P0_ISR) & D8390_ISR_OVW)) {
                    514:                eth_rx_overrun(nic);
                    515:                return(0);
                    516:        }
                    517: #endif /* INCLUDE_3C503 */
                    518:        rstat = inb(eth_nic_base+D8390_P0_RSR);
                    519:        if (!(rstat & D8390_RSTAT_PRX)) return(0);
                    520:        next = inb(eth_nic_base+D8390_P0_BOUND)+1;
                    521:        if (next >= eth_memsize) next = eth_rx_start;
                    522:        outb(D8390_COMMAND_PS1, eth_nic_base+D8390_P0_COMMAND);
                    523:        curr = inb(eth_nic_base+D8390_P1_CURR);
                    524:        outb(D8390_COMMAND_PS0, eth_nic_base+D8390_P0_COMMAND);
                    525:        if (curr >= eth_memsize) curr=eth_rx_start;
                    526:        if (curr == next) return(0);
                    527: 
                    528:        if ( ! retrieve ) return 1;
                    529: 
                    530: #ifdef INCLUDE_WD
                    531:        if (eth_flags & FLAG_16BIT) {
                    532:                outb(eth_laar | WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
                    533:                inb(0x84);
                    534:        }
                    535: #ifndef        WD_790_PIO
                    536:        if (eth_flags & FLAG_790) {
                    537:                outb(WD_MSR_MENB, eth_asic_base + WD_MSR);
                    538:                inb(0x84);
                    539:        }
                    540: #endif
                    541:        inb(0x84);
                    542: #endif
                    543:        pktoff = next << 8;
                    544:        if (eth_flags & FLAG_PIO)
                    545:                eth_pio_read(pktoff, (unsigned char *)&pkthdr, 4);
                    546:        else
                    547:                memcpy(&pkthdr, bus_to_virt(eth_rmem + pktoff), 4);
                    548:        pktoff += sizeof(pkthdr);
                    549:        /* incoming length includes FCS so must sub 4 */
                    550:        len = pkthdr.len - 4;
                    551:        if ((pkthdr.status & D8390_RSTAT_PRX) == 0 || len < ETH_ZLEN
                    552:                || len > ETH_FRAME_LEN) {
                    553:                printf("Bogus packet, ignoring\n");
                    554:                return (0);
                    555:        }
                    556:        else {
                    557:                p = nic->packet;
                    558:                nic->packetlen = len;           /* available to caller */
                    559:                frag = (eth_memsize << 8) - pktoff;
                    560:                if (len > frag) {               /* We have a wrap-around */
                    561:                        /* read first part */
                    562:                        if (eth_flags & FLAG_PIO)
                    563:                                eth_pio_read(pktoff, p, frag);
                    564:                        else
                    565:                                memcpy(p, bus_to_virt(eth_rmem + pktoff), frag);
                    566:                        pktoff = eth_rx_start << 8;
                    567:                        p += frag;
                    568:                        len -= frag;
                    569:                }
                    570:                /* read second part */
                    571:                if (eth_flags & FLAG_PIO)
                    572:                        eth_pio_read(pktoff, p, len);
                    573:                else
                    574:                        memcpy(p, bus_to_virt(eth_rmem + pktoff), len);
                    575:                ret = 1;
                    576:        }
                    577: #ifdef INCLUDE_WD
                    578: #ifndef        WD_790_PIO
                    579:        if (eth_flags & FLAG_790) {
                    580:                outb(0, eth_asic_base + WD_MSR);
                    581:                inb(0x84);
                    582:        }
                    583: #endif
                    584:        if (eth_flags & FLAG_16BIT) {
                    585:                outb(eth_laar & ~WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
                    586:                inb(0x84);
                    587:        }
                    588:        inb(0x84);
                    589: #endif
                    590:        next = pkthdr.next;             /* frame number of next packet */
                    591:        if (next == eth_rx_start)
                    592:                next = eth_memsize;
                    593:        outb(next-1, eth_nic_base+D8390_P0_BOUND);
                    594:        return(ret);
                    595: }
                    596: 
                    597: /**************************************************************************
                    598: NS8390_DISABLE - Turn off adapter
                    599: **************************************************************************/
                    600: static void ns8390_disable ( struct nic *nic ) {
                    601:        ns8390_reset(nic);
                    602: }
                    603: 
                    604: /**************************************************************************
                    605: NS8390_IRQ - Enable, Disable, or Force interrupts
                    606: **************************************************************************/
                    607: static void ns8390_irq(struct nic *nic __unused, irq_action_t action __unused)
                    608: {
                    609:   switch ( action ) {
                    610:   case DISABLE :
                    611:     break;
                    612:   case ENABLE :
                    613:     break;
                    614:   case FORCE :
                    615:     break;
                    616:   }
                    617: }
                    618: 
                    619: static struct nic_operations ns8390_operations;
                    620: static struct nic_operations ns8390_operations = {
                    621:        .connect        = dummy_connect,
                    622:        .poll           = ns8390_poll,
                    623:        .transmit       = ns8390_transmit,
                    624:        .irq            = ns8390_irq,
                    625: };
                    626: 
                    627: /**************************************************************************
                    628: ETH_PROBE - Look for an adapter
                    629: **************************************************************************/
                    630: #ifdef INCLUDE_NS8390
                    631: static int eth_probe (struct nic *nic, struct pci_device *pci)
                    632: #else
                    633: static int eth_probe (struct dev *dev, unsigned short *probe_addrs __unused)
                    634: #endif
                    635: {
                    636:        int i;
                    637: #ifdef INCLUDE_NS8390
                    638:        unsigned short pci_probe_addrs[] = { pci->ioaddr, 0 };
                    639:        unsigned short *probe_addrs = pci_probe_addrs;
                    640: #endif
                    641:        eth_vendor = VENDOR_NONE;
                    642:        eth_drain_receiver = 0;
                    643: 
                    644:        nic->irqno  = 0;
                    645: 
                    646: #ifdef INCLUDE_WD
                    647: {
                    648:        /******************************************************************
                    649:        Search for WD/SMC cards
                    650:        ******************************************************************/
                    651:        struct wd_board *brd;
                    652:        unsigned short chksum;
                    653:        unsigned char c;
                    654:        for (eth_asic_base = WD_LOW_BASE; eth_asic_base <= WD_HIGH_BASE;
                    655:                eth_asic_base += 0x20) {
                    656:                chksum = 0;
                    657:                for (i=8; i<16; i++)
                    658:                        chksum += inb(eth_asic_base+i);
                    659:                /* Extra checks to avoid soundcard */
                    660:                if ((chksum & 0xFF) == 0xFF &&
                    661:                        inb(eth_asic_base+8) != 0xFF &&
                    662:                        inb(eth_asic_base+9) != 0xFF)
                    663:                        break;
                    664:        }
                    665:        if (eth_asic_base > WD_HIGH_BASE)
                    666:                return (0);
                    667:        /* We've found a board */
                    668:        eth_vendor = VENDOR_WD;
                    669:        eth_nic_base = eth_asic_base + WD_NIC_ADDR;
                    670: 
                    671:        nic->ioaddr = eth_nic_base;
                    672: 
                    673:        c = inb(eth_asic_base+WD_BID);  /* Get board id */
                    674:        for (brd = wd_boards; brd->name; brd++)
                    675:                if (brd->id == c) break;
                    676:        if (!brd->name) {
                    677:                printf("Unknown WD/SMC NIC type %hhX\n", c);
                    678:                return (0);     /* Unknown type */
                    679:        }
                    680:        eth_flags = brd->flags;
                    681:        eth_memsize = brd->memsize;
                    682:        eth_tx_start = 0;
                    683:        eth_rx_start = D8390_TXBUF_SIZE;
                    684:        if ((c == TYPE_WD8013EP) &&
                    685:                (inb(eth_asic_base + WD_ICR) & WD_ICR_16BIT)) {
                    686:                        eth_flags = FLAG_16BIT;
                    687:                        eth_memsize = MEM_16384;
                    688:        }
                    689:        if ((c & WD_SOFTCONFIG) && (!(eth_flags & FLAG_790))) {
                    690:                eth_bmem = (0x80000 |
                    691:                 ((inb(eth_asic_base + WD_MSR) & 0x3F) << 13));
                    692:        } else
                    693:                eth_bmem = WD_DEFAULT_MEM;
                    694:        if (brd->id == TYPE_SMC8216T || brd->id == TYPE_SMC8216C) {
                    695:                /* from Linux driver, 8416BT detects as 8216 sometimes */
                    696:                unsigned int addr = inb(eth_asic_base + 0xb);
                    697:                if (((addr >> 4) & 3) == 0) {
                    698:                        brd += 2;
                    699:                        eth_memsize = brd->memsize;
                    700:                }
                    701:        }
                    702:        outb(0x80, eth_asic_base + WD_MSR);     /* Reset */
                    703:        for (i=0; i<ETH_ALEN; i++) {
                    704:                nic->node_addr[i] = inb(i+eth_asic_base+WD_LAR);
                    705:        }
                    706:        DBG ( "\n%s base %4.4x", brd->name, eth_asic_base );
                    707:        if (eth_flags & FLAG_790) {
                    708: #ifdef WD_790_PIO
                    709:                DBG ( ", PIO mode, addr %s\n", eth_ntoa ( nic->node_addr ) );
                    710:                eth_bmem = 0;
                    711:                eth_flags |= FLAG_PIO;          /* force PIO mode */
                    712:                outb(0, eth_asic_base+WD_MSR);
                    713: #else
                    714:                DBG ( ", Memory %x, MAC Addr %s\n", eth_bmem, eth_ntoa ( nic->node_addr) );
                    715: 
                    716:                outb(WD_MSR_MENB, eth_asic_base+WD_MSR);
                    717:                outb((inb(eth_asic_base+0x04) |
                    718:                        0x80), eth_asic_base+0x04);
                    719:                outb(((unsigned)(eth_bmem >> 13) & 0x0F) |
                    720:                        ((unsigned)(eth_bmem >> 11) & 0x40) |
                    721:                        (inb(eth_asic_base+0x0B) & 0xB0), eth_asic_base+0x0B);
                    722:                outb((inb(eth_asic_base+0x04) &
                    723:                        ~0x80), eth_asic_base+0x04);
                    724: #endif
                    725:        } else {
                    726: 
                    727:                DBG (", Memory %x, MAC Addr %s\n", eth_bmem, eth_ntoa ( nic->node_addr) );
                    728: 
                    729:                outb(((unsigned)(eth_bmem >> 13) & 0x3F) | 0x40, eth_asic_base+WD_MSR);
                    730:        }
                    731:        if (eth_flags & FLAG_16BIT) {
                    732:                if (eth_flags & FLAG_790) {
                    733:                        eth_laar = inb(eth_asic_base + WD_LAAR);
                    734:                        outb(WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
                    735:                } else {
                    736:                        outb((eth_laar =
                    737:                                WD_LAAR_L16EN | 1), eth_asic_base + WD_LAAR);
                    738: /*
                    739:        The previous line used to be
                    740:                                WD_LAAR_M16EN | WD_LAAR_L16EN | 1));
                    741:        [email protected] reported that removing WD_LAAR_M16EN made
                    742:        it work for WD8013s.  This seems to work for my 8013 boards. I
                    743:        don't know what is really happening.  I wish I had data sheets
                    744:        or more time to decode the Linux driver. - Ken
                    745: */
                    746:                }
                    747:                inb(0x84);
                    748:        }
                    749: }
                    750: #endif
                    751: #ifdef INCLUDE_3C503
                    752: #ifdef T503_AUI
                    753:        nic->flags = 1;         /* aui */
                    754: #else
                    755:        nic->flags = 0;         /* no aui */
                    756: #endif
                    757:         /******************************************************************
                    758:         Search for 3Com 3c503 if no WD/SMC cards
                    759:         ******************************************************************/
                    760:        if (eth_vendor == VENDOR_NONE) {
                    761:                int     idx;
                    762:                int     iobase_reg, membase_reg;
                    763:                static unsigned short   base[] = {
                    764:                        0x300, 0x310, 0x330, 0x350,
                    765:                        0x250, 0x280, 0x2A0, 0x2E0, 0 };
                    766: 
                    767:                /* Loop through possible addresses checking each one */
                    768: 
                    769:                for (idx = 0; (eth_nic_base = base[idx]) != 0; ++idx) {
                    770: 
                    771:                        eth_asic_base = eth_nic_base + _3COM_ASIC_OFFSET;
                    772: /*
                    773:  * Note that we use the same settings for both 8 and 16 bit cards:
                    774:  * both have an 8K bank of memory at page 1 while only the 16 bit
                    775:  * cards have a bank at page 0.
                    776:  */
                    777:                        eth_memsize = MEM_16384;
                    778:                        eth_tx_start = 32;
                    779:                        eth_rx_start = 32 + D8390_TXBUF_SIZE;
                    780: 
                    781:                /* Check our base address. iobase and membase should */
                    782:                /* both have a maximum of 1 bit set or be 0. */
                    783: 
                    784:                        iobase_reg = inb(eth_asic_base + _3COM_BCFR);
                    785:                        membase_reg = inb(eth_asic_base + _3COM_PCFR);
                    786: 
                    787:                        if ((iobase_reg & (iobase_reg - 1)) ||
                    788:                                (membase_reg & (membase_reg - 1)))
                    789:                                continue;               /* nope */
                    790: 
                    791:                /* Now get the shared memory address */
                    792: 
                    793:                        eth_flags = 0;
                    794: 
                    795:                        switch (membase_reg) {
                    796:                                case _3COM_PCFR_DC000:
                    797:                                        eth_bmem = 0xdc000;
                    798:                                        break;
                    799:                                case _3COM_PCFR_D8000:
                    800:                                        eth_bmem = 0xd8000;
                    801:                                        break;
                    802:                                case _3COM_PCFR_CC000:
                    803:                                        eth_bmem = 0xcc000;
                    804:                                        break;
                    805:                                case _3COM_PCFR_C8000:
                    806:                                        eth_bmem = 0xc8000;
                    807:                                        break;
                    808:                                case _3COM_PCFR_PIO:
                    809:                                        eth_flags |= FLAG_PIO;
                    810:                                        eth_bmem = 0;
                    811:                                        break;
                    812:                                default:
                    813:                                        continue;       /* nope */
                    814:                                }
                    815:                        break;
                    816:                }
                    817: 
                    818:                if (base[idx] == 0)             /* not found */
                    819:                        return (0);
                    820: #ifndef        T503_SHMEM
                    821:                eth_flags |= FLAG_PIO;          /* force PIO mode */
                    822:                eth_bmem = 0;
                    823: #endif
                    824:                eth_vendor = VENDOR_3COM;
                    825: 
                    826: 
                    827:         /* Need this to make ns8390_poll() happy. */
                    828: 
                    829:                 eth_rmem = eth_bmem - 0x2000;
                    830: 
                    831:         /* Reset NIC and ASIC */
                    832: 
                    833:                 outb(_3COM_CR_RST | _3COM_CR_XSEL, eth_asic_base + _3COM_CR );
                    834:                 outb(_3COM_CR_XSEL, eth_asic_base + _3COM_CR );
                    835: 
                    836:         /* Get our ethernet address */
                    837: 
                    838:                 outb(_3COM_CR_EALO | _3COM_CR_XSEL, eth_asic_base + _3COM_CR);
                    839:                nic->ioaddr = eth_nic_base;
                    840:                 DBG ( "\n3Com 3c503 base %4.4x, ", eth_nic_base );
                    841:                 if (eth_flags & FLAG_PIO)
                    842:                        DBG ( "PIO mode" );
                    843:                 else
                    844:                        DBG ( "memory %4.4x", eth_bmem );
                    845:                 for (i=0; i<ETH_ALEN; i++) {
                    846:                         nic->node_addr[i] = inb(eth_nic_base+i);
                    847:                 }
                    848:                 DBG ( ", %s, MAC Addr %s\n", nic->flags ? "AUI" : "internal xcvr",
                    849:                      eth_ntoa ( nic->node_addr ) );
                    850: 
                    851:                 outb(_3COM_CR_XSEL, eth_asic_base + _3COM_CR);
                    852:         /*
                    853:          * Initialize GA configuration register. Set bank and enable shared
                    854:          * mem. We always use bank 1. Disable interrupts.
                    855:          */
                    856:                 outb(_3COM_GACFR_RSEL |
                    857:                        _3COM_GACFR_MBS0 | _3COM_GACFR_TCM | _3COM_GACFR_NIM, eth_asic_base + _3COM_GACFR);
                    858: 
                    859:                 outb(0xff, eth_asic_base + _3COM_VPTR2);
                    860:                 outb(0xff, eth_asic_base + _3COM_VPTR1);
                    861:                 outb(0x00, eth_asic_base + _3COM_VPTR0);
                    862:         /*
                    863:          * Clear memory and verify that it worked (we use only 8K)
                    864:          */
                    865: 
                    866:                if (!(eth_flags & FLAG_PIO)) {
                    867:                        memset(bus_to_virt(eth_bmem), 0, 0x2000);
                    868:                        for(i = 0; i < 0x2000; ++i)
                    869:                                if (*((char *)(bus_to_virt(eth_bmem+i)))) {
                    870:                                        printf ("Failed to clear 3c503 shared mem.\n");
                    871:                                        return (0);
                    872:                                }
                    873:                }
                    874:         /*
                    875:          * Initialize GA page/start/stop registers.
                    876:          */
                    877:                 outb(eth_tx_start, eth_asic_base + _3COM_PSTR);
                    878:                 outb(eth_memsize, eth_asic_base + _3COM_PSPR);
                    879:         }
                    880: #endif
                    881: #if    defined(INCLUDE_NE) || defined(INCLUDE_NS8390)
                    882: {
                    883:        /******************************************************************
                    884:        Search for NE1000/2000 if no WD/SMC or 3com cards
                    885:        ******************************************************************/
                    886:        unsigned char c;
                    887:        if (eth_vendor == VENDOR_NONE) {
                    888:                unsigned char romdata[16];
                    889:                unsigned char testbuf[32];
                    890:                int idx;
                    891:                static unsigned char test[] = "NE*000 memory";
                    892:                static unsigned short base[] = {
                    893: #ifdef NE_SCAN
                    894:                        NE_SCAN,
                    895: #endif
                    896:                        0 };
                    897:                /* if no addresses supplied, fall back on defaults */
                    898:                if (probe_addrs == 0 || probe_addrs[0] == 0)
                    899:                        probe_addrs = base;
                    900:                eth_bmem = 0;           /* No shared memory */
                    901:                for (idx = 0; (eth_nic_base = probe_addrs[idx]) != 0; ++idx) {
                    902:                        eth_flags = FLAG_PIO;
                    903:                        eth_asic_base = eth_nic_base + NE_ASIC_OFFSET;
                    904:                        eth_memsize = MEM_16384;
                    905:                        eth_tx_start = 32;
                    906:                        eth_rx_start = 32 + D8390_TXBUF_SIZE;
                    907:                        c = inb(eth_asic_base + NE_RESET);
                    908:                        outb(c, eth_asic_base + NE_RESET);
                    909:                        (void) inb(0x84);
                    910:                        outb(D8390_COMMAND_STP |
                    911:                                D8390_COMMAND_RD2, eth_nic_base + D8390_P0_COMMAND);
                    912:                        outb(D8390_RCR_MON, eth_nic_base + D8390_P0_RCR);
                    913:                        outb(D8390_DCR_FT1 | D8390_DCR_LS, eth_nic_base + D8390_P0_DCR);
                    914:                        outb(MEM_8192, eth_nic_base + D8390_P0_PSTART);
                    915:                        outb(MEM_16384, eth_nic_base + D8390_P0_PSTOP);
                    916: #ifdef NS8390_FORCE_16BIT
                    917:                        eth_flags |= FLAG_16BIT;        /* force 16-bit mode */
                    918: #endif
                    919: 
                    920:                        eth_pio_write( (unsigned char *) test, 8192, sizeof(test));
                    921:                        eth_pio_read(8192, testbuf, sizeof(test));
                    922:                        if (!memcmp(test, testbuf, sizeof(test)))
                    923:                                break;
                    924:                        eth_flags |= FLAG_16BIT;
                    925:                        eth_memsize = MEM_32768;
                    926:                        eth_tx_start = 64;
                    927:                        eth_rx_start = 64 + D8390_TXBUF_SIZE;
                    928:                        outb(D8390_DCR_WTS |
                    929:                                D8390_DCR_FT1 | D8390_DCR_LS, eth_nic_base + D8390_P0_DCR);
                    930:                        outb(MEM_16384, eth_nic_base + D8390_P0_PSTART);
                    931:                        outb(MEM_32768, eth_nic_base + D8390_P0_PSTOP);
                    932:                        eth_pio_write( (unsigned char *) test, 16384, sizeof(test));
                    933:                        eth_pio_read(16384, testbuf, sizeof(test));
                    934:                        if (!memcmp(testbuf, test, sizeof(test)))
                    935:                                break;
                    936:                }
                    937:                if (eth_nic_base == 0)
                    938:                        return (0);
                    939:                if (eth_nic_base > ISA_MAX_ADDR)        /* PCI probably */
                    940:                        eth_flags |= FLAG_16BIT;
                    941:                eth_vendor = VENDOR_NOVELL;
                    942:                eth_pio_read(0, romdata, sizeof(romdata));
                    943:                for (i=0; i<ETH_ALEN; i++) {
                    944:                        nic->node_addr[i] = romdata[i + ((eth_flags & FLAG_16BIT) ? i : 0)];
                    945:                }
                    946:                nic->ioaddr = eth_nic_base;
                    947:                DBG ( "\nNE%c000 base %4.4x, MAC Addr %s\n",
                    948:                      (eth_flags & FLAG_16BIT) ? '2' : '1', eth_nic_base,
                    949:                      eth_ntoa ( nic->node_addr ) );
                    950:        }
                    951: }
                    952: #endif
                    953:        if (eth_vendor == VENDOR_NONE)
                    954:                return(0);
                    955:         if (eth_vendor != VENDOR_3COM)
                    956:                eth_rmem = eth_bmem;
                    957:        ns8390_reset(nic);
                    958:        nic->nic_op     = &ns8390_operations;
                    959: 
                    960:         /* Based on PnP ISA map */
                    961: #ifdef INCLUDE_WD
                    962:         dev->devid.vendor_id = htons(GENERIC_ISAPNP_VENDOR);
                    963:         dev->devid.device_id = htons(0x812a);
                    964: #endif
                    965: #ifdef INCLUDE_3C503
                    966:         dev->devid.vendor_id = htons(GENERIC_ISAPNP_VENDOR);
                    967:         dev->devid.device_id = htons(0x80f3);
                    968: #endif
                    969: #ifdef INCLUDE_NE
                    970:         dev->devid.vendor_id = htons(GENERIC_ISAPNP_VENDOR);
                    971:         dev->devid.device_id = htons(0x80d6);
                    972: #endif
                    973:        return 1;
                    974: }
                    975: 
                    976: #ifdef INCLUDE_WD
                    977: struct isa_driver wd_driver __isa_driver = {
                    978:        .type    = NIC_DRIVER,
                    979:        .name    = "WD",
                    980:        .probe   = wd_probe,
                    981:        .ioaddrs = 0, 
                    982: };
                    983: ISA_ROM("wd","WD8003/8013, SMC8216/8416, SMC 83c790 (EtherEZ)");
                    984: #endif
                    985: 
                    986: #ifdef INCLUDE_3C503
                    987: struct isa_driver t503_driver __isa_driver = {
                    988:        .type    = NIC_DRIVER,
                    989:        .name    = "3C503",
                    990:        .probe   = t503_probe,
                    991:        .ioaddrs = 0, 
                    992: };
                    993: ISA_ROM("3c503","3Com503, Etherlink II[/16]");
                    994: #endif
                    995: 
                    996: #ifdef INCLUDE_NE
                    997: struct isa_driver ne_driver __isa_driver = {
                    998:        .type    = NIC_DRIVER,
                    999:        .name    = "NE*000",
                   1000:        .probe   = ne_probe,
                   1001:        .ioaddrs = 0, 
                   1002: };
                   1003: ISA_ROM("ne","NE1000/2000 and clones");
                   1004: #endif
                   1005: 
                   1006: #ifdef INCLUDE_NS8390
                   1007: static struct pci_device_id nepci_nics[] = {
                   1008: /* A few NE2000 PCI clones, list not exhaustive */
                   1009: PCI_ROM(0x10ec, 0x8029, "rtl8029",      "Realtek 8029", 0),
                   1010: PCI_ROM(0x1186, 0x0300, "dlink-528",    "D-Link DE-528", 0),
                   1011: PCI_ROM(0x1050, 0x0940, "winbond940",   "Winbond NE2000-PCI", 0),              /* Winbond 86C940 / 89C940 */
                   1012: PCI_ROM(0x1050, 0x5a5a, "winbond940f",  "Winbond W89c940F", 0),                /* Winbond 89C940F */
                   1013: PCI_ROM(0x11f6, 0x1401, "compexrl2000", "Compex ReadyLink 2000", 0),
                   1014: PCI_ROM(0x8e2e, 0x3000, "ktiet32p2",    "KTI ET32P2", 0),
                   1015: PCI_ROM(0x4a14, 0x5000, "nv5000sc",     "NetVin NV5000SC", 0),
                   1016: PCI_ROM(0x12c3, 0x0058, "holtek80232",  "Holtek HT80232", 0),
                   1017: PCI_ROM(0x12c3, 0x5598, "holtek80229",  "Holtek HT80229", 0),
                   1018: PCI_ROM(0x10bd, 0x0e34, "surecom-ne34", "Surecom NE34", 0),
                   1019: PCI_ROM(0x1106, 0x0926, "via86c926",    "Via 86c926", 0),
                   1020: };
                   1021: 
                   1022: PCI_DRIVER ( nepci_driver, nepci_nics, PCI_NO_CLASS );
                   1023: 
                   1024: DRIVER ( "NE2000/PCI", nic_driver, pci_driver, nepci_driver,
                   1025:         nepci_probe, ns8390_disable );
                   1026: 
                   1027: #endif /* INCLUDE_NS8390 */
                   1028: 
                   1029: #endif
                   1030: 
                   1031: /*
                   1032:  * Local variables:
                   1033:  *  c-basic-offset: 8
                   1034:  *  c-indent-level: 8
                   1035:  *  tab-width: 8
                   1036:  * End:
                   1037:  */

unix.superglobalmegacorp.com

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