On Tue, Oct 17, 2017 at 10:46:22PM +0300, Artturi Alm wrote:
> 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
>
pong? am i the only fec user bitten by this?
-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;
> }