Home | History | Annotate | Download | only in net
      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 (timlegge (at) users.sourceforge.net) 09/28/2003
     17 Relocation support added by Ken Yap (ken_yap (at) users.sourceforge.net) 28/12/02
     18 3c503 support added by Bill Paul (wpaul (at) ctr.columbia.edu) on 11/15/94
     19 SMC8416 support added by Bill Paul (wpaul (at) ctr.columbia.edu) on 12/25/94
     20 3c503 PIO support added by Jim Hague (jim.hague (at) acm.org) on 2/17/98
     21 RX overrun by Klaus Espenlaub (espenlaub (at) informatik.uni-ulm.de) 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 (andrewb (at) zip.com.au) 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 <gpxe/ethernet.h>
     45 #ifdef	INCLUDE_NS8390
     46 #include <gpxe/pci.h>
     47 #else
     48 #include <gpxe/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 	jluke (at) deakin.edu.au 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  */
   1038