Mercurial > ecos
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)
