From f9c97f5d97a797e1802766a9e7cccd29012eff27 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 11 May 2002 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2002-05-11 --- pc/etherelnk3.c | 425 ++++++++++++++++++++---------------------------- pc/pci.c | 8 +- 2 files changed, 185 insertions(+), 248 deletions(-) diff --git a/pc/etherelnk3.c b/pc/etherelnk3.c index 2d752dc21dc334e39bd6fe72fbc5a46dc9b559ad..fd16423ae34a5b36c63cb80377fa2c20e0cdf0ab 100644 --- a/pc/etherelnk3.c +++ b/pc/etherelnk3.c @@ -7,40 +7,6 @@ * PCI latency timer and master enable; * errata list; * rewrite all initialisation. - * - * Product ID: - * 9150 ISA 3C509[B] - * 9050 ISA 3C509[B]-TP - * 9450 ISA 3C509[B]-COMBO - * 9550 ISA 3C509[B]-TPO - * - * 9350 EISA 3C579 - * 9250 EISA 3C579-TP - * - * 5920 EISA 3C592-[TP|COMBO|TPO] - * 5970 EISA 3C597-TX Fast Etherlink 10BASE-T/100BASE-TX - * 5971 EISA 3C597-T4 Fast Etherlink 10BASE-T/100BASE-T4 - * 5972 EISA 3C597-MII Fast Etherlink 10BASE-T/MII - * - * 5900 PCI 3C590-[TP|COMBO|TPO] - * 5950 PCI 3C595-TX Fast Etherlink Shared 10BASE-T/100BASE-TX - * 5951 PCI 3C595-T4 Fast Etherlink Shared 10BASE-T/100BASE-T4 - * 5952 PCI 3C595-MII Fast Etherlink 10BASE-T/MII - - * 7646 PCI 3CSOHO100-TX Fast Etherlink Small Office Connect (9050 downsized clone) - * - * 9000 PCI 3C900-TPO Etherlink III XL PCI 10BASE-T - * 9001 PCI 3C900-COMBO Etherlink III XL PCI 10BASE-T/10BASE-2/AUI - * 9005 PCI 3C900B-COMBO Etherlink III XL PCI 10BASE-T/10BASE-2/AUI - * 9050 PCI 3C905-TX Fast Etherlink XL Shared 10BASE-T/100BASE-TX - * 9051 PCI 3C905-T4 Fast Etherlink Shared 10BASE-T/100BASE-T4 - * 9055 PCI 3C905B-TX Fast Etherlink Shared 10BASE-T/100BASE-TX - * 9200 PCI 3C905C-TX Fast Etherlink Shared 10BASE-T/100BASE-TX - * - * 9058 PCMCIA 3C589[B]-[TP|COMBO] - * - * 627C MCA 3C529 - * 627D MCA 3C529-TP */ #include "u.h" #include "../port/lib.h" @@ -183,7 +149,7 @@ enum { /* Window 1 - operating set */ Fifo = 0x0000, RxError = 0x0004, /* 3C59[0257] only */ RxStatus = 0x0008, - Timerx = 0x000A, + TIMER = 0x000A, TxStatus = 0x000B, TxFree = 0x000C, /* RxError bits */ @@ -248,7 +214,7 @@ enum { /* Window 3 - FIFO management */ autoSelect = 0x01000000, /* MacControl bits */ deferExtendEnable = 0x0001, - deferTimerSelect = 0x001E, /* mask */ + deferTIMERSelect = 0x001E, /* mask */ fullDuplexEnable = 0x0020, allowLargePackets = 0x0040, extendAfterCollision = 0x0080, /* 3C90xB */ @@ -346,7 +312,7 @@ enum { /* Window 7 - bus master operations */ }; enum { /* 3C90x extended register set */ - Timer905 = 0x001A, /* 8-bits */ + TIMER905 = 0x001A, /* 8-bits */ TxStatus905 = 0x001B, /* 8-bits */ PktStatus = 0x0020, /* 32-bits */ DnListPtr = 0x0024, /* 32-bits, 8-byte aligned */ @@ -355,7 +321,7 @@ enum { /* 3C90x extended register set */ ListOffset = 0x002E, /* 8-bits */ TxFreeThresh = 0x002F, /* 8-bits */ UpPktStatus = 0x0030, /* 32-bits */ - FreeTimer = 0x0034, /* 16-bits */ + FreeTIMER = 0x0034, /* 16-bits */ UpListPtr = 0x0038, /* 32-bits, 8-byte aligned */ /* PktStatus bits */ @@ -397,8 +363,8 @@ enum { /* 3C90x extended register set */ */ typedef struct Pd Pd; typedef struct Pd { - ulong np; /* next pointer */ - ulong control; /* FSH or UpPktStatus */ + ulong np; /* next pointer */ + ulong control; /* FSH or UpPktStatus */ ulong addr; ulong len; @@ -406,30 +372,39 @@ typedef struct Pd { Block* bp; } Pd; -typedef struct { - Lock wlock; /* window access */ +typedef struct Ctlr Ctlr; +typedef struct Ctlr { + int port; + Pcidev* pcidev; + int irq; + Ctlr* next; + int active; + int did; + + Lock wlock; /* window access */ int attached; int busmaster; - Block* rbp; /* receive buffer */ + Block* rbp; /* receive buffer */ - Block* txbp; /* FIFO -based transmission */ + Block* txbp; /* FIFO -based transmission */ int txthreshold; int txbusy; - int nup; /* full-busmaster -based reception */ + int nup; /* full-busmaster -based reception */ void* upbase; Pd* upr; Pd* uphead; - int ndn; /* full-busmaster -based transmission */ + int ndn; /* full-busmaster -based transmission */ void* dnbase; Pd* dnr; Pd* dnhead; Pd* dntail; int dnq; - long interrupts; /* statistics */ + long interrupts; /* statistics */ + long bogusinterrupts; long timer[2]; long stats[BytesRcvdOk+3]; @@ -443,17 +418,18 @@ typedef struct { ulong dninterrupts; ulong dnqueued; - int did; /* Controller's device ID */ - ulong cbfns; /* CardBus functions */ - - int xcvr; /* transceiver type */ - int rxstatus9; /* old-style RxStatus register */ - int rxearly; /* RxEarlyThreshold */ - int ts; /* threshold shift */ + int xcvr; /* transceiver type */ + int rxstatus9; /* old-style RxStatus register */ + int rxearly; /* RxEarlyThreshold */ + int ts; /* threshold shift */ int upenabled; int dnenabled; + ulong* cbfns; /* CardBus functions */ } Ctlr; +static Ctlr* ctlrhead; +static Ctlr* ctlrtail; + static void init905(Ctlr* ctlr) { @@ -620,9 +596,11 @@ attach(Ether* ether) COMMAND(port, RxEnable, 0); COMMAND(port, TxEnable, 0); - if (ctlr->cbfns) - /* This must be a cardbus card. Acknowledge the interrupt */ - intrack3c575(KADDR(ctlr->cbfns)); + /* + * If this is a CardBus card, acknowledge any interrupts. + */ + if(ctlr->cbfns != nil) + intrack3c575(ctlr->cbfns); /* * Prime the busmaster channel for receiving directly into a @@ -779,7 +757,6 @@ txstart905(Ether* ether) coherence(); ctlr->dnhead->np = PADDR(&pd->np); - coherence(); ctlr->dnhead->control &= ~dnIndicate; ctlr->dnhead = pd; if(ctlr->dnq == 0) @@ -853,7 +830,6 @@ receive905(Ether* ether) pd->bp->wp = pd->bp->rp+len; etheriq(ether, pd->bp, 1); pd->bp = bp; - coherence(); pd->addr = PADDR(bp->rp); coherence(); } @@ -993,6 +969,7 @@ interrupt(Ureg*, void* arg) ilock(&ctlr->wlock); status = STATUS(port); if(!(status & (interruptMask|interruptLatch))){ + ctlr->bogusinterrupts++; iunlock(&ctlr->wlock); return; } @@ -1001,9 +978,9 @@ interrupt(Ureg*, void* arg) ctlr->interrupts++; if(ctlr->busmaster == 2) - ctlr->timer[0] += inb(port+Timer905) & 0xFF; + ctlr->timer[0] += inb(port+TIMER905) & 0xFF; else - ctlr->timer[0] += inb(port+Timerx) & 0xFF; + ctlr->timer[0] += inb(port+TIMER) & 0xFF; do{ if(status & hostError){ @@ -1164,14 +1141,15 @@ interrupt(Ureg*, void* arg) panic("#l%d: interrupt mask 0x%uX\n", ether->ctlrno, status); COMMAND(port, AcknowledgeInterrupt, interruptLatch); - if (ctlr->cbfns) intrack3c575((ulong *)KADDR(ctlr->cbfns)); + if(ctlr->cbfns != nil) + intrack3c575(ctlr->cbfns); }while((status = STATUS(port)) & (interruptMask|interruptLatch)); if(ctlr->busmaster == 2) - ctlr->timer[1] += inb(port+Timer905) & 0xFF; + ctlr->timer[1] += inb(port+TIMER905) & 0xFF; else - ctlr->timer[1] += inb(port+Timerx) & 0xFF; + ctlr->timer[1] += inb(port+TIMER) & 0xFF; COMMAND(port, SelectRegisterWindow, w); iunlock(&ctlr->wlock); @@ -1195,6 +1173,7 @@ ifstat(Ether* ether, void* a, long n, ulong offset) p = malloc(READSTR); len = snprint(p, READSTR, "interrupts: %lud\n", ctlr->interrupts); + len += snprint(p+len, READSTR-len, "bogusinterrupts: %lud\n", ctlr->bogusinterrupts); len += snprint(p+len, READSTR-len, "timer: %lud %lud\n", ctlr->timer[0], ctlr->timer[1]); len += snprint(p+len, READSTR-len, "carrierlost: %lud\n", @@ -1255,34 +1234,25 @@ txrxreset(int port) ; } -typedef struct Adapter { - int port; - int irq; - int tbdf; - int did; - ulong cbfns; - int active; -} Adapter; -static Block* adapter; - -static void -tcmadapter(int port, int irq, int tbdf, int did, ulong cbfns) +static Ctlr* +tcmadapter(int port, int irq, Pcidev* pcidev) { - Block *bp; - Adapter *ap; + Ctlr *ctlr; - bp = iallocb(sizeof(Adapter)); - if(bp == nil) - return; - ap = (Adapter*)bp->rp; - ap->port = port; - ap->irq = irq; - ap->tbdf = tbdf; - ap->did = did; - ap->cbfns = cbfns; - - bp->next = adapter; - adapter = bp; + ctlr = malloc(sizeof(Ctlr)); + ctlr->port = port; + ctlr->irq = irq; + if(pcidev != nil){ + ctlr->pcidev = pcidev; + } + + if(ctlrhead != nil) + ctlrtail->next = ctlr; + else + ctlrhead = ctlr; + ctlrtail = ctlr; + + return ctlr; } /* @@ -1392,8 +1362,10 @@ tcm509isa(void) * it fully. */ while(port = activate()){ - if(ioalloc(port, 0x10, 0, "tcm509isa") < 0) + if(ioalloc(port, 0x10, 0, "tcm509isa") < 0){ + print("tcm509isa: port 0x%uX in use\n", port); continue; + } /* * 6. Tag the adapter so it won't respond in future. @@ -1427,7 +1399,7 @@ tcm509isa(void) COMMAND(port, AcknowledgeInterrupt, 0xFF); irq = (ins(port+ResourceConfig)>>12) & 0x0F; - tcmadapter(port, irq, BUSUNKNOWN, 0, 0); + tcmadapter(port, irq, nil); } } @@ -1452,9 +1424,10 @@ tcm5XXeisa(void) */ for(slot = 1; slot < MaxEISA; slot++){ port = slot*0x1000; - if(ioalloc(port, 0x1000, 0, "tcm5XXeisa") < 0) + if(ioalloc(port, 0x1000, 0, "tcm5XXeisa") < 0){ + print("tcm5XXeisa: port 0x%uX in use\n", port); continue; - + } if(ins(port+0xC80+ManufacturerID) != 0x6D50){ iofree(port); continue; @@ -1472,7 +1445,7 @@ tcm5XXeisa(void) COMMAND(port, AcknowledgeInterrupt, 0xFF); irq = (ins(port+ResourceConfig)>>12) & 0x0F; - tcmadapter(port, irq, BUSUNKNOWN, 0, 0); + tcmadapter(port, irq, nil); } } @@ -1484,8 +1457,6 @@ tcm59Xpci(void) p = nil; while(p = pcimatch(p, 0x10B7, 0)){ - ulong bar; - /* * Not prepared to deal with memory-mapped * devices yet. @@ -1494,22 +1465,16 @@ tcm59Xpci(void) continue; port = p->mem[0].bar & ~0x01; if((port = ioalloc((port == 0)? -1: port, p->mem[0].size, - 0, "tcm59Xpci")) < 0) + 0, "tcm59Xpci")) < 0){ + print("tcm59Xpci: port 0x%uX in use\n", port); continue; - + } irq = p->intl; COMMAND(port, GlobalReset, 0); while(STATUS(port) & commandInProgress) ; - bar = 0; - if (p->did == 0x5157) { - /* Map the CardBus functions */ - bar = pcicfgr32(p, PciBAR2); - print("tcmp59Xpci: CardBus functions at %.8ulX\n", bar & ~KZERO); - } - - tcmadapter(port, irq, p->tbdf, p->did, bar); + tcmadapter(port, irq, p); pcisetbme(p); } } @@ -1521,32 +1486,29 @@ static char* tcmpcmcia[] = { nil, }; -static int +static Ctlr* tcm5XXpcmcia(Ether* ether) { int i; + if(ether->type == nil) + return nil; + for(i = 0; tcmpcmcia[i] != nil; i++){ - if(ether->type==nil || !cistrcmp(ether->type, tcmpcmcia[i])){ - /* - * No need for an ioalloc here, the 589 reset - * code deals with it. - if(ioalloc(ether->port, 0x10, 0, "tcm5XXpcmcia") < 0) - return 0; - */ - return ether->port; - } + if(cistrcmp(ether->type, tcmpcmcia[i])) + continue; + return tcmadapter(ether->port, ether->irq, nil); } - - return 0; + return nil; } static void -setxcvr(int port, int xcvr, int is9) +setxcvr(Ctlr* ctlr, int xcvr) { - int x; + int port, x; - if(is9){ + port = ctlr->port; + if(ctlr->rxstatus9){ COMMAND(port, SelectRegisterWindow, Wsetup); x = ins(port+AddressConfig) & ~xcvrMask9; x |= (xcvr>>20)<<14; @@ -1660,22 +1622,6 @@ scanphy(int port) } } -#ifdef notdef -static struct xxx { - int available; - int next; -} xxx[8] = { - { base10TAvailable, 1, }, /* xcvr10BaseT -> xcvrAui */ - { auiAvailable, 3, }, /* xcvrAui -> xcvr10Base2 */ - { 0, -1, }, - { coaxAvailable, -1, }, /* xcvr10Base2 -> nowhere */ - { baseTXAvailable, 5, }, /* xcvr100BaseTX-> xcvr100BaseFX */ - { baseFXAvailable, -1, }, /* xcvr100BaseFX-> nowhere */ - { miiConnector, -1, }, /* xcvrMii -> nowhere */ - { 0, -1, }, -}; -#endif /* notdef */ - static struct { char *name; int avail; @@ -1690,10 +1636,9 @@ static struct { }; static int -autoselect(int port, int xcvr, int is9) +autoselect(Ctlr* ctlr) { - int media, x; - USED(xcvr); + int media, port, x; /* * Pathetic attempt at automatic media selection. @@ -1701,7 +1646,8 @@ autoselect(int port, int xcvr, int is9) * cards operational. * It's a bonus if it works for anything else. */ - if(is9){ + port = ctlr->port; + if(ctlr->rxstatus9){ COMMAND(port, SelectRegisterWindow, Wsetup); x = ins(port+ConfigControl); media = 0; @@ -1728,7 +1674,7 @@ autoselect(int port, int xcvr, int is9) /* * Must have InternalConfig register. */ - setxcvr(port, xcvr100BaseTX, is9); + setxcvr(ctlr, xcvr100BaseTX); COMMAND(port, SelectRegisterWindow, Wdiagnostic); x = ins(port+MediaStatus) & ~(dcConverterEnabled|jabberGuardEnable); @@ -1741,7 +1687,7 @@ autoselect(int port, int xcvr, int is9) } if(media & base10TAvailable){ - setxcvr(port, xcvr10BaseT, is9); + setxcvr(ctlr, xcvr10BaseT); COMMAND(port, SelectRegisterWindow, Wdiagnostic); x = ins(port+MediaStatus) & ~dcConverterEnabled; @@ -1761,12 +1707,19 @@ autoselect(int port, int xcvr, int is9) } static int -eepromdata(int did, int port, int offset) +eepromdata(Ctlr* ctlr, int offset) { + int port; + + port = ctlr->port; + COMMAND(port, SelectRegisterWindow, Wsetup); while(EEPROMBUSY(port)) ; - EEPROMCMD(port, (did == 0x5157)? EepromRead8bRegister: EepromReadRegister, offset); + if(ctlr->pcidev && ctlr->pcidev->did == 0x5157) + EEPROMCMD(port, EepromRead8bRegister, offset); + else + EEPROMCMD(port, EepromReadRegister, offset); while(EEPROMBUSY(port)) ; return EEPROMDATA(port); @@ -1775,15 +1728,11 @@ eepromdata(int did, int port, int offset) int etherelnk3reset(Ether* ether) { - int anar, anlpar, phyaddr, phystat, timeo, xcvr; - int busmaster, did, i, ismii, j, port, rxearly, rxstatus9, x; - Block *bp, **bpp; - Adapter *ap; - uchar ea[Eaddrlen]; + char *p; Ctlr *ctlr; + uchar ea[Eaddrlen]; static int scandone; - char *p; - ulong cbfns; + int anar, anlpar, i, j, phyaddr, phystat, port, timeo, x; /* * Scan for adapter on PCI, EISA and finally @@ -1800,84 +1749,77 @@ etherelnk3reset(Ether* ether) * Any adapter matches if no ether->port is supplied, * otherwise the ports must match. */ - port = 0; - did = 0; - cbfns = 0; - bpp = &adapter; - for(bp = *bpp; bp; bp = bp->next){ - ap = (Adapter*)bp->rp; - if(ap->active) + for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){ + if(ctlr->active) continue; - if(ether->port == 0 || ether->port == ap->port){ - port = ap->port; - did = ap->did; - ether->irq = ap->irq; - ether->tbdf = ap->tbdf; - cbfns = ap->cbfns; - // *bpp = bp->next; // HIRO. - // freeb(bp); - ap->active = 1; + if(ether->port == 0 || ether->port == ctlr->port){ + ctlr->active = 1; break; } - bpp = &bp->next; } - if(port == 0 && (port = tcm5XXpcmcia(ether)) == 0) + if(ctlr == nil && (ctlr = tcm5XXpcmcia(ether)) == 0) return -1; + ether->ctlr = ctlr; + port = ctlr->port; + ether->port = port; + ether->irq = ctlr->irq; + if(ctlr->pcidev != nil) + ether->tbdf = ctlr->pcidev->tbdf; + else + ether->tbdf = BUSUNKNOWN; + /* * Read the DeviceID from the EEPROM, it's at offset 0x03, * and do something depending on capabilities. */ - ismii = 0; - switch(did = eepromdata(did, port, 0x03)){ - - case 0x9055: - case 0x9200: - case 0x7646: /* 3CSOHO100-TX */ + switch(ctlr->did = eepromdata(ctlr, 0x03)){ case 0x5157: /* 3C575 Cyclone */ + ctlr->cbfns = KADDR(pcicfgr32(ctlr->pcidev, PciBAR2)); + /*FALLTHROUGH*/ case 0x6056: - ismii = 1; + case 0x7646: /* 3CSOHO100-TX */ + case 0x9055: /* 3C905B-TX */ + case 0x9200: /* 3C905C-TX */ /*FALLTHROUGH*/ - case 0x9000: - case 0x9001: - case 0x9005: - case 0x9050: - case 0x9051: - if(BUSTYPE(ether->tbdf) != BusPCI){ - ismii = 0; + case 0x9000: /* 3C900-TPO */ + case 0x9001: /* 3C900-COMBO */ + case 0x9005: /* 3C900B-COMBO */ + case 0x9050: /* 3C905-TX */ + case 0x9051: /* 3C905-T4 */ + if(BUSTYPE(ether->tbdf) != BusPCI) goto buggery; - } - busmaster = 2; + ctlr->busmaster = 2; goto vortex; - - case 0x5900: - case 0x5920: - case 0x5950: - case 0x5951: - case 0x5952: - case 0x5970: - case 0x5971: - case 0x5972: - busmaster = 1; + case 0x5900: /* 3C590-[TP|COMBO|TPO] */ + case 0x5920: /* 3C592-[TP|COMBO|TPO] */ + case 0x5950: /* 3C595-TX */ + case 0x5951: /* 3C595-T4 */ + case 0x5952: /* 3C595-MII */ + case 0x5970: /* 3C597-TX */ + case 0x5971: /* 3C597-T4 */ + case 0x5972: /* 3C597-MII */ + ctlr->busmaster = 1; vortex: COMMAND(port, SelectRegisterWindow, Wfifo); - xcvr = inl(port+InternalConfig) & (autoSelect|xcvrMask); - rxearly = 8188; - rxstatus9 = 0; + ctlr->xcvr = inl(port+InternalConfig) & (autoSelect|xcvrMask); + ctlr->rxearly = 8188; + ctlr->rxstatus9 = 0; break; - buggery: default: - busmaster = 0; + ctlr->busmaster = 0; COMMAND(port, SelectRegisterWindow, Wsetup); x = ins(port+AddressConfig); - xcvr = ((x & xcvrMask9)>>14)<<20; + ctlr->xcvr = ((x & xcvrMask9)>>14)<<20; if(x & autoSelect9) - xcvr |= autoSelect; - rxearly = 2044; - rxstatus9 = 1; + ctlr->xcvr |= autoSelect; + ctlr->rxearly = 2044; + ctlr->rxstatus9 = 1; break; } + if(ctlr->rxearly >= 2048) + ctlr->ts = 2; /* * Check if the adapter's station address is to be overridden. @@ -1888,7 +1830,7 @@ etherelnk3reset(Ether* ether) memset(ea, 0, Eaddrlen); if(memcmp(ea, ether->ea, Eaddrlen) == 0){ for(i = 0; i < Eaddrlen/2; i++){ - x = eepromdata(did, port, i); + x = eepromdata(ctlr, i); ether->ea[2*i] = x>>8; ether->ea[2*i+1] = x; } @@ -1903,7 +1845,7 @@ etherelnk3reset(Ether* ether) * busmastering can be used. Due to bugs in the first revision * of the 3C59[05], don't use busmastering at 10Mbps. */ - XCVRDEBUG("reset: xcvr %uX\n", xcvr); + XCVRDEBUG("reset: xcvr %uX\n", ctlr->xcvr); /* * Allow user to specify desired media in plan9.ini @@ -1914,17 +1856,26 @@ etherelnk3reset(Ether* ether) p = ether->opt[i]+6; for(j = 0; j < nelem(media); j++) if(cistrcmp(p, media[j].name) == 0) - xcvr = media[j].xcvr; + ctlr->xcvr = media[j].xcvr; } /* * forgive me, but i am weak */ - if(ismii){ - xcvr = xcvrMii; + switch(ctlr->did){ + default: + if(ctlr->xcvr & autoSelect) + ctlr->xcvr = autoselect(ctlr); + break; + case 0x6056: + case 0x5157: + case 0x7646: + case 0x9055: + case 0x9200: + ctlr->xcvr = xcvrMii; txrxreset(port); XCVRDEBUG("905[BC] reset ops 0x%uX\n", ins(port+ResetOp905B)); - if (did == 0x5157) { + if(ctlr->did == 0x5157) { ushort reset_opts; COMMAND(port, SelectRegisterWindow, Wstation); @@ -1932,19 +1883,20 @@ etherelnk3reset(Ether* ether) reset_opts |= 0x0010; /* Invert LED */ outs(port + ResetOp905B, reset_opts); } + break; } - else if(xcvr & autoSelect) - xcvr = autoselect(port, xcvr, rxstatus9); - XCVRDEBUG("autoselect returns: xcvr %uX, did 0x%uX\n", xcvr, did); - - switch(xcvr){ + XCVRDEBUG("xcvr selected: %uX, did 0x%uX\n", ctlr->xcvr, ctlr->did); + switch(ctlr->xcvr){ case xcvrMii: /* * Quick hack. scanphy(port); */ - phyaddr = (did == 0x5157)? 0: 24; + if(ctlr->did == 0x5157) + phyaddr = 0; + else + phyaddr = 24; for(i = 0; i < 7; i++) XCVRDEBUG(" %2.2uX", miir(port, phyaddr, i)); XCVRDEBUG("\n"); @@ -1990,7 +1942,6 @@ etherelnk3reset(Ether* ether) /* nothing to do */ } break; - case xcvr100BaseTX: case xcvr100BaseFX: COMMAND(port, SelectRegisterWindow, Wfifo); @@ -2005,7 +1956,6 @@ etherelnk3reset(Ether* ether) if(x & dataRate100) ether->mbps = 100; break; - case xcvr10BaseT: /* * Enable Link Beat and Jabber to start the @@ -2016,10 +1966,9 @@ etherelnk3reset(Ether* ether) x |= linkBeatEnable|jabberGuardEnable; outs(port+MediaStatus, x); - if((did & 0xFF00) == 0x5900) - busmaster = 0; + if((ctlr->did & 0xFF00) == 0x5900) + ctlr->busmaster = 0; break; - case xcvr10Base2: COMMAND(port, SelectRegisterWindow, Wdiagnostic); x = ins(port+MediaStatus) & ~(linkBeatEnable|jabberGuardEnable); @@ -2042,7 +1991,7 @@ etherelnk3reset(Ether* ether) * Clear out any lingering Tx status. */ COMMAND(port, SelectRegisterWindow, Wop); - if(busmaster == 2) + if(ctlr->busmaster == 2) x = port+TxStatus905; else x = port+TxStatus; @@ -2050,29 +1999,14 @@ etherelnk3reset(Ether* ether) outb(x, 0); /* - * Allocate a controller structure, clear out the + * Clear out the * adapter statistics, clear the statistics logged into ctlr - * and enable statistics collection. Xcvr is needed in order - * to collect the BadSSD statistics. + * and enable statistics collection. */ - ether->ctlr = malloc(sizeof(Ctlr)); - ctlr = ether->ctlr; - ilock(&ctlr->wlock); - ctlr->xcvr = xcvr; statistics(ether); memset(ctlr->stats, 0, sizeof(ctlr->stats)); - ctlr->busmaster = busmaster; - ctlr->xcvr = xcvr; - ctlr->rxstatus9 = rxstatus9; - ctlr->rxearly = rxearly; - if(rxearly >= 2048) - ctlr->ts = 2; - - ctlr->did = did; - ctlr->cbfns = cbfns; - COMMAND(port, StatisticsEnable, 0); /* @@ -2093,7 +2027,7 @@ etherelnk3reset(Ether* ether) * until the whole packet has been received. */ ctlr->upenabled = 1; - x = eepromdata(did, port, 0x0F); + x = eepromdata(ctlr, 0x0F); if(!(x & 0x01)) outl(port+PktStatus, upRxEarlyEnable); @@ -2124,14 +2058,13 @@ etherelnk3reset(Ether* ether) */ ctlr->txthreshold = ETHERMAXTU/2; COMMAND(port, SetTxStartThresh, ctlr->txthreshold>>ctlr->ts); - COMMAND(port, SetRxEarlyThresh, rxearly>>ctlr->ts); + COMMAND(port, SetRxEarlyThresh, ctlr->rxearly>>ctlr->ts); iunlock(&ctlr->wlock); /* * Linkage to the generic ethernet driver. */ - ether->port = port; ether->attach = attach; ether->transmit = transmit; ether->interrupt = interrupt; @@ -2147,7 +2080,7 @@ etherelnk3reset(Ether* ether) void etherelnk3link(void) { - addethercard("elnk3", etherelnk3reset); - addethercard("3C509", etherelnk3reset); + addethercard("elnk3", etherelnk3reset); + addethercard("3C509", etherelnk3reset); addethercard("3C575", etherelnk3reset); } diff --git a/pc/pci.c b/pc/pci.c index f042b49e7c2f0eee5cffe989ed546345e996c415..eecffe97bdfbbfb84c891bb4c6d875e89c3247a5 100644 --- a/pc/pci.c +++ b/pc/pci.c @@ -64,7 +64,7 @@ static int pcimaxdno; static Pcidev* pciroot; static Pcidev* pcilist; static Pcidev* pcitail; -static int nobios; +static int nobios, nopcirouting; static int pcicfgrw32(int, int, int, int); static int pcicfgrw8(int, int, int, int); @@ -753,6 +753,9 @@ pcicfginit(void) if (getconf("*nobios")) nobios = 1; + if (getconf("*nopcirouting")) + nopcirouting = 1; + /* * Try to determine which PCI configuration mode is implemented. * Mode2 uses a byte at 0xCF8 and another at 0xCFA; Mode1 uses @@ -843,7 +846,8 @@ pcicfginit(void) return; } - pcirouting(); + if (!nopcirouting) + pcirouting(); out: unlock(&pcicfginitlock);