#include "etherboot.h"#include "nic.h"#include <gpxe/pci.h>#include <gpxe/ethernet.h>#include "3c595.h"Go to the source code of this file.
Data Structures | |
| struct | connector_entry |
Defines | |
| #define | CONNECTOR_UTP 0 |
| #define | CONNECTOR_AUI 1 |
| #define | CONNECTOR_BNC 3 |
| #define | CONNECTOR_TX 4 |
| #define | CONNECTOR_FX 5 |
| #define | CONNECTOR_MII 6 |
Functions | |
| FILE_LICENCE (BSD2) | |
| static void | vxgetlink (void) |
| static void | vxsetlink (void) |
| static void | t595_reset (struct nic *nic) |
| static void | t595_transmit (struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p) |
| static int | t595_poll (struct nic *nic, int retrieve) |
| static int | eeprom_rdy () |
| static int | get_e (int offset) |
| static void | t595_disable (struct nic *nic) |
| static void | t595_irq (struct nic *nic __unused, irq_action_t action __unused) |
| static int | t595_probe (struct nic *nic, struct pci_device *pci) |
| PCI_DRIVER (t595_driver, t595_nics, PCI_NO_CLASS) | |
| DRIVER ("3C595", nic_driver, pci_driver, t595_driver, t595_probe, t595_disable) | |
Variables | |
| static struct nic_operations | t595_operations |
| static unsigned short | eth_nic_base |
| static unsigned short | vx_connector |
| static unsigned short | vx_connectors |
| static struct connector_entry | conn_tab [VX_CONNECTORS] |
| static char | padmap [] |
| static struct pci_device_id | t595_nics [] |
| #define CONNECTOR_UTP 0 |
Referenced by vxsetlink().
| #define CONNECTOR_AUI 1 |
| #define CONNECTOR_BNC 3 |
Referenced by vxsetlink().
| #define CONNECTOR_TX 4 |
Referenced by vxsetlink().
| #define CONNECTOR_FX 5 |
Referenced by vxsetlink().
| #define CONNECTOR_MII 6 |
| FILE_LICENCE | ( | BSD2 | ) |
| static void vxgetlink | ( | void | ) | [static] |
Definition at line 357 of file 3c595.c.
References BASE, conn_tab, GO_WINDOW, inl, INTERNAL_CONNECTOR_BITS, INTERNAL_CONNECTOR_MASK, inw, k, name, printf(), vx_connector, VX_CONNECTORS, vx_connectors, VX_W3_INTERNAL_CFG, and VX_W3_RESET_OPT.
Referenced by t595_probe().
00358 { 00359 int n, k; 00360 00361 GO_WINDOW(3); 00362 vx_connectors = inw(BASE + VX_W3_RESET_OPT) & 0x7f; 00363 for (n = 0, k = 0; k < VX_CONNECTORS; k++) { 00364 if (vx_connectors & conn_tab[k].bit) { 00365 if (n > 0) { 00366 printf("/"); 00367 } 00368 printf("%s", conn_tab[k].name ); 00369 n++; 00370 } 00371 } 00372 if (vx_connectors == 0) { 00373 printf("no connectors!"); 00374 return; 00375 } 00376 GO_WINDOW(3); 00377 vx_connector = (inl(BASE + VX_W3_INTERNAL_CFG) 00378 & INTERNAL_CONNECTOR_MASK) 00379 >> INTERNAL_CONNECTOR_BITS; 00380 if (vx_connector & 0x10) { 00381 vx_connector &= 0x0f; 00382 printf("[*%s*]", conn_tab[vx_connector].name); 00383 printf(": disable 'auto select' with DOS util!"); 00384 } else { 00385 printf("[*%s*]", conn_tab[vx_connector].name); 00386 } 00387 }
| static void vxsetlink | ( | void | ) | [static] |
Definition at line 390 of file 3c595.c.
References BASE, conn_tab, CONNECTOR_BNC, CONNECTOR_FX, CONNECTOR_TX, CONNECTOR_UTP, ENABLE_UTP, GO_WINDOW, inl, INTERNAL_CONNECTOR_BITS, INTERNAL_CONNECTOR_MASK, LINKBEAT_ENABLE, name, outl, outw, printf(), START_TRANSCEIVER, STOP_TRANSCEIVER, udelay(), VX_COMMAND, vx_connector, vx_connectors, VX_W3_INTERNAL_CFG, and VX_W4_MEDIA_TYPE.
Referenced by t595_reset().
00391 { 00392 int i, j; 00393 char *reason, *warning; 00394 static char prev_conn = -1; 00395 00396 if (prev_conn == -1) { 00397 prev_conn = vx_connector; 00398 } 00399 00400 i = vx_connector; /* default in EEPROM */ 00401 reason = "default"; 00402 warning = 0; 00403 00404 if ((vx_connectors & conn_tab[vx_connector].bit) == 0) { 00405 warning = "strange connector type in EEPROM."; 00406 reason = "forced"; 00407 i = CONNECTOR_UTP; 00408 } 00409 00410 if (warning != 0) { 00411 printf("warning: %s\n", warning); 00412 } 00413 printf("selected %s. (%s)\n", conn_tab[i].name, reason); 00414 00415 /* Set the selected connector. */ 00416 GO_WINDOW(3); 00417 j = inl(BASE + VX_W3_INTERNAL_CFG) & ~INTERNAL_CONNECTOR_MASK; 00418 outl(j | (i <<INTERNAL_CONNECTOR_BITS), BASE + VX_W3_INTERNAL_CFG); 00419 00420 /* First, disable all. */ 00421 outw(STOP_TRANSCEIVER, BASE + VX_COMMAND); 00422 udelay(8000); 00423 GO_WINDOW(4); 00424 outw(0, BASE + VX_W4_MEDIA_TYPE); 00425 00426 /* Second, enable the selected one. */ 00427 switch(i) { 00428 case CONNECTOR_UTP: 00429 GO_WINDOW(4); 00430 outw(ENABLE_UTP, BASE + VX_W4_MEDIA_TYPE); 00431 break; 00432 case CONNECTOR_BNC: 00433 outw(START_TRANSCEIVER,BASE + VX_COMMAND); 00434 udelay(8000); 00435 break; 00436 case CONNECTOR_TX: 00437 case CONNECTOR_FX: 00438 GO_WINDOW(4); 00439 outw(LINKBEAT_ENABLE, BASE + VX_W4_MEDIA_TYPE); 00440 break; 00441 default: /* AUI and MII fall here */ 00442 break; 00443 } 00444 GO_WINDOW(1); 00445 }
| static void t595_reset | ( | struct nic * | nic | ) | [static] |
Definition at line 68 of file 3c595.c.
References ACK_INTR, BASE, C_INTR_LATCH, ETH_ALEN, FIL_BRDCST, FIL_INDIVIDUAL, FIL_MULTICAST, GO_WINDOW, inb, nic::node_addr, outb, outw, RX_DISABLE, RX_DISCARD_TOP_PACK, RX_ENABLE, RX_RESET, S_CARD_FAILURE, S_RX_COMPLETE, S_TX_AVAIL, S_TX_COMPLETE, SET_INTR_MASK, SET_RD_0_MASK, SET_RX_FILTER, STOP_TRANSCEIVER, TX_DISABLE, TX_ENABLE, TX_RESET, udelay(), VX_BUSY_WAIT, VX_COMMAND, VX_W1_TX_STATUS, VX_W2_ADDR_0, and vxsetlink().
Referenced by t595_disable(), and t595_probe().
00069 { 00070 int i; 00071 00072 /*********************************************************** 00073 Reset 3Com 595 card 00074 *************************************************************/ 00075 00076 /* stop card */ 00077 outw(RX_DISABLE, BASE + VX_COMMAND); 00078 outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND); 00079 VX_BUSY_WAIT; 00080 outw(TX_DISABLE, BASE + VX_COMMAND); 00081 outw(STOP_TRANSCEIVER, BASE + VX_COMMAND); 00082 udelay(8000); 00083 outw(RX_RESET, BASE + VX_COMMAND); 00084 VX_BUSY_WAIT; 00085 outw(TX_RESET, BASE + VX_COMMAND); 00086 VX_BUSY_WAIT; 00087 outw(C_INTR_LATCH, BASE + VX_COMMAND); 00088 outw(SET_RD_0_MASK, BASE + VX_COMMAND); 00089 outw(SET_INTR_MASK, BASE + VX_COMMAND); 00090 outw(SET_RX_FILTER, BASE + VX_COMMAND); 00091 00092 /* 00093 * initialize card 00094 */ 00095 VX_BUSY_WAIT; 00096 00097 GO_WINDOW(0); 00098 00099 /* Disable the card */ 00100 /* outw(0, BASE + VX_W0_CONFIG_CTRL); */ 00101 00102 /* Configure IRQ to none */ 00103 /* outw(SET_IRQ(0), BASE + VX_W0_RESOURCE_CFG); */ 00104 00105 /* Enable the card */ 00106 /* outw(ENABLE_DRQ_IRQ, BASE + VX_W0_CONFIG_CTRL); */ 00107 00108 GO_WINDOW(2); 00109 00110 /* Reload the ether_addr. */ 00111 for (i = 0; i < ETH_ALEN; i++) 00112 outb(nic->node_addr[i], BASE + VX_W2_ADDR_0 + i); 00113 00114 outw(RX_RESET, BASE + VX_COMMAND); 00115 VX_BUSY_WAIT; 00116 outw(TX_RESET, BASE + VX_COMMAND); 00117 VX_BUSY_WAIT; 00118 00119 /* Window 1 is operating window */ 00120 GO_WINDOW(1); 00121 for (i = 0; i < 31; i++) 00122 inb(BASE + VX_W1_TX_STATUS); 00123 00124 outw(SET_RD_0_MASK | S_CARD_FAILURE | S_RX_COMPLETE | 00125 S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND); 00126 outw(SET_INTR_MASK | S_CARD_FAILURE | S_RX_COMPLETE | 00127 S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND); 00128 00129 /* 00130 * Attempt to get rid of any stray interrupts that occured during 00131 * configuration. On the i386 this isn't possible because one may 00132 * already be queued. However, a single stray interrupt is 00133 * unimportant. 00134 */ 00135 00136 outw(ACK_INTR | 0xff, BASE + VX_COMMAND); 00137 00138 outw(SET_RX_FILTER | FIL_INDIVIDUAL | 00139 FIL_BRDCST|FIL_MULTICAST, BASE + VX_COMMAND); 00140 00141 vxsetlink(); 00142 /*{ 00143 int i,j; 00144 i = CONNECTOR_TX; 00145 GO_WINDOW(3); 00146 j = inl(BASE + VX_W3_INTERNAL_CFG) & ~INTERNAL_CONNECTOR_MASK; 00147 outl(BASE + VX_W3_INTERNAL_CFG, j | (i <<INTERNAL_CONNECTOR_BITS)); 00148 GO_WINDOW(4); 00149 outw(LINKBEAT_ENABLE, BASE + VX_W4_MEDIA_TYPE); 00150 GO_WINDOW(1); 00151 }*/ 00152 00153 /* start tranciever and receiver */ 00154 outw(RX_ENABLE, BASE + VX_COMMAND); 00155 outw(TX_ENABLE, BASE + VX_COMMAND); 00156 00157 }
| static void t595_transmit | ( | struct nic * | nic, | |
| const char * | d, | |||
| unsigned int | t, | |||
| unsigned int | s, | |||
| const char * | p | |||
| ) | [static] |
Definition at line 165 of file 3c595.c.
References BASE, ETH_ALEN, ETH_FRAME_LEN, ETH_HLEN, htons, inb, inw, nic::node_addr, outb, outsw, outw, padmap, printf(), S_COMMAND_IN_PROGRESS, TX_ENABLE, TX_RESET, TXS_COMPLETE, TXS_MAX_COLLISION, TXS_STATUS_OVERFLOW, TXS_UNDERRUN, VX_COMMAND, VX_STATUS, VX_W1_FREE_TX, VX_W1_TX_PIO_WR_1, and VX_W1_TX_STATUS.
00171 { 00172 register int len; 00173 int pad; 00174 int status; 00175 00176 #ifdef EDEBUG 00177 printf("{l=%d,t=%hX}",s+ETH_HLEN,t); 00178 #endif 00179 00180 /* swap bytes of type */ 00181 t= htons(t); 00182 00183 len=s+ETH_HLEN; /* actual length of packet */ 00184 pad = padmap[len & 3]; 00185 00186 /* 00187 * The 3c595 automatically pads short packets to minimum ethernet length, 00188 * but we drop packets that are too large. Perhaps we should truncate 00189 * them instead? 00190 */ 00191 if (len + pad > ETH_FRAME_LEN) { 00192 return; 00193 } 00194 00195 /* drop acknowledgements */ 00196 while(( status=inb(BASE + VX_W1_TX_STATUS) )& TXS_COMPLETE ) { 00197 if(status & (TXS_UNDERRUN|TXS_MAX_COLLISION|TXS_STATUS_OVERFLOW)) { 00198 outw(TX_RESET, BASE + VX_COMMAND); 00199 outw(TX_ENABLE, BASE + VX_COMMAND); 00200 } 00201 00202 outb(0x0, BASE + VX_W1_TX_STATUS); 00203 } 00204 00205 while (inw(BASE + VX_W1_FREE_TX) < len + pad + 4) { 00206 /* no room in FIFO */ 00207 } 00208 00209 outw(len, BASE + VX_W1_TX_PIO_WR_1); 00210 outw(0x0, BASE + VX_W1_TX_PIO_WR_1); /* Second dword meaningless */ 00211 00212 /* write packet */ 00213 outsw(BASE + VX_W1_TX_PIO_WR_1, d, ETH_ALEN/2); 00214 outsw(BASE + VX_W1_TX_PIO_WR_1, nic->node_addr, ETH_ALEN/2); 00215 outw(t, BASE + VX_W1_TX_PIO_WR_1); 00216 outsw(BASE + VX_W1_TX_PIO_WR_1, p, s / 2); 00217 if (s & 1) 00218 outb(*(p+s - 1), BASE + VX_W1_TX_PIO_WR_1); 00219 00220 while (pad--) 00221 outb(0, BASE + VX_W1_TX_PIO_WR_1); /* Padding */ 00222 00223 /* wait for Tx complete */ 00224 while((inw(BASE + VX_STATUS) & S_COMMAND_IN_PROGRESS) != 0) 00225 ; 00226 }
| static int t595_poll | ( | struct nic * | nic, | |
| int | retrieve | |||
| ) | [static] |
Definition at line 231 of file 3c595.c.
References ACK_INTR, BASE, C_INTR_LATCH, ERR_RX, ETH_ALEN, inb, insw, inw, outw, nic::packet, nic::packetlen, printf(), RX_BYTES_MASK, RX_DISCARD_TOP_PACK, RX_INCOMPLETE, S_COMMAND_IN_PROGRESS, S_RX_COMPLETE, udelay(), VX_COMMAND, VX_STATUS, VX_W1_RX_PIO_RD_1, and VX_W1_RX_STATUS.
00232 { 00233 /* common variables */ 00234 /* variables for 3C595 */ 00235 short status, cst; 00236 register short rx_fifo; 00237 00238 cst=inw(BASE + VX_STATUS); 00239 00240 #ifdef EDEBUG 00241 if(cst & 0x1FFF) 00242 printf("-%hX-",cst); 00243 #endif 00244 00245 if( (cst & S_RX_COMPLETE)==0 ) { 00246 /* acknowledge everything */ 00247 outw(ACK_INTR | cst, BASE + VX_COMMAND); 00248 outw(C_INTR_LATCH, BASE + VX_COMMAND); 00249 00250 return 0; 00251 } 00252 00253 status = inw(BASE + VX_W1_RX_STATUS); 00254 #ifdef EDEBUG 00255 printf("*%hX*",status); 00256 #endif 00257 00258 if (status & ERR_RX) { 00259 outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND); 00260 return 0; 00261 } 00262 00263 rx_fifo = status & RX_BYTES_MASK; 00264 if (rx_fifo==0) 00265 return 0; 00266 00267 if ( ! retrieve ) return 1; 00268 00269 /* read packet */ 00270 #ifdef EDEBUG 00271 printf("[l=%d",rx_fifo); 00272 #endif 00273 insw(BASE + VX_W1_RX_PIO_RD_1, nic->packet, rx_fifo / 2); 00274 if(rx_fifo & 1) 00275 nic->packet[rx_fifo-1]=inb(BASE + VX_W1_RX_PIO_RD_1); 00276 nic->packetlen=rx_fifo; 00277 00278 while(1) { 00279 status = inw(BASE + VX_W1_RX_STATUS); 00280 #ifdef EDEBUG 00281 printf("*%hX*",status); 00282 #endif 00283 rx_fifo = status & RX_BYTES_MASK; 00284 00285 if(rx_fifo>0) { 00286 insw(BASE + VX_W1_RX_PIO_RD_1, nic->packet+nic->packetlen, rx_fifo / 2); 00287 if(rx_fifo & 1) 00288 nic->packet[nic->packetlen+rx_fifo-1]=inb(BASE + VX_W1_RX_PIO_RD_1); 00289 nic->packetlen+=rx_fifo; 00290 #ifdef EDEBUG 00291 printf("+%d",rx_fifo); 00292 #endif 00293 } 00294 if(( status & RX_INCOMPLETE )==0) { 00295 #ifdef EDEBUG 00296 printf("=%d",nic->packetlen); 00297 #endif 00298 break; 00299 } 00300 udelay(1000); 00301 } 00302 00303 /* acknowledge reception of packet */ 00304 outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND); 00305 while (inw(BASE + VX_STATUS) & S_COMMAND_IN_PROGRESS); 00306 #ifdef EDEBUG 00307 { 00308 unsigned short type = 0; /* used by EDEBUG */ 00309 type = (nic->packet[12]<<8) | nic->packet[13]; 00310 if(nic->packet[0]+nic->packet[1]+nic->packet[2]+nic->packet[3]+nic->packet[4]+ 00311 nic->packet[5] == 0xFF*ETH_ALEN) 00312 printf(",t=%hX,b]",type); 00313 else 00314 printf(",t=%hX]",type); 00315 } 00316 #endif 00317 return 1; 00318 }
| static int eeprom_rdy | ( | ) | [static] |
Definition at line 326 of file 3c595.c.
References BASE, is_eeprom_busy, MAX_EEPROMBUSY, printf(), and udelay().
Referenced by get_e().
00327 { 00328 int i; 00329 00330 for (i = 0; is_eeprom_busy(BASE) && i < MAX_EEPROMBUSY; i++) 00331 udelay(1000); 00332 if (i >= MAX_EEPROMBUSY) { 00333 /* printf("3c595: eeprom failed to come ready.\n"); */ 00334 printf("3c595: eeprom is busy.\n"); /* memory in EPROM is tight */ 00335 return (0); 00336 } 00337 return (1); 00338 }
| static int get_e | ( | int | offset | ) | [static] |
Definition at line 345 of file 3c595.c.
References BASE, EEPROM_CMD_RD, eeprom_rdy(), inw, outw, VX_W0_EEPROM_COMMAND, and VX_W0_EEPROM_DATA.
Referenced by t595_probe(), and t5x9_probe().
00347 { 00348 if (!eeprom_rdy()) 00349 return (0xffff); 00350 outw(EEPROM_CMD_RD | offset, BASE + VX_W0_EEPROM_COMMAND); 00351 if (!eeprom_rdy()) 00352 return (0xffff); 00353 return (inw(BASE + VX_W0_EEPROM_DATA)); 00354 }
| static void t595_disable | ( | struct nic * | nic | ) | [static] |
Definition at line 447 of file 3c595.c.
References BASE, GO_WINDOW, outw, STOP_TRANSCEIVER, t595_reset(), udelay(), VX_COMMAND, and VX_W4_MEDIA_TYPE.
00447 { 00448 00449 t595_reset(nic); 00450 00451 outw(STOP_TRANSCEIVER, BASE + VX_COMMAND); 00452 udelay(8000); 00453 GO_WINDOW(4); 00454 outw(0, BASE + VX_W4_MEDIA_TYPE); 00455 GO_WINDOW(1); 00456 }
| static void t595_irq | ( | struct nic *nic | __unused, | |
| irq_action_t action | __unused | |||
| ) | [static] |
| static int t595_probe | ( | struct nic * | nic, | |
| struct pci_device * | pci | |||
| ) | [static] |
Definition at line 473 of file 3c595.c.
References BASE, DBG, EEPROM_OEM_ADDR_0, eth_nic_base, eth_ntoa(), get_e(), GLOBAL_RESET, GO_WINDOW, htons, nic::ioaddr, pci_device::ioaddr, nic::irqno, nic::nic_op, nic::node_addr, ntohs, outw, t595_operations, t595_reset(), VX_BUSY_WAIT, VX_COMMAND, VX_W2_ADDR_0, and vxgetlink().
00473 { 00474 00475 int i; 00476 unsigned short *p; 00477 00478 if (pci->ioaddr == 0) 00479 return 0; 00480 eth_nic_base = pci->ioaddr; 00481 00482 nic->irqno = 0; 00483 nic->ioaddr = pci->ioaddr; 00484 00485 GO_WINDOW(0); 00486 outw(GLOBAL_RESET, BASE + VX_COMMAND); 00487 VX_BUSY_WAIT; 00488 00489 vxgetlink(); 00490 00491 /* 00492 printf("\nEEPROM:"); 00493 for (i = 0; i < (EEPROMSIZE/2); i++) { 00494 printf("%hX:", get_e(i)); 00495 } 00496 printf("\n"); 00497 */ 00498 /* 00499 * Read the station address from the eeprom 00500 */ 00501 p = (unsigned short *) nic->node_addr; 00502 for (i = 0; i < 3; i++) { 00503 GO_WINDOW(0); 00504 p[i] = htons(get_e(EEPROM_OEM_ADDR_0 + i)); 00505 GO_WINDOW(2); 00506 outw(ntohs(p[i]), BASE + VX_W2_ADDR_0 + (i * 2)); 00507 } 00508 00509 DBG ( "Ethernet address: %s\n", eth_ntoa (nic->node_addr) ); 00510 00511 t595_reset(nic); 00512 nic->nic_op = &t595_operations; 00513 return 1; 00514 00515 }
| PCI_DRIVER | ( | t595_driver | , | |
| t595_nics | , | |||
| PCI_NO_CLASS | ||||
| ) |
| DRIVER | ( | "3C595" | , | |
| nic_driver | , | |||
| pci_driver | , | |||
| t595_driver | , | |||
| t595_probe | , | |||
| t595_disable | ||||
| ) |
static struct nic_operations t595_operations [static, read] |
Initial value:
{
.connect = dummy_connect,
.poll = t595_poll,
.transmit = t595_transmit,
.irq = t595_irq,
}
Definition at line 36 of file 3c595.c.
Referenced by t595_probe().
unsigned short eth_nic_base [static] |
Definition at line 38 of file 3c595.c.
Referenced by cs89x0_poll(), cs89x0_probe(), cs89x0_reset(), cs89x0_transmit(), eth_pio_read(), eth_pio_write(), eth_probe(), eth_rx_overrun(), ne_poll(), ne_probe(), ne_reset(), ne_transmit(), ns8390_poll(), ns8390_reset(), ns8390_transmit(), readreg(), send_test_pkt(), t595_probe(), and writereg().
unsigned short vx_connector [static] |
unsigned short vx_connectors [static] |
struct connector_entry conn_tab[VX_CONNECTORS] [static] |
Referenced by vxgetlink(), and vxsetlink().
struct pci_device_id t595_nics[] [static] |
Initial value:
{
PCI_ROM(0x10b7, 0x5900, "3c590", "3Com590", 0),
PCI_ROM(0x10b7, 0x5950, "3c595", "3Com595", 0),
PCI_ROM(0x10b7, 0x5951, "3c595-1", "3Com595", 0),
PCI_ROM(0x10b7, 0x5952, "3c595-2", "3Com595", 0),
PCI_ROM(0x10b7, 0x9000, "3c900-tpo", "3Com900-TPO", 0),
PCI_ROM(0x10b7, 0x9001, "3c900-t4", "3Com900-Combo", 0),
PCI_ROM(0x10b7, 0x9004, "3c900b-tpo", "3Com900B-TPO", 0),
PCI_ROM(0x10b7, 0x9005, "3c900b-combo", "3Com900B-Combo", 0),
PCI_ROM(0x10b7, 0x9006, "3c900b-tpb2", "3Com900B-2/T", 0),
PCI_ROM(0x10b7, 0x900a, "3c900b-fl", "3Com900B-FL", 0),
PCI_ROM(0x10b7, 0x9800, "3c980-cyclone-1", "3Com980-Cyclone", 0),
PCI_ROM(0x10b7, 0x9805, "3c9805-1", "3Com9805", 0),
PCI_ROM(0x10b7, 0x7646, "3csoho100-tx-1", "3CSOHO100-TX", 0),
PCI_ROM(0x10b7, 0x4500, "3c450-1", "3Com450 HomePNA Tornado", 0),
}
1.5.7.1