Module Name:    src
Committed By:   jmcneill
Date:           Thu Oct 18 12:58:19 UTC 2018

Modified Files:
        src/sys/arch/arm/sunxi: sunxi_emac.c

Log Message:
Move MAC soft reset to sunxi_emac_init_locked. Since the MAC can get stuck
in reset state with no link, ignore reset timeouts and continue with
initializing the device.

Fixes "soft reset timeout" issue at boot with no network cable plugged in.


To generate a diff of this commit:
cvs rdiff -u -r1.18 -r1.19 src/sys/arch/arm/sunxi/sunxi_emac.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/sunxi/sunxi_emac.c
diff -u src/sys/arch/arm/sunxi/sunxi_emac.c:1.18 src/sys/arch/arm/sunxi/sunxi_emac.c:1.19
--- src/sys/arch/arm/sunxi/sunxi_emac.c:1.18	Sun Oct 14 14:09:53 2018
+++ src/sys/arch/arm/sunxi/sunxi_emac.c	Thu Oct 18 12:58:19 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_emac.c,v 1.18 2018/10/14 14:09:53 martin Exp $ */
+/* $NetBSD: sunxi_emac.c,v 1.19 2018/10/18 12:58:19 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2016-2017 Jared McNeill <jmcne...@invisible.ca>
@@ -33,7 +33,7 @@
 #include "opt_net_mpsafe.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sunxi_emac.c,v 1.18 2018/10/14 14:09:53 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sunxi_emac.c,v 1.19 2018/10/18 12:58:19 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -584,6 +584,31 @@ sunxi_emac_disable_intr(struct sunxi_ema
 }
 
 static int
+sunxi_emac_reset(struct sunxi_emac_softc *sc)
+{
+	int retry;
+
+	/* Soft reset all registers and logic */
+	WR4(sc, EMAC_BASIC_CTL_1, BASIC_CTL_SOFT_RST);
+
+	/* Wait for soft reset bit to self-clear */
+	for (retry = SOFT_RST_RETRY; retry > 0; retry--) {
+		if ((RD4(sc, EMAC_BASIC_CTL_1) & BASIC_CTL_SOFT_RST) == 0)
+			break;
+		delay(10);
+	}
+	if (retry == 0) {
+		aprint_debug_dev(sc->dev, "soft reset timed out\n");
+#ifdef SUNXI_EMAC_DEBUG
+		sunxi_emac_dump_regs(sc);
+#endif
+		return ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+static int
 sunxi_emac_init_locked(struct sunxi_emac_softc *sc)
 {
 	struct ifnet *ifp = &sc->ec.ec_if;
@@ -595,6 +620,13 @@ sunxi_emac_init_locked(struct sunxi_emac
 	if ((ifp->if_flags & IFF_RUNNING) != 0)
 		return 0;
 
+	/* Soft reset EMAC core */
+	sunxi_emac_reset(sc);
+
+	/* Write transmit and receive descriptor base address registers */
+	WR4(sc, EMAC_TX_DMA_LIST, sc->tx.desc_ring_paddr);
+	WR4(sc, EMAC_RX_DMA_LIST, sc->rx.desc_ring_paddr);
+
 	sunxi_emac_setup_rxfilter(sc);
 
 	/* Configure DMA burst length and priorities */
@@ -1154,37 +1186,6 @@ sunxi_emac_phy_reset(struct sunxi_emac_s
 }
 
 static int
-sunxi_emac_reset(struct sunxi_emac_softc *sc)
-{
-	int retry;
-
-	/* Reset PHY if necessary */
-	if (sunxi_emac_phy_reset(sc) != 0) {
-		aprint_error_dev(sc->dev, "failed to reset PHY\n");
-		return ENXIO;
-	}
-
-	/* Soft reset all registers and logic */
-	WR4(sc, EMAC_BASIC_CTL_1, BASIC_CTL_SOFT_RST);
-
-	/* Wait for soft reset bit to self-clear */
-	for (retry = SOFT_RST_RETRY; retry > 0; retry--) {
-		if ((RD4(sc, EMAC_BASIC_CTL_1) & BASIC_CTL_SOFT_RST) == 0)
-			break;
-		delay(10);
-	}
-	if (retry == 0) {
-		aprint_error_dev(sc->dev, "soft reset timed out\n");
-#ifdef SUNXI_EMAC_DEBUG
-		sunxi_emac_dump_regs(sc);
-#endif
-		return ETIMEDOUT;
-	}
-
-	return 0;
-}
-
-static int
 sunxi_emac_setup_dma(struct sunxi_emac_softc *sc)
 {
 	struct mbuf *m;
@@ -1276,10 +1277,6 @@ sunxi_emac_setup_dma(struct sunxi_emac_s
 	    0, sc->rx.desc_map->dm_mapsize,
 	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
 
-	/* Write transmit and receive descriptor base address registers */
-	WR4(sc, EMAC_TX_DMA_LIST, sc->tx.desc_ring_paddr);
-	WR4(sc, EMAC_RX_DMA_LIST, sc->rx.desc_ring_paddr);
-
 	return 0;
 }
 
@@ -1400,9 +1397,11 @@ sunxi_emac_attach(device_t parent, devic
 	sunxi_emac_get_eaddr(sc, eaddr);
 	aprint_normal_dev(self, "Ethernet address %s\n", ether_sprintf(eaddr));
 
-	/* Soft reset EMAC core */
-	if (sunxi_emac_reset(sc) != 0)
+	/* Reset PHY if necessary */
+	if (sunxi_emac_phy_reset(sc) != 0) {
+		aprint_error_dev(self, "failed to reset PHY\n");
 		return;
+	}
 
 	/* Setup DMA descriptors */
 	if (sunxi_emac_setup_dma(sc) != 0) {

Reply via email to