summaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorAntony Pavlov <antonynpavlov@gmail.com>2015-05-12 00:00:51 +0300
committerSascha Hauer <s.hauer@pengutronix.de>2015-05-12 08:22:19 +0200
commit92f9b36fc0701d2c95d1f5182feeb927a3a25bfa (patch)
tree84733f4ec38869ef079f262e23d97668912ec522 /drivers/net
parentd818f02639cfd6fe4f654bcbdc9378df0e6cd53a (diff)
downloadbarebox-92f9b36fc0701d2c95d1f5182feeb927a3a25bfa.tar.gz
barebox-92f9b36fc0701d2c95d1f5182feeb927a3a25bfa.tar.xz
net: dm9k: fix reset routine
Based on Linux's commit: commit 09ee9f87d02e779e4fc3f5c29212c733d6d6e349 Author: Michael Abbott <michael.abbott@diamond.ac.uk> Date: Wed Oct 16 11:41:33 2013 +0300 dm9000: Implement full reset of DM9000 network device A Davicom application note for the DM9000 network device recommends performing software reset twice to correctly initialise the device. Without this reset some devices fail to initialise correctly on system startup. N.B. DM9000B on MIPS Creator CI20 board needs additional workaround (see the 'Make all GPIO pins outputs' and 'Power internal PHY' lines). This workaround was taken from this U-boot's commit: commit fbcb7ece0ea1e364180f1cf963e0fa0ce7f6560d Author: Remy Bohmer <linux@bohmer.net> Date: Tue Jun 3 15:26:24 2008 +0200 DM9000: Improve eth_reset() routine According to the application notes of the DM9000 v1.22 chapter 5.2 bullet 2, the reset procedure must be done twice to properly reset the DM9000 by means of software. This errata is not needed anymore for the DM9000A, but it does not bother it. This change has been tested with DM9000A, DM9000E, DM9000EP. Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/dm9k.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/drivers/net/dm9k.c b/drivers/net/dm9k.c
index 4251a91590..c3c2a8052a 100644
--- a/drivers/net/dm9k.c
+++ b/drivers/net/dm9k.c
@@ -48,6 +48,7 @@
# define NCR_FCOL (1 << 4)
# define NCR_FDX (1 << 3)
# define NCR_LBK (3 << 1)
+# define NCR_MAC_LBK (1 << 1)
# define NCR_RST (1 << 0)
#define DM9K_NSR 0x01
@@ -472,8 +473,28 @@ static void dm9k_reset(struct dm9k *priv)
struct device_d *dev = priv->miibus.parent;
dev_dbg(dev, "%s\n", __func__);
- dm9k_iow(priv, DM9K_NCR, NCR_RST);
- udelay(1000); /* delay 1ms */
+
+ /* Reset DM9000, see DM9000 Application Notes V1.22 Jun 11, 2004 page 29
+ * The essential point is that we have to do a double reset, and the
+ * instruction is to set LBK into MAC internal loopback mode.
+ */
+
+ /* Make all GPIO pins outputs */
+ dm9k_iow(priv, DM9K_GPCR, 0x0F);
+ /* Power internal PHY by writing 0 to GPIO0 pin */
+ dm9k_iow(priv, DM9K_GPR, 0);
+
+ dm9k_iow(priv, DM9K_NCR, NCR_RST | NCR_MAC_LBK);
+ udelay(100); /* Application note says at least 20 us */
+ if (dm9k_ior(priv, DM9K_NCR) & NCR_RST)
+ dev_err(dev, "dm9000 did not respond to first reset\n");
+
+ dm9k_iow(priv, DM9K_NCR, 0);
+ dm9k_iow(priv, DM9K_NCR, NCR_RST | NCR_MAC_LBK);
+ udelay(100);
+
+ if (dm9k_ior(priv, DM9K_NCR) & NCR_RST)
+ dev_err(dev, "dm9000 did not respond to second reset\n");
}
static int dm9k_eth_open(struct eth_device *edev)