From a5da6053df47f9cbd3b02bbf8a49a4355023f009 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 19 Apr 2001 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2001-04-19 --- pc/ether82557.c | 110 ++++++++++++++++++++++++------------------------ 1 file changed, 54 insertions(+), 56 deletions(-) diff --git a/pc/ether82557.c b/pc/ether82557.c index 3429bb480051abdeb957c3d4e89ff3b9a88a6610..4b4a9ac39cea8fd33f8bf9d5250f9c64f74e5656 100644 --- a/pc/ether82557.c +++ b/pc/ether82557.c @@ -183,11 +183,16 @@ enum { /* CbTransmit count */ CbEOF = 0x8000, }; +typedef struct Ctlr Ctlr; typedef struct Ctlr { Lock slock; /* attach */ int state; int port; + Pcidev* pcidev; + Ctlr* next; + int active; + int eepromsz; /* address size in bits */ ushort* eeprom; @@ -219,6 +224,9 @@ typedef struct Ctlr { ulong dump[17]; } Ctlr; +static Ctlr* ctlrhead; +static Ctlr* ctlrtail; + static uchar configdata[24] = { 0x16, /* byte count */ 0x08, /* Rx/Tx FIFO limit */ @@ -882,34 +890,12 @@ reread: return data; } -typedef struct Adapter { - int port; - int irq; - int tbdf; -} Adapter; -static Block* adapter; - -static void -i82557adapter(Block** bpp, int port, int irq, int tbdf) -{ - Block *bp; - Adapter *ap; - - bp = allocb(sizeof(Adapter)); - ap = (Adapter*)bp->rp; - ap->port = port; - ap->irq = irq; - ap->tbdf = tbdf; - - bp->next = *bpp; - *bpp = bp; -} - static void i82557pci(void) { - Pcidev *p; int port; + Pcidev *p; + Ctlr *ctlr; p = nil; while(p = pcimatch(p, 0x8086, 0x1229)){ @@ -919,11 +905,21 @@ i82557pci(void) * bar[2] is for the flash ROM (1MB). */ port = p->mem[1].bar & ~0x01; - if(ioalloc(port, p->mem[1].size, 0, "i82557pci") < 0){ - print("i82557pci: port 0x%uX in use\n", port); + if(ioalloc(port, p->mem[1].size, 0, "i82557") < 0){ + print("i82557: port 0x%uX in use\n", port); continue; } - i82557adapter(&adapter, port, p->intl, p->tbdf); + + ctlr = malloc(sizeof(Ctlr)); + ctlr->port = port; + ctlr->pcidev = p; + + if(ctlrhead != nil) + ctlrtail->next = ctlr; + else + ctlrhead = ctlr; + ctlrtail = ctlr; + pcisetbme(p); } } @@ -970,51 +966,41 @@ scanphy(Ctlr* ctlr) static int reset(Ether* ether) { - int anar, anlpar, bmcr, bmsr, i, k, medium, phyaddr, port, x; + int anar, anlpar, bmcr, bmsr, i, k, medium, phyaddr, x; unsigned short sum; - Block *bp, **bpp; - Adapter *ap; uchar ea[Eaddrlen]; Ctlr *ctlr; - static int scandone; - if(scandone == 0){ + if(ctlrhead == nil) i82557pci(); - scandone = 1; - } /* - * Any adapter matches if no port is supplied, + * Any adapter matches if no ether->port is supplied, * otherwise the ports must match. */ - port = 0; - bpp = &adapter; - for(bp = *bpp; bp; bp = bp->next){ - ap = (Adapter*)bp->rp; - if(ether->port == 0 || ether->port == ap->port){ - port = ap->port; - ether->irq = ap->irq; - ether->tbdf = ap->tbdf; - *bpp = bp->next; - freeb(bp); + for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){ + if(ctlr->active) + continue; + if(ether->port == 0 || ether->port == ctlr->port){ + ctlr->active = 1; break; } - bpp = &bp->next; } - if(port == 0) + if(ctlr == nil) return -1; /* - * Allocate a controller structure and start to initialise it. + * Initialise the Ctlr structure. * Perform a software reset after which should ensure busmastering * is still enabled. The EtherExpress PRO/100B appears to leave * the PCI configuration alone (see the 'To do' list above) so punt * for now. * Load the RUB and CUB registers for linear addressing (0). */ - ether->ctlr = malloc(sizeof(Ctlr)); - ctlr = ether->ctlr; - ctlr->port = port; + ether->ctlr = ctlr; + ether->port = ctlr->port; + ether->irq = ctlr->pcidev->intl; + ether->tbdf = ctlr->pcidev->tbdf; ilock(&ctlr->rlock); csr32w(ctlr, Port, 0); @@ -1053,16 +1039,29 @@ reset(Ether* ether) * to set any PHY specific options and determine the speed. * Unfortunately, sometimes the EEPROM is blank except for * the ether address and checksum; in this case look at the - * controller type and if 0 scan for the first PHY and try to - * use that. + * controller type and if it's am 82558 or 82559 it has an + * embedded PHY so scan for that. * If no PHY, assume 82503 (serial) operation. */ if((ctlr->eeprom[6] & 0x1F00) && !(ctlr->eeprom[6] & 0x8000)) phyaddr = ctlr->eeprom[6] & 0x00FF; - else if(!(ctlr->eeprom[5] & 0xFF00)) - phyaddr = scanphy(ctlr); else + switch(ctlr->pcidev->rid){ + case 0x01: /* 82557 A-step */ + case 0x02: /* 82557 B-step */ + case 0x03: /* 82557 C-step */ + default: phyaddr = -1; + break; + case 0x04: /* 82558 A-step */ + case 0x05: /* 82558 B-step */ + case 0x06: /* 82559 A-step */ + case 0x07: /* 82559 B-step */ + case 0x08: /* 82559 C-step */ + case 0x09: /* 82559ER A-step */ + phyaddr = scanphy(ctlr); + break; + } if(phyaddr >= 0){ /* * Resolve the highest common ability of the two @@ -1234,7 +1233,6 @@ reset(Ether* ether) /* * Linkage to the generic ethernet driver. */ - ether->port = port; ether->attach = attach; ether->transmit = transmit; ether->interrupt = interrupt;