This is the mail archive of the ecos-patches@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

LAN91CXX 32bit mode fixed


Hi,

after some days of debugging, i fixed the 32bit mode of the SMSC 91Cxx driver. The original driver does anything right for the complete packet size in recv, but the multiple buffers the ethernet driver requested, where not filled correctly. I also added the config item for the 32bit mode.

Here's the patch:

Index: ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/eth/smsc/lan91cxx/current/ChangeLog,v
retrieving revision 1.19
diff -b -B -U3 -w -r1.19 ChangeLog
--- ChangeLog 24 May 2004 12:14:22 -0000 1.19
+++ ChangeLog 27 Jun 2005 13:42:07 -0000
@@ -1,3 +1,9 @@
+2005-06-27 Stefan Sommerfeld <sommerfeld@mikrom.com>
+
+ * src/if_lan91cxx.c: Changed some debug messages to output right hex syntax (0x....)
+ * src/if_lan91cxx.c: 32bit mode can now be selected is correctly working. The old
+ implementation truncated some data.
+
2004-05-22 Andrew Dyer <adyer@righthandtech.com>


* src/if_lan91cxx.c: Fail initialization if no device found.
Index: cdl/smsc_lan91cxx_eth_drivers.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/eth/smsc/lan91cxx/current/cdl/smsc_lan91cxx_eth_drivers.cdl,v
retrieving revision 1.6
diff -b -B -U3 -w -r1.6 smsc_lan91cxx_eth_drivers.cdl
--- cdl/smsc_lan91cxx_eth_drivers.cdl 6 Jan 2004 21:05:14 -0000 1.6
+++ cdl/smsc_lan91cxx_eth_drivers.cdl 27 Jun 2005 10:11:34 -0000
@@ -67,6 +67,15 @@
puts $::cdl_header "#include CYGDAT_DEVS_ETH_SMSC_LAN91CXX_CFG";
}


+ cdl_option CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT {
+ display "use 32 bit data access"
+ default_value 0
+ description "
+ The device driver uses 32 bit data access if
+ this option is enabled, otherwise 16 bit data access is
+ used."
+ }
+
cdl_option CYGSEM_DEVS_ETH_SMSC_LAN91CXX_WRITE_EEPROM {
display "SIOCSIFHWADDR records ESA (MAC address) in EEPROM"
default_value 0
Index: src/if_lan91cxx.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/eth/smsc/lan91cxx/current/src/if_lan91cxx.c,v
retrieving revision 1.17
diff -b -B -U3 -w -r1.17 if_lan91cxx.c
--- src/if_lan91cxx.c 24 May 2004 12:14:23 -0000 1.17
+++ src/if_lan91cxx.c 27 Jun 2005 10:56:19 -0000
@@ -747,7 +747,7 @@
tcr = get_reg(sc, LAN91CXX_TCR);
if ( 0 == (LAN91CXX_TCR_TXENA & tcr) ) {
#if DEBUG & 1
- db_printf("%s: ENGINE RESTART: tcr %x\n", __FUNCTION__, tcr );
+ db_printf("%s: ENGINE RESTART: tcr 0x%04x\n", __FUNCTION__, tcr );
#endif
// Complete any outstanding activity:
if ( cpd->txbusy ) {
@@ -790,7 +790,7 @@
tcr = get_reg(sc, LAN91CXX_TCR);
if ( 0 == (LAN91CXX_TCR_TXENA & tcr) ) {
#if DEBUG & 1
- db_printf("%s: ENGINE RESTART: tcr %x\n", __FUNCTION__, tcr );
+ db_printf("%s: ENGINE RESTART: tcr 0x%04x\n", __FUNCTION__, tcr );
#endif
tcr |= LAN91CXX_TCR_TXENA;
put_reg(sc, LAN91CXX_TCR, tcr);
@@ -844,7 +844,7 @@
} while (0);


#if DEBUG & 4
- db_printf("#####Tx packet allocated %x (previous %x)\n",
+ db_printf("#####Tx packet allocated 0x%04x (previous 0x%04x)\n",
packet, cpd->txpacket);
#endif
cpd->txpacket = packet;
@@ -962,7 +962,7 @@
tcr = get_reg(sc, LAN91CXX_TCR);
if ( 0 == (LAN91CXX_TCR_TXENA & tcr) ) {
#if DEBUG & 1
- db_printf("%s: ENGINE RESTART: tcr %x ints %04x\n", __FUNCTION__, tcr, ints);
+ db_printf("%s: ENGINE RESTART: tcr 0x%04x ints %04x\n", __FUNCTION__, tcr, ints);
#endif
tcr |= LAN91CXX_TCR_TXENA;
put_reg(sc, LAN91CXX_TCR, tcr);
@@ -983,7 +983,7 @@
lan91cxx_txfifo_good++;
#endif
#if DEBUG & 4
- db_printf("#####Tx packet freed %x (expected %x)\n", packet, cpd->txpacket );
+ db_printf("#####Tx packet freed 0x%04x (expected 0x%04x)\n", packet, cpd->txpacket );
#endif
// and then free the packet
put_reg(sc, LAN91CXX_PNR, cpd->txpacket);
@@ -1022,7 +1022,7 @@
struct lan91cxx_priv_data *cpd =
(struct lan91cxx_priv_data *)sc->driver_private;
unsigned short stat, len;
-#ifdef LAN91CXX_32BIT_RX
+#ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT
cyg_uint32 val;
#endif


@@ -1043,7 +1043,7 @@
    INCR_STAT( rx_count );

#if DEBUG & 4
- db_printf("#####Rx packet allocated %x (previous %x)\n",
+ db_printf("#####Rx packet allocated 0x%04x (previous 0x%04x)\n",
0xff & (stat >> 8), cpd->rxpacket );
#endif
// There is an Rx Packet ready
@@ -1052,7 +1052,7 @@
// Read status and (word) length
put_reg(sc, LAN91CXX_POINTER, (LAN91CXX_POINTER_RCV | LAN91CXX_POINTER_READ |
LAN91CXX_POINTER_AUTO_INCR | 0x0000));
-#ifdef LAN91CXX_32BIT_RX
+#ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT
val = get_data(sc);
val = CYG_LE32_TO_CPU(val);
stat = val & 0xffff;
@@ -1120,8 +1120,13 @@
#endif
int i;
short mlen=0, plen;
- rxd_t *data=NULL, val;
- unsigned char *cp, cval;
+ cyg_uint16 *data=NULL;
+ unsigned char *cp, cval, odd_even = 0;
+#ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT
+ cyg_uint32 val;
+#else
+ cyg_uint16 val;
+#endif


DEBUG_FUNCTION();

@@ -1132,7 +1137,7 @@
    val = get_data(sc);

    // packet length (minus header/footer)
-#ifdef LAN91CXX_32BIT_RX
+#ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT
    val = CYG_LE32_TO_CPU(val);
    plen = (val >> 16) - 6;
#else
@@ -1145,31 +1150,55 @@
 plen++;

    for (i = 0;  i < sg_len;  i++) {
-        data = (rxd_t *)sg_list[i].buf;
+        data = (cyg_uint16 *)sg_list[i].buf;
        mlen = sg_list[i].len;

CYG_ASSERT(0 == (mlen & (sizeof(*data) - 1)) || (i == (sg_len-1)), "odd length");

#if DEBUG & 1
- db_printf("%s : mlen %x, plen %x\n", __FUNCTION__, mlen, plen);
+ db_printf("%s : mlen 0x%04x, plen 0x%04x\n", __FUNCTION__, mlen, plen);
#endif
if (data) {
while (mlen >= sizeof(*data)) {
- *data++ = get_data(sc);
+#ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT
+ if (!(odd_even)) { // because of the 32bit to 16bit conversion, read only every 2nd word
+#endif
+ val = get_data(sc);
+#ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT
+ odd_even = 1;
+ }
+ else {
+ val >>= 16;
+ odd_even = 0;
+ }
+#endif
+ *data++ = val;
mlen -= sizeof(*data);
plen -= sizeof(*data);
}
}
else { // must actively discard ie. read it from the chip anyway.
while (mlen >= sizeof(*data)) {
- (void)get_data(sc);
+#ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT
+ if (!(odd_even)) {
+#endif
+ val = get_data(sc);
+#ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT
+ odd_even = 1;
+ }
+ else {
+ val >>= 16;
+ odd_even = 0;
+ }
+#endif
mlen -= sizeof(*data);
plen -= sizeof(*data);
}
}
}
+ if (!(odd_even)) { // read the control word only if we not already have it because of a 32bit access
val = get_data(sc); // Read control word (and potential data) unconditionally
-#ifdef LAN91CXX_32BIT_RX
+#ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT
val = CYG_LE32_TO_CPU(val);
if (plen & 2) {
if (data)
@@ -1177,10 +1206,11 @@
cp = (unsigned char *)data + 2;
val >>= 16;
mlen -= 2;
- } else
+ }
#else
val = CYG_LE16_TO_CPU(val);
#endif
+ }
cp = (unsigned char *)data;


CYG_ASSERT(val & LAN91CXX_CONTROLBYTE_RX,
@@ -1195,10 +1225,10 @@
val = get_reg(sc, LAN91CXX_FIFO_PORTS);
#if DEBUG & 4
if ( 0x8000 & val ) // Then the Rx FIFO is empty
- db_printf("#####Rx packet NOT freed, stat is %x (expected %x)\n",
+ db_printf("#####Rx packet NOT freed, stat is 0x%04x (expected 0x%04x)\n",
val, cpd->rxpacket);
else
- db_printf("#####Rx packet freed %x (expected %x)\n",
+ db_printf("#####Rx packet freed 0x%04x (expected 0x%04x)\n",
0xff & (val >> 8), cpd->rxpacket );
#endif
CYG_ASSERT( (0xff & (val >> 8)) == cpd->rxpacket, "Unexpected rx packet" );
Index: src/smsc_lan91cxx.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/eth/smsc/lan91cxx/current/src/smsc_lan91cxx.h,v
retrieving revision 1.11
diff -b -B -U3 -w -r1.11 smsc_lan91cxx.h
--- src/smsc_lan91cxx.h 19 Dec 2003 11:34:16 -0000 1.11
+++ src/smsc_lan91cxx.h 27 Jun 2005 10:13:39 -0000
@@ -339,7 +339,7 @@


#include CYGDAT_DEVS_ETH_SMSC_LAN91CXX_INL

-#ifdef LAN91CXX_32BIT_RX
+#ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT
typedef cyg_uint32 rxd_t;
#else
typedef cyg_uint16 rxd_t;
@@ -406,7 +406,7 @@
    struct lan91cxx_priv_data *cpd =
        (struct lan91cxx_priv_data *)sc->driver_private;

-#ifdef LAN91CXX_32BIT_RX
+#ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT
HAL_READ_UINT32(cpd->base+((LAN91CXX_DATA_HIGH & 0x7) << cpd->addrsh), val);
#else
HAL_READ_UINT16(cpd->base+((LAN91CXX_DATA & 0x7) << cpd->addrsh), val);



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]