static int miiphyinit(Mii *mii) { ulong dev; Ctlr *ctlr; Gbereg *reg; ctlr = (Ctlr*)mii->ctlr; reg = ctlr->reg; dev = reg->phy; MIIDBG("phy dev addr %lux\n", dev); /* leds link & activity */ miiregpage(mii, dev, Pagled); /* low 4 bits == 1: on - link, blink - activity, off - no link */ miiwr(mii, dev, Scr, (miird(mii, dev, Scr) & ~0xf) | 1); miiregpage(mii, dev, Pagrgmii); miiwr(mii, dev, Scr, miird(mii, dev, Scr) | Rgmiipwrup); /* must now do a software reset, says the manual */ miireset(ctlr->mii); /* enable RGMII delay on Tx and Rx for CPU port */ miiwr(mii, dev, Recr, miird(mii, dev, Recr) | Rxtiming | Rxtiming); /* must now do a software reset, says the manual */ miireset(ctlr->mii); miiregpage(mii, dev, Pagcopper); miiwr(mii, dev, Scr, (miird(mii, dev, Scr) & ~(Pwrdown|Endetect)) | Mdix); return 0; }
static int kirkwoodmii(Ether *ether) { int i; Ctlr *ctlr; MiiPhy *phy; MIIDBG("mii\n"); ctlr = ether->ctlr; if((ctlr->mii = malloc(sizeof(Mii))) == nil) return -1; ctlr->mii->ctlr = ctlr; ctlr->mii->mir = miird; ctlr->mii->miw = miiwr; if(mymii(ctlr->mii, ~0) == 0 || (phy = ctlr->mii->curphy) == nil){ print("#l%d: ether1116: init mii failure\n", ether->ctlrno); free(ctlr->mii); ctlr->mii = nil; return -1; } /* oui 005043 is marvell */ MIIDBG("oui %#X phyno %d\n", phy->oui, phy->phyno); // TODO: does this make sense? shouldn't each phy be initialised? if((ctlr->ether->ctlrno == 0 || hackflavour != Hackdual) && miistatus(ctlr->mii) < 0){ miireset(ctlr->mii); MIIDBG("miireset\n"); if(miiane(ctlr->mii, ~0, 0, ~0) < 0){ iprint("miiane failed\n"); return -1; } MIIDBG("miistatus\n"); miistatus(ctlr->mii); if(miird(ctlr->mii, phy->phyno, Bmsr) & BmsrLs){ for(i = 0; ; i++){ if(i > 600){ iprint("ether1116: autonegotiation failed\n"); break; } if(miird(ctlr->mii, phy->phyno, Bmsr) & BmsrAnc) break; delay(10); } if(miistatus(ctlr->mii) < 0) iprint("miistatus failed\n"); }else{ iprint("ether1116: no link\n"); phy->speed = 10; /* simple default */ } } ether->mbps = phy->speed; MIIDBG("#l%d: kirkwoodmii: fd %d speed %d tfc %d rfc %d\n", ctlr->port, phy->fd, phy->speed, phy->tfc, phy->rfc); MIIDBG("mii done\n"); return 0; }
static void phyinit(Dev *d) { int i; miiwr(d, Bmcr, Bmcrreset|Anenable); for(i = 0; i < Resettime/10; i++){ if((miird(d, Bmcr) & Bmcrreset) == 0) break; sleep(10); } miiwr(d, Advertise, Adcsma|Adall|Adpause|Adpauseasym); // miiwr(d, Advertise, Adcsma|Ad10f|Ad10h|Adpause|Adpauseasym); miird(d, Phyintsrc); miiwr(d, Phyintmask, Anegcomp|Linkdown); miiwr(d, Bmcr, miird(d, Bmcr)|Anenable|Anrestart); }