changeset 1599:bf994e1a516c

Big/Little endian changes from Bob Koninckx
author gthomas
date Wed, 21 Apr 2004 17:03:23 +0000
parents d177755187d3
children f98ccb45a59c
files packages/devs/eth/cl/cs8900a/current/ChangeLog packages/devs/eth/cl/cs8900a/current/cdl/cl_cs8900a_eth_drivers.cdl packages/devs/eth/cl/cs8900a/current/include/cs8900.h packages/devs/eth/cl/cs8900a/current/src/if_cs8900a.c
diffstat 4 files changed, 70 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/packages/devs/eth/cl/cs8900a/current/ChangeLog
+++ b/packages/devs/eth/cl/cs8900a/current/ChangeLog
@@ -1,3 +1,14 @@
+2004-04-19  Bob Koninckx <bob.koninckx@o-3s.com>
+	* src/if_cs8900a.c: function cs8900a_int_vector, return the vector
+	instead of a boolean.
+
+2004-04-08  Bob Koninckx <bob.koninckx@o-3s.com>
+	* cdl/cl_cs8900a_eth_drivers.cdl
+	* include/if_cs8900a.c
+	* src/if_cs8900a.c: Made hardware swapping or software swapping of
+    data bytes (mostly relevant to big endian machines) a configuration
+    option
+
 2003-11-05  Bob Koninckx <bob.koninckx@mech.kuleuven.ac.be>
 
 	* src/if_cs8900a.c: Fix handling of odd bytes on big endian machines
--- a/packages/devs/eth/cl/cs8900a/current/cdl/cl_cs8900a_eth_drivers.cdl
+++ b/packages/devs/eth/cl/cs8900a/current/cdl/cl_cs8900a_eth_drivers.cdl
@@ -68,6 +68,29 @@ cdl_package CYGPKG_DEVS_ETH_CL_CS8900A {
         puts $::cdl_header "#include CYGDAT_DEVS_ETH_CL_CS8900A_CFG";
     }
 
+	cdl_option CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED {
+	    display "Byte swapped data bus"
+		flavor  bool
+		default_value 0
+		description   "
+		    From the application note AN205 from Cirrus Logic ...The CS8900a
+			assumes a litte-endian ISA type system. However, network byte order
+			is always big-endian.Therefore to minimize software manipulation of
+			frame data in ISA systems, the CS8900 byte-swaps frame data
+			internally. The control and status registers are not byte-swapped.
+			In a big-endian system you can either byte-swap the network data
+			(to reverse the byte swapping done internally to the CS8900) in
+			software or you can do it in hardware (byte swap the data lines to
+			the chip). Byte swapping the data lines is much more efficient; you
+	        will only need to byte swap the control/status/counter values in
+			software and not the frame data. (Most of the read/writes to the chip
+			are frame data.) Since network byte order is always big endian, this
+		    scheme works without special support on the other end of the network...
+			Normally, you won't need to check this option unless you are using a
+			CS8900a ethernet controller with a big endian machine and hardware
+			that has been designed with the cs8900a in mind."
+    }
+
     cdl_component CYGPKG_DEVS_ETH_CL_CS8900A_OPTIONS {
         display "Cirrus Logic ethernet driver build options"
         flavor  none
--- a/packages/devs/eth/cl/cs8900a/current/include/cs8900.h
+++ b/packages/devs/eth/cl/cs8900a/current/include/cs8900.h
@@ -167,27 +167,25 @@ typedef struct cs8900a_priv_data {
 # define CS8900A_PDATA  (6*CS8900A_step)
 #endif
 
-#if(CYG_BYTEORDER == CYG_LSBFIRST)
+#ifndef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED
 #define ISQ_RxEvent     0x0004
 #define ISQ_TxEvent     0x0008
 #define ISQ_BufEvent    0x000C
 #define ISQ_RxMissEvent 0x0010
 #define ISQ_TxColEvent  0x0012
 #define ISQ_EventMask   0x003F
-#elif(CYG_BYTEORDER == CYG_MSBFIRST)
+#else
 #define ISQ_RxEvent     0x0400
 #define ISQ_TxEvent     0x0800
 #define ISQ_BufEvent    0x0C00
 #define ISQ_RxMissEvent 0x1000
 #define ISQ_TxColEvent  0x1200
 #define ISQ_EventMask   0x3F00
-#else
-# error You must define CYG_BYTEORDER to equal CYG_LSBFIRST or CYG_MSBFIRST
 #endif
 
 // ------------------------------------------------------------------------
 // Registers available via "page pointer" (indirect access)
-#if(CYG_BYTEORDER == CYG_LSBFIRST)
+#ifndef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED
 
 #define PP_ChipID    0x0000  // Chip identifier - must be 0x630e
 #define PP_ChipRev   0x0002  // Chip revision, model codes
@@ -310,7 +308,7 @@ typedef struct cs8900a_priv_data {
 #define PP_LAF       0x0150  // Logical address filter (6 bytes)
 #define PP_IA        0x0158  // Individual address (MAC)
 
-#elif(CYG_BYTEORDER == CYG_MSBFIRST)
+#else
 
 #define PP_ChipID    0x0000  // Chip identifier - must be 0x0e63
 #define PP_ChipRev   0x0200  // Chip revision, model codes
@@ -433,8 +431,6 @@ typedef struct cs8900a_priv_data {
 #define PP_LAF       0x5001  // Logical address filter (6 bytes)
 #define PP_IA        0x5801  // Individual address (MAC)
 
-#else
-# error You must define CYG_BYTEORDER to equal CYG_LSBFIRST or CYG_MSBFIRST
 #endif
 
 // ------------------------------------------------------------------------
--- a/packages/devs/eth/cl/cs8900a/current/src/if_cs8900a.c
+++ b/packages/devs/eth/cl/cs8900a/current/src/if_cs8900a.c
@@ -159,7 +159,7 @@ static int
 cs8900a_int_vector(struct eth_drv_sc *sc)
 {
     cs8900a_priv_data_t *cpd = (cs8900a_priv_data_t *)sc->driver_private;
-    return (cpd->interrupt) ? 1 : 0;
+    return (cpd->interrupt);
 }
 
 static bool 
@@ -264,16 +264,14 @@ cs8900a_init(struct cyg_netdevtab_entry 
         // Get ESA from EEPROM - via the PP_IA registers
         cyg_uint16 esa_word;
         for (i = 0;  i < sizeof(cpd->esa);  i += 2) {
-#if(CYG_BYTEORDER == CYG_LSBFIRST)
+#ifndef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED
             esa_word = get_reg(base, PP_IA+i);
             cpd->esa[i] = (esa_word & 0xFF);
             cpd->esa[i+1] = (esa_word >> 8) & 0xFF;
-#elif(CYG_BYTEORDER == CYG_MSBFIRST)
+#else
             esa_word = get_reg(base, PP_IA+CYG_SWAP16(i));
             cpd->esa[i+1] = (esa_word & 0xFF);
             cpd->esa[i] = (esa_word >> 8) & 0xFF;
-#else
-# error You must define CYG_BYTEORDER to equal CYG_LSBFIRST or CYG_MSBFIRST
 #endif
         }
         esa_configured = true;
@@ -287,17 +285,17 @@ cs8900a_init(struct cyg_netdevtab_entry 
 
     // Tell the chip what ESA to use
     for (i = 0;  i < sizeof(cpd->esa);  i += 2) {
-#if(CYG_BYTEORDER == CYG_LSBFIRST)
+#ifndef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED
         put_reg(base, PP_IA+i, cpd->esa[i] | (cpd->esa[i+1] << 8));
-#elif(CYG_BYTEORDER == CYG_MSBFIRST)
+#else
         put_reg(base, PP_IA+CYG_SWAP16(i), cpd->esa[i+1] | (cpd->esa[i] << 8));
 #endif
     }
     // Set logical address mask
     for (i = 0;  i < 8;  i += 2) {
-#if(CYG_BYTEORDER == CYG_LSBFIRST)
+#ifndef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED
         put_reg(base, PP_LAF+i, 0xFFFF);
-#elif(CYG_BYTEORDER == CYG_MSBFIRST)
+#else
         put_reg(base, PP_LAF+CYG_SWAP16(i), 0xFFFF);
 #endif
     }
@@ -438,7 +436,7 @@ cs8900a_send(struct eth_drv_sc *sc, stru
 #endif
 
     // Start the xmit sequence
-#if(CYG_BYTEORDER == CYG_MSBFIRST)      
+#ifdef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED
     total_len = CYG_SWAP16(total_len);
 #endif
         
@@ -472,12 +470,12 @@ cs8900a_send(struct eth_drv_sc *sc, stru
         if (len > 0) {
             /* Finish the last word. */
             if (odd_byte) {
-#if(CYG_BYTEORDER == CYG_LSBFIRST)                              
-                // Add data to the most significant byte
+// This new byte must get on the bus _after_ the last saved odd byte, it therefore
+// belongs in the MSB of the CS8900a
+#ifdef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED                            
+                saved_data |= *data++;
+#else
                 saved_data |= ((cyg_uint16)*data++) << 8;
-#elif(CYG_BYTEORDER == CYG_MSBFIRST)
-                // Add data to the least significant byte
-                saved_data |= *data++;
 #endif
                 HAL_WRITE_UINT16(cpd->base+CS8900A_RTDATA, saved_data);
                 len--;
@@ -487,7 +485,13 @@ cs8900a_send(struct eth_drv_sc *sc, stru
                 /* Aligned on 16-bit boundary, so output contiguous words. */
                 sdata = (cyg_uint16 *)data;
                 while (len > 1) {
+					// Make sure data get on the bus in Big Endian format
+#if((CYG_BYTEORDER == CYG_MSBFIRST) && defined(CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED) || \
+    (CYG_BYTEORDER == CYG_LSBFIRST) && !defined(CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED ))
                     HAL_WRITE_UINT16(cpd->base+CS8900A_RTDATA, *sdata++);
+#else
+                    HAL_WRITE_UINT16(cpd->base+CS8900A_RTDATA, CYG_SWAP16(*sdata++));
+#endif
                     len -= sizeof(cyg_uint16);
                 }
                 data = (cyg_uint8 *)sdata;
@@ -495,7 +499,9 @@ cs8900a_send(struct eth_drv_sc *sc, stru
                 /* Not 16-bit aligned, so byte copy */
                 while (len > 1) {
                     saved_data = (cyg_uint16)*data++;   // reuse saved_data
-#if CYG_BYTEORDER == CYG_MSBFIRST
+					// Make sure data get on the bus in Big Endian format, the first byte belongs in the
+					// LSB of the CS8900A
+#ifdef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED
                     saved_data =  ((cyg_uint16)*data++) | (saved_data << 8);
 #else
                     saved_data |= ((cyg_uint16)*data++) << 8;
@@ -507,7 +513,9 @@ cs8900a_send(struct eth_drv_sc *sc, stru
             /* Save last byte, if necessary. */
             if (len == 1) {
                 saved_data = (cyg_uint16)*data;
-#if CYG_BYTEORDER == CYG_MSBFIRST				
+// This _last_ byte must get on the bus _first_, it therefore belongs in the LSB of
+// the CS8900a
+#ifdef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED
                 saved_data = (saved_data << 8);
 #endif
                 odd_byte = true;
@@ -534,7 +542,7 @@ cs8900a_RxEvent(struct eth_drv_sc *sc)
     HAL_READ_UINT16(base+CS8900A_RTDATA, stat);
     HAL_READ_UINT16(base+CS8900A_RTDATA, len);
 
-#if(CYG_BYTEORDER == CYG_MSBFIRST)
+#ifdef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED
     len = CYG_SWAP16(len);
 #endif
         
@@ -566,13 +574,18 @@ cs8900a_recv(struct eth_drv_sc *sc, stru
         while (mlen >= sizeof(*data)) {
             HAL_READ_UINT16(base+CS8900A_RTDATA, val);
             if (data) {
+#if((CYG_BYTEORDER == CYG_MSBFIRST) && defined(CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED) || \
+    (CYG_BYTEORDER == CYG_LSBFIRST) && !defined(CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED ))
                 *data++ = val;
+#else
+                *data++ = CYG_SWAP16(val);
+#endif
             }
             mlen -= sizeof(*data);
         }
         if (mlen) {
             HAL_READ_UINT16(base+CS8900A_RTDATA, val);
-#if(CYG_BYTEORDER == CYG_LSBFIRST)                      
+#ifndef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED 
             // last odd byte will be in the LSB
             cval = (cyg_uint8)(val);
 #elif(CYG_BYTEORDER == CYG_MSBFIRST)