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]

Improved big-endian support


As before, but fixing a recently found problem as well :-)
? cs8900a.patch
Index: current/ChangeLog
===================================================================
RCS file: /cvs/o3s/software/ecos/packages/devs/eth/cl/cs8900a/current/ChangeLog,v
retrieving revision 1.1.1.2
retrieving revision 1.3
diff -u -5 -r1.1.1.2 -r1.3
--- current/ChangeLog	24 Nov 2003 19:46:27 -0000	1.1.1.2
+++ current/ChangeLog	19 Apr 2004 08:08:14 -0000	1.3
@@ -1,5 +1,16 @@
+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
 
 2003-04-12  Jonathan Larmour  <jifl@eCosCentric.com>
Index: current/cdl/cl_cs8900a_eth_drivers.cdl
===================================================================
RCS file: /cvs/o3s/software/ecos/packages/devs/eth/cl/cs8900a/current/cdl/cl_cs8900a_eth_drivers.cdl,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -5 -r1.1.1.1 -r1.2
--- current/cdl/cl_cs8900a_eth_drivers.cdl	7 Jun 2003 09:01:57 -0000	1.1.1.1
+++ current/cdl/cl_cs8900a_eth_drivers.cdl	8 Apr 2004 19:33:30 -0000	1.2
@@ -66,10 +66,33 @@
     define_proc {
         puts $::cdl_header "#include <pkgconf/system.h>";
         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
 	no_define
 
Index: current/include/cs8900.h
===================================================================
RCS file: /cvs/o3s/software/ecos/packages/devs/eth/cl/cs8900a/current/include/cs8900.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -5 -r1.1.1.1 -r1.2
--- current/include/cs8900.h	7 Jun 2003 09:01:57 -0000	1.1.1.1
+++ current/include/cs8900.h	8 Apr 2004 19:33:30 -0000	1.2
@@ -165,31 +165,29 @@
 # define CS8900A_ISQ    (4*CS8900A_step)
 # define CS8900A_PPTR   (5*CS8900A_step)
 # 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
 #define PP_ChipID_CL           0x630e
 
@@ -308,11 +306,11 @@
 #define PP_BusStat_TxRDY       0x0100  // Ready for Tx 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
 #define PP_ChipID_CL           0x0e63
 
@@ -431,12 +429,10 @@
 #define PP_BusStat_TxRDY       0x0001  // Ready for Tx 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
 
 // ------------------------------------------------------------------------
 // "page pointer" access functions
 static __inline__ cyg_uint16
Index: current/src/if_cs8900a.c
===================================================================
RCS file: /cvs/o3s/software/ecos/packages/devs/eth/cl/cs8900a/current/src/if_cs8900a.c,v
retrieving revision 1.1.1.2
retrieving revision 1.4
diff -u -5 -r1.1.1.2 -r1.4
--- current/src/if_cs8900a.c	24 Nov 2003 19:46:27 -0000	1.1.1.2
+++ current/src/if_cs8900a.c	19 Apr 2004 08:08:14 -0000	1.4
@@ -157,11 +157,11 @@
 
 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 
 cs8900a_init(struct cyg_netdevtab_entry *tab)
 {
@@ -262,20 +262,18 @@
     }
     if (!esa_configured && (chip_status & PP_SelfStat_EEPROM)) {
         // 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;
     }
     if (!esa_configured) {
@@ -285,21 +283,21 @@
         return false;
     }
 
     // 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
     }
 # if DEBUG & 8
     diag_printf("ESA %02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -436,11 +434,11 @@
 #ifdef CYGPKG_KERNEL
     cpd->txstart = cyg_current_time();
 #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
         
     // The hardware indicates that there are options as to when the actual
     // packet transmission will start wrt moving of data into the transmit
@@ -470,34 +468,42 @@
         len = sg_list[i].len;
 
         if (len > 0) {
             /* Finish the last word. */
             if (odd_byte) {
-#if(CYG_BYTEORDER == CYG_LSBFIRST)                              
-                // Add data to the most significant byte
-                saved_data |= ((cyg_uint16)*data++) << 8;
-#elif(CYG_BYTEORDER == CYG_MSBFIRST)
-                // Add data to the least 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;
 #endif
                 HAL_WRITE_UINT16(cpd->base+CS8900A_RTDATA, saved_data);
                 len--;
                 odd_byte = false;
             }
             if (((CYG_ADDRESS)data & 0x1) == 0) {
                 /* 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;
             } else {
                 /* 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;
 #endif
                     HAL_WRITE_UINT16(cpd->base+CS8900A_RTDATA, saved_data);
@@ -505,11 +511,13 @@
                 }
             }
             /* 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;
             }
         }
@@ -532,11 +540,11 @@
     cyg_uint16 stat, len;
 
     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
         
 #ifdef CYGDBG_IO_ETH_DRIVERS_DEBUG
     if (cyg_io_eth_net_debug) {
@@ -564,17 +572,22 @@
         data = (cyg_uint16 *)sg_list[i].buf;
         mlen = sg_list[i].len;
         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)
             // last odd byte will be in the MSB
             cval = (cyg_uint8)(val >> 8);

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