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;
> > >  }
> > 
> > 

Reply via email to