You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ns8390.c 31KB

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