public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot] LAN91C96
@ 2010-12-25  7:55 Yanjun Yang
  2010-12-25  9:42 ` Albert ARIBAUD
  0 siblings, 1 reply; 2+ messages in thread
From: Yanjun Yang @ 2010-12-25  7:55 UTC (permalink / raw)
  To: u-boot

Hello all,

I just recently made a LAN91C96 chip work for my hardware. Some changes
to the source code might be useful to whom interested. Any comments and
suggestions are welcome.

1. The device name passed to the eth_device exceed the limit of NAMESIZE

@@ -767,8 +775,8 @@
        {8, "LAN91C100FD"},
        {7, "LAN91C100"},
        {5, "LAN91C95"},
-       {4, "LAN91C94/LAN91C96"},
-       {3, "LAN91C90/LAN91C92"},
+       {4, "LAN91C94/96"},
+       {3, "LAN91C90/92"},
 };
 /* lan91c96_detect_chip
  * See:

2. The lan91c96_detect_chip routine seems wrong, following patch is
just a quick fix.

@@ -780,7 +788,7 @@
        u8 chip_id;
        int r;
        SMC_SELECT_BANK(dev, 3);
-       chip_id = SMC_inw(dev, 0xA) & LAN91C96_REV_REVID;
+       chip_id = (SMC_inw(dev, 0xA) & LAN91C96_REV_CHIPID) >> 4;
        SMC_SELECT_BANK(dev, 0);
        for (r = 0; r < sizeof(supported_chips) / sizeof(struct id_type); r++)
                if (chip_id == supported_chips[r].id)

3. Following lines of code are necessary for my hardware, it seems that the chip
can only be reset into a known state using attribute space.


@@ -216,6 +216,8 @@
 */
 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,13 @@

        /* 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);
+//     SMC_outw(dev, SMC_inw(dev, LAN91C96_CONTROL) | LAN91C96_CTR_BIT_8,
+//                       LAN91C96_CONTROL);

        /* Disable all interrupts */
        SMC_outb(dev, 0, LAN91C96_INT_MASK);
@@ -256,7 +263,7 @@
        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
@@ -791,6 +799,7 @@
 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 +808,19 @@
        }
        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) {

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2010-12-25  9:42 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-12-25  7:55 [U-Boot] LAN91C96 Yanjun Yang
2010-12-25  9:42 ` Albert ARIBAUD

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox