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...@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 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot