[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