diff options
Diffstat (limited to 'board/xilinx/xilinx_enet/xemac_polled.c')
-rw-r--r-- | board/xilinx/xilinx_enet/xemac_polled.c | 482 |
1 files changed, 0 insertions, 482 deletions
diff --git a/board/xilinx/xilinx_enet/xemac_polled.c b/board/xilinx/xilinx_enet/xemac_polled.c deleted file mode 100644 index 23768bc..0000000 --- a/board/xilinx/xilinx_enet/xemac_polled.c +++ /dev/null @@ -1,482 +0,0 @@ -/****************************************************************************** -* -* 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; -} |