On Wed, Oct 11, 2017 at 04:56:34AM +0300, Artturi Alm wrote:
> Hi,
> 
> i shot down my guess at imxuart by hexediting output like w/diff below,
> and tested latest snapshot too, same thing.
> 
> diff --git a/sys/arch/armv7/imx/imxuart.c b/sys/arch/armv7/imx/imxuart.c
> index ac4554e2fd5..6743203d212 100644
> --- a/sys/arch/armv7/imx/imxuart.c
> +++ b/sys/arch/armv7/imx/imxuart.c
> @@ -183,7 +183,7 @@ imxuart_attach(struct device *parent, struct device 
> *self, void *aux)
>                               break;
>               cn_tab->cn_dev = makedev(maj, sc->sc_dev.dv_unit);
>  
> -             printf(": console");
> +             printf("\n%s: console", sc->sc_dev.dv_xname);
>       }
>  
>       timeout_set(&sc->sc_diag_tmo, imxuart_diag, sc);
> 
> 
> so when that was out of the way i saw "ifconfig ... delete ...",
> and i was able to trigger the bug from GENERIC w/just:
> 
> # ifconfig fec0 delete down
> # ifconfig fec0
> fec0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> mtu 1500
>         lladdr 00:1f:7b:b4:04:49
>         index 1 priority 0 llprio 3
>         groups: egress
> <FROZEN>
> 
> no diff, as i hope this is easy fix to someone more experienced,
> with some free time:)
> -Artturi

ping?

i've ran w/the diff below since initial report, but it doesn't fix fec,
merely avoids the deadlock, so fec0 won't work after "ifconfig fec0 down",
without reboot.

-Artturi


diff --git a/sys/arch/armv7/imx/if_fec.c b/sys/arch/armv7/imx/if_fec.c
index 899c1904144..b7008a69522 100644
--- a/sys/arch/armv7/imx/if_fec.c
+++ b/sys/arch/armv7/imx/if_fec.c
@@ -181,6 +181,9 @@
 #define ENET_TXD_INT           (1 << 30)
 #endif
 
+#define        ENET_MII_TIMEOUT        100000  /* --loop_cnt { delay(5); } */
+#define        ENET_RST_TIMEOUT        100000
+
 /*
  * Bus dma allocation structure used by
  * fec_dma_malloc and fec_dma_free.
@@ -286,6 +289,7 @@ fec_attach(struct device *parent, struct device *self, void 
*aux)
        int tsize, rsize, tbsize, rbsize, s;
        uint32_t phy_reset_gpio[3];
        uint32_t phy_reset_duration;
+       u_int timo = ENET_RST_TIMEOUT;
 
        if (faa->fa_nreg < 1)
                return;
@@ -339,7 +343,8 @@ 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);
+       while ((HREAD4(sc, ENET_ECR) & ENET_ECR_RESET) && --timo)
+               delay(5);
 
        HWRITE4(sc, ENET_EIMR, 0);
        HWRITE4(sc, ENET_EIR, 0xffffffff);
@@ -600,11 +605,13 @@ void
 fec_init(struct fec_softc *sc)
 {
        struct ifnet *ifp = &sc->sc_ac.ac_if;
+       u_int timo = ENET_RST_TIMEOUT;
        int speed = 0;
 
        /* reset the controller */
        HSET4(sc, ENET_ECR, ENET_ECR_RESET);
-       while(HREAD4(sc, ENET_ECR) & ENET_ECR_RESET);
+       while ((HREAD4(sc, ENET_ECR) & ENET_ECR_RESET) && --timo)
+               delay(5);
 
        /* set hw address */
        HWRITE4(sc, ENET_PALR,
@@ -691,6 +698,7 @@ void
 fec_stop(struct fec_softc *sc)
 {
        struct ifnet *ifp = &sc->sc_ac.ac_if;
+       u_int timo = ENET_RST_TIMEOUT;
 
        /*
         * Mark the interface down and cancel the watchdog timer.
@@ -701,9 +709,12 @@ fec_stop(struct fec_softc *sc)
 
        timeout_del(&sc->sc_tick);
 
+       mii_down(&sc->sc_mii);
+
        /* reset the controller */
        HSET4(sc, ENET_ECR, ENET_ECR_RESET);
-       while(HREAD4(sc, ENET_ECR) & ENET_ECR_RESET);
+       while ((HREAD4(sc, ENET_ECR) & ENET_ECR_RESET) && --timo)
+               delay(5);
 }
 
 void
@@ -996,6 +1007,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 +1015,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 +1032,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 +1041,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