Annotation of qemu/roms/ipxe/src/drivers/net/3c595.c, revision 1.1

1.1     ! root        1: /*
        !             2: * 3c595.c -- 3COM 3C595 Fast Etherlink III PCI driver for etherboot
        !             3: *
        !             4: * Copyright (C) 2000 Shusuke Nisiyama <[email protected]>
        !             5: * All rights reserved.
        !             6: * Mar. 14, 2000
        !             7: *
        !             8: *  This software may be used, modified, copied, distributed, and sold, in
        !             9: *  both source and binary form provided that the above copyright and these
        !            10: *  terms are retained. Under no circumstances are the authors responsible for
        !            11: *  the proper functioning of this software, nor do the authors assume any
        !            12: *  responsibility for damages incurred with its use.
        !            13: *
        !            14: * This code is based on Martin Renters' etherboot-4.4.3 3c509.c and 
        !            15: * Herb Peyerl's FreeBSD 3.4-RELEASE if_vx.c driver.
        !            16: *
        !            17: *  Copyright (C) 1993-1994, David Greenman, Martin Renters.
        !            18: *  Copyright (C) 1993-1995, Andres Vega Garcia.
        !            19: *  Copyright (C) 1995, Serge Babkin.
        !            20: *
        !            21: *  Copyright (c) 1994 Herb Peyerl <[email protected]>
        !            22: *
        !            23: * timlegge     08-24-2003      Add Multicast Support
        !            24: */
        !            25: 
        !            26: FILE_LICENCE ( BSD2 );
        !            27: 
        !            28: /* #define EDEBUG */
        !            29: 
        !            30: #include "etherboot.h"
        !            31: #include "nic.h"
        !            32: #include <ipxe/pci.h>
        !            33: #include <ipxe/ethernet.h>
        !            34: #include "3c595.h"
        !            35: 
        !            36: static struct nic_operations t595_operations;
        !            37: 
        !            38: static unsigned short  eth_nic_base;
        !            39: static unsigned short  vx_connector, vx_connectors;
        !            40: 
        !            41: static struct connector_entry {
        !            42:   int bit;
        !            43:   char *name;
        !            44: } conn_tab[VX_CONNECTORS] = {
        !            45: #define CONNECTOR_UTP   0
        !            46:   { 0x08, "utp"},
        !            47: #define CONNECTOR_AUI   1
        !            48:   { 0x20, "aui"},
        !            49: /* dummy */
        !            50:   { 0, "???"},
        !            51: #define CONNECTOR_BNC   3
        !            52:   { 0x10, "bnc"},
        !            53: #define CONNECTOR_TX    4
        !            54:   { 0x02, "tx"},
        !            55: #define CONNECTOR_FX    5
        !            56:   { 0x04, "fx"},
        !            57: #define CONNECTOR_MII   6
        !            58:   { 0x40, "mii"},
        !            59:   { 0, "???"}
        !            60: };
        !            61: 
        !            62: static void vxgetlink(void);
        !            63: static void vxsetlink(void);
        !            64: 
        !            65: /**************************************************************************
        !            66: ETH_RESET - Reset adapter
        !            67: ***************************************************************************/
        !            68: static void t595_reset(struct nic *nic)
        !            69: {
        !            70:        int i;
        !            71: 
        !            72:        /***********************************************************
        !            73:                        Reset 3Com 595 card
        !            74:        *************************************************************/
        !            75: 
        !            76:        /* stop card */
        !            77:        outw(RX_DISABLE, BASE + VX_COMMAND);
        !            78:        outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND);
        !            79:        VX_BUSY_WAIT;
        !            80:        outw(TX_DISABLE, BASE + VX_COMMAND);
        !            81:        outw(STOP_TRANSCEIVER, BASE + VX_COMMAND);
        !            82:        udelay(8000);
        !            83:        outw(RX_RESET, BASE + VX_COMMAND);
        !            84:        VX_BUSY_WAIT;
        !            85:        outw(TX_RESET, BASE + VX_COMMAND);
        !            86:        VX_BUSY_WAIT;
        !            87:        outw(C_INTR_LATCH, BASE + VX_COMMAND);
        !            88:        outw(SET_RD_0_MASK, BASE + VX_COMMAND);
        !            89:        outw(SET_INTR_MASK, BASE + VX_COMMAND);
        !            90:        outw(SET_RX_FILTER, BASE + VX_COMMAND);
        !            91: 
        !            92:        /*
        !            93:        * initialize card
        !            94:        */
        !            95:        VX_BUSY_WAIT;
        !            96: 
        !            97:        GO_WINDOW(0);
        !            98: 
        !            99:        /* Disable the card */
        !           100: /*     outw(0, BASE + VX_W0_CONFIG_CTRL); */
        !           101: 
        !           102:        /* Configure IRQ to none */
        !           103: /*     outw(SET_IRQ(0), BASE + VX_W0_RESOURCE_CFG); */
        !           104: 
        !           105:        /* Enable the card */
        !           106: /*     outw(ENABLE_DRQ_IRQ, BASE + VX_W0_CONFIG_CTRL); */
        !           107: 
        !           108:        GO_WINDOW(2);
        !           109: 
        !           110:        /* Reload the ether_addr. */
        !           111:        for (i = 0; i < ETH_ALEN; i++)
        !           112:                outb(nic->node_addr[i], BASE + VX_W2_ADDR_0 + i);
        !           113: 
        !           114:        outw(RX_RESET, BASE + VX_COMMAND);
        !           115:        VX_BUSY_WAIT;
        !           116:        outw(TX_RESET, BASE + VX_COMMAND);
        !           117:        VX_BUSY_WAIT;
        !           118: 
        !           119:        /* Window 1 is operating window */
        !           120:        GO_WINDOW(1);
        !           121:        for (i = 0; i < 31; i++)
        !           122:                inb(BASE + VX_W1_TX_STATUS);
        !           123: 
        !           124:        outw(SET_RD_0_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
        !           125:                S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND);
        !           126:        outw(SET_INTR_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
        !           127:                S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND);
        !           128: 
        !           129: /*
        !           130:  * Attempt to get rid of any stray interrupts that occured during
        !           131:  * configuration.  On the i386 this isn't possible because one may
        !           132:  * already be queued.  However, a single stray interrupt is
        !           133:  * unimportant.
        !           134:  */
        !           135: 
        !           136:        outw(ACK_INTR | 0xff, BASE + VX_COMMAND);
        !           137: 
        !           138:        outw(SET_RX_FILTER | FIL_INDIVIDUAL |
        !           139:            FIL_BRDCST|FIL_MULTICAST, BASE + VX_COMMAND);
        !           140: 
        !           141:        vxsetlink();
        !           142: /*{
        !           143:        int i,j;
        !           144:        i = CONNECTOR_TX;
        !           145:        GO_WINDOW(3);
        !           146:        j = inl(BASE + VX_W3_INTERNAL_CFG) & ~INTERNAL_CONNECTOR_MASK;
        !           147:        outl(BASE + VX_W3_INTERNAL_CFG, j | (i <<INTERNAL_CONNECTOR_BITS));
        !           148:         GO_WINDOW(4);
        !           149:         outw(LINKBEAT_ENABLE, BASE + VX_W4_MEDIA_TYPE);
        !           150:         GO_WINDOW(1);
        !           151: }*/
        !           152: 
        !           153:        /* start tranciever and receiver */
        !           154:        outw(RX_ENABLE, BASE + VX_COMMAND);
        !           155:        outw(TX_ENABLE, BASE + VX_COMMAND);
        !           156: 
        !           157: }
        !           158: 
        !           159: /**************************************************************************
        !           160: ETH_TRANSMIT - Transmit a frame
        !           161: ***************************************************************************/
        !           162: static char padmap[] = {
        !           163:        0, 3, 2, 1};
        !           164: 
        !           165: static void t595_transmit(
        !           166: struct nic *nic,
        !           167: const char *d,                 /* Destination */
        !           168: unsigned int t,                        /* Type */
        !           169: unsigned int s,                        /* size */
        !           170: const char *p)                 /* Packet */
        !           171: {
        !           172:        register int len;
        !           173:        int pad;
        !           174:        int status;
        !           175: 
        !           176: #ifdef EDEBUG
        !           177:        printf("{l=%d,t=%hX}",s+ETH_HLEN,t);
        !           178: #endif
        !           179: 
        !           180:        /* swap bytes of type */
        !           181:        t= htons(t);
        !           182: 
        !           183:        len=s+ETH_HLEN; /* actual length of packet */
        !           184:        pad = padmap[len & 3];
        !           185: 
        !           186:        /*
        !           187:        * The 3c595 automatically pads short packets to minimum ethernet length,
        !           188:        * but we drop packets that are too large. Perhaps we should truncate
        !           189:        * them instead?
        !           190:        */
        !           191:        if (len + pad > ETH_FRAME_LEN) {
        !           192:                return;
        !           193:        }
        !           194: 
        !           195:        /* drop acknowledgements */
        !           196:        while(( status=inb(BASE + VX_W1_TX_STATUS) )& TXS_COMPLETE ) {
        !           197:                if(status & (TXS_UNDERRUN|TXS_MAX_COLLISION|TXS_STATUS_OVERFLOW)) {
        !           198:                        outw(TX_RESET, BASE + VX_COMMAND);
        !           199:                        outw(TX_ENABLE, BASE + VX_COMMAND);
        !           200:                }
        !           201: 
        !           202:                outb(0x0, BASE + VX_W1_TX_STATUS);
        !           203:        }
        !           204: 
        !           205:        while (inw(BASE + VX_W1_FREE_TX) < len + pad + 4) {
        !           206:                /* no room in FIFO */
        !           207:        }
        !           208: 
        !           209:        outw(len, BASE + VX_W1_TX_PIO_WR_1);
        !           210:        outw(0x0, BASE + VX_W1_TX_PIO_WR_1);    /* Second dword meaningless */
        !           211: 
        !           212:        /* write packet */
        !           213:        outsw(BASE + VX_W1_TX_PIO_WR_1, d, ETH_ALEN/2);
        !           214:        outsw(BASE + VX_W1_TX_PIO_WR_1, nic->node_addr, ETH_ALEN/2);
        !           215:        outw(t, BASE + VX_W1_TX_PIO_WR_1);
        !           216:        outsw(BASE + VX_W1_TX_PIO_WR_1, p, s / 2);
        !           217:        if (s & 1)
        !           218:                outb(*(p+s - 1), BASE + VX_W1_TX_PIO_WR_1);
        !           219: 
        !           220:        while (pad--)
        !           221:                outb(0, BASE + VX_W1_TX_PIO_WR_1);      /* Padding */
        !           222: 
        !           223:         /* wait for Tx complete */
        !           224:         while((inw(BASE + VX_STATUS) & S_COMMAND_IN_PROGRESS) != 0)
        !           225:                 ;
        !           226: }
        !           227: 
        !           228: /**************************************************************************
        !           229: ETH_POLL - Wait for a frame
        !           230: ***************************************************************************/
        !           231: static int t595_poll(struct nic *nic, int retrieve)
        !           232: {
        !           233:        /* common variables */
        !           234:        /* variables for 3C595 */
        !           235:        short status, cst;
        !           236:        register short rx_fifo;
        !           237: 
        !           238:        cst=inw(BASE + VX_STATUS);
        !           239: 
        !           240: #ifdef EDEBUG
        !           241:        if(cst & 0x1FFF)
        !           242:                printf("-%hX-",cst);
        !           243: #endif
        !           244: 
        !           245:        if( (cst & S_RX_COMPLETE)==0 ) {
        !           246:                /* acknowledge  everything */
        !           247:                outw(ACK_INTR | cst, BASE + VX_COMMAND);
        !           248:                outw(C_INTR_LATCH, BASE + VX_COMMAND);
        !           249: 
        !           250:                return 0;
        !           251:        }
        !           252: 
        !           253:        status = inw(BASE + VX_W1_RX_STATUS);
        !           254: #ifdef EDEBUG
        !           255:        printf("*%hX*",status);
        !           256: #endif
        !           257: 
        !           258:        if (status & ERR_RX) {
        !           259:                outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND);
        !           260:                return 0;
        !           261:        }
        !           262: 
        !           263:        rx_fifo = status & RX_BYTES_MASK;
        !           264:        if (rx_fifo==0)
        !           265:                return 0;
        !           266: 
        !           267:        if ( ! retrieve ) return 1;
        !           268: 
        !           269:                /* read packet */
        !           270: #ifdef EDEBUG
        !           271:        printf("[l=%d",rx_fifo);
        !           272: #endif
        !           273:        insw(BASE + VX_W1_RX_PIO_RD_1, nic->packet, rx_fifo / 2);
        !           274:        if(rx_fifo & 1)
        !           275:                nic->packet[rx_fifo-1]=inb(BASE + VX_W1_RX_PIO_RD_1);
        !           276:        nic->packetlen=rx_fifo;
        !           277: 
        !           278:        while(1) {
        !           279:                status = inw(BASE + VX_W1_RX_STATUS);
        !           280: #ifdef EDEBUG
        !           281:                printf("*%hX*",status);
        !           282: #endif
        !           283:                rx_fifo = status & RX_BYTES_MASK;
        !           284: 
        !           285:                if(rx_fifo>0) {
        !           286:                        insw(BASE + VX_W1_RX_PIO_RD_1, nic->packet+nic->packetlen, rx_fifo / 2);
        !           287:                        if(rx_fifo & 1)
        !           288:                                nic->packet[nic->packetlen+rx_fifo-1]=inb(BASE + VX_W1_RX_PIO_RD_1);
        !           289:                        nic->packetlen+=rx_fifo;
        !           290: #ifdef EDEBUG
        !           291:                        printf("+%d",rx_fifo);
        !           292: #endif
        !           293:                }
        !           294:                if(( status & RX_INCOMPLETE )==0) {
        !           295: #ifdef EDEBUG
        !           296:                        printf("=%d",nic->packetlen);
        !           297: #endif
        !           298:                        break;
        !           299:                }
        !           300:                udelay(1000);
        !           301:        }
        !           302: 
        !           303:        /* acknowledge reception of packet */
        !           304:        outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND);
        !           305:        while (inw(BASE + VX_STATUS) & S_COMMAND_IN_PROGRESS);
        !           306: #ifdef EDEBUG
        !           307: {
        !           308:        unsigned short type = 0;        /* used by EDEBUG */
        !           309:        type = (nic->packet[12]<<8) | nic->packet[13];
        !           310:        if(nic->packet[0]+nic->packet[1]+nic->packet[2]+nic->packet[3]+nic->packet[4]+
        !           311:            nic->packet[5] == 0xFF*ETH_ALEN)
        !           312:                printf(",t=%hX,b]",type);
        !           313:        else
        !           314:                printf(",t=%hX]",type);
        !           315: }
        !           316: #endif
        !           317:        return 1;
        !           318: }
        !           319: 
        !           320: 
        !           321: /*************************************************************************
        !           322:        3Com 595 - specific routines
        !           323: **************************************************************************/
        !           324: 
        !           325: static int
        !           326: eeprom_rdy()
        !           327: {
        !           328:        int i;
        !           329: 
        !           330:        for (i = 0; is_eeprom_busy(BASE) && i < MAX_EEPROMBUSY; i++)
        !           331:                udelay(1000);
        !           332:        if (i >= MAX_EEPROMBUSY) {
        !           333:                /* printf("3c595: eeprom failed to come ready.\n"); */
        !           334:                printf("3c595: eeprom is busy.\n"); /* memory in EPROM is tight */
        !           335:                return (0);
        !           336:        }
        !           337:        return (1);
        !           338: }
        !           339: 
        !           340: /*
        !           341:  * get_e: gets a 16 bits word from the EEPROM. we must have set the window
        !           342:  * before
        !           343:  */
        !           344: static int
        !           345: get_e(offset)
        !           346: int offset;
        !           347: {
        !           348:        if (!eeprom_rdy())
        !           349:                return (0xffff);
        !           350:        outw(EEPROM_CMD_RD | offset, BASE + VX_W0_EEPROM_COMMAND);
        !           351:        if (!eeprom_rdy())
        !           352:                return (0xffff);
        !           353:        return (inw(BASE + VX_W0_EEPROM_DATA));
        !           354: }
        !           355: 
        !           356: static void            
        !           357: vxgetlink(void)
        !           358: {
        !           359:     int n, k;
        !           360: 
        !           361:     GO_WINDOW(3);
        !           362:     vx_connectors = inw(BASE + VX_W3_RESET_OPT) & 0x7f;
        !           363:     for (n = 0, k = 0; k < VX_CONNECTORS; k++) {
        !           364:       if (vx_connectors & conn_tab[k].bit) {
        !           365:         if (n > 0) {
        !           366:           printf("/");
        !           367:        }
        !           368:         printf("%s", conn_tab[k].name );
        !           369:         n++;
        !           370:       }
        !           371:     }
        !           372:     if (vx_connectors == 0) {
        !           373:         printf("no connectors!");
        !           374:         return;
        !           375:     }
        !           376:     GO_WINDOW(3);
        !           377:     vx_connector = (inl(BASE + VX_W3_INTERNAL_CFG) 
        !           378:                         & INTERNAL_CONNECTOR_MASK) 
        !           379:                         >> INTERNAL_CONNECTOR_BITS;
        !           380:     if (vx_connector & 0x10) {
        !           381:         vx_connector &= 0x0f;
        !           382:         printf("[*%s*]", conn_tab[vx_connector].name);
        !           383:         printf(": disable 'auto select' with DOS util!");
        !           384:     } else {
        !           385:         printf("[*%s*]", conn_tab[vx_connector].name);
        !           386:     }
        !           387: }
        !           388: 
        !           389: static void            
        !           390: vxsetlink(void)
        !           391: {       
        !           392:     int i, j;
        !           393:     char *reason, *warning;
        !           394:     static char prev_conn = -1;
        !           395: 
        !           396:     if (prev_conn == -1) {
        !           397:         prev_conn = vx_connector;
        !           398:     }
        !           399: 
        !           400:     i = vx_connector;       /* default in EEPROM */
        !           401:     reason = "default";
        !           402:     warning = 0;
        !           403: 
        !           404:     if ((vx_connectors & conn_tab[vx_connector].bit) == 0) {
        !           405:         warning = "strange connector type in EEPROM.";
        !           406:         reason = "forced";
        !           407:         i = CONNECTOR_UTP;
        !           408:     }
        !           409: 
        !           410:         if (warning != 0) {
        !           411:             printf("warning: %s\n", warning);
        !           412:         }
        !           413:         printf("selected %s. (%s)\n", conn_tab[i].name, reason);
        !           414: 
        !           415:     /* Set the selected connector. */
        !           416:     GO_WINDOW(3);
        !           417:     j = inl(BASE + VX_W3_INTERNAL_CFG) & ~INTERNAL_CONNECTOR_MASK;
        !           418:     outl(j | (i <<INTERNAL_CONNECTOR_BITS), BASE + VX_W3_INTERNAL_CFG);
        !           419: 
        !           420:     /* First, disable all. */
        !           421:     outw(STOP_TRANSCEIVER, BASE + VX_COMMAND);
        !           422:     udelay(8000);
        !           423:     GO_WINDOW(4);
        !           424:     outw(0, BASE + VX_W4_MEDIA_TYPE);
        !           425: 
        !           426:     /* Second, enable the selected one. */
        !           427:     switch(i) {
        !           428:       case CONNECTOR_UTP:
        !           429:         GO_WINDOW(4);
        !           430:         outw(ENABLE_UTP, BASE + VX_W4_MEDIA_TYPE);
        !           431:         break;
        !           432:       case CONNECTOR_BNC:
        !           433:         outw(START_TRANSCEIVER,BASE + VX_COMMAND);
        !           434:         udelay(8000);
        !           435:         break;
        !           436:       case CONNECTOR_TX:
        !           437:       case CONNECTOR_FX:
        !           438:         GO_WINDOW(4);
        !           439:         outw(LINKBEAT_ENABLE, BASE + VX_W4_MEDIA_TYPE);
        !           440:         break;
        !           441:       default:  /* AUI and MII fall here */
        !           442:         break;
        !           443:     }
        !           444:     GO_WINDOW(1)        !           445: }
        !           446: 
        !           447: static void t595_disable ( struct nic *nic ) {
        !           448: 
        !           449:        t595_reset(nic);
        !           450: 
        !           451:        outw(STOP_TRANSCEIVER, BASE + VX_COMMAND);
        !           452:        udelay(8000);
        !           453:        GO_WINDOW(4);
        !           454:        outw(0, BASE + VX_W4_MEDIA_TYPE);
        !           455:        GO_WINDOW(1);
        !           456: }
        !           457: 
        !           458: static void t595_irq(struct nic *nic __unused, irq_action_t action __unused)
        !           459: {
        !           460:   switch ( action ) {
        !           461:   case DISABLE :
        !           462:     break;
        !           463:   case ENABLE :
        !           464:     break;
        !           465:   case FORCE :
        !           466:     break;
        !           467:   }
        !           468: }
        !           469: 
        !           470: /**************************************************************************
        !           471: ETH_PROBE - Look for an adapter
        !           472: ***************************************************************************/
        !           473: static int t595_probe ( struct nic *nic, struct pci_device *pci ) {
        !           474: 
        !           475:        int i;
        !           476:        unsigned short *p;
        !           477: 
        !           478:        if (pci->ioaddr == 0)
        !           479:                return 0;
        !           480:        eth_nic_base = pci->ioaddr;
        !           481: 
        !           482:        nic->irqno  = 0;
        !           483:        nic->ioaddr = pci->ioaddr;
        !           484: 
        !           485:        GO_WINDOW(0);
        !           486:        outw(GLOBAL_RESET, BASE + VX_COMMAND);
        !           487:        VX_BUSY_WAIT;
        !           488: 
        !           489:        vxgetlink();
        !           490: 
        !           491: /*
        !           492:        printf("\nEEPROM:");
        !           493:        for (i = 0; i < (EEPROMSIZE/2); i++) {
        !           494:          printf("%hX:", get_e(i));
        !           495:        }
        !           496:        printf("\n");
        !           497: */
        !           498:        /*
        !           499:        * Read the station address from the eeprom
        !           500:        */
        !           501:        p = (unsigned short *) nic->node_addr;
        !           502:        for (i = 0; i < 3; i++) {
        !           503:                GO_WINDOW(0);
        !           504:                p[i] = htons(get_e(EEPROM_OEM_ADDR_0 + i));
        !           505:                GO_WINDOW(2);
        !           506:                outw(ntohs(p[i]), BASE + VX_W2_ADDR_0 + (i * 2));
        !           507:        }
        !           508: 
        !           509:        DBG ( "Ethernet address: %s\n", eth_ntoa (nic->node_addr) );
        !           510: 
        !           511:        t595_reset(nic);
        !           512:        nic->nic_op     = &t595_operations;
        !           513:        return 1;
        !           514: 
        !           515: }
        !           516: 
        !           517: static struct nic_operations t595_operations = {
        !           518:        .connect        = dummy_connect,
        !           519:        .poll           = t595_poll,
        !           520:        .transmit       = t595_transmit,
        !           521:        .irq            = t595_irq,
        !           522: 
        !           523: };
        !           524: 
        !           525: static struct pci_device_id t595_nics[] = {
        !           526: PCI_ROM(0x10b7, 0x5900, "3c590",           "3Com590", 0),              /* Vortex 10Mbps */
        !           527: PCI_ROM(0x10b7, 0x5950, "3c595",           "3Com595", 0),              /* Vortex 100baseTx */
        !           528: PCI_ROM(0x10b7, 0x5951, "3c595-1",         "3Com595", 0),              /* Vortex 100baseT4 */
        !           529: PCI_ROM(0x10b7, 0x5952, "3c595-2",         "3Com595", 0),              /* Vortex 100base-MII */
        !           530: PCI_ROM(0x10b7, 0x9000, "3c900-tpo",       "3Com900-TPO", 0),  /* 10 Base TPO */
        !           531: PCI_ROM(0x10b7, 0x9001, "3c900-t4",        "3Com900-Combo", 0),        /* 10/100 T4 */
        !           532: PCI_ROM(0x10b7, 0x9004, "3c900b-tpo",      "3Com900B-TPO", 0), /* 10 Base TPO */
        !           533: PCI_ROM(0x10b7, 0x9005, "3c900b-combo",    "3Com900B-Combo", 0),       /* 10 Base Combo */
        !           534: PCI_ROM(0x10b7, 0x9006, "3c900b-tpb2",     "3Com900B-2/T", 0), /* 10 Base TP and Base2 */
        !           535: PCI_ROM(0x10b7, 0x900a, "3c900b-fl",       "3Com900B-FL", 0),  /* 10 Base F */
        !           536: PCI_ROM(0x10b7, 0x9800, "3c980-cyclone-1", "3Com980-Cyclone", 0),      /* Cyclone */
        !           537: PCI_ROM(0x10b7, 0x9805, "3c9805-1",        "3Com9805", 0),             /* Dual Port Server Cyclone */
        !           538: PCI_ROM(0x10b7, 0x7646, "3csoho100-tx-1",  "3CSOHO100-TX", 0), /* Hurricane */
        !           539: PCI_ROM(0x10b7, 0x4500, "3c450-1",         "3Com450 HomePNA Tornado", 0),
        !           540: };
        !           541: 
        !           542: PCI_DRIVER ( t595_driver, t595_nics, PCI_NO_CLASS );
        !           543: 
        !           544: DRIVER ( "3C595", nic_driver, pci_driver, t595_driver,
        !           545:         t595_probe, t595_disable );
        !           546: 
        !           547: /*
        !           548:  * Local variables:
        !           549:  *  c-basic-offset: 8
        !           550:  *  c-indent-level: 8
        !           551:  *  tab-width: 8
        !           552:  * End:
        !           553:  */

unix.superglobalmegacorp.com

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