This is the mail archive of the
ecos-patches@sources.redhat.com
mailing list for the eCos project.
[patch] fix odd byte problem on smsc91c111 revision 0 chips
- From: jeroen dobbelaere <jeroen dot dobbelaere at acunia dot com>
- To: ecos-patches at sources dot redhat dot com
- Date: Wed, 18 Jun 2003 16:30:15 +0200
- Subject: [patch] fix odd byte problem on smsc91c111 revision 0 chips
- Organization: ACUNIA
- Following patch fixes a problem when using revision 0 versions of the
smsc 91c111 chip.
- It will also identify and display the chip (version, revision).
(patch against eCos v2.0)
Greetings
--
Jeroen Dobbelaere
Embedded Software Engineer
ACUNIA Embedded Solutions
http://www.acunia.com/aes
diff -ru ecos-tmp/packages/devs/eth/smsc/lan91cxx/current/src/if_lan91cxx.c ecos/packages/devs/eth/smsc/lan91cxx/current/src/if_lan91cxx.c
--- ecos-tmp/packages/devs/eth/smsc/lan91cxx/current/src/if_lan91cxx.c Wed Jun 18 15:51:17 2003
+++ ecos/packages/devs/eth/smsc/lan91cxx/current/src/if_lan91cxx.c Wed Jun 18 16:04:33 2003
@@ -127,6 +127,20 @@
#include "smsc_lan91cxx.h"
+static const char* chip_ids[ 15 ] =
+{
+ NULL, NULL, NULL,
+ /* 3 */ "SMC91C90/91C92",
+ /* 4 */ "SMC91C94",
+ /* 5 */ "SMC91C95",
+ /* 6 */ "SMC91C96",
+ /* 7 */ "SMC91C100",
+ /* 8 */ "SMC91C100FD",
+ /* 9 */ "SMC91C11xFD",
+ NULL, NULL,
+ NULL, NULL, NULL
+};
+
#ifdef LAN91CXX_IS_LAN91C111
static void lan91cxx_write_phy(struct eth_drv_sc *sc, cyg_uint8 phyaddr,
cyg_uint8 phyreg, cyg_uint16 value);
@@ -266,6 +280,19 @@
CYG_ASSERT( 0x3300 == (0xff00 & val), "No 91Cxx signature" );
val = get_reg(sc, LAN91CXX_REVISION);
+ cpd->chip_id = val;
+ {
+ int chip_type = (val>>4) & 0xF;
+
+ diag_printf("LAN91CXX - type: %01x (%s), rev: %01x\n",
+ chip_type,
+ (chip_ids[chip_type] != NULL ? chip_ids[chip_type] : "unknown"),
+ val & 0xf);
+ if(chip_type == 9) { // 91c111
+ unsigned short config_val = get_reg(sc, LAN91CXX_CONFIG);
+ put_reg(sc, LAN91CXX_CONFIG, config_val | 0x1000); // enable NO_WAIT
+ }
+ }
#if DEBUG & 9
diag_printf("LAN91CXX - type: %01x, rev: %01x\n",
@@ -979,8 +1006,16 @@
INCR_STAT( rx_good );
// Then it's OK
- if (stat & LAN91CXX_RX_STATUS_ODDFRM)
- len++;
+
+ if (
+ (stat & LAN91CXX_RX_STATUS_ODDFRM)
+#ifdef LAN91CXX_IS_LAN91C111
+ /* fix odd byte problem in rev0 of smc91111 */
+ || (cpd->chip_id == 0x90)
+#endif
+ ) {
+ len++;
+ }
#if DEBUG & 1
diag_printf("RxEvent good rx - stat: 0x%04x, len: 0x%04x\n", stat, len);
@@ -1015,7 +1050,7 @@
static void
lan91cxx_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
{
-#if (4 & DEBUG) || defined(CYGPKG_INFRA_DEBUG) || defined(KEEP_STATISTICS)
+#if (4 & DEBUG) || defined(CYGPKG_INFRA_DEBUG) || defined(KEEP_STATISTICS) || defined(LAN91CXX_IS_LAN91C111)
struct lan91cxx_priv_data *cpd =
(struct lan91cxx_priv_data *)sc->driver_private;
#endif
@@ -1080,7 +1115,12 @@
"Controlbyte is not for Rx");
CYG_ASSERT( (1 == mlen) == (0 != (val & LAN91CXX_CONTROLBYTE_ODD)),
"Controlbyte does not match");
- if (data && (1 == mlen) && (val & LAN91CXX_CONTROLBYTE_ODD)) {
+ if (data && (1 == mlen) && ((val & LAN91CXX_CONTROLBYTE_ODD)
+#ifdef LAN91CXX_IS_LAN91C111
+ /* fix odd byte problem in rev0 of smc91111 */
+ || (cpd->chip_id == 0x90)
+#endif
+ )) {
cval = val & 0x00ff; // last byte contains data
*cp = cval;
}
Only in ecos/packages/devs/eth/smsc/lan91cxx/current/src: if_lan91cxx.c~
diff -ru ecos-tmp/packages/devs/eth/smsc/lan91cxx/current/src/smsc_lan91cxx.h ecos/packages/devs/eth/smsc/lan91cxx/current/src/smsc_lan91cxx.h
--- ecos-tmp/packages/devs/eth/smsc/lan91cxx/current/src/smsc_lan91cxx.h Wed Jun 18 15:52:09 2003
+++ ecos/packages/devs/eth/smsc/lan91cxx/current/src/smsc_lan91cxx.h Wed Jun 18 15:53:22 2003
@@ -319,6 +319,7 @@
int rxpacket;
int within_send;
int addrsh; // Address bits to shift
+ unsigned char chip_id;
#ifdef KEEP_STATISTICS
struct smsc_lan91cxx_stats stats;
#endif
Only in ecos/packages/devs/eth/smsc/lan91cxx/current/src: smsc_lan91cxx.h~