[U-Boot] [RFC] Make sure the chip reset and init right
Yanjun Yang
yangyj.ee at gmail.com
Sun Dec 26 03:43:00 CET 2010
It seems that the chip can only be reset into a known
state by using attribute space. The smc_reset and
smc_enable function also need more lines to make the
chip work.
Signed-off-by: YanJun Yang <yangyj.ee at gmail.com>
---
drivers/net/lan91c96.c | 26 ++++++++++++++++++++++----
1 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/drivers/net/lan91c96.c b/drivers/net/lan91c96.c
index 2550aa2..0b3321f 100644
--- a/drivers/net/lan91c96.c
+++ b/drivers/net/lan91c96.c
@@ -216,6 +216,8 @@ static int poll4int (struct eth_device *dev, byte
mask, int timeout)
*/
static void smc_reset(struct eth_device *dev)
{
+ unsigned int tmp;
+
PRINTK2("%s:smc_reset\n", dev->name);
/* This resets the registers mostly to defaults, but doesn't
@@ -231,8 +233,11 @@ static void smc_reset(struct eth_device *dev)
/* set the control register */
SMC_SELECT_BANK(dev, 1);
- SMC_outw(dev, SMC_inw(dev, LAN91C96_CONTROL) | LAN91C96_CTR_BIT_8,
- LAN91C96_CONTROL);
+ tmp = SMC_inw(dev, LAN91C96_CONFIG);
+ tmp |= LAN91C96_CR_SET_SQLCH | LAN91C96_CR_NO_WAIT | LAN91C96_CR_16BIT;
+ tmp &= ~(LAN91C96_CR_DIS_LINK | LAN91C96_CR_AUI_SELECT);
+ SMC_outw(dev, tmp, LAN91C96_CONFIG);
+ SMC_outw(dev, LAN91C96_CTR_TE_ENABLE | LAN91C96_CTR_BIT_8,
LAN91C96_CONTROL);
/* Disable all interrupts */
SMC_outb(dev, 0, LAN91C96_INT_MASK);
@@ -256,7 +261,7 @@ static void smc_enable(struct eth_device *dev)
SMC_outw(dev, LAN91C96_MCR_TRANSMIT_PAGES, LAN91C96_MCR);
/* Initialize the Transmit Control Register */
- SMC_outw(dev, LAN91C96_TCR_TXENA, LAN91C96_TCR);
+ SMC_outw(dev, LAN91C96_TCR_TXENA | LAN91C96_TCR_PAD_EN |
LAN91C96_TCR_FDSE, LAN91C96_TCR);
/* Initialize the Receive Control Register
* FIXME:
* The promiscuous bit set because I could not receive ARP reply
@@ -264,6 +269,7 @@ static void smc_enable(struct eth_device *dev)
* when I set the promiscuous bit
*/
SMC_outw(dev, LAN91C96_RCR_RXEN | LAN91C96_RCR_PRMS, LAN91C96_RCR);
+ udelay( 750 );
}
/*
@@ -791,6 +797,7 @@ static int lan91c96_detect_chip(struct eth_device *dev)
int lan91c96_initialize(u8 dev_num, int base_addr)
{
struct eth_device *dev;
+ volatile unsigned *attaddr = (unsigned *)CONFIG_LAN91C96_ATTR;
int r = 0;
dev = malloc(sizeof(*dev));
@@ -799,8 +806,19 @@ int lan91c96_initialize(u8 dev_num, int base_addr)
}
memset(dev, 0, sizeof(*dev));
- dev->iobase = base_addr;
+ /* first reset, then enable the device. Sequence is critical */
+ attaddr[LAN91C96_ECOR] |= LAN91C96_ECOR_SRESET;
+ udelay( 750 );
+ attaddr[LAN91C96_ECOR] &= ~LAN91C96_ECOR_SRESET;
+ udelay( 750 );
+ attaddr[LAN91C96_ECOR] |= LAN91C96_ECOR_ENABLE;
+ udelay( 750 );
+ /* force 16-bit mode */
+ attaddr[LAN91C96_ECSR] &= ~LAN91C96_ECSR_IOIS8;
+ udelay( 750 );
+
+ dev->iobase = base_addr;
/* Try to detect chip. Will fail if not present. */
r = lan91c96_detect_chip(dev);
if (!r) {
--
1.5.6.5
More information about the U-Boot
mailing list