diff --git a/sys/src/9/imx8/etherimx.c b/sys/src/9/imx8/etherimx.c index 2f3d8ed28..9b816920f 100644 --- a/sys/src/9/imx8/etherimx.c +++ b/sys/src/9/imx8/etherimx.c @@ -9,7 +9,10 @@ #include "../port/ethermii.h" enum { - Moduleclk = 125000000, /* 125Mhz */ + Ptpclk = 100*Mhz, + Busclk = 266*Mhz, + Txclk = 125*Mhz, + Maxtu = 1518, R_BUF_SIZE = ((Maxtu+BLOCKALIGN-1)&~BLOCKALIGN), @@ -231,6 +234,7 @@ struct Ctlr struct { Mii; + int done; Rendez; } mii[1]; @@ -245,7 +249,7 @@ static int mdiodone(void *arg) { Ctlr *ctlr = arg; - return rr(ctlr, ENET_EIR) & INT_MII; + return ctlr->mii->done || (rr(ctlr, ENET_EIR) & INT_MII) != 0; } static int mdiowait(Ctlr *ctlr) @@ -265,9 +269,13 @@ mdiow(Mii* mii, int phy, int addr, int data) Ctlr *ctlr = mii->ctlr; data &= 0xFFFF; + wr(ctlr, ENET_EIR, INT_MII); + ctlr->mii->done = 0; + wr(ctlr, ENET_MMFR, MMFR_WR | MMFR_ST | MMFR_TA | phy<ctlr; wr(ctlr, ENET_EIR, INT_MII); + ctlr->mii->done = 0; + wr(ctlr, ENET_MMFR, MMFR_RD | MMFR_ST | MMFR_TA | phy<rx); if(e & INT_TXF) wakeup(ctlr->tx); - if(e & INT_MII) wakeup(ctlr->mii); + if(e & INT_MII) { + ctlr->mii->done = 1; + wakeup(ctlr->mii); + } + wr(ctlr, ENET_EIR, e); } static void @@ -450,13 +463,11 @@ linkproc(void *arg) Ether *edev = arg; Ctlr *ctlr = edev->ctlr; MiiPhy *phy; - int link = -1; + int link = 0; while(waserror()) ; - - miiane(ctlr->mii, ~0, AnaAP|AnaP, ~0); - + miiane(ctlr->mii, ~0, ~0, ~0); for(;;){ miistatus(ctlr->mii); phy = ctlr->mii->curphy; @@ -505,7 +516,7 @@ linkproc(void *arg) edev->mbps = phy->speed; wr(ctlr, ENET_RDAR, RDAR_ACTIVE); - } + } edev->link = link; print("#l%d: link %d speed %d\n", edev->ctlrno, edev->link, edev->mbps); } @@ -532,7 +543,7 @@ attach(Ether *edev) wr(ctlr, ENET_RCR, RCR_MII_MODE | RCR_RGMII_EN | Maxtu<intmask |= INT_MII; wr(ctlr, ENET_EIMR, ctlr->intmask); @@ -586,8 +597,8 @@ attach(Ether *edev) wr(ctlr, ENET_TFWR, TFWR_STRFWD); /* interrupt coalescing: 200 pkts, 1000 µs */ - wr(ctlr, ENET_RXIC0, IC_EN | 200<intmask |= INT_TXF | INT_RXF; wr(ctlr, ENET_EIMR, ctlr->intmask); @@ -708,9 +719,9 @@ pnp(Ether *edev) setclkgate("enet1.ipp_ind_mac0_txclk", 0); setclkgate("sim_enet.mainclk", 0); - setclkrate("enet1.ipg_clk", "system_pll1_div3", 266*Mhz); - setclkrate("enet1.ipp_ind_mac0_txclk", "system_pll2_div8", Moduleclk); - setclkrate("enet1.ipg_clk_time", "system_pll2_div10", 25*Mhz); + setclkrate("enet1.ipg_clk", "system_pll1_div3", Busclk); + setclkrate("enet1.ipp_ind_mac0_txclk", "system_pll2_div8", Txclk); + setclkrate("enet1.ipg_clk_time", "system_pll2_div10", Ptpclk); setclkgate("enet1.ipp_ind_mac0_txclk", 1); setclkgate("sim_enet.mainclk", 1); diff --git a/sys/src/9/port/ethermii.c b/sys/src/9/port/ethermii.c index d75c35072..dcb3915e2 100644 --- a/sys/src/9/port/ethermii.c +++ b/sys/src/9/port/ethermii.c @@ -87,6 +87,8 @@ miireset(Mii* mii) if(mii == nil || mii->ctlr == nil || mii->curphy == nil) return -1; bmcr = mii->mir(mii, mii->curphy->phyno, Bmcr); + if(bmcr == -1) + return -1; bmcr |= BmcrR; mii->miw(mii, mii->curphy->phyno, Bmcr, bmcr); microdelay(1); @@ -104,6 +106,8 @@ miiane(Mii* mii, int a, int p, int e) phyno = mii->curphy->phyno; bmsr = mii->mir(mii, phyno, Bmsr); + if(bmsr == -1) + return -1; if(!(bmsr & BmsrAna)) return -1; @@ -113,6 +117,8 @@ miiane(Mii* mii, int a, int p, int e) anar = mii->curphy->anar; else{ anar = mii->mir(mii, phyno, Anar); + if(anar == -1) + return -1; anar &= ~(AnaAP|AnaP|AnaT4|AnaTXFD|AnaTXHD|Ana10FD|Ana10HD); if(bmsr & Bmsr10THD) anar |= Ana10HD; @@ -133,6 +139,8 @@ miiane(Mii* mii, int a, int p, int e) if(bmsr & BmsrEs){ mscr = mii->mir(mii, phyno, Mscr); + if(mscr == -1) + return -1; mscr &= ~(Mscr1000TFD|Mscr1000THD); if(e != ~0) mscr |= (Mscr1000TFD|Mscr1000THD) & e; @@ -140,6 +148,8 @@ miiane(Mii* mii, int a, int p, int e) mscr = mii->curphy->mscr; else{ r = mii->mir(mii, phyno, Esr); + if(r == -1) + return -1; if(r & Esr1000THD) mscr |= Mscr1000THD; if(r & Esr1000TFD) @@ -148,9 +158,12 @@ miiane(Mii* mii, int a, int p, int e) mii->curphy->mscr = mscr; mii->miw(mii, phyno, Mscr, mscr); } - mii->miw(mii, phyno, Anar, anar); + if(mii->miw(mii, phyno, Anar, anar) == -1) + return -1; r = mii->mir(mii, phyno, Bmcr); + if(r == -1) + return -1; if(!(r & BmcrR)){ r |= BmcrAne|BmcrRan; mii->miw(mii, phyno, Bmcr, r); @@ -175,12 +188,16 @@ miistatus(Mii* mii) * (Read status twice as the Ls bit is sticky). */ bmsr = mii->mir(mii, phyno, Bmsr); + if(bmsr == -1) + return -1; if(!(bmsr & (BmsrAnc|BmsrAna))) { // print("miistatus: auto-neg incomplete\n"); return -1; } bmsr = mii->mir(mii, phyno, Bmsr); + if(bmsr == -1) + return -1; if(!(bmsr & BmsrLs)){ // print("miistatus: link down\n"); phy->link = 0; @@ -190,6 +207,8 @@ miistatus(Mii* mii) phy->speed = phy->fd = phy->rfc = phy->tfc = 0; if(phy->mscr){ r = mii->mir(mii, phyno, Mssr); + if(r == -1) + return -1; if((phy->mscr & Mscr1000TFD) && (r & Mssr1000TFD)){ phy->speed = 1000; phy->fd = 1; @@ -199,6 +218,8 @@ miistatus(Mii* mii) } anlpar = mii->mir(mii, phyno, Anlpar); + if(anlpar == -1) + return -1; if(phy->speed == 0){ r = phy->anar & anlpar; if(r & AnaTXFD){