static int wpiinit(Ether *edev) { Ctlr *ctlr; char *err; uchar b[64]; int i, j; Powergrp *g; ctlr = edev->ctlr; if((err = poweron(ctlr)) != nil) goto Err; if((csr32r(ctlr, EepromGp) & 0x6) == 0){ err = "bad rom signature"; goto Err; } /* Clear HW ownership of EEPROM. */ csr32w(ctlr, EepromGp, csr32r(ctlr, EepromGp) & ~0x180); if((err = eepromread(ctlr, b, 1, 0x45)) != nil) goto Err; ctlr->eeprom.cap = b[0]; if((err = eepromread(ctlr, b, 2, 0x35)) != nil) goto Err; ctlr->eeprom.rev = get16(b); if((err = eepromread(ctlr, b, 1, 0x4a)) != nil) goto Err; ctlr->eeprom.type = b[0]; if((err = eepromread(ctlr, b, 4, 0x60)) != nil) goto Err; strncpy(ctlr->eeprom.regdom, (char*)b, 4); ctlr->eeprom.regdom[4] = '\0'; print("wpi: %X %X %X %s\n", ctlr->eeprom.cap, ctlr->eeprom.rev, ctlr->eeprom.type, ctlr->eeprom.regdom); if((err = eepromread(ctlr, b, 6, 0x15)) != nil) goto Err; memmove(edev->ea, b, Eaddrlen); for(i = 0; i < nelem(bands); i++){ if((err = eepromread(ctlr, b, 2*bands[i].nchan, bands[i].addr)) != nil) goto Err; for(j = 0; j < bands[i].nchan; j++){ if(!(b[j*2] & 1)) continue; ctlr->maxpwr[bands[i].chan[j]] = b[j*2+1]; } } for(i = 0; i < nelem(ctlr->eeprom.pwrgrps); i++){ if((err = eepromread(ctlr, b, 64, 0x100 + i*32)) != nil) goto Err; g = &ctlr->eeprom.pwrgrps[i]; g->maxpwr = b[60]; g->chan = b[61]; g->temp = get16(b+62); for(j = 0; j < 5; j++){ g->samples[j].index = b[j*4]; g->samples[j].power = b[j*4+1]; } } poweroff(ctlr); return 0; Err: print("wpiinit: %s\n", err); poweroff(ctlr); return -1; }
/* * No doc. we are doing what Linux does as closely * as we can. */ static int ctlrinit(Ether *ether) { Dev *d; int i; int bmcr; int gpio; int ee17; int rc; d = ether->dev; switch(ether->cid){ case A8817x: case A88179: fprint(2, "%s: card known but not implemented\n", argv0); /* fall through */ default: return -1; case A88178: deprint(2, "%s: setting up A88178\n", argv0); gpio = getgpio(d); if(gpio < 0) return -1; deprint(2, "%s: gpio sts %#x\n", argv0, gpio); asixset(d, Cwena, 0); ee17 = eepromread(d, 0x0017); asixset(d, Cwdis, 0); asixset(d, Cwgpio, Gpiorse|Gpiogpo1|Gpiogpo1en); if((ee17 >> 8) != 1){ asixset(d, Cwgpio, 0x003c); asixset(d, Cwgpio, 0x001c); asixset(d, Cwgpio, 0x003c); }else{ asixset(d, Cwgpio, Gpiogpo1en); asixset(d, Cwgpio, Gpiogpo1|Gpiogpo1en); } asixset(d, Creset, Rclear); sleep(150); asixset(d, Creset, Rippd|Rprl); sleep(150); asixset(d, Cwrxctl, 0); if(getmac(d, ether->addr) < 0) return -1; ether->phy = getphy(d); if(ee17 < 0 || (ee17 & 0x7) == 0){ miiwrite(d, ether->phy, Miimctl, Mtxrxdly); sleep(60); } miiwrite(d, ether->phy, Miibmcr, Bmcrreset|Bmcranena); miiwrite(d, ether->phy, Miiad, Adall|Adcsma|Adpause); miiwrite(d, ether->phy, Miic1000, Ad1000f); bmcr = miiread(d, ether->phy, Miibmcr); if((bmcr & Bmcranena) != 0){ bmcr |= Bmcrar; miiwrite(d, ether->phy, Miibmcr, bmcr); } asixset(d, Cwmedium, Mall178); asixset(d, Cwrxctl, Rxctlso|Rxctlab); break; case A88772: deprint(2, "%s: setting up A88772\n", argv0); if(asixset(d, Cwgpio, Gpiorse|Gpiogpo2|Gpiogpo2en) < 0) return -1; ether->phy = getphy(d); dprint(2, "%s: phy %#x\n", argv0, ether->phy); if((ether->phy & Pmask) == Pembed){ /* embedded 10/100 ethernet */ rc = asixset(d, Cwphy, 1); }else rc = asixset(d, Cwphy, 0); if(rc < 0) return -1; if(asixset(d, Creset, Rippd|Rprl) < 0) return -1; sleep(150); if((ether->phy & Pmask) == Pembed) rc = asixset(d, Creset, Riprl); else rc = asixset(d, Creset, Rprte); if(rc < 0) return -1; sleep(150); rc = getrxctl(d); deprint(2, "%s: rxctl is %#x\n", argv0, rc); if(asixset(d, Cwrxctl, 0) < 0) return -1; if(getmac(d, ether->addr) < 0) return -1; if(asixset(d, Creset, Rprl) < 0) return -1; sleep(150); if(asixset(d, Creset, Riprl|Rprl) < 0) return -1; sleep(150); miiwrite(d, ether->phy, Miibmcr, Bmcrreset); miiwrite(d, ether->phy, Miiad, Adall|Adcsma); bmcr = miiread(d, ether->phy, Miibmcr); if((bmcr & Bmcranena) != 0){ bmcr |= Bmcrar; miiwrite(d, ether->phy, Miibmcr, bmcr); } if(asixset(d, Cwmedium, Mall772) < 0) return -1; if(asixset(d, Cwipg, Ipgdflt) < 0) return -1; if(asixset(d, Cwrxctl, Rxctlso|Rxctlab) < 0) return -1; deprint(2, "%s: final rxctl: %#x\n", argv0, getrxctl(d)); break; }