📄 ether83815.mii.c
字号:
data = mdior(ctlr, 18); if(data & 0x10000) return -1; return data & 0xFFFF;}static intns83815miimiw(Mii* mii, int pa, int ra, int data){ Ctlr *ctlr; ctlr = mii->ctlr; /* * MII Management Interface Write. * * Preamble; * ST+OP+PA+RA+LT + 16 data bits; * Z. */ mdiow(ctlr, 0xFFFFFFFF, 32); data &= 0xFFFF; data |= (0x05<<(5+5+2+16))|(pa<<(5+2+16))|(ra<<(2+16))|(0x02<<16); mdiow(ctlr, data, 32); return data & 0xFFFF; /* TODO: what's the caller expect here? */}// TODO: finish thisstatic intsismiimir(Mii* mii, int pa, int ra){ int data; Ctlr *ctlr; ctlr = mii->ctlr; /* * MII Management Interface Read. * * Preamble; * ST+OP+PA+RA; * LT + 16 data bits. */ mdiow(ctlr, 0xFFFFFFFF, 32); mdiow(ctlr, 0x1800|(pa<<5)|ra, 14); data = mdior(ctlr, 18); if(data & 0x10000) return -1; return data & 0xFFFF;}// TODO: finish thisstatic intsismiimiw(Mii* mii, int pa, int ra, int data){ Ctlr *ctlr; ctlr = mii->ctlr; /* * MII Management Interface Write. * * Preamble; * ST+OP+PA+RA+LT + 16 data bits; * Z. */ mdiow(ctlr, 0xFFFFFFFF, 32); data &= 0xFFFF; data |= (0x05<<(5+5+2+16))|(pa<<(5+2+16))|(ra<<(2+16))|(0x02<<16); mdiow(ctlr, data, 32); return data & 0xFFFF; /* TODO: what's the caller expect here? */}// MII// TODO: finish thisstatic intmedia(Ether* ether){ Ctlr* ctlr; ulong cfg; ctlr = ether->ctlr; cfg = csr32r(ctlr, Rcfg); if(waserror()){err: if(ctlr->mii != nil){ free(ctlr->mii); ctlr->mii = nil; }#ifdef FS return 10;#else nexterror();#endif } switch (ctlr->id) { case SiS900: case SiS7016: if (1){ if((ctlr->mii = malloc(sizeof(Mii))) == nil) error(Enomem); ctlr->mii->ctlr = ctlr; ctlr->mii->mir = sismiimir; ctlr->mii->miw = sismiimiw; if(mii(ctlr->mii, ~0) == 0) error("no PHY"); // ctlr->cfg |= Dupstsien|Lnkstsien|Spdstsien; // ctlr->imr |= Phy; } break; case Nat83815: if (1){ if((ctlr->mii = malloc(sizeof(Mii))) == nil) error(Enomem); ctlr->mii->ctlr = ctlr; ctlr->mii->mir = ns83815miimir; ctlr->mii->miw = ns83815miimiw; if(mii(ctlr->mii, ~0) == 0) error("no PHY"); // ctlr->cfg |= Dupstsien|Lnkstsien|Spdstsien; // ctlr->imr |= Phy; } break; } ctlr->fd = (cfg & Fdup) != 0; if(cfg & Speed100) return 100; if((cfg & Lnksts) == 0) return 100; /* no link: use 100 to ensure larger queues */ return 10;}static char* mediatable[9] = { "10BASE-T", /* TP */ "10BASE-2", /* BNC */ "10BASE-5", /* AUI */ "100BASE-TX", "10BASE-TFD", "100BASE-TXFD", "100BASE-T4", "100BASE-FX", "100BASE-FXFD",};enum { MagicReg = 0x48, MagicRegSz = 1, Magicrden = 0x40, /* read enable, apparently */ Paddr= 0x70, /* address port */ Pdata= 0x71, /* data port */};/* rcmos() originally from LANL's SiS 900 driver's rcmos() */static intsisrdcmos(Ctlr *ctlr){ int i; unsigned reg; ulong port; Pcidev *p; p = pcimatch(nil, SiS, SiS630bridge); if (p == nil) { print("ns83815: no SiS 630 rev. %ux bridge for mac addr\n", ctlr->pcidev->rid); return 0; } port = p->mem[0].bar & ~0x01; print("ns83815: SiS 630 rev. %ux reading mac addr from cmos via bridge at port 0x%lux\n", ctlr->pcidev->rid, port); reg = pcicfgr8(p, MagicReg); pcicfgw8(p, MagicReg, reg|Magicrden); for (i = 0; i < Eaddrlen; i++) { outb(port+Paddr, SiS630eenodeaddr + i); ctlr->sromea[i] = inb(port+Pdata); } pcicfgw8(p, MagicReg, reg & ~Magicrden); return 1;}static intis630(ulong id, Pcidev *p){ if (id == SiS900) switch (p->rid) { case SiSrev630s: case SiSrev630e: case SiSrev630ea1: return 1; } return 0;}/* * If this is a SiS 630E chipset with an embedded SiS 900 controller, * we have to read the MAC address from the APC CMOS RAM. - sez freebsd. * However, CMOS *is* NVRAM normally. See devrtc.c:440, memory.c:88. */static voidsissrom(Ctlr *ctlr){ union { uchar eaddr[Eaddrlen]; ushort alignment; } ee; int i, off = SiSeenodeaddr, cnt = sizeof ee.eaddr / sizeof(short); ushort *shp = (ushort *)ee.eaddr; if (!is630(ctlr->id, ctlr->pcidev) || !sisrdcmos(ctlr)) { print("ns83815: reading SiS mac address from eeprom\n"); for (i = 0; i < cnt; i++) *shp++ = eegetw(ctlr, off++); memmove(ctlr->sromea, ee.eaddr, sizeof ctlr->sromea); }}static voidnssrom(Ctlr *ctlr){ int i, j; debug("ns83815: fa311: reading mac address from eeprom & swizzling\n"); for(i = 0; i < nelem(ctlr->srom); i++) ctlr->srom[i] = eegetw(ctlr, i); /* * the MAC address is reversed, straddling word boundaries */ j = Nseenodeaddr*16 + 15; // bit offset to read for (i=0; i<48; i++, j++) ctlr->sromea[i>>3] |= ((ctlr->srom[j>>4] >> (15-(j&0xF))) & 1) << (i&7);}static voidsrom(Ctlr* ctlr){ memset(ctlr->sromea, 0, sizeof(ctlr->sromea)); switch (ctlr->id) { case SiS900: case SiS7016: sissrom(ctlr); break; case Nat83815: nssrom(ctlr); break; default: print("ns83815: srom: unknown id 0x%ux\n", ctlr->id); break; }}// from pci.cenum { Pcinetctlr = 0x02, /* network controller */// PciCCRp = 0x09, /* programming interface class code */// PciCCRu = 0x0A, /* sub-class code */// PciCCRb = 0x0B, /* base class code */};static voidscanpci83815(void){ typedef struct { ulong bar; /* base address */ int size; } Bar; int port; ulong id; Bar *portbarp; Ctlr *ctlr; Pcidev *p = nil; while(p = pcimatch(p, 0, 0)){ /* ccru is a short in the FS kernel, thus the cast to uchar */ if (p->ccrb != Pcinetctlr || (uchar)p->ccru != 0) continue; // not a nic id = (p->did<<16)|p->vid; // print("ns83815: id 0x%lux on pci bus\n", id); switch(id){ case Nat83815: print("ns83815: FA31[12] found\n"); break; case SiS900: print("ns83815: SiS900"); if (is630(id, p)) print(" (within SiS630)"); print(" found\n"); break; case SiS7016: print("ns83815: SiS7016 found\n"); break; default: continue; // unrecognised } portbarp = &p->mem[0]; port = portbarp->bar & ~1; /* * bar[0] is the I/O port register address and * bar[1] is the memory-mapped register address. */ ctlr = mallocz(sizeof(Ctlr), 1); ctlr->port = port; ctlr->pcidev = p; ctlr->id = id; if(ioalloc(ctlr->port, portbarp->size, 0, "ns83815") < 0){ print("ns83815: port 0x%ux in use\n", ctlr->port); free(ctlr); continue; } softreset(ctlr, 0); srom(ctlr); if(ctlrhead != nil) ctlrtail->next = ctlr; else ctlrhead = ctlr; ctlrtail = ctlr; }}intdp83815reset(Ether* ether){ Ctlr *ctlr; int i, x; ulong ctladdr; uchar ea[Eaddrlen]; static int scandone; if(scandone == 0){ scanpci83815(); scandone = 1; } /* * Any adapter matches if no ether->port is supplied, * otherwise the ports must match. */ for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){ if(ctlr->active) continue; if(ether->port == 0 || ether->port == ctlr->port){ ctlr->active = 1; break; } } if(ctlr == nil) return -1; ether->ctlr = ctlr; ether->port = ctlr->port; ether->irq = ctlr->pcidev->intl; ether->tbdf = ctlr->pcidev->tbdf; /* * Check if the adapter's station address is to be overridden. * If not, read it from the EEPROM and set in ether->ea prior to * loading the station address in the hardware. */ memset(ea, 0, Eaddrlen); if(memcmp(ea, ether->ea, Eaddrlen) == 0) memmove(ether->ea, ctlr->sromea, Eaddrlen); print("ns83815: setting mac addr\n"); /* DEBUG */ for(i=0; i<Eaddrlen; i+=2){ x = ether->ea[i] | (ether->ea[i+1]<<8); ctladdr = (ctlr->id == Nat83815? i: i<<15); csr32w(ctlr, Rrfcr, ctladdr); csr32w(ctlr, Rrfdr, x); } csr32w(ctlr, Rrfcr, Rfen|Apm|Aab|Aam); ether->mbps = media(ether); /* * Look for a medium override in case there's no autonegotiation * or the autonegotiation fails. */ for(i = 0; i < ether->nopt; i++){ if(cistrcmp(ether->opt[i], "FD") == 0){ ctlr->fd = 1; continue; } for(x = 0; x < nelem(mediatable); x++){ debug("compare <%s> <%s>\n", mediatable[x], ether->opt[i]); if(cistrcmp(mediatable[x], ether->opt[i]) == 0){ if(x != 4 && x >= 3) ether->mbps = 100; else ether->mbps = 10; switch(x){ default: ctlr->fd = 0; break; case 0x04: /* 10BASE-TFD */ case 0x05: /* 100BASE-TXFD */ case 0x08: /* 100BASE-FXFD */ ctlr->fd = 1; break; } break; } } } /* * Initialise descriptor rings, ethernet address. */ ctlr->nrdr = Nrde; ctlr->ntdr = Ntde; pcisetbme(ctlr->pcidev); ctlrinit(ether); /* * Linkage to the generic ethernet driver. */ ether->attach = attach; ether->transmit = transmit; ether->interrupt = interrupt;#ifndef FS ether->ifstat = ifstat; ether->arg = ether; ether->promiscuous = promiscuous;#endif debug("ns83815: dp83815reset: done\n"); return 0;}#ifndef FSvoidether83815link(void){ addethercard("83815", dp83815reset);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -