* [RFC] net: dm9k: fix reset routine
@ 2014-09-11 11:20 Antony Pavlov
2014-09-12 5:54 ` Sascha Hauer
0 siblings, 1 reply; 2+ messages in thread
From: Antony Pavlov @ 2014-09-11 11:20 UTC (permalink / raw)
To: barebox
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>
---
drivers/net/dm9k.c | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/drivers/net/dm9k.c b/drivers/net/dm9k.c
index 9e7b415..b407f19 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
@@ -471,8 +472,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)
--
2.1.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [RFC] net: dm9k: fix reset routine
2014-09-11 11:20 [RFC] net: dm9k: fix reset routine Antony Pavlov
@ 2014-09-12 5:54 ` Sascha Hauer
0 siblings, 0 replies; 2+ messages in thread
From: Sascha Hauer @ 2014-09-12 5:54 UTC (permalink / raw)
To: Antony Pavlov; +Cc: barebox
On Thu, Sep 11, 2014 at 03:20:01PM +0400, Antony Pavlov wrote:
> 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.
>
> # 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
> @@ -471,8 +472,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");
How about using a loop to save a few bytes? Otherwise fine with me.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2014-09-12 5:55 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-11 11:20 [RFC] net: dm9k: fix reset routine Antony Pavlov
2014-09-12 5:54 ` Sascha Hauer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox