[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[microblaze-uclinux] [patch] Ethernet driver update



Hi,

Attached is a patch on the Xilinx ethernet driver and supporting xilinx_ocp
files, that applies cleanly on current CVS head.

If those who are experiencing issues with the ethernet driver could please test
it out and report their findings back to the list, that would be greatly
appreciated.  Once it gets the all clear I'll commit to CVS.

Features:

 - Support most recent Xilinx EMAC core, and back-compatible to earlier versions
 - Support hardware TCP checksum offload and data realignment engine (DRE) if
enabled on the EMAC core (auto-config'd of course)
 - Minor cleanup and revup of Xilinx level 0/1 drivers

Thanks to Vasanth from Xilinx who did most of the work on this, including
merging the TCP offload and DRE support from the PPC drivers.

With a full SGDMA, checksum offlaod and DRE configuration, raw TCP throughput
around 50Mbps is achievable on 100MHz MicroBlaze uClinux designs.

Thanks,

John
-- 
Dr John Williams, Research Fellow,
Embedded Systems Group / Reconfigurable Computing
School of ITEE, The University of Queensland, Brisbane, Australia
(p) +61 7 33652185  (f) +61 7 33654999 (m) +61 403969243
? xilinx_enet_update.patch
Index: arch/microblaze/xilinx_ocp/xbasic_types.h
===================================================================
RCS file: /var/cvs/uClinux-2.4.x/arch/microblaze/xilinx_ocp/xbasic_types.h,v
retrieving revision 1.4
diff -u -b -B -w -p -r1.4 xbasic_types.h
--- arch/microblaze/xilinx_ocp/xbasic_types.h	15 Feb 2005 05:27:23 -0000	1.4
+++ arch/microblaze/xilinx_ocp/xbasic_types.h	23 Jun 2006 00:46:35 -0000
@@ -76,10 +76,14 @@
 #define FALSE 0
 #endif
 
+/** Null */
 #ifndef NULL
-#define NULL 0
+#define NULL 0l
+#endif
+
+#ifndef XNULL
+#define XNULL 0L
 #endif
-/** Null */
 
 #define XCOMPONENT_IS_READY     0x11111111	/* component has been initialized */
 #define XCOMPONENT_IS_STARTED   0x22222222	/* component has been started */
Index: arch/microblaze/xilinx_ocp/xbuf_descriptor.h
===================================================================
RCS file: /var/cvs/uClinux-2.4.x/arch/microblaze/xilinx_ocp/xbuf_descriptor.h,v
retrieving revision 1.3
diff -u -b -B -w -p -r1.3 xbuf_descriptor.h
--- arch/microblaze/xilinx_ocp/xbuf_descriptor.h	15 Feb 2005 05:27:23 -0000	1.3
+++ arch/microblaze/xilinx_ocp/xbuf_descriptor.h	23 Jun 2006 00:46:38 -0000
@@ -1,3 +1,4 @@
+/* $Id: xbuf_descriptor.h,v 1.7 2005/11/30 18:58:31 meinelte Exp $ */
 /******************************************************************************
 *
 *     Author: Xilinx, Inc.
@@ -9,37 +10,34 @@
 *     option) any later version.
 *     
 *     
-*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
-*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
-*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
-*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
-*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
-*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
-*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
-*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
-*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
-*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
-*     FITNESS FOR A PARTICULAR PURPOSE.
-*     
-*     
-*     Xilinx hardware products are not intended for use in life support
-*     appliances, devices, or systems. Use in such applications is
-*     expressly prohibited.
+ *       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+ *       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+ *       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+ *       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+ *       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+ *       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+ *       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+ *       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+ *       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+ *       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+ *       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+ *       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ *       FOR A PARTICULAR PURPOSE.
 *     
-*     
-*     (c) Copyright 2002-2004 Xilinx Inc.
+ *       (c) Copyright 2001-2004 Xilinx Inc.
 *     All rights reserved.
 *     
-*     
 *     You should have received a copy of the GNU General Public License along
 *     with this program; if not, write to the Free Software Foundation, Inc.,
 *     675 Mass Ave, Cambridge, MA 02139, USA.
 *
-* FILENAME:
+ ******************************************************************************/
+/*****************************************************************************/
+/**
 *
-* xbuf_descriptor.h
+ * @file xbuf_descriptor.h
 *
-* DESCRIPTION:
+ * <b>Description</b>
 *
 * This file contains the interface for the XBufDescriptor component.
 * The XBufDescriptor component is a passive component that only maps over
@@ -48,12 +46,21 @@
 * the buffer descriptor processing.  See the source file xbuf_descriptor.c for
 * details.
 *
-* NOTES:
+ * @note
 *
 * Most of the functions of this component are implemented as macros in order
 * to optimize the processing.  The names are not all uppercase such that they
 * can be switched between macros and functions easily.
 *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver   Who  Date     Changes
+ * ----- ---- -------- -----------------------------------------------
+ * 1.00a xd   10/27/04 Doxygenated for inclusion in API documentation
+ * 1.00b ecm  10/31/05 Updated for the check sum offload changes.
+ * </pre>
+ *
 ******************************************************************************/
 
 #ifndef XBUF_DESCRIPTOR_H	/* prevent circular inclusions */
@@ -66,12 +73,15 @@
 
 /************************** Constant Definitions *****************************/
 
-/* The following constants allow access to all fields of a buffer descriptor
- * and are necessary at this level of visibility to allow macros to access
+/** @name Buffer Descriptor fields
+ *
+ * @{
+ */
+/** This constant allows access to fields of a buffer descriptor
+ * and is necessary at this level of visibility to allow macros to access
  * and modify the fields of a buffer descriptor.  It is not expected that the
- * user of a buffer descriptor would need to use these constants.
+ * user of a buffer descriptor would need to use this constant.
  */
-
 #define XBD_DEVICE_STATUS_OFFSET    0
 #define XBD_CONTROL_OFFSET          1
 #define XBD_SOURCE_OFFSET           2
@@ -82,10 +92,10 @@
 #define XBD_ID_OFFSET               7
 #define XBD_FLAGS_OFFSET            8
 #define XBD_RQSTED_LENGTH_OFFSET    9
-
 #define XBD_SIZE_IN_WORDS           10
+/* @} */
 
-/*
+/**
  * The following constants define the bits of the flags field of a buffer
  * descriptor
  */
@@ -98,11 +107,33 @@ typedef u32 XBufDescriptor[XBD_SIZE_IN_W
 
 /***************** Macros (Inline Functions) Definitions *********************/
 
-/* each of the following macros are named the same as functions rather than all
+/**
+ * each of the following macros are named the same as functions rather than all
  * upper case in order to allow either the macros or the functions to be
  * used, see the source file xbuf_descriptor.c for documentation
  */
 
+
+/*****************************************************************************/
+/**
+ *
+ * This function initializes a buffer descriptor component by zeroing all of the
+ * fields of the buffer descriptor.  This function should be called prior to
+ * using a buffer descriptor.
+ *
+ * @param
+ *
+ * InstancePtr points to the buffer descriptor to operate on.
+ *
+ * @return
+ *
+ * None.
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
 #define XBufDescriptor_Initialize(InstancePtr)                  \
 {                                                               \
     (*((u32 *)InstancePtr + XBD_CONTROL_OFFSET) = 0);       \
@@ -117,85 +148,890 @@ typedef u32 XBufDescriptor[XBD_SIZE_IN_W
     (*((u32 *)InstancePtr + XBD_RQSTED_LENGTH_OFFSET) = 0); \
 }
 
+/*****************************************************************************/
+/**
+ *
+ * This function gets the control field of a buffer descriptor component.  The
+ * DMA channel hardware transfers the control field from the buffer descriptor
+ * into the DMA control register when a buffer descriptor is processed.  It
+ * controls the details of the DMA transfer.
+ *
+ * @param
+ *
+ * InstancePtr points to the buffer descriptor to operate on.
+ *
+ * @return
+ *
+ * The control field contents of the buffer descriptor. One or more of the
+ * following values may be contained the field.  Each of the values are
+ * unique bit masks.
+ *                               <br><br>
+ * - XDC_DMACR_SOURCE_INCR_MASK  Increment the source address
+ *                               <br><br>
+ * - XDC_DMACR_DEST_INCR_MASK    Increment the destination address
+ *                               <br><br>
+ * - XDC_DMACR_SOURCE_LOCAL_MASK Local source address
+ *                               <br><br>
+ * - XDC_DMACR_DEST_LOCAL_MASK   Local destination address
+ *                               <br><br>
+ * - XDC_DMACR_SG_ENABLE_MASK    Scatter gather enable
+ *                               <br><br>
+ * - XDC_DMACR_GEN_BD_INTR_MASK  Individual buffer descriptor interrupt
+ *                               <br><br>
+ * - XDC_DMACR_LAST_BD_MASK      Last buffer descriptor in a packet
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
 #define XBufDescriptor_GetControl(InstancePtr)   \
     (u32)(*((u32 *)InstancePtr + XBD_CONTROL_OFFSET))
 
+/*****************************************************************************/
+/**
+ *
+ * This function sets the control field of a buffer descriptor component.  The
+ * DMA channel hardware transfers the control field from the buffer descriptor
+ * into the DMA control register when a buffer descriptor is processed.  It
+ * controls the details of the DMA transfer such as
+ *
+ * @param
+ *
+ * InstancePtr points to the buffer descriptor to operate on.
+ *
+ * @param
+ *
+ * Control contains the value to be written to the control field of the buffer
+ * descriptor. One or more of the following values may be contained the field.
+ * Each of the values are unique bit masks such that they may be ORed together
+ * to enable multiple bits or inverted and ANDed to disable multiple bits.
+ * - XDC_DMACR_SOURCE_INCR_MASK  Increment the source address
+ * - XDC_DMACR_DEST_INCR_MASK    Increment the destination address
+ * - XDC_DMACR_SOURCE_LOCAL_MASK Local source address
+ * - XDC_DMACR_DEST_LOCAL_MASK   Local destination address
+ * - XDC_DMACR_SG_ENABLE_MASK    Scatter gather enable
+ * - XDC_DMACR_GEN_BD_INTR_MASK  Individual buffer descriptor interrupt
+ * - XDC_DMACR_LAST_BD_MASK      Last buffer descriptor in a packet
+ *
+ * @return
+ *
+ * None.
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
 #define XBufDescriptor_SetControl(InstancePtr, Control)  \
     (*((u32 *)InstancePtr + XBD_CONTROL_OFFSET) = (u32)Control)
 
+/*****************************************************************************/
+/**
+ *
+ * This function determines if this buffer descriptor is marked as being the
+ * last in the control field.  A packet may be broken up across multiple
+ * buffer descriptors such that the last buffer descriptor is the end of the
+ * packet.  The DMA channel hardware copies the control field from the buffer
+ * descriptor to the control register of the DMA channel when the buffer
+ * descriptor is processed.
+ *
+ * @param
+ *
+ * InstancePtr points to the buffer descriptor to operate on.
+ *
+ * @return
+ *
+ * TRUE if the buffer descriptor is marked as last in the control field,
+ * otherwise, FALSE.
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
 #define XBufDescriptor_IsLastControl(InstancePtr) \
     (u32)((*((u32 *)InstancePtr + XBD_CONTROL_OFFSET) & \
                XDC_CONTROL_LAST_BD_MASK) == XDC_CONTROL_LAST_BD_MASK)
 
+/*****************************************************************************/
+/**
+ *
+ * This function marks the buffer descriptor as being last in the control
+ * field of the buffer descriptor.  A packet may be broken up across multiple
+ * buffer descriptors such that the last buffer descriptor is the end of the
+ * packet.  The DMA channel hardware copies the control field from the buffer
+ * descriptor to the control register of the DMA channel when the buffer
+ * descriptor is processed.
+ *
+ * @param
+ *
+ * InstancePtr points to the buffer descriptor to operate on.
+ *
+ * @return
+ *
+ * None.
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
 #define XBufDescriptor_SetLast(InstancePtr) \
     (*((u32 *)InstancePtr + XBD_CONTROL_OFFSET) |= XDC_CONTROL_LAST_BD_MASK)
 
+/*****************************************************************************/
+/**
+ *
+ * This function gets the source address field of the buffer descriptor.
+ * The source address indicates the address of memory which is the
+ * source of a DMA scatter gather operation.  The DMA channel hardware
+ * copies the source address from the buffer descriptor to the source
+ * address register of the DMA channel when the buffer descriptor is processed.
+ *
+ * @param
+ *
+ * InstancePtr points to the buffer descriptor to operate on.
+ *
+ * @return
+ *
+ * The source address field of the buffer descriptor.
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
 #define XBufDescriptor_GetSrcAddress(InstancePtr) \
     ((u32 *)(*((u32 *)InstancePtr + XBD_SOURCE_OFFSET)))
 
+/*****************************************************************************/
+/**
+ *
+ * This function sets the source address field of the buffer descriptor.
+ * The source address indicates the address of memory which is the
+ * source of a DMA scatter gather operation.  The DMA channel hardware
+ * copies the source address from the buffer descriptor to the source
+ * address register of the DMA channel when the buffer descriptor is processed.
+ *
+ * @param
+ *
+ * InstancePtr points to the buffer descriptor to operate on.
+ *
+ * @param
+ *
+ * SourceAddress contains the source address field for the buffer descriptor.
+ *
+ * @return
+ *
+ * None.
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
 #define XBufDescriptor_SetSrcAddress(InstancePtr, Source) \
     (*((u32 *)InstancePtr + XBD_SOURCE_OFFSET) = (u32)Source)
 
+/*****************************************************************************/
+/**
+ *
+ * This function gets the destination address field of the buffer descriptor.
+ * The destination address indicates the address of memory which is the
+ * destination of a DMA scatter gather operation.  The DMA channel hardware
+ * copies the destination address from the buffer descriptor to the destination
+ * address register of the DMA channel when the buffer descriptor is processed.
+ *
+ * @param
+ *
+ * InstancePtr points to the buffer descriptor to operate on.
+ *
+ * @return
+ *
+ * The destination address field of the buffer descriptor.
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
 #define XBufDescriptor_GetDestAddress(InstancePtr) \
     ((u32 *)(*((u32 *)InstancePtr + XBD_DESTINATION_OFFSET)))
 
+/*****************************************************************************/
+/**
+ *
+ * This function sets the destination address field of the buffer descriptor.
+ * The destination address indicates the address of memory which is the
+ * destination of a DMA scatter gather operation.  The DMA channel hardware
+ * copies the destination address from the buffer descriptor to the destination
+ * address register of the DMA channel when the buffer descriptor is processed.
+ *
+ * @param
+ *
+ * InstancePtr points to the buffer descriptor to operate on.
+ *
+ * @param
+ *
+ * DestinationAddress contains the destination address field for the buffer
+ * descriptor.
+ *
+ * @return
+ *
+ * None.
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
 #define XBufDescriptor_SetDestAddress(InstancePtr, Destination) \
     (*((u32 *)InstancePtr + XBD_DESTINATION_OFFSET) = (u32)Destination)
 
+/*****************************************************************************/
+/**
+ *
+ * This function gets the length of the data transfer if the buffer descriptor
+ * has been processed by the DMA channel hardware.  If the buffer descriptor
+ * has not been processed, the return value will be zero indicating that no data
+ * has been transferred yet.  This function uses both the length and requested
+ * length fields of the buffer descriptor to determine the number of bytes
+ * transferred by the DMA operation. The length field of the buffer descriptor
+ * contains the number of bytes remaining from the requested length.
+ *
+ * @param
+ *
+ * InstancePtr points to the buffer descriptor to operate on.
+ *
+ * @return
+ *
+ * The number of bytes which have been transferred by a DMA operation on the
+ * buffer descriptor.
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
 #define XBufDescriptor_GetLength(InstancePtr)                           \
     (u32)(*((u32 *)InstancePtr + XBD_RQSTED_LENGTH_OFFSET) -    \
               *((u32 *)InstancePtr + XBD_LENGTH_OFFSET))
 
+/*****************************************************************************/
+/**
+ *
+ * This function sets the length and the requested length fields of the buffer
+ * descriptor.  The length field indicates the number of bytes to transfer for
+ * the DMA operation and the requested length is written with the same value.
+ * The requested length is not modified by the DMA hardware while the length
+ * field is modified by the hardware to indicate the number of bytes remaining
+ * in the transfer after the transfer is complete.  The requested length allows
+ * the software to calculate the actual number of bytes transferred for the DMA
+ * operation.
+ *
+ * @param
+ *
+ * InstancePtr points to the buffer descriptor to operate on.
+ *
+ * @param
+ *
+ * Length contains the length to put in the length and requested length fields
+ * of the buffer descriptor.
+ *
+ * @return
+ *
+ * None.
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
 #define XBufDescriptor_SetLength(InstancePtr, Length)                       \
 {                                                                           \
     (*((u32 *)InstancePtr + XBD_LENGTH_OFFSET) = (u32)(Length));    \
     (*((u32 *)InstancePtr + XBD_RQSTED_LENGTH_OFFSET) = (u32)(Length));\
 }
 
+/*****************************************************************************/
+/**
+ *
+ * This function gets the status field of a buffer descriptor component. The
+ * status field is written to the buffer descriptor by the DMA channel hardware
+ * after processing of a buffer descriptor is complete.  The status field
+ * indicates the status of the DMA operation.
+ *
+ * @param
+ *
+ * InstancePtr points to the buffer descriptor to operate on.
+ *
+ * @return
+ *
+ * The status field contents of the buffer descriptor. One or more of the
+ * following values may be contained the field. Each of the values are
+ * unique bit masks.
+ *                               <br><br>
+ * - XDC_DMASR_BUSY_MASK         The DMA channel is busy
+ *                               <br><br>
+ * - XDC_DMASR_BUS_ERROR_MASK    A bus error occurred
+ *                               <br><br>
+ * - XDC_DMASR_BUS_TIMEOUT_MASK  A bus timeout occurred
+ *                               <br><br>
+ * - XDC_DMASR_LAST_BD_MASK      The last buffer descriptor of a packet
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
 #define XBufDescriptor_GetStatus(InstancePtr)    \
     (u32)(*((u32 *)InstancePtr + XBD_STATUS_OFFSET))
 
+/*****************************************************************************/
+/**
+ *
+ * This function sets the status field of a buffer descriptor component.  The
+ * status field is written to the buffer descriptor by the DMA channel hardware
+ * after processing of a buffer descriptor is complete.  This function would
+ * typically be used during debugging of buffer descriptor processing.
+ *
+ * @param
+ *
+ * InstancePtr points to the buffer descriptor to operate on.
+ *
+ * @param
+ *
+ * Status contains the status field for the buffer descriptor.
+ * The status register contents of the DMA channel. One or more of the
+ * following values may be contained the register. Each of the values are
+ * unique bit masks.
+ * - XDC_DMASR_BUSY_MASK         The DMA channel is busy
+ * - XDC_DMASR_BUS_ERROR_MASK    A bus error occurred
+ * - XDC_DMASR_BUS_TIMEOUT_MASK  A bus timeout occurred
+ * - XDC_DMASR_LAST_BD_MASK      The last buffer descriptor of a packet
+ *
+ * @return
+ *
+ * None.
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
 #define XBufDescriptor_SetStatus(InstancePtr, Status)    \
     (*((u32 *)InstancePtr + XBD_STATUS_OFFSET) = (u32)Status)
 
+/*****************************************************************************/
+/**
+ *
+ * This function determines if this buffer descriptor is marked as being the
+ * last in the status field.  A packet may be broken up across multiple
+ * buffer descriptors such that the last buffer descriptor is the end of the
+ * packet.  The DMA channel hardware copies the status register contents to
+ * the buffer descriptor of the DMA channel after processing of the buffer
+ * descriptor is complete.
+ *
+ * @param
+ *
+ * InstancePtr points to the buffer descriptor to operate on.
+ *
+ * @return
+ *
+ * TRUE if the buffer descriptor is marked as last in the status field,
+ * otherwise, FALSE.
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
 #define XBufDescriptor_IsLastStatus(InstancePtr) \
     (u32)((*((u32 *)InstancePtr + XBD_STATUS_OFFSET) & \
                XDC_STATUS_LAST_BD_MASK) == XDC_STATUS_LAST_BD_MASK)
 
+/*****************************************************************************/
+/**
+ *
+ * This function gets the device status field of the buffer descriptor.  The
+ * device status is device specific such that the definition of the contents
+ * of this field are not defined in this function. The device is defined as the
+ * device which is using the DMA channel, such as an ethernet controller.  The
+ * DMA channel hardware copies the contents of the device status register into
+ * the buffer descriptor when processing of the buffer descriptor is complete.
+ * This value is typically used by the device driver for the device to determine
+ * the status of the DMA operation with respect to the device.
+ *
+ * @param
+ *
+ * InstancePtr points to the buffer descriptor to operate on.
+ *
+ * @return
+ *
+ * The device status field of the buffer descriptor.
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
 #define XBufDescriptor_GetDeviceStatus(InstancePtr) \
     ((u32)(*((u32 *)InstancePtr + XBD_DEVICE_STATUS_OFFSET)))
 
+/*****************************************************************************/
+/**
+ *
+ * This function sets the device status field of the buffer descriptor.  The
+ * device status is device specific such that the definition of the contents
+ * of this field are not defined in this function. The device is defined as the
+ * device which is using the DMA channel, such as an ethernet controller.  This
+ * function is typically only used for debugging/testing.
+ *
+ * The DMA channel hardware copies the contents of the device status register
+ * into the buffer descriptor when processing of the buffer descriptor is
+ * complete.  This value is typically used by the device driver for the device
+ * to determine the status of the DMA operation with respect to the device.
+ *
+ * @param
+ *
+ * InstancePtr points to the buffer descriptor to operate on.
+ *
+ * @param
+ *
+ * Status contains the device status field for the buffer descriptor.
+ *
+ * @return
+ *
+ * None.
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
 #define XBufDescriptor_SetDeviceStatus(InstancePtr, Status) \
-    (*((u32 *)InstancePtr + XBD_DEVICE_STATUS_OFFSET) = (u32)Status)
+{                                                                   \
+    u32 Register;                                               \
+    Register = (*((u32 *)InstancePtr + XBD_DEVICE_STATUS_OFFSET));     \
+    Register &= XDC_DMACR_RX_CS_RAW_MASK;                         \
+    (*((u32 *)InstancePtr + XBD_DEVICE_STATUS_OFFSET)) =               \
+              Register | ((u32) (Status));               \
+}
 
+/*****************************************************************************/
+/**
+ *
+ * This function gets the next pointer field of the buffer descriptor.  This
+ * field is used to link the buffer descriptors together such that multiple DMA
+ * operations can be automated for scatter gather.  It also allows a single
+ * packet to be broken across multiple buffer descriptors.  The DMA channel
+ * hardware traverses the list of buffer descriptors using the next pointer
+ * of each buffer descriptor.
+ *
+ * @param
+ *
+ * InstancePtr points to the buffer descriptor to operate on.
+ *
+ * @return
+ *
+ * The next pointer field of the buffer descriptor.
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
 #define XBufDescriptor_GetNextPtr(InstancePtr) \
     (XBufDescriptor *)(*((u32 *)InstancePtr + XBD_NEXT_PTR_OFFSET))
 
+/*****************************************************************************/
+/**
+ *
+ * This function sets the next pointer field of the buffer descriptor.  This
+ * field is used to link the buffer descriptors together such that many DMA
+ * operations can be automated for scatter gather.  It also allows a single
+ * packet to be broken across multiple buffer descriptors.  The DMA channel
+ * hardware traverses the list of buffer descriptors using the next pointer
+ * of each buffer descriptor.
+ *
+ * @param
+ *
+ * InstancePtr points to the buffer descriptor to operate on.
+ *
+ * @param
+ *
+ * NextPtr contains the next pointer field for the buffer descriptor.
+ *
+ * @return
+ *
+ * None.
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
 #define XBufDescriptor_SetNextPtr(InstancePtr, NextPtr) \
     (*((u32 *)InstancePtr + XBD_NEXT_PTR_OFFSET) = (u32)NextPtr)
 
+/*****************************************************************************/
+/**
+ *
+ * This function gets the ID field of the buffer descriptor.  The ID field is
+ * provided to allow a device driver to correlate the buffer descriptor to other
+ * data structures which may be operating system specific, such as a pointer to
+ * a higher level memory block. The ID field is not used by the DMA channel
+ * hardware and is application specific.
+ *
+ * @param
+ *
+ * InstancePtr points to the buffer descriptor to operate on.
+ *
+ * @return
+ *
+ * The ID field of the buffer descriptor.
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
 #define XBufDescriptor_GetId(InstancePtr) \
     (u32)(*((u32 *)InstancePtr + XBD_ID_OFFSET))
 
+/*****************************************************************************/
+/**
+ *
+ * This function sets the ID field of the buffer descriptor.  The ID field is
+ * provided to allow a device driver to correlate the buffer descriptor to other
+ * data structures which may be operating system specific, such as a pointer to
+ * a higher level memory block. The ID field is not used by the DMA channel
+ * hardware and is application specific.
+ *
+ * @param
+ *
+ * InstancePtr points to the buffer descriptor to operate on.
+ *
+ * @param
+ *
+ * Id contains the ID field for the buffer descriptor.
+ *
+ * @return
+ *
+ * None.
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
 #define XBufDescriptor_SetId(InstancePtr, Id) \
     (*((u32 *)InstancePtr + XBD_ID_OFFSET) = (u32)Id)
 
+/*****************************************************************************/
+/**
+ *
+ * This function gets the flags field of the buffer descriptor.  The flags
+ * field is not used by the DMA channel hardware and is used for software
+ * processing of buffer descriptors.
+ *
+ * @param
+ *
+ * InstancePtr points to the buffer descriptor to operate on.
+ *
+ * @return
+ *
+ * The flags field of the buffer descriptor.  The field may contain one or more
+ * of the following values which are bit masks.
+ *                               <br><br>
+ * - XBD_FLAGS_LOCKED_MASK       Indicates the buffer descriptor is locked
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
 #define XBufDescriptor_GetFlags(InstancePtr) \
     (u32)(*((u32 *)InstancePtr + XBD_FLAGS_OFFSET))
 
+/*****************************************************************************/
+/**
+ *
+ * This function sets the flags field of the buffer descriptor.  The flags
+ * field is not used by the DMA channel hardware and is used for software
+ * processing of buffer descriptors.
+ *
+ * @param
+ *
+ * InstancePtr points to the buffer descriptor to operate on.
+ *
+ * @param
+ *
+ * Flags contains the flags field for the buffer descriptor.  The field may
+ * contain one or more of the following values which are bit masks.
+ * - XBD_FLAGS_LOCKED_MASK       Indicates the buffer descriptor is locked
+ *
+ * @return
+ *
+ * None.
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
 #define XBufDescriptor_SetFlags(InstancePtr, Flags) \
     (*((u32 *)InstancePtr + XBD_FLAGS_OFFSET) = (u32)Flags)
 
+/*****************************************************************************/
+/**
+ *
+ * This function locks the buffer descriptor. A lock is specific to the
+ * scatter gather processing and prevents a buffer descriptor from being
+ * overwritten in the scatter gather list.  This field is not used by the DMA
+ * channel hardware such that the hardware could still write to the buffer
+ * descriptor.  Locking a buffer descriptor is application specific and not
+ * necessary to allow the DMA channel to use the buffer descriptor, but is
+ * provided for flexibility in designing device drivers.
+ *
+ * @param
+ *
+ * InstancePtr points to the buffer descriptor to operate on.
+ *
+ * @return
+ *
+ * None.
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
 #define XBufDescriptor_Lock(InstancePtr) \
     (*((u32 *)InstancePtr + XBD_FLAGS_OFFSET) |= XBD_FLAGS_LOCKED_MASK)
 
+/*****************************************************************************/
+/**
+ *
+ * This function unlocks the buffer descriptor.  A lock is specific to the
+ * scatter gather processing and prevents a buffer descriptor from being
+ * overwritten in the scatter gather list.  This field is not used by the DMA
+ * channel hardware such that the hardware could still write to the buffer
+ * descriptor.  Locking a buffer descriptor is application specific and not
+ * necessary to allow the DMA channel to use the buffer descriptor, but is
+ * provided for flex ability in designing device drivers.
+ *
+ * @param
+ *
+ * InstancePtr points to the buffer descriptor to operate on.
+ *
+ * @return
+ *
+ * None.
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
 #define XBufDescriptor_Unlock(InstancePtr) \
     (*((u32 *)InstancePtr + XBD_FLAGS_OFFSET) &= ~XBD_FLAGS_LOCKED_MASK)
 
+/*****************************************************************************/
+/**
+ *
+ * This function determines if the buffer descriptor is locked.  The lock
+ * is not used by the DMA channel hardware and is used for software processing
+ * of buffer descriptors.
+ *
+ * @param
+ *
+ * InstancePtr points to the buffer descriptor to operate on.
+ *
+ * @return
+ *
+ * TRUE if the buffer descriptor is locked, otherwise FALSE.
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
 #define XBufDescriptor_IsLocked(InstancePtr) \
     (u32) ((*((u32 *)InstancePtr + XBD_FLAGS_OFFSET) & \
         XBD_FLAGS_LOCKED_MASK) == XBD_FLAGS_LOCKED_MASK)
 
+/*****************************************************************************/
+/**
+ *
+ * This function gets the Initial value for the CS offload function.
+ *
+ * @param
+ *
+ * InstancePtr contains a pointer to the DMA channel to operate on.
+ *
+ * @return
+ *
+ * The initial value that will be used for checksum offload operation as DMA
+ * moves the data.
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
+#define XBufDescriptor_GetCSInit(InstancePtr)\
+(*((u32 *)InstancePtr + XBD_CONTROL_OFFSET) &= XDC_DMACR_TX_CS_INIT_MASK)
+
+/*****************************************************************************/
+/**
+ *
+ * This function Sets the Initial value for the CS offload function.
+ *
+ * @param
+ *
+ * InstancePtr contains a pointer to the DMA channel to operate on.
+ *
+ * @return
+ *
+ * None
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
+#define XBufDescriptor_SetCSInit(InstancePtr, InitialValue)            \
+{                                                                   \
+    u32 Register;                                               \
+    Register = (*((u32 *)InstancePtr + XBD_CONTROL_OFFSET));     \
+    Register &= ~XDC_DMACR_TX_CS_INIT_MASK;                         \
+    (*((u32 *)InstancePtr + XBD_CONTROL_OFFSET)) =               \
+              Register | ((u32) (InitialValue));               \
+}
+/*****************************************************************************/
+/**
+ *
+ * This function gets the byte position where the CS offload function
+ * inserts the calculated checksum.
+ *
+ * @param
+ *
+ * InstancePtr contains a pointer to the DMA channel to operate on.
+ *
+ * @return
+ *
+ * The insert byte location value that will be used to place the results of
+ * the checksum offload.
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
+#define XBufDescriptor_GetCSInsertLoc(InstancePtr)                     \
+(*((u32 *)InstancePtr + XBD_DESTINATION_OFFSET) &= XDC_DAREG_CS_INSERT_MASK)
+
+/*****************************************************************************/
+/**
+ *
+ * This function sets the byte position where the CS offload function
+ * inserts the calculated checksum.
+ *
+ * @param
+ *
+ * InstancePtr contains a pointer to the DMA channel to operate on.
+ *
+ * @return
+ *
+ * None
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
+#define XBufDescriptor_SetCSInsertLoc(InstancePtr, InsertLocation)            \
+{                                                                   \
+    u32 Register;                                               \
+    Register = (*((u32 *)InstancePtr + XBD_DESTINATION_OFFSET));      \
+    Register &= ~XDC_DAREG_CS_INSERT_MASK;                         \
+    (*((u32 *)InstancePtr + XBD_DESTINATION_OFFSET)) =                \
+              Register | ((u32) (InsertLocation));             \
+}
+
+/*****************************************************************************/
+/**
+ *
+ * This function gets the byte position where the CS offload function
+ * begins the calculation of the checksum.
+ *
+ * @param
+ *
+ * InstancePtr contains a pointer to the DMA channel to operate on.
+ *
+ * @return
+ *
+ * The insert byte location value that will be used to place the results of
+ * the checksum offload.
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
+#define XBufDescriptor_GetCSBegin(InstancePtr)                      \
+(u16)((*((u32 *)InstancePtr + XBD_DESTINATION_OFFSET)) >> 16)
+/*****************************************************************************/
+/**
+ *
+ * This function sets the byte position where the CS offload function
+ * begins the calculation of the checksum.
+ *
+ * @param
+ *
+ * InstancePtr contains a pointer to the DMA channel to operate on.
+ *
+ * @return
+ *
+ * None
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
+#define XBufDescriptor_SetCSBegin(InstancePtr, BeginLocation)               \
+{                                                                           \
+    u32 Register;                                                       \
+    Register = (*((u32 *)InstancePtr + XBD_DESTINATION_OFFSET));             \
+    Register &= ~XDC_DAREG_CS_BEGIN_MASK;                                 \
+    (*((u32 *)InstancePtr + XBD_DESTINATION_OFFSET)) =                       \
+              Register | (((u32) (BeginLocation)) << 16);               \
+}
+/*****************************************************************************/
+/**
+ *
+ * This function gets the resulting checksum from the rx channel.
+ *
+ * @param
+ *
+ * InstancePtr contains a pointer to the DMA channel to operate on.
+ *
+ * @return
+ *
+ * The raw checksum calculation from the receive operation. It needs to
+ * be adjusted to remove the header and packet FCS to be correct.
+ *
+ * @note
+ *
+ * None.
+ *
+ ******************************************************************************/
+#define XBufDescriptor_GetCSRaw(InstancePtr)                     \
+(u16)((*((u32 *)InstancePtr + XBD_DEVICE_STATUS_OFFSET)) >> 16)
+
 /************************** Function Prototypes ******************************/
 
 /* The following prototypes are provided to allow each of the functions to
@@ -245,6 +1081,17 @@ void XBufDescriptor_Lock(XBufDescriptor*
 void XBufDescriptor_Unlock(XBufDescriptor* InstancePtr);
 u32 XBufDescriptor_IsLocked(XBufDescriptor* InstancePtr);
 
+ u16 XBufDescriptor_GetCSInit(XBufDescriptor* InstancePtr)
+ void XBufDescriptor_SetCSInit(XBufDescriptor* InstancePtr, u16 InitialValue)
+
+ u16 XBufDescriptor_GetCSInsertLoc(XBufDescriptor* InstancePtr)
+ void XBufDescriptor_SetCSInsertLoc(XBufDescriptor* InstancePtr, u16 InsertLocation)
+
+ u16 XBufDescriptor_GetCSBegin(XBufDescriptor* InstancePtr)
+ void XBufDescriptor_SetCSBegin(XBufDescriptor* InstancePtr, u16 BeginLocation)
+
+ u16 XBufDescriptor_GetCSRaw(XBufDescriptor* InstancePtr)
+
 void XBufDescriptor_Copy(XBufDescriptor* InstancePtr,
                          XBufDescriptor* DestinationPtr);
 
Index: arch/microblaze/xilinx_ocp/xdma_channel.h
===================================================================
RCS file: /var/cvs/uClinux-2.4.x/arch/microblaze/xilinx_ocp/xdma_channel.h,v
retrieving revision 1.3
diff -u -b -B -w -p -r1.3 xdma_channel.h
--- arch/microblaze/xilinx_ocp/xdma_channel.h	15 Feb 2005 05:27:23 -0000	1.3
+++ arch/microblaze/xilinx_ocp/xdma_channel.h	23 Jun 2006 00:46:39 -0000
@@ -192,6 +192,10 @@
 									/*     descriptor  */
 #define XDC_DMACR_DRE_MODE_MASK		0x01000000UL	/* DRE/normal mode */
 
+#define XDC_DMACR_TX_CS_INIT_MASK    0x0000FFFFUL /**< Initial value for TX
+						     CS offload */
+#define XDC_DMACR_CS_OFFLOAD_MASK    0x00800000UL /**< Enable CS offload */
+
 /* the following constants provide access to the bit fields of the DMA status
  * register (DMASR)
  */
@@ -202,6 +206,20 @@
 								/* descriptor  */
 #define XDC_DMASR_SG_BUSY_MASK		0x08000000UL	/* scatter gather is busy */
 
+#define XDC_DMACR_RX_CS_RAW_MASK     0xFFFF0000UL /**< RAW CS value for RX data */
+/* @} */
+
+/** @name DMA destination address register bit fields when checksum offload is
+ * used
+ *
+ * the following constants provide access to the bit fields of the
+ * Destination Address Register (DAREG)
+ * @{
+ */
+#define XDC_DAREG_CS_BEGIN_MASK      0xFFFF0000UL /**< byte position to begin
+						     checksum calculation*/
+#define XDC_DAREG_CS_INSERT_MASK     0x0000FFFFUL /**< byte position to place
+						     calculated checksum */
 /* the following constants provide access to the bit fields of the interrupt
  * status register (ISR) and the interrupt enable register (IER), bit masks
  * match for both registers such that they are named IXR
Index: drivers/net/xilinx_enet/adapter.c
===================================================================
RCS file: /var/cvs/uClinux-2.4.x/drivers/net/xilinx_enet/adapter.c,v
retrieving revision 1.17
diff -u -b -B -w -p -r1.17 adapter.c
--- drivers/net/xilinx_enet/adapter.c	21 Feb 2006 09:35:14 -0000	1.17
+++ drivers/net/xilinx_enet/adapter.c	23 Jun 2006 00:47:04 -0000
@@ -38,15 +38,26 @@
 #include <asm/atomic.h>
 #include <asm/pgalloc.h>
 #include <linux/ethtool.h>
-
+#include <asm/checksum.h>
 #include <xbasic_types.h>
 #include "xemac.h"
 #include "xemac_i.h"
 #include "xipif_v1_23_b.h"
 
+/*
+ * Add a delay (in ms) after resetting the EMAC since it
+ * also resets the PHY - which needs a delay before using it. - RPM
+ */
+#define RESET_DELAY 1500
+#ifdef RESET_DELAY
+#   include <linux/delay.h>
+#endif
+
+
 #undef XEM_DFT_SEND_DESC
-#define XEM_DFT_SEND_DESC    64
+#define XEM_DFT_SEND_DESC	256 
 #undef XEM_DFT_RECV_DESC
+#define DFT_LOCAL_SEND_DESC	64
 #define XEM_DFT_RECV_DESC   256
 
 #define DRIVER_NAME "Xilinx Eth MAC driver"
@@ -105,6 +116,25 @@ static struct ethernet_desc ether_table[
 #ifdef CONFIG_XILINX_ETHERNET_7_INSTANCE
 	#error Edit this file to add more devices.
 #endif
+#ifdef CONFIG_XILINX_ETHERNET_3_INSTANCE
+	{CONFIG_XILINX_ETHERNET_3_BASEADDR, CONFIG_XILINX_ETHERNET_3_IRQ,
+		CONFIG_XILINX_ETHERNET_3_MACADDR },
+#endif
+#ifdef CONFIG_XILINX_ETHERNET_4_INSTANCE
+	{CONFIG_XILINX_ETHERNET_4_BASEADDR, CONFIG_XILINX_ETHERNET_4_IRQ,
+		CONFIG_XILINX_ETHERNET_4_MACADDR },
+#endif
+#ifdef CONFIG_XILINX_ETHERNET_5_INSTANCE
+	{CONFIG_XILINX_ETHERNET_5_BASEADDR, CONFIG_XILINX_ETHERNET_5_IRQ,
+		CONFIG_XILINX_ETHERNET_5_MACADDR },
+#endif
+#ifdef CONFIG_XILINX_ETHERNET_6_INSTANCE
+	{CONFIG_XILINX_ETHERNET_6_BASEADDR, CONFIG_XILINX_ETHERNET_6_IRQ,
+		CONFIG_XILINX_ETHERNET_6_MACADDR },
+#endif
+#ifdef CONFIG_XILINX_ETHERNET_7_INSTANCE
+#error Edit this file to add more devices.
+#endif
 };
 
 static int num_ether_devices = sizeof(ether_table)/sizeof(struct ethernet_desc);
@@ -114,9 +144,15 @@ static int num_ether_devices = sizeof(et
  * For simplicity, we always align to 8 bytes.
  */
 #define ALIGNMENT         8
+#define ENET_HDR_SIZ	14
+#define ETHERTYPE_IP	0x0800  /* IP protocol */
+
+#define RX_PSEUDO_HEADER_DATA_START	12
+#define RX_PSEUDO_HEADER_DATA_END	18
 
 /* BUFFER_ALIGN(adr) calculates the number of bytes to the next alignment. */
 #define BUFFER_ALIGN(adr) ((ALIGNMENT - ((u32) adr)) % ALIGNMENT)
+#define BUFFER_ALIGN_HALF_WORD(adr) (((ALIGNMENT - ((u32) adr)) % ALIGNMENT) + 2)
 
 /* physical to virtual pointer conversion */
 #define P_TO_V(InstancePtr, p) \
@@ -310,6 +346,10 @@ reset(struct net_device *dev, DUPLEX dup
 
 	XEmac_Reset(&lp->Emac);
 
+#ifdef RESET_DELAY
+	mdelay(RESET_DELAY);
+#endif
+
 	/*
 	 * The following three functions will return an error if the
 	 * EMAC is already started.  We just stopped it by calling
@@ -381,6 +421,67 @@ reset(struct net_device *dev, DUPLEX dup
 		netif_wake_queue(dev);
 }
 
+/******************************************************************************
+ *
+ * FUNCTION:
+ *
+ * AddCsumRxPseudoHeader
+ *
+ * DESCRIPTION:
+ *
+ * Calculate the Pseudo header checksum of the provided IP packet
+ *
+ * ARGUMENTS:
+ *
+ * skb is the buffer containing the received packet. The entire packet is
+ * within this skb.
+ *
+ * Initial Checksum - Checksum to start with, InitCSum
+ *
+ * Length of the Data, IpPayloadLen
+ *
+ * ProtoTTL is the data from the IP header containing the Time To Live (TTL)
+ *	  and the protocol type, 6 = TCP and 16 = UDP
+ *
+ *
+ * RETURN VALUE:
+ *
+ * Completed checksum or 0 if not an IP/TCP or IP/UDP packet
+ *
+ ******************************************************************************/
+inline static u16 AddCsumRxPseudoHeader(struct sk_buff *skb, u16 InitCSum,
+					u16 IpPayloadLen, u16 ProtoTTL)
+{
+	register u32 Csum;
+	int i;
+
+	Csum = InitCSum;
+
+	/*
+	 * Add in the pseudoheader source address and destination address info
+	 */
+
+	for (i = RX_PSEUDO_HEADER_DATA_START;
+		i <= RX_PSEUDO_HEADER_DATA_END;
+		i = i + 2)
+	{
+		Csum += (u32)(*(u16*)(skb->data + i));
+	}
+
+	Csum += (u32)(ProtoTTL & 0x00FF);
+
+	/* Add in the length of the TCP/UDP data payload */
+	Csum += (u32)(IpPayloadLen);
+
+
+	/* Handle the carries */
+	Csum += (( Csum & 0xFFFF0000) >> 16);
+
+	return (Csum);
+}
+
+
+
 static int
 get_phy_status(struct net_device *dev, DUPLEX * duplex, int *linkup)
 {
@@ -753,7 +855,6 @@ FifoSendHandler(void *CallbackRef)
    double copying to me.  Might be more efficient to do the DMA xfer from 
    the incoming sk_buff, and just wait till the transfer completes...
    If we implement that optimisation, must beware alignment of skb->data,
-   
 */
 static int
 xenet_SgSend(struct sk_buff *skb, struct net_device *dev)
@@ -769,12 +870,15 @@ xenet_SgSend(struct sk_buff *skb, struct
         len = skb->len;
         virtAddr = lp->ddrVirtPtr + lp->ddrOffset;
 
-        if (skb->ip_summed == CHECKSUM_NONE)
+	if (skb->ip_summed == CHECKSUM_NONE) {
           /*cacheable_*/memcpy(virtAddr, skb->data, len);
-        else
+	}
+	else {
           skb_copy_and_csum_dev(skb, virtAddr);
+	}
         
         dev_kfree_skb(skb);
+
 #if 1
 	/* 
 	 * Microblaze requires no bus mapping, just do 
@@ -831,6 +935,230 @@ xenet_SgSend(struct sk_buff *skb, struct
 	return 0;
 }
 
+
+
+/*
+ * The send function for frames sent in DMA mode using DRE and
+ * Checksum offload in the DMA.
+ */
+
+static XBufDescriptor bd[10];
+
+static int
+xenet_SgSendDre(struct sk_buff *skb, struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *) dev->priv;
+	unsigned int len;
+	int result;
+	u32 physAddr;
+	u8 *virtAddr;
+	u32 i, flags;
+	u16 csum_insert_offset;
+	u16 PhCSum, IpDataLen, IpHeaderLength, ProtoTTL;
+	volatile u32 num_frag;
+	skb_frag_t *frag;
+	XBufDescriptor *prev_p, *cur_p;
+
+	virtAddr = lp->ddrVirtPtr + lp->ddrOffset;
+
+	num_frag = skb_shinfo(skb)->nr_frags;
+	frag = &skb_shinfo(skb)->frags[0];
+ 
+	cur_p = &bd[0];
+	prev_p = 0;
+ 
+	if (num_frag > 9) {
+		printk("num_frag:%8.8x \n", num_frag);
+	} 
+
+	/*
+	 * Return to the default configuration for the driver
+	 */
+	XEmac_mDisableTxHwCsum(&lp->Emac);
+
+	/*
+	 * Queue up the buffer descriptors only if there is space in the ring for this
+	 * batch with extra room. The netif_stop_queue will not occur until after the
+	 * next call to this function, therefore I need to leave enough for at least
+	 * one more call in the descriptor ring.
+	 */
+	if ((lp->availSendBds.counter) < (num_frag+4)) {
+		netif_stop_queue(dev);
+	}
+
+	for (i=0;i<(num_frag+1); ++i) {
+		/*
+		 * Initialize the buffer desctiptor and then
+		 * lock the buffer descriptor to prevent lower layers from reusing
+		 * it before the adapter has a chance to deallocate the buffer
+		 * attached to it. The adapter will unlock it in the callback function
+		 * that handles confirmation of transmits
+		 */
+		XBufDescriptor_Initialize(cur_p);
+		XBufDescriptor_Lock(cur_p);
+
+		if (prev_p) {
+			XBufDescriptor_SetNextPtr(prev_p, cur_p);
+		}
+
+		if (i==0) {
+
+
+			/*
+			 * Set the ID for the first descriptor to be the
+			 * address of the skbuffer to be freed in the BH
+			 */
+			XBufDescriptor_SetId(cur_p, skb);
+
+			/* Grab protocol */
+			ProtoTTL = (*(u16*)(skb->data + 22));
+
+			/*
+			 * The 2.4 kernel does not send frames down with CHECKSUM_HW
+			 * set unless they are TCP, UDP is always CHECKSUM_NONE due
+			 * to the TCP_SENDFILE test requirement
+			 */
+			if ((XEmac_mIsTxHwCsum(&lp->Emac)) && ((ProtoTTL & 0x00FF) == 6)) {
+				if (skb->ip_summed == CHECKSUM_HW) {
+					XEmac_mEnableTxHwCsum(&lp->Emac);
+
+					len = skb_headlen(skb);
+
+					/*
+					 * Determine the length of the IP header which is used
+					 * for the offset into the data for the protocol field.
+					 */
+
+					IpHeaderLength =
+						((((*(u16*)(skb->data + 14)) & 0x0F00) >> 8) * 4);
+
+					/*
+					 * Determine the proper offset for the insert
+					 * TCP offset is 16, UDP offset is 6 but the
+					 * 2.4 stack does not use this for UDP
+					 */
+					csum_insert_offset = IpHeaderLength + 16 + ENET_HDR_SIZ;
+
+					/*
+					 * 0 works for the TCP TX checksum offload initial value
+					 */
+					XBufDescriptor_SetCSInit(cur_p, 0);
+					XBufDescriptor_SetCSInsertLoc(cur_p, csum_insert_offset);
+					XBufDescriptor_SetCSBegin(cur_p, IpHeaderLength + ENET_HDR_SIZ);
+
+					virtAddr = skb->data;
+
+				}
+				else {
+					/*
+					 * Has checksum offload but ip_summed == CHECKSUM_NONE TCP only
+					 */
+					virtAddr = skb->data;
+					len = skb_headlen(skb);
+				}
+
+				XBufDescriptor_SetLength(cur_p, len);
+
+#if 1
+				/* 
+				 * Microblaze requires no bus mapping, just do 
+				 * a (dummy) virt to phys conversion.
+				 */
+				physAddr = virt_to_phys(virtAddr);
+#else
+				physAddr = (u32) pci_map_single(NULL, virtAddr, len, PCI_DMA_TODEVICE);
+#endif
+				XBufDescriptor_SetSrcAddress(cur_p, physAddr);
+
+			}
+			else {
+				/*
+				 * First fragment, no hardware checksum offload or is it not TCP
+				 */
+				virtAddr = skb->data;
+				len = skb_headlen(skb);
+
+				XBufDescriptor_SetLength(cur_p, len);
+
+#if 1
+				/* 
+				 * Microblaze requires no bus mapping, just do 
+				 * a (dummy) virt to phys conversion.
+				 */
+				physAddr = virt_to_phys(virtAddr);
+#else
+				physAddr = (u32) pci_map_single(NULL, virtAddr, len, PCI_DMA_TODEVICE);
+#endif
+				XBufDescriptor_SetSrcAddress(cur_p, physAddr);
+
+			}
+		}
+		else {
+			/*
+			 * Fragment is not number 0
+			 */
+			virtAddr = ((void *) page_address(frag->page) +
+					frag->page_offset);
+#if 1
+			/* 
+			 * Microblaze requires no bus mapping, just do 
+			 * a (dummy) virt to phys conversion.
+			 */
+			physAddr = virt_to_phys(virtAddr);
+#else
+			physAddr = (u32) pci_map_single(NULL, virtAddr, len, PCI_DMA_TODEVICE);
+#endif
+			XBufDescriptor_SetSrcAddress(cur_p, physAddr);
+			XBufDescriptor_SetCSInit(cur_p, 0);
+
+			XBufDescriptor_SetCSInsertLoc(cur_p, csum_insert_offset);
+			XBufDescriptor_SetCSBegin(cur_p, IpHeaderLength + ENET_HDR_SIZ);
+
+
+			len = frag->size;
+			XBufDescriptor_SetLength(cur_p, len);
+
+			frag++;
+		}
+
+		if (i == num_frag) {
+			/*
+			 * This is the last descriptor in the chain
+			 */
+			XBufDescriptor_SetLast(cur_p);
+		}
+		prev_p = cur_p;
+		cur_p++;
+	}
+
+	spin_lock_irqsave(reset_lock, flags);
+	for (i=0;i<(num_frag+1); ++i) {
+
+		result = XEmac_SgSend(&lp->Emac, &bd[i], XEM_SGDMA_NODELAY);
+		if (result != XST_SUCCESS) {
+			lp->stats.tx_dropped++;
+			printk(/*KERN_ERR */"%s: ERROR, could not send transmit buffer (%d).\n",
+				dev->name, result);
+			/* we should never get here in the first place, but
+			 * for some reason the kernel doesn't like -EBUSY here,
+			 * so just return 0 and let the stack handle dropped packets.
+			 */
+			spin_unlock_irqrestore(reset_lock, flags);
+			return 0;
+		}
+
+	}
+
+	if ((atomic_sub_return((num_frag+1),&lp->availSendBds)) == 0) {
+		netif_stop_queue(dev);
+	}
+
+	spin_unlock_irqrestore(reset_lock, flags);
+	dev->trans_start = jiffies;
+
+	return 0;
+}
+
 /* The callback function for completed frames sent in DMA mode. */
 static void SgSendHandlerBH (unsigned long p);
 static void SgRecvHandlerBH (unsigned long p);
@@ -848,6 +1176,7 @@ SgSendHandlerBH (unsigned long p)
 	u32 len;
 	XBufDescriptor *curbd;
 	unsigned long flags;
+	struct sk_buff *skb;
 
 	while (1) {
 		spin_lock_irqsave(xmitSpin,flags);
@@ -858,7 +1187,6 @@ SgSendHandlerBH (unsigned long p)
 		lp = list_entry(sentQueue.next, struct net_local, xmit);
 		list_del_init(&(lp->xmit));
 		NumBds = lp->xmitBds;
-		bh_entry--;
 		BdPtr = lp->xmitBdPtr;
 		dev = lp->dev;
 		atomic_add(NumBds, &lp->availSendBds);
@@ -880,10 +1208,21 @@ SgSendHandlerBH (unsigned long p)
 			BdPtr = P_TO_V(&lp->Emac.SendChannel,
 				XBufDescriptor_GetNextPtr(BdPtr));
 			XBufDescriptor_Unlock(curbd);
+
+			/*
+			 * If the descriptor was part of a fragment list, the ID is
+			 * the skbuffer which can be freed at this point
+			 */
+			skb = XBufDescriptor_GetId(curbd);
+			if (skb != 0UL) {
+				dev_kfree_skb(skb);
+			}
+
 		}
 		spin_unlock_irqrestore(xmitSpin,flags);
 		netif_wake_queue(dev);
 	}
+	bh_entry = 0;
 }
 
 static void
@@ -924,6 +1263,11 @@ SgRecvHandlerBH (unsigned long p)
 	XStatus result;
 	XBufDescriptor *curbd;
 	unsigned long flags;
+	u16 HwCSum, PhCSum;
+	u16 IpDataLen, IpHeaderLength, ProtoTTL;
+	u32 CalcCSum;
+	u32 EmacFCS;
+	u8 *EmacFCSPtr;
 
 	while (1) {
 		spin_lock_irqsave(rcvSpin,flags);
@@ -944,8 +1288,16 @@ SgRecvHandlerBH (unsigned long p)
 			skb = (struct sk_buff *) XBufDescriptor_GetId(BdPtr);
 			len = XBufDescriptor_GetLength(BdPtr);
 
+			/*
+			 * Retrieve hardware Checksum regardless, check later if
+			 * valid to use
+			 */
+
+			HwCSum = XBufDescriptor_GetCSRaw(BdPtr);
+
+
 			/* Flush the cache */
-			flush_dcache_range((unsigned)skb,(unsigned)skb+len);
+			flush_dcache_range((unsigned)(skb->data),(unsigned)(skb->data+len));
 
 			/* we have all the information we need - move on */
 			curbd = BdPtr;
@@ -964,8 +1316,15 @@ SgRecvHandlerBH (unsigned long p)
 				return;
 			}
 
+			if (!(XEmac_mIsRxDre(&lp->Emac)))
+			{
 			/* make sure we're long-word aligned */
 			align = BUFFER_ALIGN(new_skb->data);
+			} else {
+				/* MicroBlaze can't do unaligned accesses. 
+				   By starting the skb->data at half-word, IP data becomes word aligned */
+				align = BUFFER_ALIGN_HALF_WORD(new_skb->data);
+			}
 			if (align) {
 				skb_reserve(new_skb, align);
 			}
@@ -996,7 +1355,10 @@ SgRecvHandlerBH (unsigned long p)
 			/* back to the original skb */
 			skb->len = len;
 			skb->dev = dev;
+			skb->protocol = eth_type_trans(skb, dev);
+			skb->ip_summed = CHECKSUM_NONE;
 
+			if (!(XEmac_mIsRxDre(&lp->Emac))) {
 			/* Adjust alignment of ethernet frame to be half-word
 			   so that tcp/ip header will be full-word aligned */
 			memmove(skb->head+2, skb->data, skb->len); 
@@ -1004,13 +1366,87 @@ SgRecvHandlerBH (unsigned long p)
 			/* Fix up skbuff ptrs */
 			skb->tail -= (skb->data-(skb->head+2));
 			skb->data=skb->head+2;
-
-			skb->protocol = eth_type_trans(skb, dev);
-			skb->ip_summed = CHECKSUM_NONE;
+			}
 
 			lp->stats.rx_packets++;
 			lp->stats.rx_bytes += len;
 
+			/*
+			 * Check if Checksum offload in in the hardware, if so
+			 * verify the checksum here and then sent up the stack
+			 */
+			if ((len > 76 /*64*/) && (skb->protocol == ETHERTYPE_IP) && (XEmac_mIsRxHwCsum(&lp->Emac))) {
+
+				EmacFCS = 0;
+				EmacFCSPtr = (u8 *)&EmacFCS;
+
+				IpHeaderLength = ((((*(u16*)(skb->data)) & 0x0F00) >> 8) * 4);
+
+				/* Grab protocol */
+				ProtoTTL = (*(u16*)(skb->data + 8)) & 0x00FF;
+
+				/*
+				 * Set the length of the IP payload for the CS calculation
+				 */
+				IpDataLen = len - IpHeaderLength - ENET_HDR_SIZ;
+
+				/*
+				 * Adjust the hardware checksum due to the fact that it ALWAYS includes
+				 * the FCS field in the RX data, regardless of whether the.
+				 * XEM_STRIP_PAD_FCS_OPTION is set or not set around 2400.
+				 */
+
+				CalcCSum = HwCSum;
+
+				if (((IpDataLen & 0x0003) == 2) || ((IpDataLen & 0x0003) == 0)) {
+					/*
+					 * 16-bit alignment case
+					 */
+					EmacFCSPtr[0] = (*(u8*)(skb->mac.raw + len - 4));
+					EmacFCSPtr[1] = (*(u8*)(skb->mac.raw + len - 3));
+					EmacFCSPtr[2] = (*(u8*)(skb->mac.raw + len - 2));
+					EmacFCSPtr[3] = (*(u8*)(skb->mac.raw + len - 1));
+				}
+				else if ((IpDataLen & 0x0003) == 1) {
+					/*
+					 * 8-bit alignment case one
+					 */
+					EmacFCSPtr[0] = (*(u8*)(skb->mac.raw + len - 3));
+					EmacFCSPtr[1] = (*(u8*)(skb->mac.raw + len - 2));
+					EmacFCSPtr[2] = (*(u8*)(skb->mac.raw + len - 1));
+					EmacFCSPtr[3] = (*(u8*)(skb->mac.raw + len - 4));
+				}
+				else if ((IpDataLen & 0x0003) == 3) {
+					/*
+					 * 8-bit alignment case two
+					 */
+					EmacFCSPtr[0] = (*(u8*)(skb->mac.raw + len - 1));
+					EmacFCSPtr[1] = (*(u8*)(skb->mac.raw + len - 4));
+					EmacFCSPtr[2] = (*(u8*)(skb->mac.raw + len - 3));
+					EmacFCSPtr[3] = (*(u8*)(skb->mac.raw + len - 2));
+				}
+
+				CalcCSum += (u32) ((*(u16*)(&(EmacFCSPtr[0]))) ^ 0xFFFF);
+				CalcCSum += (u32) ((*(u16*)(&(EmacFCSPtr[2]))) ^ 0xFFFF);
+				CalcCSum += (u32) (0xFFFB); /* this is the subtraction of 4, trust me */
+
+				HwCSum = ((CalcCSum >> 16) + (CalcCSum & 0x0000FFFF));
+
+				PhCSum = AddCsumRxPseudoHeader(skb, HwCSum, IpDataLen, ProtoTTL);
+
+				/*
+				 * The resulting checksum should be equal to 0xFFFF. If not, the upper
+				 * layers can calculate where the error is and retransmit if needed.
+				 */
+
+				if (PhCSum == 0xFFFF) {
+
+					skb->ip_summed = CHECKSUM_UNNECESSARY;
+					skb->len -= 4;
+					skb->csum = 0xFFFF;
+				}
+			}
+
 			netif_rx(skb);          /* Send the packet upstream. */
 		}
 	}
@@ -1185,14 +1621,19 @@ descriptor_init(struct net_device *dev)
 	}
 	lp->desc_space_size = dftsize;
 
-        lp->ddrSize = XEM_DFT_SEND_DESC * (XEM_MAX_FRAME_SIZE + ALIGNMENT);
+	lp->ddrSize = DFT_LOCAL_SEND_DESC * (XEM_MAX_FRAME_SIZE + ALIGNMENT);
         lp->ddrOffset = 0;
         lp->ddrVirtPtr = kmalloc(lp->ddrSize, GFP_ATOMIC);
         
         if (lp->ddrVirtPtr == 0)
           return -1;
 
+	if (XEmac_mIsTxDre(&lp->Emac)){
         atomic_set(&lp->availSendBds, XEM_DFT_SEND_DESC);
+	}
+	else {
+		atomic_set(&lp->availSendBds, DFT_LOCAL_SEND_DESC);
+	}
 
 	/* calc size of send and recv descriptor space */
 	recvsize = XEM_DFT_RECV_DESC * sizeof (XBufDescriptor);
@@ -1220,7 +1661,11 @@ descriptor_init(struct net_device *dev)
 			return -1;
 		}
 
+		if (!(XEmac_mIsRxDre(&lp->Emac))) {
 		align = BUFFER_ALIGN(skb->data);
+		} else {
+			align = BUFFER_ALIGN_HALF_WORD(skb->data);
+		}
 		if (align)
 			skb_reserve(skb, align);
 
@@ -1277,6 +1722,92 @@ free_descriptor_skb (struct net_device *
 	}
 }
 
+static void
+xenet_set_multicast_list(struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *) dev->priv;
+	u32 Options;
+	int ret = 0;
+	unsigned long flags;
+	static int was_promisc=-1L;
+
+	/*
+	 * XEmac_Start, XEmac_Stop and XEmac_SetOptions are supposed to
+	 * be protected by a semaphore. We do have one area in which
+	 * this is a problem.
+	 *
+	 * xenet_set_multicast_list() is called while the link is up and
+	 * interrupts are enabled, so at any point in time we could get
+	 * an error that causes our reset() to be called.  reset() calls
+	 * the aforementioned functions, and we need to call them from
+	 * here as well.
+	 *
+	 * The solution is to make sure that we don't get interrupts or
+	 * timers popping while we are in this function.
+	 */
+	spin_lock_irqsave(reset_lock, flags);
+
+	if ((ret = XEmac_Stop(&lp->Emac)) == XST_SUCCESS) {
+
+		Options = XEmac_GetOptions(&lp->Emac);
+
+		/* See if PROMISC has changed. Only output message if status changes */ 
+		if(was_promisc!=(dev->flags & IFF_PROMISC)) 
+		{ 
+			printk(KERN_NOTICE "%s: Promiscuous mode %s.\n", 
+				dev->name,  
+				(dev->flags & IFF_PROMISC) ? "enabled" : "disabled"); 
+		} 
+		was_promisc=(dev->flags & IFF_PROMISC); 
+
+		/* Clear out the bits we may set. */
+		Options &= ~(XEM_PROMISC_OPTION | XEM_MULTICAST_OPTION);
+
+		if (dev->flags & IFF_PROMISC)
+			Options |= XEM_PROMISC_OPTION;
+#if 0
+		else {
+			/*
+			 * SAATODO: Xilinx is going to add multicast support to their
+			 * VxWorks adapter and OS independent layer.  After that is
+			 * done, this skeleton code should be fleshed out.  Note that
+			 * IFF_MULTICAST is being masked out from dev->flags in probe,
+			 * so that will need to be removed to actually do multidrop.
+			 */
+			if ((dev->flags & IFF_ALLMULTI)
+			    || dev->mc_count > MAX_MULTICAST ? ? ?) {
+				xemac_get_all_multicast ? ? ? ();
+				Options |= XEM_MULTICAST_OPTION;
+			} else if (dev->mc_count != 0) {
+				struct dev_mc_list *mc;
+
+				XEmac_MulticastClear(&lp->Emac);
+				for (mc = dev->mc_list; mc; mc = mc->next)
+					XEmac_MulticastAdd(&lp->Emac, mc->dmi_addr);
+				Options |= XEM_MULTICAST_OPTION;
+			}
+		}
+#endif
+
+		/*
+		 * The following function will return an error if the EMAC is already
+		 * started.  We know it isn't started so we can safely ignore the
+		 * return value.  We cast it to void to make that explicit.
+		 */
+		(void) XEmac_SetOptions(&lp->Emac, Options);
+
+		/*
+		 * XEmac_Start returns an error when: it is already started, the send
+		 * and receive handlers are not set, or a scatter-gather DMA list is
+		 * missing.  None of these can happen at this point, so we cast the
+		 * return to void to make that explicit.
+		 */
+		(void) XEmac_Start(&lp->Emac);
+	}
+	/* All done, get those interrupts and timers going again. */
+	spin_unlock_irqrestore(reset_lock, flags);
+}
+
 static int
 xenet_ethtool_get_settings (struct net_device *dev, struct ethtool_cmd* ecmd)
 {
@@ -1701,6 +2232,14 @@ static int __init xilinx_emac_hw_addr_se
 	int count;
 	static int interface=0;
 
+	/* Don't accept too many addresses */
+	if (interface >= num_ether_devices) {
+		printk(KERN_WARNING
+			"There are only %d Xilinx ethernet devices; MAC address will be ignored.\n",
+			num_ether_devices);
+		return 0;
+	}
+
 	/* Scan the kernel param for HW MAC address */
 	count=sscanf(addrs, "%2x:%2x:%2x:%2x:%2x:%2x",hw_addr+0, hw_addr+1,
 						 hw_addr+2, hw_addr+3,
@@ -1747,7 +2285,6 @@ xenet_ioctl(struct net_device *dev, stru
 		return xenet_do_ethtool_ioctl(dev, rq);
 
         case SIOCSIFHWADDR:
-            {
             	printk(KERN_INFO "%s: SIOCSIFHWADDR\n", dev->name);
 
 		/* Copy MAC address in from user space*/
@@ -1761,8 +2298,6 @@ xenet_ioctl(struct net_device *dev, stru
 			return -EIO;
 		}
 	    	break;
-	    }
-
 	case SIOCGMIIPHY:	/* Get address of MII PHY in use. */
 	case SIOCDEVPRIVATE:	/* for binary compat, remove in 2.5 */
 		data->phy_id = lp->mii_addr;
@@ -1926,6 +2461,7 @@ probe(int index)
 	XEmac_Config *cfg;
 	unsigned int irq;
 	u32 maddr;
+	u32 Options;
 
 	if(index>=num_ether_devices)
 		return -ENODEV;
@@ -1971,6 +2507,15 @@ probe(int index)
 		return -ENODEV;
 	}
 
+#ifdef RESET_DELAY
+	mdelay(RESET_DELAY);
+#endif
+
+	/* Disable auto-insertion of the Ethernet source address */ 
+	Options = XEmac_GetOptions(&lp->Emac); 
+	Options &= ~(XEM_INSERT_ADDR_OPTION | XEM_OVWRT_ADDR_OPTION); 
+	(void) XEmac_SetOptions(&lp->Emac, Options);           
+
 	/* Copy MAC address in from descriptor table */
         memcpy(dev->dev_addr, ether_table[index].macaddr,6);
 
@@ -1987,7 +2532,35 @@ probe(int index)
 		printk(KERN_ERR "%s: using sgDMA mode.\n", dev->name);
 		XEmac_SetSgRecvHandler(&lp->Emac, dev, SgRecvHandler);
 		XEmac_SetSgSendHandler(&lp->Emac, dev, SgSendHandler);
+		if (XEmac_mIsTxDre(&lp->Emac))
+		{
+			printk(KERN_ERR "%s: TX DRE Mode enabled.\n", dev->name);
+			dev->hard_start_xmit =  xenet_SgSendDre;
+		}
+		else
+		{
 		dev->hard_start_xmit = xenet_SgSend;
+			if (XEmac_mIsTxHwCsum(&lp->Emac))
+			{
+				printk(KERN_ERR "%s: HW CONFIGURATION ERROR, Checksum offload without TX DRE!!!!!!.\n", dev->name);
+			}
+		}
+		
+		if (XEmac_mIsRxDre(&lp->Emac))
+		{
+			printk(KERN_ERR "%s: RX DRE Mode enabled.\n", dev->name);
+		}
+		
+		if (XEmac_mIsTxHwCsum(&lp->Emac))
+		{
+			printk(KERN_ERR "%s: TX Checksum offload Mode enabled.\n", dev->name);
+		}
+		
+		if (XEmac_mIsRxHwCsum(&lp->Emac))
+		{
+			printk(KERN_ERR "%s: RX Checksum offload Mode enabled.\n", dev->name);
+		}
+		
 		lp->Isr = XEmac_IntrHandlerDma;
 
 		result = descriptor_init(dev);
@@ -2002,9 +2575,10 @@ probe(int index)
                 (void) XEmac_SetPktWaitBound(&lp->Emac, XEM_SEND, 5);
                 (void) XEmac_SetPktWaitBound(&lp->Emac, XEM_RECV, 5);
 
-                /* disable SGEND interrupt */
+		/* disable SGEND interrupt and enable stripping of FCS and PAD*/
                 XEmac_SetOptions(&lp->Emac, XEmac_GetOptions(&lp->Emac) |
-                                 XEM_NO_SGEND_INT_OPTION);
+				(XEM_NO_SGEND_INT_OPTION /* | XEM_STRIP_PAD_FCS_OPTION */));
+
 	} else {
 		printk(KERN_ERR "%s: using fifo mode.\n", dev->name);
 		XEmac_SetFifoRecvHandler(&lp->Emac, dev, FifoRecvHandler);
@@ -2049,11 +2623,17 @@ probe(int index)
 	dev->stop = xenet_close;
 	dev->get_stats = xenet_get_stats;
 	dev->flags &= ~IFF_MULTICAST;
+	dev->set_multicast_list = xenet_set_multicast_list;
 	dev->do_ioctl = xenet_ioctl;
 	dev->tx_timeout = xenet_tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
 
-        dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HW_CSUM;
+	dev->features = NETIF_F_SG | NETIF_F_FRAGLIST /*| NETIF_F_HW_CSUM*/;
+
+	if ((XEmac_mIsTxHwCsum(&lp->Emac)) && (XEmac_mIsTxDre(&lp->Emac)))
+	{
+		dev->features |= NETIF_F_IP_CSUM;	/* added ecm 051129 */
+	}
 
 	printk(KERN_INFO
 	       "%s: Xilinx EMAC #%d at 0x%08X mapped to 0x%08X, irq=%d\n",
Index: drivers/net/xilinx_enet/xemac.c
===================================================================
RCS file: /var/cvs/uClinux-2.4.x/drivers/net/xilinx_enet/xemac.c,v
retrieving revision 1.4
diff -u -b -B -w -p -r1.4 xemac.c
--- drivers/net/xilinx_enet/xemac.c	15 Feb 2005 05:30:22 -0000	1.4
+++ drivers/net/xilinx_enet/xemac.c	23 Jun 2006 00:47:06 -0000
@@ -1,41 +1,23 @@
-/* $Id: xemac.c,v 1.1 2004/04/06 16:49:36 robertm Exp $ */
+/* $Id: xemac.c,v 1.1 2005/10/26 15:44:52 meinelte Exp $ */
 /******************************************************************************
 *
-*     Author: Xilinx, Inc.
+ *       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+ *       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+ *       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+ *       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+ *       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+ *       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+ *       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+ *       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+ *       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+ *       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+ *       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+ *       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ *       FOR A PARTICULAR PURPOSE.
 *     
-*     
-*     This program is free software; you can redistribute it and/or modify it
-*     under the terms of the GNU General Public License as published by the
-*     Free Software Foundation; either version 2 of the License, or (at your
-*     option) any later version.
-*     
-*     
-*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
-*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
-*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
-*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
-*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
-*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
-*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
-*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
-*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
-*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
-*     FITNESS FOR A PARTICULAR PURPOSE.
-*     
-*     
-*     Xilinx hardware products are not intended for use in life support
-*     appliances, devices, or systems. Use in such applications is
-*     expressly prohibited.
-*     
-*     
-*     (c) Copyright 2002-2004 Xilinx Inc.
+ *       (c) Copyright 2003 Xilinx Inc.
 *     All rights reserved.
 *     
-*     
-*     You should have received a copy of the GNU General Public License along
-*     with this program; if not, write to the Free Software Foundation, Inc.,
-*     675 Mass Ave, Cambridge, MA 02139, USA.
-*
 ******************************************************************************/
 /*****************************************************************************/
 /**
@@ -66,6 +48,8 @@
 *                     the packet fifo driver.
 * 1.00e rmm  04/06/04 Changed XEmac_Initialize() to clear the instance data.
 *                     Added XEM_NO_SGEND_INT_OPTION processing to XEmac_Start().
+ * 1.01a ecm  09/26/05 Changed XEmac_Initialize() to  create instance variable
+ *                     which has the default DMA control words for the hardware.
 * </pre>
 ******************************************************************************/
 
@@ -74,6 +58,7 @@
 #include "xbasic_types.h"
 #include "xemac_i.h"
 #include "xio.h"
+#include "xbuf_descriptor.h"
 #include "xipif_v1_23_b.h"	/* Uses v1.23b of the IPIF */
 
 /************************** Constant Definitions *****************************/
@@ -123,8 +112,7 @@ static void StubSgHandler(void *CallBack
 * None.
 *
 ******************************************************************************/
-XStatus
-XEmac_Initialize(XEmac * InstancePtr, u16 DeviceId)
+XStatus XEmac_Initialize(XEmac *InstancePtr, u16 DeviceId)
 {
 	XStatus Result;
 	XEmac_Config *ConfigPtr;	/* configuration information */
@@ -151,6 +140,11 @@ XEmac_Initialize(XEmac * InstancePtr, u1
 	InstancePtr->IpIfDmaConfig = ConfigPtr->IpIfDmaConfig;
 	InstancePtr->HasMii = ConfigPtr->HasMii;
 	InstancePtr->HasMulticastHash = FALSE;
+    InstancePtr->TxDre = ConfigPtr->TxDre;
+    InstancePtr->RxDre = ConfigPtr->RxDre;
+    InstancePtr->TxHwCsum = ConfigPtr->TxHwCsum;
+    InstancePtr->RxHwCsum = ConfigPtr->RxHwCsum;
+    InstancePtr->ConfigPtr = ConfigPtr;
 
 	/* Always default polled to false, let user configure this mode */
 	InstancePtr->IsPolled = FALSE;
@@ -161,7 +155,7 @@ XEmac_Initialize(XEmac * InstancePtr, u1
 	InstancePtr->SgSendHandler = StubSgHandler;
 
 	/*
-	 * Initialize the device register base addresses
+     * Save the baseaddress for faster access
 	 */
 	InstancePtr->BaseAddress = ConfigPtr->BaseAddress;
 	InstancePtr->PhysAddress = ConfigPtr->PhysAddress;
@@ -170,7 +164,8 @@ XEmac_Initialize(XEmac * InstancePtr, u1
 	 * Configure the send and receive FIFOs in the MAC
 	 */
 	Result = ConfigureFifo(InstancePtr);
-	if (Result != XST_SUCCESS) {
+    if (Result != XST_SUCCESS)
+    {
 		return Result;
 	}
 
@@ -178,11 +173,44 @@ XEmac_Initialize(XEmac * InstancePtr, u1
 	 * If the device is configured for DMA, configure the send and receive DMA
 	 * channels in the MAC.
 	 */
-	if (XEmac_mIsDma(InstancePtr)) {
+    if (XEmac_mIsDma(InstancePtr))
+    {
 		Result = ConfigureDma(InstancePtr);
-		if (Result != XST_SUCCESS) {
+        if (Result != XST_SUCCESS)
+        {
 			return Result;
 		}
+
+        if (XEmac_mIsTxDre(InstancePtr) == TRUE)
+        {
+            InstancePtr->TxDmaControlWord = XEM_DFT_SEND_BD_MASK |
+		XDC_DMACR_DRE_MODE_MASK;
+        }
+        else
+        {
+            InstancePtr->TxDmaControlWord = XEM_DFT_SEND_BD_MASK;
+        }
+
+        if (XEmac_mIsRxDre(InstancePtr) == TRUE)
+        {
+            InstancePtr->RxDmaControlWord = XEM_DFT_RECV_BD_MASK |
+		XDC_DMACR_DRE_MODE_MASK;
+        }
+        else
+        {
+            InstancePtr->RxDmaControlWord = XEM_DFT_RECV_BD_MASK;
+        }
+
+        /*
+         * TX Checksum offload is dynamic and needs to be set for every
+         * BD that uses it. It is not applicable to all data types so the
+         * adapter needs to handle each call individually
+         */
+
+        if (XEmac_mIsRxHwCsum(InstancePtr) == TRUE)
+        {
+            InstancePtr->RxDmaControlWord |= XDC_DMACR_CS_OFFLOAD_MASK;
+        }
 	}
 
 	/*
@@ -255,8 +283,7 @@ XEmac_Initialize(XEmac * InstancePtr, u1
 * provide protection of this shared data (typically using a semaphore).
 *
 ******************************************************************************/
-XStatus
-XEmac_Start(XEmac * InstancePtr)
+XStatus XEmac_Start(XEmac *InstancePtr)
 {
 	u32 ControlReg;
 	XStatus Result;
@@ -267,51 +294,55 @@ XEmac_Start(XEmac * InstancePtr)
 	/*
 	 * If it is already started, return a status indicating so
 	 */
-	if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+    if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED)
+    {
 		return XST_DEVICE_IS_STARTED;
 	}
 
 	/*
 	 * If not polled, enable interrupts
 	 */
-	if (!InstancePtr->IsPolled) {
+    if (!InstancePtr->IsPolled)
+    {
 		/*
 		 * Verify that the callbacks have been registered, then enable
 		 * interrupts
 		 */
-		if (XEmac_mIsSgDma(InstancePtr)) {
+        if (XEmac_mIsSgDma(InstancePtr))
+        {
 			if ((InstancePtr->SgRecvHandler == StubSgHandler) ||
-			    (InstancePtr->SgSendHandler == StubSgHandler)) {
+                (InstancePtr->SgSendHandler == StubSgHandler))
+            {
 				return XST_NO_CALLBACK;
 			}
 
 			/* Enable IPIF interrupts */
 			XIIF_V123B_WRITE_DIER(InstancePtr->BaseAddress,
-					      XEM_IPIF_DMA_DFT_MASK |
-					      XIIF_V123B_ERROR_MASK);
+				  XEM_IPIF_DMA_DFT_MASK | XIIF_V123B_ERROR_MASK);
 			XIIF_V123B_WRITE_IIER(InstancePtr->BaseAddress,
 					      XEM_EIR_DFT_SG_MASK);
 
 			/* Enable scatter-gather DMA interrupts */
 			ControlReg = XEM_DMA_SG_INTR_MASK;	/* Default mask */
-			if (InstancePtr->IsSgEndDisable) {
+            if (InstancePtr->IsSgEndDisable)
+            {
 				ControlReg &= ~XDC_IXR_SG_END_MASK;	/* Don't enable SGEND */
 			}
 
-			XDmaChannel_SetIntrEnable(&InstancePtr->RecvChannel,
-						  ControlReg);
-			XDmaChannel_SetIntrEnable(&InstancePtr->SendChannel,
-						  ControlReg);
-		} else {
+            XDmaChannel_SetIntrEnable(&InstancePtr->RecvChannel, ControlReg);
+            XDmaChannel_SetIntrEnable(&InstancePtr->SendChannel, ControlReg);
+        }
+        else
+        {
 			if ((InstancePtr->FifoRecvHandler == StubFifoHandler) ||
-			    (InstancePtr->FifoSendHandler == StubFifoHandler)) {
+                (InstancePtr->FifoSendHandler == StubFifoHandler))
+            {
 				return XST_NO_CALLBACK;
 			}
 
 			/* Enable IPIF interrupts (used by simple DMA also) */
 			XIIF_V123B_WRITE_DIER(InstancePtr->BaseAddress,
-					      XEM_IPIF_FIFO_DFT_MASK |
-					      XIIF_V123B_ERROR_MASK);
+				  XEM_IPIF_FIFO_DFT_MASK | XIIF_V123B_ERROR_MASK);
 			XIIF_V123B_WRITE_IIER(InstancePtr->BaseAddress,
 					      XEM_EIR_DFT_FIFO_MASK);
 		}
@@ -345,7 +376,8 @@ XEmac_Start(XEmac * InstancePtr)
 	 * The DMA SgStart function uses data that can be modified during interrupt
 	 * context, so a critical section is required here.
 	 */
-	if ((XEmac_mIsSgDma(InstancePtr)) && (!InstancePtr->IsPolled)) {
+    if ((XEmac_mIsSgDma(InstancePtr)) && (!InstancePtr->IsPolled))
+    {
 		XIIF_V123B_GINTR_DISABLE(InstancePtr->BaseAddress);
 
 		/*
@@ -354,14 +386,15 @@ XEmac_Start(XEmac * InstancePtr)
 		 * added yet (the list is empty). Other errors are benign at this point.
 		 */
 		Result = XDmaChannel_SgStart(&InstancePtr->RecvChannel);
-		if ((Result == XST_DMA_SG_NO_LIST)
-		    || (Result == XST_DMA_SG_LIST_EMPTY)) {
+        if ((Result == XST_DMA_SG_NO_LIST) || (Result == XST_DMA_SG_LIST_EMPTY))
+        {
 			XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
 			return Result;
 		}
 
 		Result = XDmaChannel_SgStart(&InstancePtr->SendChannel);
-		if (Result == XST_DMA_SG_NO_LIST) {
+        if (Result == XST_DMA_SG_NO_LIST)
+        {
 			XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
 			return Result;
 		}
@@ -409,8 +442,7 @@ XEmac_Start(XEmac * InstancePtr)
 * provide protection of this shared data (typically using a semaphore).
 *
 ******************************************************************************/
-XStatus
-XEmac_Stop(XEmac * InstancePtr)
+XStatus XEmac_Stop(XEmac *InstancePtr)
 {
 	u32 ControlReg;
 
@@ -421,7 +453,8 @@ XEmac_Stop(XEmac * InstancePtr)
 	 * If the device is already stopped, do nothing but return a status
 	 * indicating so
 	 */
-	if (InstancePtr->IsStarted != XCOMPONENT_IS_STARTED) {
+    if (InstancePtr->IsStarted != XCOMPONENT_IS_STARTED)
+    {
 		return XST_DEVICE_IS_STOPPED;
 	}
 
@@ -431,7 +464,8 @@ XEmac_Stop(XEmac * InstancePtr)
 	 * here between SgStart and SgStop, and SgStart can be called in interrupt
 	 * context, so disable interrupts while calling SgStop.
 	 */
-	if (XEmac_mIsSgDma(InstancePtr)) {
+    if (XEmac_mIsSgDma(InstancePtr))
+    {
 		XBufDescriptor *BdTemp;	/* temporary descriptor pointer */
 
 		XIIF_V123B_GINTR_DISABLE(InstancePtr->BaseAddress);
@@ -454,7 +488,8 @@ XEmac_Stop(XEmac * InstancePtr)
 	 * If not in polled mode, disable interrupts for IPIF (includes MAC and
 	 * DMAs)
 	 */
-	if (!InstancePtr->IsPolled) {
+    if (!InstancePtr->IsPolled)
+    {
 		XIIF_V123B_GINTR_DISABLE(InstancePtr->BaseAddress);
 	}
 
@@ -522,8 +557,7 @@ XEmac_Stop(XEmac * InstancePtr)
 * care of resetting all hardware blocks, including the MAC.
 *
 ******************************************************************************/
-void
-XEmac_Reset(XEmac * InstancePtr)
+void XEmac_Reset(XEmac *InstancePtr)
 {
 	XASSERT_VOID(InstancePtr != NULL);
 	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
@@ -546,7 +580,8 @@ XEmac_Reset(XEmac * InstancePtr)
 	 */
 	XIIF_V123B_RESET(InstancePtr->BaseAddress);
 
-	if (XEmac_mIsSgDma(InstancePtr)) {
+    if (XEmac_mIsSgDma(InstancePtr))
+    {
 		/*
 		 * After reset, configure the scatter-gather DMA packet threshold and
 		 * packet wait bound registers to default values. Ignore the return
@@ -583,8 +618,7 @@ XEmac_Reset(XEmac * InstancePtr)
 * None.
 *
 ******************************************************************************/
-XStatus
-XEmac_SetMacAddress(XEmac * InstancePtr, u8 * AddressPtr)
+XStatus XEmac_SetMacAddress(XEmac *InstancePtr, u8 *AddressPtr)
 {
 	u32 MacAddr = 0;
 
@@ -595,7 +629,8 @@ XEmac_SetMacAddress(XEmac * InstancePtr,
 	/*
 	 * The device must be stopped before setting the MAC address
 	 */
-	if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+    if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED)
+    {
 		return XST_DEVICE_IS_STARTED;
 	}
 
@@ -632,8 +667,7 @@ XEmac_SetMacAddress(XEmac * InstancePtr,
 * None.
 *
 ******************************************************************************/
-void
-XEmac_GetMacAddress(XEmac * InstancePtr, u8 * BufferPtr)
+void XEmac_GetMacAddress(XEmac *InstancePtr, u8 *BufferPtr)
 {
 	u32 MacAddrHi;
 	u32 MacAddrLo;
@@ -669,8 +703,7 @@ XEmac_GetMacAddress(XEmac * InstancePtr,
 * None.
 *
 ******************************************************************************/
-static XStatus
-ConfigureDma(XEmac * InstancePtr)
+static XStatus ConfigureDma(XEmac *InstancePtr)
 {
 	XStatus Result;
 
@@ -680,15 +713,14 @@ ConfigureDma(XEmac * InstancePtr)
 	 * will need to be set later by the upper layer.
 	 */
 	Result = XDmaChannel_Initialize(&InstancePtr->RecvChannel,
-					InstancePtr->BaseAddress +
-					XEM_DMA_RECV_OFFSET);
-	if (Result != XST_SUCCESS) {
+				    InstancePtr->BaseAddress + XEM_DMA_RECV_OFFSET);
+    if (Result != XST_SUCCESS)
+    {
 		return Result;
 	}
 
 	Result = XDmaChannel_Initialize(&InstancePtr->SendChannel,
-					InstancePtr->BaseAddress +
-					XEM_DMA_SEND_OFFSET);
+				    InstancePtr->BaseAddress + XEM_DMA_SEND_OFFSET);
 
 	return Result;
 }
@@ -710,8 +742,7 @@ ConfigureDma(XEmac * InstancePtr)
 * None.
 *
 ******************************************************************************/
-static XStatus
-ConfigureFifo(XEmac * InstancePtr)
+static XStatus ConfigureFifo(XEmac *InstancePtr)
 {
 	XStatus Result;
 
@@ -720,19 +751,16 @@ ConfigureFifo(XEmac * InstancePtr)
 	 * they always return success.
 	 */
 	Result = XPacketFifoV200a_Initialize(&InstancePtr->RecvFifo,
-					     InstancePtr->BaseAddress +
-					     XEM_PFIFO_RXREG_OFFSET,
-					     InstancePtr->BaseAddress +
-					     XEM_PFIFO_RXDATA_OFFSET);
-	if (Result != XST_SUCCESS) {
+					 InstancePtr->BaseAddress + XEM_PFIFO_RXREG_OFFSET,
+					 InstancePtr->BaseAddress + XEM_PFIFO_RXDATA_OFFSET);
+    if (Result != XST_SUCCESS)
+    {
 		return Result;
 	}
 
 	Result = XPacketFifoV200a_Initialize(&InstancePtr->SendFifo,
-					     InstancePtr->BaseAddress +
-					     XEM_PFIFO_TXREG_OFFSET,
-					     InstancePtr->BaseAddress +
-					     XEM_PFIFO_TXDATA_OFFSET);
+					 InstancePtr->BaseAddress + XEM_PFIFO_TXREG_OFFSET,
+					 InstancePtr->BaseAddress + XEM_PFIFO_TXDATA_OFFSET);
 	return Result;
 }
 
@@ -755,8 +783,8 @@ ConfigureFifo(XEmac * InstancePtr)
 * None.
 *
 ******************************************************************************/
-static void
-StubSgHandler(void *CallBackRef, XBufDescriptor * BdPtr, u32 NumBds)
+static void StubSgHandler(void *CallBackRef, XBufDescriptor *BdPtr,
+                          u32 NumBds)
 {
 	XASSERT_VOID_ALWAYS();
 }
@@ -778,8 +806,7 @@ StubSgHandler(void *CallBackRef, XBufDes
 * None.
 *
 ******************************************************************************/
-static void
-StubFifoHandler(void *CallBackRef)
+static void StubFifoHandler(void *CallBackRef)
 {
 	XASSERT_VOID_ALWAYS();
 }
@@ -802,8 +829,7 @@ StubFifoHandler(void *CallBackRef)
 * None.
 *
 ******************************************************************************/
-static void
-StubErrorHandler(void *CallBackRef, XStatus ErrorCode)
+static void StubErrorHandler(void *CallBackRef, XStatus ErrorCode)
 {
 	XASSERT_VOID_ALWAYS();
 }
@@ -819,15 +845,14 @@ StubErrorHandler(void *CallBackRef, XSta
 * @return
 *
 * A pointer to the configuration table entry corresponding to the given
-* device ID, or NULL if no match is found.
+ * device ID, or XNULL if no match is found.
 *
 * @note
 *
 * None.
 *
 ******************************************************************************/
-XEmac_Config *
-XEmac_LookupConfig(u16 DeviceId)
+XEmac_Config *XEmac_LookupConfig(u16 DeviceId)
 {
 	XEmac_Config *CfgPtr = NULL;
 	int i;
Index: drivers/net/xilinx_enet/xemac.h
===================================================================
RCS file: /var/cvs/uClinux-2.4.x/drivers/net/xilinx_enet/xemac.h,v
retrieving revision 1.4
diff -u -b -B -w -p -r1.4 xemac.h
--- drivers/net/xilinx_enet/xemac.h	15 Feb 2005 05:30:22 -0000	1.4
+++ drivers/net/xilinx_enet/xemac.h	23 Jun 2006 00:47:08 -0000
@@ -46,24 +46,25 @@
 *
 * The Xilinx Ethernet 10/100 MAC supports the following features:
 *   - Simple and scatter-gather DMA operations, as well as simple memory
-*     mapped direct I/O interface (FIFOs).
+*     mapped direct I/O interface (FIFOs)
 *   - Media Independent Interface (MII) for connection to external
-*     10/100 Mbps PHY transceivers.
+*     10/100 Mbps PHY transceivers
 *   - MII management control reads and writes with MII PHYs
 *   - Independent internal transmit and receive FIFOs
 *   - CSMA/CD compliant operations for half-duplex modes
 *   - Programmable PHY reset signal
-*   - Unicast, broadcast, and promiscuous address filtering
-*   - Reception of all multicast addresses (no multicast filtering yet)
-*     (NOTE: EMAC core may not support this - check the specification)
+*   - Unicast, broadcast, multicast, and promiscuous address filtering
+*   - Reception of any address that matches a CAM entry.
 *   - Internal loopback
 *   - Automatic source address insertion or overwrite (programmable)
 *   - Automatic FCS insertion and stripping (programmable)
 *   - Automatic pad insertion and stripping (programmable)
 *   - Pause frame (flow control) detection in full-duplex mode
 *   - Programmable interframe gap
-*   - VLAN frame support.
+*   - VLAN frame support
 *   - Pause frame support
+*   - Jumbo frame support
+*   - Dynamic Re-alignment Engine (DRE) support handled automatically
 *
 * The device driver supports all the features listed above.
 *
@@ -92,12 +93,28 @@
 *
 * It is important to note that when using direct FIFO communication (either
 * polled or interrupt-driven), packet buffers must be 32-bit aligned. When
-* using DMA and the OPB 10/100 Ethernet core, packet buffers must be 32-bit
-* aligned. When using DMA and the PLB 10/100 Ethernet core, packet buffers
-* must be 64-bit aligned.  When using scatter-gather DMA, the buffer
-* descriptors must be 32-bit aligned (for either the OPB or the PLB core).
-* The driver may not enforce this alignment and it is up to the user to
-* guarantee the proper alignment.
+* using DMA without DRE and the OPB 10/100 Ethernet core, packet buffers
+* must be 32-bit aligned. When using DMA without DRE and the PLB 10/100
+* Ethernet core, packet buffers must be 64-bit aligned.
+*
+* When using scatter-gather DMA, the buffer descriptors must be 32-bit
+* aligned (for either the OPB or the PLB core). The driver may not enforce
+* this alignment so it is up to the user to guarantee the proper alignment.
+*
+* When DRE is available in the DMA engine, only the buffer descriptors must
+* be aligned, the actual buffers do not need to be aligned to any particular
+* addressing convention, the DRE takes care of that in hardware.
+*
+* <b>Receive Address Filtering</b>
+*
+* The device can be set to accept frames whose destination MAC address:
+*
+*   - Match the station MAC address (see XEmac_SetMacAddress())
+*   - Match the broadcast MAC address (see XEM_BROADCAST_OPTION)
+*   - Match any multicast MAC address (see XEM_MULTICAST_OPTION)
+*   - Match any one of the 64 possible CAM addresses (see XEmac_MulticastAdd()
+*     and XEM_MULTICAST_CAM_OPTION). The CAM is optional.
+*   - Match any MAC address (see XEM_PROMISC_OPTION)
 *
 * <b>PHY Communication</b>
 *
@@ -268,6 +285,12 @@
 *                     for all packets received for an interrupt event. Added
 *                     XEmac_GetSgRecvFreeDesc() and GetSgSendFreeDesc()
 *                     functions. Moved some IFG and PHY constants to xemac_l.h.
+* 1.00f rmm  10/19/04 Added programmable CAM address filtering. Added jumbo
+*                     frame support. Added XEmac_PhyReset() function.
+* 1.01a ecm  09/01/05 Added DRE support through Control words in instance which
+*                     are set at initialization.
+*                     Added the config structure items to support separate
+*                     Tx and Rx capabilities..
 * </pre>
 *
 ******************************************************************************/
@@ -275,6 +298,10 @@
 #ifndef XEMAC_H			/* prevent circular inclusions */
 #define XEMAC_H			/* by using protection macros */
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /***************************** Include Files *********************************/
 
 #include "xbasic_types.h"
@@ -322,14 +349,22 @@
                                                     transmit. This is only used
                                                     only used if source address
                                                     insertion is on (defaults on) */
+#define XEM_NO_SGEND_INT_OPTION   0x00001000UL /**< Disables the SGEND interrupt
+                                                    with SG DMA. Setting this
+                                                    option to ON may help bulk
+                                                    data transfer performance
+                                                    when utilizing higher packet
+                                                    threshold counts on slower
+                                                    systems (default is off) */
 #define XEM_STRIP_PAD_FCS_OPTION  0x00002000UL /**< Strip FCS and padding from
                                                     received frames (defaults off) */
-
-/** Disables the SGEND interrupt with SG DMA. Setting this option to ON may
- * help bulk data transfer performance when utilizing higher packet threshold
- * counts on slower systems (default is off) */
-#define XEM_NO_SGEND_INT_OPTION   0x00001000UL
-
+#define XEM_JUMBO_OPTION          0x00004000UL /**< Allow reception of Jumbo frames,
+                                                    transmission of Jumbo frames is
+                                                    always enabled.
+                                                    (default is off) */
+#define XEM_MULTICAST_CAM_OPTION  0x00008000UL /**< Allow Rx address filtering
+                                                    for multicast CAM entries
+                                                    (default is off) */
 /*@}*/
 
 /*
@@ -364,17 +399,22 @@
 #define XEM_CFG_SIMPLE_DMA          2	/* Simple DMA */
 #define XEM_CFG_DMA_SG              3	/* DMA scatter gather */
 
+#define XEM_MULTI_CAM_ENTRIES       64      /* Number of storable addresses in
+                                               the CAM */
+
 /*
  * The next few constants help upper layers determine the size of memory
  * pools used for Ethernet buffers and descriptor lists.
  */
 #define XEM_MAC_ADDR_SIZE   6	/* six-byte MAC address */
 #define XEM_MTU             1500	/* max size of Ethernet frame */
+#define XEM_JUMBO_MTU       8982    /* max payload size of jumbo frame */
 #define XEM_HDR_SIZE        14	/* size of Ethernet header */
 #define XEM_HDR_VLAN_SIZE   18	/* size of Ethernet header with VLAN */
 #define XEM_TRL_SIZE        4	/* size of Ethernet trailer (FCS) */
 #define XEM_MAX_FRAME_SIZE  (XEM_MTU + XEM_HDR_SIZE + XEM_TRL_SIZE)
 #define XEM_MAX_VLAN_FRAME_SIZE  (XEM_MTU + XEM_HDR_VLAN_SIZE + XEM_TRL_SIZE)
+#define XEM_MAX_JUMBO_FRAME_SIZE (XEM_JUMBO_MTU + XEM_HDR_SIZE + XEM_TRL_SIZE)
 
 /*
  * Define a default number of send and receive buffers
@@ -403,11 +444,11 @@
 /**
  * Ethernet statistics (see XEmac_GetStats() and XEmac_ClearStats())
  */
-typedef struct {
+typedef struct
+{
 	u32 XmitFrames;		 /**< Number of frames transmitted */
 	u32 XmitBytes;		 /**< Number of bytes transmitted */
-	u32 XmitLateCollisionErrors;
-				 /**< Number of transmission failures
+    u32 XmitLateCollisionErrors; /**< Number of transmission failures
                                           due to late collisions */
 	u32 XmitExcessDeferral;	 /**< Number of transmission failures
                                           due o excess collision deferrals */
@@ -422,12 +463,10 @@ typedef struct {
 	u32 RecvOverrunErrors;	 /**< Number of frames discarded due
                                           to overrun errors */
 	u32 RecvUnderrunErrors;	 /**< Number of recv underrun errors */
-	u32 RecvMissedFrameErrors;
-				 /**< Number of frames missed by MAC */
+    u32 RecvMissedFrameErrors;   /**< Number of frames missed by MAC */
 	u32 RecvCollisionErrors; /**< Number of frames discarded due
                                           to collisions */
-	u32 RecvLengthFieldErrors;
-				 /**< Number of frames discarded with
+    u32 RecvLengthFieldErrors;   /**< Number of frames discarded with
                                           invalid length field */
 	u32 RecvShortErrors;	 /**< Number of short frames discarded */
 	u32 RecvLongErrors;	 /**< Number of long frames discarded */
@@ -442,16 +481,23 @@ typedef struct {
 /**
  * This typedef contains configuration information for a device.
  */
-typedef struct {
+typedef struct
+{
 	u16 DeviceId;	    /**< Unique ID  of device */
 	u32 BaseAddress;    /**< Register base address */
 	u32 PhysAddress;    /**< Physical Base address */
 	u32 HasCounters;   /**< Does device have counters? */
 	u8 IpIfDmaConfig;   /**< IPIF/DMA hardware configuration */
 	u32 HasMii;	   /**< Does device support MII? */
-
+    u32 HasCam;            /**< Does device have multicast CAM */
+    u32 HasJumbo;          /**< Can device transfer jumbo frames */
+    u32 TxDre;             /**< Has data realignment engine on TX channel */
+    u32 RxDre;             /**< Has data realignment engine on RX channel */
+    u32 TxHwCsum;          /**< Has checksum offload on TX channel */
+    u32 RxHwCsum;          /**< Has checksum offload on RX channel */
 } XEmac_Config;
 
+
 /** @name Typedefs for callbacks
  * Callback functions.
  * @{
@@ -498,15 +544,23 @@ typedef void (*XEmac_ErrorHandler) (void
  * variable of this type for every EMAC device in the system. A pointer
  * to a variable of this type is then passed to the driver API functions.
  */
-typedef struct {
-	u32 BaseAddress;	/* Base address, virtual (of IPIF) */
+typedef struct
+{
+    u32 BaseAddress;         /* Base address (of IPIF) */
 	u32 PhysAddress;	/* Base address, physical  (of IPIF) */
 	u32 IsStarted;		/* Device is currently started */
 	u32 IsReady;		/* Device is initialized and ready */
+    u32 TxDmaControlWord;    /* TX SGDMA channel control word */
+    u32 RxDmaControlWord;    /* RX SGDMA channel control word */
 	u32 IsPolled;		/* Device is in polled mode */
 	u8 IpIfDmaConfig;	/* IPIF/DMA hardware configuration */
 	u32 HasMii;		/* Does device support MII? */
 	u32 HasMulticastHash;	/* Does device support multicast hash table? */
+    u32 TxDre;   /* Does device support TX DRE? */
+    u32 RxDre;   /* Does device support TX DRE? */
+    u32 TxHwCsum;   /* Does device support TX checksum offload? */
+    u32 RxHwCsum;   /* Does device support TX checksum offload? */
+    XEmac_Config *ConfigPtr;     /* Configuration table entry */
 
 	XEmac_Stats Stats;
 	XPacketFifoV200a RecvFifo;	/* FIFO used to receive frames */
@@ -532,8 +586,8 @@ typedef struct {
 	void *SgSendRef;
 } XEmac;
 
-/***************** Macros (Inline Functions) Definitions *********************/
 
+/***************** Macros (Inline Functions) Definitions *********************/
 /*****************************************************************************/
 /**
 *
@@ -594,6 +648,230 @@ typedef struct {
 #define XEmac_mIsDma(InstancePtr) \
             (XEmac_mIsSimpleDma(InstancePtr) || XEmac_mIsSgDma(InstancePtr))
 
+/*****************************************************************************/
+/**
+*
+* This macro determines if the device has CAM option for storing additional
+* receive filters for multicast or unicast addresses.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* Boolean TRUE if the device is configured with the CAM, or FALSE otherwise
+*
+* @note
+*
+* Signature: u32 XEmac_mHasCam(XEmac *InstancePtr)
+*
+******************************************************************************/
+#define XEmac_mHasCam(InstancePtr) \
+    (((InstancePtr)->ConfigPtr->HasCam == 1) ? TRUE : FALSE)
+
+/*****************************************************************************/
+/**
+*
+* This macro determines if the device has the MII option for communications
+* with a PHY.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* Boolean TRUE if the device is configured with MII, or FALSE otherwise
+*
+* @note
+*
+* Signature: u32 XEmac_mHasMii(XEmac *InstancePtr)
+*
+******************************************************************************/
+#define XEmac_mHasMii(InstancePtr) \
+    (((InstancePtr)->ConfigPtr->HasMii == 1) ? TRUE : FALSE)
+
+/*****************************************************************************/
+/**
+*
+* This macro determines if the device has the option to transfer jumbo sized
+* frames.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* Boolean TRUE if the device is configured with jubmo frame capability, or
+* FALSE otherwise
+*
+* @note
+*
+* Signature: u32 XEmac_mHasJumbo(XEmac *InstancePtr)
+*
+******************************************************************************/
+#define XEmac_mHasJumbo(InstancePtr) \
+    (((InstancePtr)->ConfigPtr->HasJumbo == 1) ? TRUE : FALSE)
+
+/*****************************************************************************/
+/**
+*
+* This macro determines if the device is configured with the Data Realignment
+* Engine (DRE)
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* Boolean TRUE if the device is configured with TX DRE, or FALSE otherwise.
+* Note that earlier versions do not have DRE capability so this macro always
+* returns FALSE.
+*
+* @note
+*
+* Signature: u32 XEmac_mIsTxDre(XEmac *InstancePtr)
+*
+******************************************************************************/
+#define XEmac_mIsTxDre(InstancePtr)                                         \
+    ((InstancePtr)->TxDre !=0 )
+
+/*****************************************************************************/
+/**
+*
+* This macro determines if the device is configured with the Data Realignment
+* Engine (DRE)
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* Boolean TRUE if the device is configured with RX DRE, or FALSE otherwise.
+* Note that earlier versions do not have DRE capability so this macro always
+* returns FALSE.
+*
+* @note
+*
+* Signature: u32 XEmac_mIsRxDre(XEmac *InstancePtr)
+*
+******************************************************************************/
+#define XEmac_mIsRxDre(InstancePtr)                                         \
+    ((InstancePtr)->RxDre != 0)
+
+/*****************************************************************************/
+/**
+*
+* This macro determines if the device is configured with the Checksum offload
+* functionality
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* Boolean TRUE if the device is configured with TX CSum, or FALSE otherwise.
+* Note that earlier versions do not have CSum capability so this macro always
+* returns FALSE.
+*
+* @note
+*
+* Signature: u32 XEmac_mIsTxHwCsum(XEmac *InstancePtr)
+*
+******************************************************************************/
+#define XEmac_mIsTxHwCsum(InstancePtr)                                         \
+    (((InstancePtr)->TxHwCsum == 1) ? TRUE : FALSE)
+/*****************************************************************************/
+/**
+*
+* This macro determines if the device is configured with the Checksum offload
+* functionality
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* Boolean TRUE if the device is configured with RX CSum, or FALSE otherwise.
+* Note that earlier versions do not have CSum capability so this macro always
+* returns FALSE.
+*
+* @note
+*
+* Signature: u32 XEmac_mIsRxHwCsum(XEmac *InstancePtr)
+*
+******************************************************************************/
+#define XEmac_mIsRxHwCsum(InstancePtr)                                         \
+    (((InstancePtr)->RxHwCsum == 1) ? TRUE : FALSE)
+
+/*****************************************************************************/
+/**
+*
+* This macro enables the TxHwCsum for the EMAC
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* none
+*
+* @note
+*
+* Signature: void XEmac_mEnableTxHwCsum(XEmac *InstancePtr)
+*
+******************************************************************************/
+#define XEmac_mEnableTxHwCsum(InstancePtr)                                    \
+        ((InstancePtr)->TxDmaControlWord |= XDC_DMACR_CS_OFFLOAD_MASK);
+
+/*****************************************************************************/
+/**
+*
+* This macro disables the TxHwCsum for the EMAC
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* none
+*
+* @note
+*
+* Signature: void XEmac_mDisableTxHwCsum(XEmac *InstancePtr)
+*
+******************************************************************************/
+#define XEmac_mDisableTxHwCsum(InstancePtr)                                    \
+        ((InstancePtr)->TxDmaControlWord &= ~XDC_DMACR_CS_OFFLOAD_MASK);
+
+/*****************************************************************************/
+/**
+*
+* This macro disables the Global interrupt for the EMAC
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* none
+*
+* @note
+*
+* Signature: void XEmac_mDisableGIE(XEmac *InstancePtr)
+*
+******************************************************************************/
+#define XEmac_mDisableGIE(InstancePtr)                                           \
+    XIIF_V123B_GINTR_DISABLE((InstancePtr)->BaseAddress);
+
+/*****************************************************************************/
+/**
+*
+* This macro enables the Global interrupt for the EMAC
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* none
+*
+* @note
+*
+* Signature: void XEmac_mEnableGIE(XEmac *InstancePtr)
+*
+******************************************************************************/
+#define XEmac_mEnableGIE(InstancePtr)                                           \
+    XIIF_V123B_GINTR_ENABLE((InstancePtr)->BaseAddress);
+
 /************************** Function Prototypes ******************************/
 
 /*
@@ -614,14 +892,16 @@ XStatus XEmac_SelfTest(XEmac * InstanceP
  * Polled functions in xemac_polled.c
  */
 XStatus XEmac_PollSend(XEmac * InstancePtr, u8 * BufPtr, u32 ByteCount);
-XStatus XEmac_PollRecv(XEmac * InstancePtr, u8 * BufPtr, u32 * ByteCountPtr);
+XStatus XEmac_PollRecv(XEmac *InstancePtr, u8 *BufPtr,
+                       u32 *ByteCountPtr);
 
 /*
  * Interrupts with scatter-gather DMA functions in xemac_intr_dma.c
  */
 XStatus XEmac_SgSend(XEmac * InstancePtr, XBufDescriptor * BdPtr, int Delay);
 XStatus XEmac_SgRecv(XEmac * InstancePtr, XBufDescriptor * BdPtr);
-XStatus XEmac_SetPktThreshold(XEmac * InstancePtr, u32 Direction, u8 Threshold);
+XStatus XEmac_SetPktThreshold(XEmac *InstancePtr, u32 Direction,
+                              u8 Threshold);
 XStatus XEmac_GetPktThreshold(XEmac * InstancePtr, u32 Direction,
 			      u8 * ThreshPtr);
 XStatus XEmac_SetPktWaitBound(XEmac * InstancePtr, u32 Direction,
@@ -646,7 +926,8 @@ void XEmac_IntrHandlerDma(void *Instance
  * for simple DMA.
  */
 XStatus XEmac_FifoSend(XEmac * InstancePtr, u8 * BufPtr, u32 ByteCount);
-XStatus XEmac_FifoRecv(XEmac * InstancePtr, u8 * BufPtr, u32 * ByteCountPtr);
+XStatus XEmac_FifoRecv(XEmac *InstancePtr, u8 *BufPtr,
+                       u32 *ByteCountPtr);
 void XEmac_SetFifoRecvHandler(XEmac * InstancePtr, void *CallBackRef,
 			      XEmac_FifoHandler FuncPtr);
 void XEmac_SetFifoSendHandler(XEmac * InstancePtr, void *CallBackRef,
@@ -668,17 +949,19 @@ u32 XEmac_GetOptions(XEmac * InstancePtr
 XStatus XEmac_SetMacAddress(XEmac * InstancePtr, u8 * AddressPtr);
 void XEmac_GetMacAddress(XEmac * InstancePtr, u8 * BufferPtr);
 XStatus XEmac_SetInterframeGap(XEmac * InstancePtr, u8 Part1, u8 Part2);
-void XEmac_GetInterframeGap(XEmac * InstancePtr, u8 * Part1Ptr, u8 * Part2Ptr);
+void XEmac_GetInterframeGap(XEmac *InstancePtr, u8 *Part1Ptr,
+                            u8* Part2Ptr);
 
 /*
- * Multicast functions in xemac_multicast.c (not supported by EMAC yet)
+ * Multicast functions in xemac_multicast.c
  */
-XStatus XEmac_MulticastAdd(XEmac * InstancePtr, u8 * AddressPtr);
-XStatus XEmac_MulticastClear(XEmac * InstancePtr);
+XStatus XEmac_MulticastAdd(XEmac *InstancePtr, u8 *AddressPtr, int Entry);
+XStatus XEmac_MulticastClear(XEmac *InstancePtr, int Entry);
 
 /*
  * PHY configuration in xemac_phy.c
  */
+void    XEmac_PhyReset(XEmac *InstancePtr);
 XStatus XEmac_PhyRead(XEmac * InstancePtr, u32 PhyAddress,
 		      u32 RegisterNum, u16 * PhyDataPtr);
 XStatus XEmac_PhyWrite(XEmac * InstancePtr, u32 PhyAddress,
@@ -690,4 +973,9 @@ XStatus XEmac_PhyWrite(XEmac * InstanceP
 void XEmac_GetStats(XEmac * InstancePtr, XEmac_Stats * StatsPtr);
 void XEmac_ClearStats(XEmac * InstancePtr);
 
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif				/* end of protection macro */
Index: drivers/net/xilinx_enet/xemac_g.c
===================================================================
RCS file: /var/cvs/uClinux-2.4.x/drivers/net/xilinx_enet/xemac_g.c,v
retrieving revision 1.5
diff -u -b -B -w -p -r1.5 xemac_g.c
--- drivers/net/xilinx_enet/xemac_g.c	21 Feb 2006 09:35:14 -0000	1.5
+++ drivers/net/xilinx_enet/xemac_g.c	23 Jun 2006 00:47:08 -0000
@@ -53,7 +53,33 @@ XEmac_Config XEmac_ConfigTable[] = {
 	 CONFIG_XILINX_ETHERNET_0_BASEADDR,
 	 CONFIG_XILINX_ETHERNET_0_ERR_COUNT_EXIST,
 	 CONFIG_XILINX_ETHERNET_0_DMA_PRESENT,
-	 CONFIG_XILINX_ETHERNET_0_MII_EXIST}
+	CONFIG_XILINX_ETHERNET_0_MII_EXIST,
+	0,
+	0,
+#ifdef CONFIG_XILINX_ETHERNET_0_TX_DRE_TYPE
+	CONFIG_XILINX_ETHERNET_0_TX_DRE_TYPE,
+#else
+	0,
+#endif
+
+#ifdef CONFIG_XILINX_ETHERNET_0_RX_DRE_TYPE
+	CONFIG_XILINX_ETHERNET_0_RX_DRE_TYPE,
+#else
+	0,
+#endif
+#ifdef CONFIG_XILINX_ETHERNET_0_TX_INCLUDE_CSUM
+	CONFIG_XILINX_ETHERNET_0_TX_INCLUDE_CSUM,
+#else
+	0,
+#endif
+
+#ifdef CONFIG_XILINX_ETHERNET_0_RX_INCLUDE_CSUM
+	CONFIG_XILINX_ETHERNET_0_RX_INCLUDE_CSUM
+#else
+	0
+#endif
+
+    }
 #ifdef CONFIG_XILINX_ETHERNET_1_INSTANCE
 	,
 	{
Index: drivers/net/xilinx_enet/xemac_intr.c
===================================================================
RCS file: /var/cvs/uClinux-2.4.x/drivers/net/xilinx_enet/xemac_intr.c,v
retrieving revision 1.3
diff -u -b -B -w -p -r1.3 xemac_intr.c
Index: drivers/net/xilinx_enet/xemac_intr_dma.c
===================================================================
RCS file: /var/cvs/uClinux-2.4.x/drivers/net/xilinx_enet/xemac_intr_dma.c,v
retrieving revision 1.5
diff -u -b -B -w -p -r1.5 xemac_intr_dma.c
--- drivers/net/xilinx_enet/xemac_intr_dma.c	22 Feb 2005 02:40:09 -0000	1.5
+++ drivers/net/xilinx_enet/xemac_intr_dma.c	23 Jun 2006 00:47:12 -0000
@@ -1,40 +1,23 @@
+/* $Id: xemac_intr_dma.c,v 1.1 2005/10/26 15:44:52 meinelte Exp $ */
 /******************************************************************************
 *
-*     Author: Xilinx, Inc.
+ *       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+ *       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+ *       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+ *       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+ *       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+ *       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+ *       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+ *       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+ *       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+ *       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+ *       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+ *       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ *       FOR A PARTICULAR PURPOSE.
 *     
-*     
-*     This program is free software; you can redistribute it and/or modify it
-*     under the terms of the GNU General Public License as published by the
-*     Free Software Foundation; either version 2 of the License, or (at your
-*     option) any later version.
-*     
-*     
-*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
-*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
-*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
-*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
-*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
-*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
-*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
-*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
-*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
-*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
-*     FITNESS FOR A PARTICULAR PURPOSE.
-*     
-*     
-*     Xilinx hardware products are not intended for use in life support
-*     appliances, devices, or systems. Use in such applications is
-*     expressly prohibited.
-*     
-*     
-*     (c) Copyright 2002-2004 Xilinx Inc.
+ *       (c) Copyright 2003 Xilinx Inc.
 *     All rights reserved.
 *     
-*     
-*     You should have received a copy of the GNU General Public License along
-*     with this program; if not, write to the Free Software Foundation, Inc.,
-*     675 Mass Ave, Cambridge, MA 02139, USA.
-*
 ******************************************************************************/
 /*****************************************************************************/
 /**
@@ -71,6 +54,8 @@
 *                     send/recv callbacks are invoked once for all packets.
 *                     Added functions XEmac_GetSgRecvFreeDesc() and XEmac_Get-
 *                     SgSendFreeDesc().
+ * 1.01a ecm  09/01/05 Added DRE support through Control words in instance which
+ *                     are set at initialization.
 * </pre>
 *
 ******************************************************************************/
@@ -165,21 +154,21 @@ static void HandleEmacDmaIntr(XEmac * In
 * started.
 *
 ******************************************************************************/
-XStatus
-XEmac_SgSend(XEmac * InstancePtr, XBufDescriptor * BdPtr, int Delay)
+XStatus XEmac_SgSend(XEmac *InstancePtr, XBufDescriptor *BdPtr, int Delay)
 {
 	XStatus Result;
 	u32 BdControl;
 
-	XASSERT_NONVOID(InstancePtr != NULL);
-	XASSERT_NONVOID(BdPtr != NULL);
+    XASSERT_NONVOID(InstancePtr != XNULL);
+    XASSERT_NONVOID(BdPtr != XNULL);
 	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
 
 	/*
 	 * Be sure the device is configured for scatter-gather DMA, then be sure
 	 * it is started.
 	 */
-	if (!XEmac_mIsSgDma(InstancePtr)) {
+    if (!XEmac_mIsSgDma(InstancePtr))
+    {
 		return XST_NOT_SGDMA;
 	}
 
@@ -189,11 +178,18 @@ XEmac_SgSend(XEmac * InstancePtr, XBufDe
 	 * (the FIFO).  These are the same for every transmit descriptor.
 	 */
 	BdControl = XBufDescriptor_GetControl(BdPtr);
-	XBufDescriptor_SetControl(BdPtr, BdControl | XEM_DFT_SEND_BD_MASK);
+    XBufDescriptor_SetControl(BdPtr, BdControl | (InstancePtr->TxDmaControlWord));
 
+    /*
+     * If the TX channel has Checksum offload enabled, do not overwrite
+     * the Data in the destination address location, it is offload related
+     * not the actual address for the data to be written to
+     */
+    if ((InstancePtr->TxDmaControlWord & XDC_DMACR_CS_OFFLOAD_MASK) == 0)
+    {
 	XBufDescriptor_SetDestAddress(BdPtr,
-				      InstancePtr->PhysAddress +
-				      XEM_PFIFO_TXDATA_OFFSET);
+				      InstancePtr->BaseAddress + XEM_PFIFO_TXDATA_OFFSET);
+    }
 
 	/*
 	 * Put the descriptor in the send list. The DMA component accesses data
@@ -203,7 +199,8 @@ XEmac_SgSend(XEmac * InstancePtr, XBufDe
 	XIIF_V123B_GINTR_DISABLE(InstancePtr->BaseAddress);
 
 	Result = XDmaChannel_PutDescriptor(&InstancePtr->SendChannel, BdPtr);
-	if (Result != XST_SUCCESS) {
+    if (Result != XST_SUCCESS)
+    {
 		XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
 		return Result;
 	}
@@ -212,14 +209,17 @@ XEmac_SgSend(XEmac * InstancePtr, XBufDe
 	 * If this is the last buffer in the frame, commit the inserts and start
 	 * the DMA engine if necessary
 	 */
-	if (XBufDescriptor_IsLastControl(BdPtr)) {
+    if (XBufDescriptor_IsLastControl(BdPtr))
+    {
 		Result = XDmaChannel_CommitPuts(&InstancePtr->SendChannel);
-		if (Result != XST_SUCCESS) {
+	if (Result != XST_SUCCESS)
+	{
 			XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
 			return Result;
 		}
 
-		if (Delay == XEM_SGDMA_NODELAY) {
+	if (Delay == XEM_SGDMA_NODELAY)
+	{
 			/*
 			 * Start the DMA channel. Ignore the return status since we know the
 			 * list exists and has at least one entry and we don't care if the
@@ -278,20 +278,20 @@ XEmac_SgSend(XEmac * InstancePtr, XBufDe
 * started.
 *
 ******************************************************************************/
-XStatus
-XEmac_SgRecv(XEmac * InstancePtr, XBufDescriptor * BdPtr)
+XStatus XEmac_SgRecv(XEmac *InstancePtr, XBufDescriptor *BdPtr)
 {
 	XStatus Result;
 	u32 BdControl;
 
-	XASSERT_NONVOID(InstancePtr != NULL);
-	XASSERT_NONVOID(BdPtr != NULL);
+    XASSERT_NONVOID(InstancePtr != XNULL);
+    XASSERT_NONVOID(BdPtr != XNULL);
 	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
 
 	/*
 	 * Be sure the device is configured for scatter-gather DMA
 	 */
-	if (!XEmac_mIsSgDma(InstancePtr)) {
+    if (!XEmac_mIsSgDma(InstancePtr))
+    {
 		return XST_NOT_SGDMA;
 	}
 
@@ -301,10 +301,9 @@ XEmac_SgRecv(XEmac * InstancePtr, XBufDe
 	 * the same for every receive descriptor.
 	 */
 	BdControl = XBufDescriptor_GetControl(BdPtr);
-	XBufDescriptor_SetControl(BdPtr, BdControl | XEM_DFT_RECV_BD_MASK);
+    XBufDescriptor_SetControl(BdPtr, BdControl | (InstancePtr->RxDmaControlWord));
 	XBufDescriptor_SetSrcAddress(BdPtr,
-				     InstancePtr->PhysAddress +
-				     XEM_PFIFO_RXDATA_OFFSET);
+				 InstancePtr->BaseAddress + XEM_PFIFO_RXDATA_OFFSET);
 
 	/*
 	 * Put the descriptor into the channel's descriptor list and commit.
@@ -316,13 +315,15 @@ XEmac_SgRecv(XEmac * InstancePtr, XBufDe
 	XIIF_V123B_GINTR_DISABLE(InstancePtr->BaseAddress);
 
 	Result = XDmaChannel_PutDescriptor(&InstancePtr->RecvChannel, BdPtr);
-	if (Result != XST_SUCCESS) {
+    if (Result != XST_SUCCESS)
+    {
 		XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
 		return Result;
 	}
 
 	Result = XDmaChannel_CommitPuts(&InstancePtr->RecvChannel);
-	if (Result != XST_SUCCESS) {
+    if (Result != XST_SUCCESS)
+    {
 		XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
 		return Result;
 	}
@@ -362,8 +364,7 @@ XEmac_SgRecv(XEmac * InstancePtr, XBufDe
 * None.
 *
 ******************************************************************************/
-void
-XEmac_IntrHandlerDma(void *InstancePtr)
+void XEmac_IntrHandlerDma(void *InstancePtr)
 {
 	u32 IntrStatus;
 	XEmac *EmacPtr = (XEmac *) InstancePtr;
@@ -379,40 +380,45 @@ XEmac_IntrHandlerDma(void *InstancePtr)
 	/*
 	 * See which type of interrupt is being requested, and service it
 	 */
-	if (IntrStatus & XEM_IPIF_RECV_DMA_MASK) {	/* Receive DMA interrupt */
+    if (IntrStatus & XEM_IPIF_RECV_DMA_MASK)    /* Receive DMA interrupt */
+    {
 		EmacPtr->Stats.RecvInterrupts++;
 		HandleDmaRecvIntr(EmacPtr);
 	}
 
-	if (IntrStatus & XEM_IPIF_SEND_DMA_MASK) {	/* Send DMA interrupt */
+    if (IntrStatus & XEM_IPIF_SEND_DMA_MASK)    /* Send DMA interrupt */
+    {
 		EmacPtr->Stats.XmitInterrupts++;
 		HandleDmaSendIntr(EmacPtr);
 	}
 
-	if (IntrStatus & XEM_IPIF_EMAC_MASK) {	/* MAC interrupt */
+    if (IntrStatus & XEM_IPIF_EMAC_MASK)        /* MAC interrupt */
+    {
 		EmacPtr->Stats.EmacInterrupts++;
 		HandleEmacDmaIntr(EmacPtr);
 	}
 
-	if (IntrStatus & XEM_IPIF_RECV_FIFO_MASK) {	/* Receive FIFO interrupt */
+    if (IntrStatus & XEM_IPIF_RECV_FIFO_MASK)   /* Receive FIFO interrupt */
+    {
 		EmacPtr->Stats.RecvInterrupts++;
 		XEmac_CheckFifoRecvError(EmacPtr);
 	}
 
-	if (IntrStatus & XEM_IPIF_SEND_FIFO_MASK) {	/* Send FIFO interrupt */
+    if (IntrStatus & XEM_IPIF_SEND_FIFO_MASK)   /* Send FIFO interrupt */
+    {
 		EmacPtr->Stats.XmitInterrupts++;
 		XEmac_CheckFifoSendError(EmacPtr);
 	}
 
-	if (IntrStatus & XIIF_V123B_ERROR_MASK) {
+    if (IntrStatus & XIIF_V123B_ERROR_MASK)
+    {
 		/*
 		 * An error occurred internal to the IPIF. This is more of a debug and
 		 * integration issue rather than a production error. Don't do anything
 		 * other than clear it, which provides a spot for software to trap
 		 * on the interrupt and begin debugging.
 		 */
-		XIIF_V123B_WRITE_DISR(EmacPtr->BaseAddress,
-				      XIIF_V123B_ERROR_MASK);
+	XIIF_V123B_WRITE_DISR(EmacPtr->BaseAddress, XIIF_V123B_ERROR_MASK);
 	}
 }
 
@@ -453,21 +459,23 @@ XEmac_IntrHandlerDma(void *InstancePtr)
 * caused confustion.
 *
 ******************************************************************************/
-XStatus
-XEmac_SetPktThreshold(XEmac * InstancePtr, u32 Direction, u8 Threshold)
+XStatus XEmac_SetPktThreshold(XEmac *InstancePtr, u32 Direction,
+                              u8 Threshold)
 {
-	XASSERT_NONVOID(InstancePtr != NULL);
+    XASSERT_NONVOID(InstancePtr != XNULL);
 	XASSERT_NONVOID(Direction == XEM_SEND || Direction == XEM_RECV);
 	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
 
 	/*
 	 * Be sure device is configured for scatter-gather DMA and has been stopped
 	 */
-	if (!XEmac_mIsSgDma(InstancePtr)) {
+    if (!XEmac_mIsSgDma(InstancePtr))
+    {
 		return XST_NOT_SGDMA;
 	}
 
-	if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+    if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED)
+    {
 		return XST_DEVICE_IS_STARTED;
 	}
 
@@ -476,7 +484,8 @@ XEmac_SetPktThreshold(XEmac * InstancePt
 	 * corresponding DMA channel component.  Default to the receive
 	 * channel threshold register (if an invalid Direction is passed).
 	 */
-	switch (Direction) {
+    switch (Direction)
+    {
 	case XEM_SEND:
 		return XDmaChannel_SetPktThreshold(&InstancePtr->SendChannel,
 						   Threshold);
@@ -520,15 +529,16 @@ XEmac_SetPktThreshold(XEmac * InstancePt
 * None.
 *
 ******************************************************************************/
-XStatus
-XEmac_GetPktThreshold(XEmac * InstancePtr, u32 Direction, u8 * ThreshPtr)
+XStatus XEmac_GetPktThreshold(XEmac *InstancePtr, u32 Direction,
+                              u8 *ThreshPtr)
 {
-	XASSERT_NONVOID(InstancePtr != NULL);
+    XASSERT_NONVOID(InstancePtr != XNULL);
 	XASSERT_NONVOID(Direction == XEM_SEND || Direction == XEM_RECV);
-	XASSERT_NONVOID(ThreshPtr != NULL);
+    XASSERT_NONVOID(ThreshPtr != XNULL);
 	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
 
-	if (!XEmac_mIsSgDma(InstancePtr)) {
+    if (!XEmac_mIsSgDma(InstancePtr))
+    {
 		return XST_NOT_SGDMA;
 	}
 
@@ -538,15 +548,14 @@ XEmac_GetPktThreshold(XEmac * InstancePt
 	 * the receive channel threshold register (if an invalid Direction
 	 * is passed).
 	 */
-	switch (Direction) {
+    switch (Direction)
+    {
 	case XEM_SEND:
-		*ThreshPtr =
-		    XDmaChannel_GetPktThreshold(&InstancePtr->SendChannel);
+	  *ThreshPtr = XDmaChannel_GetPktThreshold(&InstancePtr->SendChannel);
 		break;
 
 	case XEM_RECV:
-		*ThreshPtr =
-		    XDmaChannel_GetPktThreshold(&InstancePtr->RecvChannel);
+	  *ThreshPtr = XDmaChannel_GetPktThreshold(&InstancePtr->RecvChannel);
 		break;
 
 	default:
@@ -586,10 +595,10 @@ XEmac_GetPktThreshold(XEmac * InstancePt
 * None.
 *
 ******************************************************************************/
-XStatus
-XEmac_SetPktWaitBound(XEmac * InstancePtr, u32 Direction, u32 TimerValue)
+XStatus XEmac_SetPktWaitBound(XEmac *InstancePtr, u32 Direction,
+                              u32 TimerValue)
 {
-	XASSERT_NONVOID(InstancePtr != NULL);
+    XASSERT_NONVOID(InstancePtr != XNULL);
 	XASSERT_NONVOID(Direction == XEM_SEND || Direction == XEM_RECV);
 	XASSERT_NONVOID(TimerValue <= XEM_SGDMA_MAX_WAITBOUND);
 	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
@@ -597,11 +606,13 @@ XEmac_SetPktWaitBound(XEmac * InstancePt
 	/*
 	 * Be sure device is configured for scatter-gather DMA and has been stopped
 	 */
-	if (!XEmac_mIsSgDma(InstancePtr)) {
+    if (!XEmac_mIsSgDma(InstancePtr))
+    {
 		return XST_NOT_SGDMA;
 	}
 
-	if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+    if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED)
+    {
 		return XST_DEVICE_IS_STARTED;
 	}
 
@@ -610,15 +621,14 @@ XEmac_SetPktWaitBound(XEmac * InstancePt
 	 * corresponding DMA channel component.  Default to the receive
 	 * channel wait bound register (if an invalid Direction is passed).
 	 */
-	switch (Direction) {
+    switch (Direction)
+    {
 	case XEM_SEND:
-		XDmaChannel_SetPktWaitBound(&InstancePtr->SendChannel,
-					    TimerValue);
+	  XDmaChannel_SetPktWaitBound(&InstancePtr->SendChannel, TimerValue);
 		break;
 
 	case XEM_RECV:
-		XDmaChannel_SetPktWaitBound(&InstancePtr->RecvChannel,
-					    TimerValue);
+	  XDmaChannel_SetPktWaitBound(&InstancePtr->RecvChannel, TimerValue);
 		break;
 
 	default:
@@ -657,15 +667,16 @@ XEmac_SetPktWaitBound(XEmac * InstancePt
 * None.
 *
 ******************************************************************************/
-XStatus
-XEmac_GetPktWaitBound(XEmac * InstancePtr, u32 Direction, u32 * WaitPtr)
+XStatus XEmac_GetPktWaitBound(XEmac *InstancePtr, u32 Direction,
+                              u32 *WaitPtr)
 {
-	XASSERT_NONVOID(InstancePtr != NULL);
+    XASSERT_NONVOID(InstancePtr != XNULL);
 	XASSERT_NONVOID(Direction == XEM_SEND || Direction == XEM_RECV);
-	XASSERT_NONVOID(WaitPtr != NULL);
+    XASSERT_NONVOID(WaitPtr != XNULL);
 	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
 
-	if (!XEmac_mIsSgDma(InstancePtr)) {
+    if (!XEmac_mIsSgDma(InstancePtr))
+    {
 		return XST_NOT_SGDMA;
 	}
 
@@ -675,15 +686,14 @@ XEmac_GetPktWaitBound(XEmac * InstancePt
 	 * the receive channel wait bound register (if an invalid Direction
 	 * is passed).
 	 */
-	switch (Direction) {
+    switch (Direction)
+    {
 	case XEM_SEND:
-		*WaitPtr =
-		    XDmaChannel_GetPktWaitBound(&InstancePtr->SendChannel);
+	  *WaitPtr = XDmaChannel_GetPktWaitBound(&InstancePtr->SendChannel);
 		break;
 
 	case XEM_RECV:
-		*WaitPtr =
-		    XDmaChannel_GetPktWaitBound(&InstancePtr->RecvChannel);
+	  *WaitPtr = XDmaChannel_GetPktWaitBound(&InstancePtr->RecvChannel);
 		break;
 
 	default:
@@ -723,8 +733,7 @@ XEmac_GetPktWaitBound(XEmac * InstancePt
 * components must be initialized before the memory space is set.
 *
 ******************************************************************************/
-XStatus
-XEmac_SetSgRecvSpace(XEmac * InstancePtr, u32 * MemoryPtr,
+XStatus XEmac_SetSgRecvSpace(XEmac *InstancePtr, u32 *MemoryPtr,
 		     u32 ByteCount, void *PhyPtr)
 {
 	XASSERT_NONVOID(InstancePtr != NULL);
@@ -732,7 +741,8 @@ XEmac_SetSgRecvSpace(XEmac * InstancePtr
 	XASSERT_NONVOID(ByteCount != 0);
 	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
 
-	if (!XEmac_mIsSgDma(InstancePtr)) {
+    if (!XEmac_mIsSgDma(InstancePtr))
+    {
 		return XST_NOT_SGDMA;
 	}
 
@@ -770,8 +780,7 @@ XEmac_SetSgRecvSpace(XEmac * InstancePtr
 * components must be initialized before the memory space is set.
 *
 ******************************************************************************/
-XStatus
-XEmac_SetSgSendSpace(XEmac * InstancePtr, u32 * MemoryPtr,
+XStatus XEmac_SetSgSendSpace(XEmac *InstancePtr, u32 *MemoryPtr,
 		     u32 ByteCount, void *PhyPtr)
 {
 	XASSERT_NONVOID(InstancePtr != NULL);
@@ -779,7 +788,8 @@ XEmac_SetSgSendSpace(XEmac * InstancePtr
 	XASSERT_NONVOID(ByteCount != 0);
 	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
 
-	if (!XEmac_mIsSgDma(InstancePtr)) {
+    if (!XEmac_mIsSgDma(InstancePtr))
+    {
 		return XST_NOT_SGDMA;
 	}
 
@@ -789,6 +799,7 @@ XEmac_SetSgSendSpace(XEmac * InstancePtr
 
 /*****************************************************************************/
 /**
+ *
 * Return the number of free buffer descriptor slots that can be added to the 
 * send descriptor ring with XEmac_SgSend() before filling it up.
 *
@@ -804,8 +815,7 @@ XEmac_SetSgSendSpace(XEmac * InstancePtr
 * None.
 *
 ******************************************************************************/
-unsigned
-XEmac_GetSgSendFreeDesc(XEmac * InstancePtr)
+unsigned XEmac_GetSgSendFreeDesc(XEmac *InstancePtr)
 {
 	unsigned Slots;
 
@@ -836,8 +847,7 @@ XEmac_GetSgSendFreeDesc(XEmac * Instance
 * None.
 *
 ******************************************************************************/
-unsigned
-XEmac_GetSgRecvFreeDesc(XEmac * InstancePtr)
+unsigned XEmac_GetSgRecvFreeDesc(XEmac *InstancePtr)
 {
 	unsigned Slots;
 
@@ -853,7 +864,6 @@ XEmac_GetSgRecvFreeDesc(XEmac * Instance
 /*****************************************************************************/
 /**
 *
-*
 * Set the callback function for handling received frames in scatter-gather DMA
 * mode.  The upper layer software should call this function during
 * initialization.  The callback is called once per frame received. The head of
@@ -881,16 +891,15 @@ XEmac_GetSgRecvFreeDesc(XEmac * Instance
 * None.
 *
 ******************************************************************************/
-void
-XEmac_SetSgRecvHandler(XEmac * InstancePtr, void *CallBackRef,
+void XEmac_SetSgRecvHandler(XEmac *InstancePtr, void *CallBackRef,
 		       XEmac_SgHandler FuncPtr)
 {
 	/*
 	 * Asserted IsDmaSg here instead of run-time check because there is really
 	 * no ill-effects of setting these when not configured for scatter-gather.
 	 */
-	XASSERT_VOID(InstancePtr != NULL);
-	XASSERT_VOID(FuncPtr != NULL);
+    XASSERT_VOID(InstancePtr != XNULL);
+    XASSERT_VOID(FuncPtr != XNULL);
 	XASSERT_VOID(XEmac_mIsSgDma(InstancePtr));
 	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
 
@@ -927,16 +936,15 @@ XEmac_SetSgRecvHandler(XEmac * InstanceP
 * None.
 *
 ******************************************************************************/
-void
-XEmac_SetSgSendHandler(XEmac * InstancePtr, void *CallBackRef,
+void XEmac_SetSgSendHandler(XEmac *InstancePtr, void *CallBackRef,
 		       XEmac_SgHandler FuncPtr)
 {
 	/*
 	 * Asserted IsDmaSg here instead of run-time check because there is really
 	 * no ill-effects of setting these when not configured for scatter-gather.
 	 */
-	XASSERT_VOID(InstancePtr != NULL);
-	XASSERT_VOID(FuncPtr != NULL);
+    XASSERT_VOID(InstancePtr != XNULL);
+    XASSERT_VOID(FuncPtr != XNULL);
 	XASSERT_VOID(XEmac_mIsSgDma(InstancePtr));
 	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
 
@@ -992,8 +1000,7 @@ XEmac_SetSgSendHandler(XEmac * InstanceP
 * None.
 *
 ******************************************************************************/
-static void
-HandleDmaRecvIntr(XEmac * InstancePtr)
+static void HandleDmaRecvIntr(XEmac *InstancePtr)
 {
 	XStatus Result;
 	u32 IntrStatus;
@@ -1016,31 +1023,27 @@ HandleDmaRecvIntr(XEmac * InstancePtr)
 	 * hardware has room to put new packets.
 	 */
 	if (IntrStatus & (XDC_IXR_PKT_THRESHOLD_MASK |
-			  XDC_IXR_PKT_WAIT_BOUND_MASK | XDC_IXR_SG_END_MASK)) {
+		      XDC_IXR_PKT_WAIT_BOUND_MASK | XDC_IXR_SG_END_MASK))
+    {
 		/* Get the number of packets that need processing */
-		PacketsLeft =
-		    XDmaChannel_GetPktCount(&InstancePtr->RecvChannel);
+	PacketsLeft = XDmaChannel_GetPktCount(&InstancePtr->RecvChannel);
 
-		if (PacketsLeft) {
+	if (PacketsLeft)
+	{
 			/* Get the buffer descriptor at the head of the list */
-			Result =
-			    XDmaChannel_GetDescriptor(&InstancePtr->RecvChannel,
+	    Result = XDmaChannel_GetDescriptor(&InstancePtr->RecvChannel,
 						      &BdHeadPtr);
 			BdPtr = BdHeadPtr;
 			NumBds = 0;
 
 			/* Loop until all packets have been pulled or an error occurs */
-			while (1) {
-				char *buf_start;
-				int buf_len;
-
+	    while(1)
+	    {
 				NumBds++;
 			
-				/* flush buffer descriptor, if we aren't using 
-				   real uncached memory */
+		/* flush buffer descriptor, if we aren't using real uncached memory */
 			#if !CONFIG_XILINX_UNCACHED_SHADOW
-				flush_dcache_range((unsigned)BdPtr,
-							(unsigned)(BdPtr+1));
+		flush_dcache_range(BdPtr, (unsigned)(BdPtr + 1));
 			#endif
 				/*
 				 * An error getting a buffer descriptor from the list.
@@ -1048,38 +1051,36 @@ HandleDmaRecvIntr(XEmac * InstancePtr)
 				 * the error callback and break out of the loop to service
 				 * other interrupts.
 				 */
-				if (Result != XST_SUCCESS) {
-					InstancePtr->ErrorHandler(InstancePtr->
-								  ErrorRef,
-								  Result);
+		if (Result != XST_SUCCESS)
+		{
+		    InstancePtr->ErrorHandler(InstancePtr->ErrorRef, Result);
 					break;
 				}
+
 				/* Bump statistics */
-				InstancePtr->Stats.RecvBytes +=
-				    XBufDescriptor_GetLength(BdPtr);
+		InstancePtr->Stats.RecvBytes += XBufDescriptor_GetLength(BdPtr);
 
 				/* Have all BDs been read for this packet */
-				if (XBufDescriptor_IsLastStatus(BdPtr)) {
+		if (XBufDescriptor_IsLastStatus(BdPtr))
+		{
 					/*
 					 * Decrement the packet count register to reflect the fact
 					 * we just processed a packet
 					 */
-					XDmaChannel_DecrementPktCount
-					    (&InstancePtr->RecvChannel);
+		    XDmaChannel_DecrementPktCount(&InstancePtr->RecvChannel);
 
 					/* Bump statistics */
 					InstancePtr->Stats.RecvFrames++;
 
 					/* Test loop exit condition */
-					if (--PacketsLeft == 0) {
+		    if (--PacketsLeft == 0)
+		    {
 						break;
 					}
 				}
 
 				/* Get the next buffer descriptor in the list */
-				Result =
-				    XDmaChannel_GetDescriptor(&InstancePtr->
-							      RecvChannel,
+		Result = XDmaChannel_GetDescriptor(&InstancePtr->RecvChannel,
 							      &BdPtr);
 			}	/* while */
 
@@ -1088,19 +1089,18 @@ HandleDmaRecvIntr(XEmac * InstancePtr)
 			 * out of the for loop if there was one so other interrupts can
 			 * be serviced.
 			 */
-			if (Result == XST_SUCCESS) {
+	    if (Result == XST_SUCCESS)
+	    {
 				/*
 				 * Make the callback to the upper layers, passing it the first
 				 * descriptor in the first packet and the number of descriptors
 				 * in the list.
 				 */
-				InstancePtr->SgRecvHandler(InstancePtr->
-							   SgRecvRef, BdHeadPtr,
+		InstancePtr->SgRecvHandler(InstancePtr->SgRecvRef, BdHeadPtr,
 							   NumBds);
 			}
-		}
+	} /* if (PacketsLeft) */
 
-		/* if (PacketsLeft) */
 		/*
 		   * If the interrupt was an end-ack, check the descriptor list again to
 		   * see if it is empty. If not, go ahead and restart the scatter-gather
@@ -1112,7 +1112,8 @@ HandleDmaRecvIntr(XEmac * InstancePtr)
 		   * reached the end of the list.  In that case, this interrupt is
 		   * generated and we can restart the hardware here.
 		 */
-		if (IntrStatus & XDC_IXR_SG_END_MASK) {
+	if (IntrStatus & XDC_IXR_SG_END_MASK)
+	{
 			/*
 			 * Ignore the return status since we know the list exists and we
 			 * don't care if the list is empty or the channel is already started.
@@ -1138,7 +1139,8 @@ HandleDmaRecvIntr(XEmac * InstancePtr)
 	 * occurred (DMA bus or timeout error), which should result in a reset of
 	 * the device by the upper layer software.
 	 */
-	if (IntrStatus & XDC_IXR_DMA_ERROR_MASK) {
+    if (IntrStatus & XDC_IXR_DMA_ERROR_MASK)
+    {
 		InstancePtr->Stats.DmaErrors++;
 		InstancePtr->ErrorHandler(InstancePtr->ErrorRef, XST_DMA_ERROR);
 	}
@@ -1192,8 +1194,7 @@ HandleDmaRecvIntr(XEmac * InstancePtr)
 * None.
 *
 ******************************************************************************/
-static void
-HandleDmaSendIntr(XEmac * InstancePtr)
+static void HandleDmaSendIntr(XEmac *InstancePtr)
 {
 	XStatus Result;
 	u32 IntrStatus;
@@ -1218,31 +1219,29 @@ HandleDmaSendIntr(XEmac * InstancePtr)
 	 * always occur before the wait bound expires.
 	 */
 	if (IntrStatus & (XDC_IXR_PKT_THRESHOLD_MASK |
-			  XDC_IXR_PKT_WAIT_BOUND_MASK | XDC_IXR_SG_END_MASK)) {
+		      XDC_IXR_PKT_WAIT_BOUND_MASK | XDC_IXR_SG_END_MASK))
+    {
 		/* Get the number of packets that need processing */
-		PacketsLeft =
-		    XDmaChannel_GetPktCount(&InstancePtr->SendChannel);
+	PacketsLeft = XDmaChannel_GetPktCount(&InstancePtr->SendChannel);
 
-		if (PacketsLeft) {
+	if (PacketsLeft)
+	{
 			/* Get the buffer descriptor at the head of the list */
-			Result =
-			    XDmaChannel_GetDescriptor(&InstancePtr->SendChannel,
+	    Result = XDmaChannel_GetDescriptor(&InstancePtr->SendChannel,
 						      &BdHeadPtr);
 			BdPtr = BdHeadPtr;
 			NumBds = 0;
 			PacketStart = 1;
 
 			/* Loop until all packets have been pulled or an error occurs */
-			while (1) {
+	    while(1)
+	    {
 				NumBds++;
 
-				/* flush buffer descriptor, if we aren't using 
-				   real uncached memory */
+		/* flush buffer descriptor, if we aren't using real uncached memory */
 			#if !CONFIG_XILINX_UNCACHED_SHADOW
-				flush_dcache_range((unsigned)BdPtr,
-						(unsigned)(BdPtr+1));
+		flush_dcache_range(BdPtr, (unsigned)(BdPtr + 1));
 			#endif
-
 				/*
 				 * An error getting a buffer descriptor from the list.
 				 * This should not happen, but if it does, report it to
@@ -1249,51 +1248,47 @@ HandleDmaSendIntr(XEmac * InstancePtr)
 				 * the error callback and break out of the loop to service
 				 * other interrupts.
 				 */
-				if (Result != XST_SUCCESS) {
-					InstancePtr->ErrorHandler(InstancePtr->
-								  ErrorRef,
-								  Result);
+		if (Result != XST_SUCCESS)
+		{
+		    InstancePtr->ErrorHandler(InstancePtr->ErrorRef, Result);
 					break;
 				}
 
 				/* Bump statistics */
-				InstancePtr->Stats.XmitBytes +=
-				    XBufDescriptor_GetLength(BdPtr);
+		InstancePtr->Stats.XmitBytes += XBufDescriptor_GetLength(BdPtr);
  
 				/* If 1st BD in a packet, then check xmit status */
-				if (PacketStart) {
-					XmitStatus =
-					    XBufDescriptor_GetDeviceStatus
-					    (BdPtr);
-					if (XmitStatus &
-					    XEM_TSR_EXCESS_DEFERRAL_MASK) {
-						InstancePtr->Stats.
-						    XmitExcessDeferral++;
+		if (PacketStart)
+		{
+		    XmitStatus = XBufDescriptor_GetDeviceStatus(BdPtr);
+		    if (XmitStatus & XEM_TSR_EXCESS_DEFERRAL_MASK)
+		    {
+			InstancePtr->Stats.XmitExcessDeferral++;
 					}
 
-					if (XmitStatus &
-					    XEM_TSR_LATE_COLLISION_MASK) {
-						InstancePtr->Stats.
-						    XmitLateCollisionErrors++;
+		    if (XmitStatus & XEM_TSR_LATE_COLLISION_MASK)
+		    {
+			InstancePtr->Stats.XmitLateCollisionErrors++;
 					}
 
 					PacketStart = 0;
 				}
 
 				/* Have all BDs been read for this packet */
-				if (XBufDescriptor_IsLastStatus(BdPtr)) {
+		if (XBufDescriptor_IsLastStatus(BdPtr))
+		{
 					/*
 					 * Decrement the packet count register to reflect the fact
 					 * we just processed a packet
 					 */
-					XDmaChannel_DecrementPktCount
-					    (&InstancePtr->SendChannel);
+		    XDmaChannel_DecrementPktCount(&InstancePtr->SendChannel);
 
 					/* Bump statistics */
 					InstancePtr->Stats.XmitFrames++;
 
 					/* Test loop exit condition */
-					if (--PacketsLeft == 0) {
+		    if (--PacketsLeft == 0)
+		    {
 						break;
 					}
 
@@ -1302,9 +1297,7 @@ HandleDmaSendIntr(XEmac * InstancePtr)
 				}
 
 				/* Get the next buffer descriptor in the list */
-				Result =
-				    XDmaChannel_GetDescriptor(&InstancePtr->
-							      SendChannel,
+		Result = XDmaChannel_GetDescriptor(&InstancePtr->SendChannel,
 							      &BdPtr);
 			}	/* while */
 
@@ -1313,19 +1306,18 @@ HandleDmaSendIntr(XEmac * InstancePtr)
 			 * out of the for loop if there was one so other interrupts can
 			 * be serviced.
 			 */
-			if (Result == XST_SUCCESS) {
+	    if (Result == XST_SUCCESS)
+	    {
 				/*
 				 * Make the callback to the upper layers, passing it the first
 				 * descriptor in the first packet and the number of descriptors
 				 * in the list.
 				 */
-				InstancePtr->SgSendHandler(InstancePtr->
-							   SgSendRef, BdHeadPtr,
+		InstancePtr->SgSendHandler(InstancePtr->SgSendRef, BdHeadPtr,
 							   NumBds);
 			}
-		}
+	} /* if (PacketsLeft) */
 
-		/* if (PacketsLeft) */
 		/*
 		   * If the interrupt was an end-ack, check the descriptor list again to
 		   * see if it is empty. If not, go ahead and restart the scatter-gather
@@ -1337,7 +1329,8 @@ HandleDmaSendIntr(XEmac * InstancePtr)
 		   * reached the end of the list.  In that case, this interrupt is
 		   * generated and we can restart the hardware here.
 		 */
-		if (IntrStatus & XDC_IXR_SG_END_MASK) {
+	if (IntrStatus & XDC_IXR_SG_END_MASK)
+	{
 			/*
 			 * Ignore the return status since we know the list exists and we
 			 * don't care if the list is empty or the channel is already started.
@@ -1363,7 +1356,8 @@ HandleDmaSendIntr(XEmac * InstancePtr)
 	 * occurred (DMA bus or timeout error), which should result in a reset of
 	 * the device by the upper layer software.
 	 */
-	if (IntrStatus & XDC_IXR_DMA_ERROR_MASK) {
+    if (IntrStatus & XDC_IXR_DMA_ERROR_MASK)
+    {
 		InstancePtr->Stats.DmaErrors++;
 		InstancePtr->ErrorHandler(InstancePtr->ErrorRef, XST_DMA_ERROR);
 	}
@@ -1386,8 +1380,7 @@ HandleDmaSendIntr(XEmac * InstancePtr)
 * None.
 *
 ******************************************************************************/
-static void
-HandleEmacDmaIntr(XEmac * InstancePtr)
+static void HandleEmacDmaIntr(XEmac *InstancePtr)
 {
 	u32 IntrStatus;
 
Index: drivers/net/xilinx_enet/xemac_options.c
===================================================================
RCS file: /var/cvs/uClinux-2.4.x/drivers/net/xilinx_enet/xemac_options.c,v
retrieving revision 1.3
diff -u -b -B -w -p -r1.3 xemac_options.c