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.
> 

Pong; i dropped imx, and replugged a64pine in it's place, but here's
a lesser version untested of a diff that fixed the bug for me.

-Artturi


diff --git a/sys/arch/armv7/imx/if_fec.c b/sys/arch/armv7/imx/if_fec.c
index 899c1904144..461ab74041d 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  /* 5sec: --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 (possibly outstanding) 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,9 @@ fec_stop(struct fec_softc *sc)
 {
        struct ifnet *ifp = &sc->sc_ac.ac_if;
 
+       /* stop the controller, will be reset on _init() */
+       HCLR4(sc, ENET_ECR, ENET_ECR_ETHEREN);
+
        /*
         * Mark the interface down and cancel the watchdog timer.
         */
@@ -700,10 +704,6 @@ fec_stop(struct fec_softc *sc)
        ifq_clr_oactive(&ifp->if_snd);
 
        timeout_del(&sc->sc_tick);
-
-       /* reset the controller */
-       HSET4(sc, ENET_ECR, ENET_ECR_RESET);
-       while(HREAD4(sc, ENET_ECR) & ENET_ECR_RESET);
 }
 
 void
@@ -996,6 +996,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,7 +1004,8 @@ 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);
 
@@ -1014,6 +1016,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 +1025,8 @@ 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);
 
        return;
 }

Reply via email to