mirror of
				https://xff.cz/git/u-boot/
				synced 2025-10-31 02:15:45 +01:00 
			
		
		
		
	Add support for the Xilinx ML300 platform * Patch by Stephan Linz, 17 Feb 2004: Fix watchdog support for NIOS * Patch by Josh Fryman, 16 Feb 2004: Fix byte-swapping for cfi_flash.c for different bus widths * Patch by Jon Diekema, 14 Jeb 2004: Remove duplicate "FPGA Support" notes from the README file
		
			
				
	
	
		
			483 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			483 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /******************************************************************************
 | |
| *
 | |
| *     Author: Xilinx, Inc.
 | |
| *
 | |
| *
 | |
| *     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.
 | |
| *     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.
 | |
| *
 | |
| ******************************************************************************/
 | |
| /*****************************************************************************/
 | |
| /**
 | |
| *
 | |
| * @file xemac_polled.c
 | |
| *
 | |
| * Contains functions used when the driver is in polled mode. Use the
 | |
| * XEmac_SetOptions() function to put the driver into polled mode.
 | |
| *
 | |
| * <pre>
 | |
| * MODIFICATION HISTORY:
 | |
| *
 | |
| * Ver   Who  Date     Changes
 | |
| * ----- ---- -------- -----------------------------------------------
 | |
| * 1.00a rpm  07/31/01 First release
 | |
| * 1.00b rpm  02/20/02 Repartitioned files and functions
 | |
| * 1.00c rpm  12/05/02 New version includes support for simple DMA
 | |
| * </pre>
 | |
| *
 | |
| ******************************************************************************/
 | |
| 
 | |
| /***************************** Include Files *********************************/
 | |
| 
 | |
| #include "xbasic_types.h"
 | |
| #include "xemac_i.h"
 | |
| #include "xio.h"
 | |
| #include "xipif_v1_23_b.h"	/* Uses v1.23b of the IPIF */
 | |
| 
 | |
| /************************** Constant Definitions *****************************/
 | |
| 
 | |
| /**************************** Type Definitions *******************************/
 | |
| 
 | |
| /***************** Macros (Inline Functions) Definitions *********************/
 | |
| 
 | |
| /************************** Variable Definitions *****************************/
 | |
| 
 | |
| /************************** Function Prototypes ******************************/
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /**
 | |
| *
 | |
| * Send an Ethernet frame in polled mode.  The device/driver must be in polled
 | |
| * mode before calling this function. The driver writes the frame directly to
 | |
| * the MAC's packet FIFO, then enters a loop checking the device status for
 | |
| * completion or error. Statistics are updated if an error occurs. The buffer
 | |
| * to be sent must be word-aligned.
 | |
| *
 | |
| * It is assumed that the upper layer software supplies a correctly formatted
 | |
| * Ethernet frame, including the destination and source addresses, the
 | |
| * type/length field, and the data field.  It is also assumed that upper layer
 | |
| * software does not append FCS at the end of the frame.
 | |
| *
 | |
| * @param InstancePtr is a pointer to the XEmac instance to be worked on.
 | |
| * @param BufPtr is a pointer to a word-aligned buffer containing the Ethernet
 | |
| *        frame to be sent.
 | |
| * @param ByteCount is the size of the Ethernet frame.
 | |
| *
 | |
| * @return
 | |
| *
 | |
| * - XST_SUCCESS if the frame was sent successfully
 | |
| * - XST_DEVICE_IS_STOPPED if the device has not yet been started
 | |
| * - XST_NOT_POLLED if the device is not in polled mode
 | |
| * - XST_FIFO_NO_ROOM if there is no room in the EMAC's length FIFO for this frame
 | |
| * - XST_FIFO_ERROR if the FIFO was overrun or underrun. This error is critical
 | |
| *   and requires the caller to reset the device.
 | |
| * - XST_EMAC_COLLISION if the send failed due to excess deferral or late
 | |
| *   collision
 | |
| *
 | |
| * @note
 | |
| *
 | |
| * There is the possibility that this function will not return if the hardware
 | |
| * is broken (i.e., it never sets the status bit indicating that transmission is
 | |
| * done). If this is of concern to the user, the user should provide protection
 | |
| * from this problem - perhaps by using a different timer thread to monitor the
 | |
| * PollSend thread. On a 10Mbps MAC, it takes about 1.21 msecs to transmit a
 | |
| * maximum size Ethernet frame (1518 bytes). On a 100Mbps MAC, it takes about
 | |
| * 121 usecs to transmit a maximum size Ethernet frame.
 | |
| *
 | |
| * @internal
 | |
| *
 | |
| * The EMAC uses FIFOs behind its length and status registers. For this reason,
 | |
| * it is important to keep the length, status, and data FIFOs in sync when
 | |
| * reading or writing to them.
 | |
| *
 | |
| ******************************************************************************/
 | |
| XStatus
 | |
| XEmac_PollSend(XEmac * InstancePtr, u8 * BufPtr, u32 ByteCount)
 | |
| {
 | |
| 	u32 IntrStatus;
 | |
| 	u32 XmitStatus;
 | |
| 	XStatus Result;
 | |
| 
 | |
| 	XASSERT_NONVOID(InstancePtr != NULL);
 | |
| 	XASSERT_NONVOID(BufPtr != NULL);
 | |
| 	XASSERT_NONVOID(ByteCount > XEM_HDR_SIZE);	/* send at least 1 byte */
 | |
| 	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
 | |
| 
 | |
| 	/*
 | |
| 	 * Be sure the device is configured for polled mode and it is started
 | |
| 	 */
 | |
| 	if (!InstancePtr->IsPolled) {
 | |
| 		return XST_NOT_POLLED;
 | |
| 	}
 | |
| 
 | |
| 	if (InstancePtr->IsStarted != XCOMPONENT_IS_STARTED) {
 | |
| 		return XST_DEVICE_IS_STOPPED;
 | |
| 	}
 | |
| 
 | |
| 	/*
 | |
| 	 * Check for overruns and underruns for the transmit status and length
 | |
| 	 * FIFOs and make sure the send packet FIFO is not deadlocked. Any of these
 | |
| 	 * conditions is bad enough that we do not want to continue. The upper layer
 | |
| 	 * software should reset the device to resolve the error.
 | |
| 	 */
 | |
| 	IntrStatus = XIIF_V123B_READ_IISR(InstancePtr->BaseAddress);
 | |
| 
 | |
| 	/*
 | |
| 	 * Overrun errors
 | |
| 	 */
 | |
| 	if (IntrStatus & (XEM_EIR_XMIT_SFIFO_OVER_MASK |
 | |
| 			  XEM_EIR_XMIT_LFIFO_OVER_MASK)) {
 | |
| 		InstancePtr->Stats.XmitOverrunErrors++;
 | |
| 		InstancePtr->Stats.FifoErrors++;
 | |
| 		return XST_FIFO_ERROR;
 | |
| 	}
 | |
| 
 | |
| 	/*
 | |
| 	 * Underrun errors
 | |
| 	 */
 | |
| 	if (IntrStatus & (XEM_EIR_XMIT_SFIFO_UNDER_MASK |
 | |
| 			  XEM_EIR_XMIT_LFIFO_UNDER_MASK)) {
 | |
| 		InstancePtr->Stats.XmitUnderrunErrors++;
 | |
| 		InstancePtr->Stats.FifoErrors++;
 | |
| 		return XST_FIFO_ERROR;
 | |
| 	}
 | |
| 
 | |
| 	if (XPF_V100B_IS_DEADLOCKED(&InstancePtr->SendFifo)) {
 | |
| 		InstancePtr->Stats.FifoErrors++;
 | |
| 		return XST_FIFO_ERROR;
 | |
| 	}
 | |
| 
 | |
| 	/*
 | |
| 	 * Before writing to the data FIFO, make sure the length FIFO is not
 | |
| 	 * full.  The data FIFO might not be full yet even though the length FIFO
 | |
| 	 * is. This avoids an overrun condition on the length FIFO and keeps the
 | |
| 	 * FIFOs in sync.
 | |
| 	 */
 | |
| 	if (IntrStatus & XEM_EIR_XMIT_LFIFO_FULL_MASK) {
 | |
| 		/*
 | |
| 		 * Clear the latched LFIFO_FULL bit so next time around the most
 | |
| 		 * current status is represented
 | |
| 		 */
 | |
| 		XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress,
 | |
| 				      XEM_EIR_XMIT_LFIFO_FULL_MASK);
 | |
| 		return XST_FIFO_NO_ROOM;
 | |
| 	}
 | |
| 
 | |
| 	/*
 | |
| 	 * This is a non-blocking write. The packet FIFO returns an error if there
 | |
| 	 * is not enough room in the FIFO for this frame.
 | |
| 	 */
 | |
| 	Result =
 | |
| 	    XPacketFifoV100b_Write(&InstancePtr->SendFifo, BufPtr, ByteCount);
 | |
| 	if (Result != XST_SUCCESS) {
 | |
| 		return Result;
 | |
| 	}
 | |
| 
 | |
| 	/*
 | |
| 	 * Loop on the MAC's status to wait for any pause to complete.
 | |
| 	 */
 | |
| 	IntrStatus = XIIF_V123B_READ_IISR(InstancePtr->BaseAddress);
 | |
| 
 | |
| 	while ((IntrStatus & XEM_EIR_XMIT_PAUSE_MASK) != 0) {
 | |
| 		IntrStatus = XIIF_V123B_READ_IISR(InstancePtr->BaseAddress);
 | |
| 		/*
 | |
| 		   * Clear the pause status from the transmit status register
 | |
| 		 */
 | |
| 		XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress,
 | |
| 				      IntrStatus & XEM_EIR_XMIT_PAUSE_MASK);
 | |
| 	}
 | |
| 
 | |
| 	/*
 | |
| 	 * Set the MAC's transmit packet length register to tell it to transmit
 | |
| 	 */
 | |
| 	XIo_Out32(InstancePtr->BaseAddress + XEM_TPLR_OFFSET, ByteCount);
 | |
| 
 | |
| 	/*
 | |
| 	 * Loop on the MAC's status to wait for the transmit to complete. The
 | |
| 	 * transmit status is in the FIFO when the XMIT_DONE bit is set.
 | |
| 	 */
 | |
| 	do {
 | |
| 		IntrStatus = XIIF_V123B_READ_IISR(InstancePtr->BaseAddress);
 | |
| 	}
 | |
| 	while ((IntrStatus & XEM_EIR_XMIT_DONE_MASK) == 0);
 | |
| 
 | |
| 	XmitStatus = XIo_In32(InstancePtr->BaseAddress + XEM_TSR_OFFSET);
 | |
| 
 | |
| 	InstancePtr->Stats.XmitFrames++;
 | |
| 	InstancePtr->Stats.XmitBytes += ByteCount;
 | |
| 
 | |
| 	/*
 | |
| 	 * Check for various errors, bump statistics, and return an error status.
 | |
| 	 */
 | |
| 
 | |
| 	/*
 | |
| 	 * Overrun errors
 | |
| 	 */
 | |
| 	if (IntrStatus & (XEM_EIR_XMIT_SFIFO_OVER_MASK |
 | |
| 			  XEM_EIR_XMIT_LFIFO_OVER_MASK)) {
 | |
| 		InstancePtr->Stats.XmitOverrunErrors++;
 | |
| 		InstancePtr->Stats.FifoErrors++;
 | |
| 		return XST_FIFO_ERROR;
 | |
| 	}
 | |
| 
 | |
| 	/*
 | |
| 	 * Underrun errors
 | |
| 	 */
 | |
| 	if (IntrStatus & (XEM_EIR_XMIT_SFIFO_UNDER_MASK |
 | |
| 			  XEM_EIR_XMIT_LFIFO_UNDER_MASK)) {
 | |
| 		InstancePtr->Stats.XmitUnderrunErrors++;
 | |
| 		InstancePtr->Stats.FifoErrors++;
 | |
| 		return XST_FIFO_ERROR;
 | |
| 	}
 | |
| 
 | |
| 	/*
 | |
| 	 * Clear the interrupt status register of transmit statuses
 | |
| 	 */
 | |
| 	XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress,
 | |
| 			      IntrStatus & XEM_EIR_XMIT_ALL_MASK);
 | |
| 
 | |
| 	/*
 | |
| 	 * Collision errors are stored in the transmit status register
 | |
| 	 * instead of the interrupt status register
 | |
| 	 */
 | |
| 	if (XmitStatus & XEM_TSR_EXCESS_DEFERRAL_MASK) {
 | |
| 		InstancePtr->Stats.XmitExcessDeferral++;
 | |
| 		return XST_EMAC_COLLISION_ERROR;
 | |
| 	}
 | |
| 
 | |
| 	if (XmitStatus & XEM_TSR_LATE_COLLISION_MASK) {
 | |
| 		InstancePtr->Stats.XmitLateCollisionErrors++;
 | |
| 		return XST_EMAC_COLLISION_ERROR;
 | |
| 	}
 | |
| 
 | |
| 	return XST_SUCCESS;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /**
 | |
| *
 | |
| * Receive an Ethernet frame in polled mode. The device/driver must be in polled
 | |
| * mode before calling this function. The driver receives the frame directly
 | |
| * from the MAC's packet FIFO. This is a non-blocking receive, in that if there
 | |
| * is no frame ready to be received at the device, the function returns with an
 | |
| * error. The MAC's error status is not checked, so statistics are not updated
 | |
| * for polled receive. The buffer into which the frame will be received must be
 | |
| * word-aligned.
 | |
| *
 | |
| * @param InstancePtr is a pointer to the XEmac instance to be worked on.
 | |
| * @param BufPtr is a pointer to a word-aligned buffer into which the received
 | |
| *        Ethernet frame will be copied.
 | |
| * @param ByteCountPtr is both an input and an output parameter. It is a pointer
 | |
| *        to a 32-bit word that contains the size of the buffer on entry into the
 | |
| *        function and the size the received frame on return from the function.
 | |
| *
 | |
| * @return
 | |
| *
 | |
| * - XST_SUCCESS if the frame was sent successfully
 | |
| * - XST_DEVICE_IS_STOPPED if the device has not yet been started
 | |
| * - XST_NOT_POLLED if the device is not in polled mode
 | |
| * - XST_NO_DATA if there is no frame to be received from the FIFO
 | |
| * - XST_BUFFER_TOO_SMALL if the buffer to receive the frame is too small for
 | |
| *   the frame waiting in the FIFO.
 | |
| *
 | |
| * @note
 | |
| *
 | |
| * Input buffer must be big enough to hold the largest Ethernet frame. Buffer
 | |
| * must also be 32-bit aligned.
 | |
| *
 | |
| * @internal
 | |
| *
 | |
| * The EMAC uses FIFOs behind its length and status registers. For this reason,
 | |
| * it is important to keep the length, status, and data FIFOs in sync when
 | |
| * reading or writing to them.
 | |
| *
 | |
| ******************************************************************************/
 | |
| XStatus
 | |
| XEmac_PollRecv(XEmac * InstancePtr, u8 * BufPtr, u32 * ByteCountPtr)
 | |
| {
 | |
| 	XStatus Result;
 | |
| 	u32 PktLength;
 | |
| 	u32 IntrStatus;
 | |
| 
 | |
| 	XASSERT_NONVOID(InstancePtr != NULL);
 | |
| 	XASSERT_NONVOID(BufPtr != NULL);
 | |
| 	XASSERT_NONVOID(ByteCountPtr != NULL);
 | |
| 	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
 | |
| 
 | |
| 	/*
 | |
| 	 * Be sure the device is configured for polled mode and it is started
 | |
| 	 */
 | |
| 	if (!InstancePtr->IsPolled) {
 | |
| 		return XST_NOT_POLLED;
 | |
| 	}
 | |
| 
 | |
| 	if (InstancePtr->IsStarted != XCOMPONENT_IS_STARTED) {
 | |
| 		return XST_DEVICE_IS_STOPPED;
 | |
| 	}
 | |
| 
 | |
| 	/*
 | |
| 	 * Make sure the buffer is big enough to hold the maximum frame size.
 | |
| 	 * We need to do this because as soon as we read the MAC's packet length
 | |
| 	 * register, which is actually a FIFO, we remove that length from the
 | |
| 	 * FIFO.  We do not want to read the length FIFO without also reading the
 | |
| 	 * data FIFO since this would get the FIFOs out of sync.  So we have to
 | |
| 	 * make this restriction.
 | |
| 	 */
 | |
| 	if (*ByteCountPtr < XEM_MAX_FRAME_SIZE) {
 | |
| 		return XST_BUFFER_TOO_SMALL;
 | |
| 	}
 | |
| 
 | |
| 	/*
 | |
| 	 * First check for packet FIFO deadlock and return an error if it has
 | |
| 	 * occurred. A reset by the caller is necessary to correct this problem.
 | |
| 	 */
 | |
| 	if (XPF_V100B_IS_DEADLOCKED(&InstancePtr->RecvFifo)) {
 | |
| 		InstancePtr->Stats.FifoErrors++;
 | |
| 		return XST_FIFO_ERROR;
 | |
| 	}
 | |
| 
 | |
| 	/*
 | |
| 	 * Get the interrupt status to know what happened (whether an error occurred
 | |
| 	 * and/or whether frames have been received successfully). When clearing the
 | |
| 	 * intr status register, clear only statuses that pertain to receive.
 | |
| 	 */
 | |
| 	IntrStatus = XIIF_V123B_READ_IISR(InstancePtr->BaseAddress);
 | |
| 	XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress,
 | |
| 			      IntrStatus & XEM_EIR_RECV_ALL_MASK);
 | |
| 
 | |
| 	/*
 | |
| 	 * Check receive errors and bump statistics so the caller will have a clue
 | |
| 	 * as to why data may not have been received. We continue on if an error
 | |
| 	 * occurred since there still may be frames that were received successfully.
 | |
| 	 */
 | |
| 	if (IntrStatus & (XEM_EIR_RECV_LFIFO_OVER_MASK |
 | |
| 			  XEM_EIR_RECV_DFIFO_OVER_MASK)) {
 | |
| 		InstancePtr->Stats.RecvOverrunErrors++;
 | |
| 		InstancePtr->Stats.FifoErrors++;
 | |
| 	}
 | |
| 
 | |
| 	if (IntrStatus & XEM_EIR_RECV_LFIFO_UNDER_MASK) {
 | |
| 		InstancePtr->Stats.RecvUnderrunErrors++;
 | |
| 		InstancePtr->Stats.FifoErrors++;
 | |
| 	}
 | |
| 
 | |
| 	/*
 | |
| 	 * General receive errors
 | |
| 	 */
 | |
| 	if (IntrStatus & XEM_EIR_RECV_ERROR_MASK) {
 | |
| 		if (IntrStatus & XEM_EIR_RECV_MISSED_FRAME_MASK) {
 | |
| 			InstancePtr->Stats.RecvMissedFrameErrors =
 | |
| 			    XIo_In32(InstancePtr->BaseAddress +
 | |
| 				     XEM_RMFC_OFFSET);
 | |
| 		}
 | |
| 
 | |
| 		if (IntrStatus & XEM_EIR_RECV_COLLISION_MASK) {
 | |
| 			InstancePtr->Stats.RecvCollisionErrors =
 | |
| 			    XIo_In32(InstancePtr->BaseAddress + XEM_RCC_OFFSET);
 | |
| 		}
 | |
| 
 | |
| 		if (IntrStatus & XEM_EIR_RECV_FCS_ERROR_MASK) {
 | |
| 			InstancePtr->Stats.RecvFcsErrors =
 | |
| 			    XIo_In32(InstancePtr->BaseAddress +
 | |
| 				     XEM_RFCSEC_OFFSET);
 | |
| 		}
 | |
| 
 | |
| 		if (IntrStatus & XEM_EIR_RECV_LEN_ERROR_MASK) {
 | |
| 			InstancePtr->Stats.RecvLengthFieldErrors++;
 | |
| 		}
 | |
| 
 | |
| 		if (IntrStatus & XEM_EIR_RECV_SHORT_ERROR_MASK) {
 | |
| 			InstancePtr->Stats.RecvShortErrors++;
 | |
| 		}
 | |
| 
 | |
| 		if (IntrStatus & XEM_EIR_RECV_LONG_ERROR_MASK) {
 | |
| 			InstancePtr->Stats.RecvLongErrors++;
 | |
| 		}
 | |
| 
 | |
| 		if (IntrStatus & XEM_EIR_RECV_ALIGN_ERROR_MASK) {
 | |
| 			InstancePtr->Stats.RecvAlignmentErrors =
 | |
| 			    XIo_In32(InstancePtr->BaseAddress +
 | |
| 				     XEM_RAEC_OFFSET);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/*
 | |
| 	 * Before reading from the length FIFO, make sure the length FIFO is not
 | |
| 	 * empty. We could cause an underrun error if we try to read from an
 | |
| 	 * empty FIFO.
 | |
| 	 */
 | |
| 	if ((IntrStatus & XEM_EIR_RECV_DONE_MASK) == 0) {
 | |
| 		return XST_NO_DATA;
 | |
| 	}
 | |
| 
 | |
| 	/*
 | |
| 	 * Determine, from the MAC, the length of the next packet available
 | |
| 	 * in the data FIFO (there should be a non-zero length here)
 | |
| 	 */
 | |
| 	PktLength = XIo_In32(InstancePtr->BaseAddress + XEM_RPLR_OFFSET);
 | |
| 	if (PktLength == 0) {
 | |
| 		return XST_NO_DATA;
 | |
| 	}
 | |
| 
 | |
| 	/*
 | |
| 	 * Write the RECV_DONE bit in the status register to clear it. This bit
 | |
| 	 * indicates the RPLR is non-empty, and we know it's set at this point.
 | |
| 	 * We clear it so that subsequent entry into this routine will reflect the
 | |
| 	 * current status. This is done because the non-empty bit is latched in the
 | |
| 	 * IPIF, which means it may indicate a non-empty condition even though
 | |
| 	 * there is something in the FIFO.
 | |
| 	 */
 | |
| 	XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress, XEM_EIR_RECV_DONE_MASK);
 | |
| 
 | |
| 	/*
 | |
| 	 * We assume that the MAC never has a length bigger than the largest
 | |
| 	 * Ethernet frame, so no need to make another check here.
 | |
| 	 */
 | |
| 
 | |
| 	/*
 | |
| 	 * This is a non-blocking read. The FIFO returns an error if there is
 | |
| 	 * not at least the requested amount of data in the FIFO.
 | |
| 	 */
 | |
| 	Result =
 | |
| 	    XPacketFifoV100b_Read(&InstancePtr->RecvFifo, BufPtr, PktLength);
 | |
| 	if (Result != XST_SUCCESS) {
 | |
| 		return Result;
 | |
| 	}
 | |
| 
 | |
| 	InstancePtr->Stats.RecvFrames++;
 | |
| 	InstancePtr->Stats.RecvBytes += PktLength;
 | |
| 
 | |
| 	*ByteCountPtr = PktLength;
 | |
| 
 | |
| 	return XST_SUCCESS;
 | |
| }
 |