|
|
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: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.