
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) {

Le 25/12/2010 08:55, Yanjun Yang a écrit :
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.
Hi,
In the changes you indicate, you don't specify which file is modified, and you provide only part of the patches. Can you produce a standard patch (see 'git format-patch' and 'git send-email'), and add to your post subject a tag: "[RFC]" if you just want comments or "[PATCH]" if you offer the code for addition to U-boot?
See http://www.denx.de/wiki/U-Boot/Patches for details about sending patches.
Amicalement,
participants (2)
-
Albert ARIBAUD
-
Yanjun Yang