On Sun, Dec 10, 2017 at 07:05:11PM +0100, Mark Kettenis wrote: > > Date: Sun, 10 Dec 2017 19:03:41 +0200 > > From: Artturi Alm <artturi....@gmail.com> > > > > On Wed, Nov 29, 2017 at 11:45:51AM +0200, Artturi Alm wrote: > > > Hi, > > > > > > > > > there's more work to be done for fec, but this will allow changing > > > changing address/ifconfig up&down etc. without the freeze/kernel hangup > > > preventing ie. autoinstall i've reported to bugs@. > > > > > > i didn't see these while loops being done in nbsd if_enet, where i think > > > fec originates from. > > > > > > -Artturi > > > > > > > Ping? should I minimize the diff i sent earlier, or? > > Does this fix any real problems? If not, just drop it. >
Yes, the problem/hang/bug is very real, and reported[0], it does prevent normal things from happening. -Artturi [0] https://marc.info/?l=openbsd-bugs&m=150762924913018&w=2 > > > diff --git a/sys/arch/armv7/imx/if_fec.c b/sys/arch/armv7/imx/if_fec.c > > > index 899c1904144..5b494a6c92c 100644 > > > --- a/sys/arch/armv7/imx/if_fec.c > > > +++ b/sys/arch/armv7/imx/if_fec.c > > > @@ -181,6 +181,8 @@ > > > #define ENET_TXD_INT (1 << 30) > > > #endif > > > > > > +#define ENET_MII_TIMEOUT 100000 /* --loop_cnt { delay(5); } */ > > > + > > > /* > > > * Bus dma allocation structure used by > > > * fec_dma_malloc and fec_dma_free. > > > @@ -339,7 +341,6 @@ fec_attach(struct device *parent, struct device > > > *self, void *aux) > > > > > > /* reset the controller */ > > > HSET4(sc, ENET_ECR, ENET_ECR_RESET); > > > - while(HREAD4(sc, ENET_ECR) & ENET_ECR_RESET); > > > > > > HWRITE4(sc, ENET_EIMR, 0); > > > HWRITE4(sc, ENET_EIR, 0xffffffff); > > > @@ -604,7 +605,6 @@ fec_init(struct fec_softc *sc) > > > > > > /* reset the controller */ > > > HSET4(sc, ENET_ECR, ENET_ECR_RESET); > > > - while(HREAD4(sc, ENET_ECR) & ENET_ECR_RESET); > > > > > > /* set hw address */ > > > HWRITE4(sc, ENET_PALR, > > > @@ -616,7 +616,8 @@ fec_init(struct fec_softc *sc) > > > (sc->sc_ac.ac_enaddr[4] << 24) | > > > (sc->sc_ac.ac_enaddr[5] << 16)); > > > > > > - /* clear outstanding interrupts */ > > > + /* mask and clear all interrupts */ > > > + HWRITE4(sc, ENET_EIMR, 0); > > > HWRITE4(sc, ENET_EIR, 0xffffffff); > > > > > > /* set max receive buffer size, 3-0 bits always zero for alignment */ > > > @@ -692,6 +693,8 @@ fec_stop(struct fec_softc *sc) > > > { > > > struct ifnet *ifp = &sc->sc_ac.ac_if; > > > > > > + HCLR4(sc, ENET_ECR, ENET_ECR_ETHEREN); > > > + > > > /* > > > * Mark the interface down and cancel the watchdog timer. > > > */ > > > @@ -701,9 +704,7 @@ fec_stop(struct fec_softc *sc) > > > > > > timeout_del(&sc->sc_tick); > > > > > > - /* reset the controller */ > > > - HSET4(sc, ENET_ECR, ENET_ECR_RESET); > > > - while(HREAD4(sc, ENET_ECR) & ENET_ECR_RESET); > > > + mii_down(&sc->sc_mii); > > > } > > > > > > void > > > @@ -996,6 +997,7 @@ fec_miibus_readreg(struct device *dev, int phy, int > > > reg) > > > { > > > int r = 0; > > > struct fec_softc *sc = (struct fec_softc *)dev; > > > + u_int timo = ENET_MII_TIMEOUT; > > > > > > HSET4(sc, ENET_EIR, ENET_EIR_MII); > > > > > > @@ -1003,10 +1005,16 @@ fec_miibus_readreg(struct device *dev, int phy, > > > int reg) > > > ENET_MMFR_ST | ENET_MMFR_OP_RD | ENET_MMFR_TA | > > > phy << ENET_MMFR_PA_SHIFT | reg << ENET_MMFR_RA_SHIFT); > > > > > > - while(!(HREAD4(sc, ENET_EIR) & ENET_EIR_MII)); > > > + while (!(HREAD4(sc, ENET_EIR) & ENET_EIR_MII) && --timo) > > > + delay(5); > > > > > > r = bus_space_read_4(sc->sc_iot, sc->sc_ioh, ENET_MMFR); > > > > > > +#ifdef DIAGNOSTIC > > > + if (!timo) > > > + printf("%s: %s timeout\n", sc->sc_dev.dv_xname, __func__); > > > +#endif > > > + > > > return (r & 0xffff); > > > } > > > > > > @@ -1014,6 +1022,7 @@ void > > > fec_miibus_writereg(struct device *dev, int phy, int reg, int val) > > > { > > > struct fec_softc *sc = (struct fec_softc *)dev; > > > + u_int timo = ENET_MII_TIMEOUT; > > > > > > HSET4(sc, ENET_EIR, ENET_EIR_MII); > > > > > > @@ -1022,7 +1031,12 @@ fec_miibus_writereg(struct device *dev, int phy, > > > int reg, int val) > > > phy << ENET_MMFR_PA_SHIFT | reg << ENET_MMFR_RA_SHIFT | > > > (val & 0xffff)); > > > > > > - while(!(HREAD4(sc, ENET_EIR) & ENET_EIR_MII)); > > > + while (!(HREAD4(sc, ENET_EIR) & ENET_EIR_MII) && --timo) > > > + delay(5); > > > +#ifdef DIAGNOSTIC > > > + if (!timo) > > > + printf("%s: %s timeout\n", sc->sc_dev.dv_xname, __func__); > > > +#endif > > > > > > return; > > > } > > > >