summaryrefslogtreecommitdiff
path: root/FreeRTOS/Demo/MicroBlaze_Kintex7_EthernetLite/BSP/microblaze_0/libsrc/emaclite_v4_0/src/xemaclite.c
diff options
context:
space:
mode:
Diffstat (limited to 'FreeRTOS/Demo/MicroBlaze_Kintex7_EthernetLite/BSP/microblaze_0/libsrc/emaclite_v4_0/src/xemaclite.c')
-rw-r--r--FreeRTOS/Demo/MicroBlaze_Kintex7_EthernetLite/BSP/microblaze_0/libsrc/emaclite_v4_0/src/xemaclite.c967
1 files changed, 967 insertions, 0 deletions
diff --git a/FreeRTOS/Demo/MicroBlaze_Kintex7_EthernetLite/BSP/microblaze_0/libsrc/emaclite_v4_0/src/xemaclite.c b/FreeRTOS/Demo/MicroBlaze_Kintex7_EthernetLite/BSP/microblaze_0/libsrc/emaclite_v4_0/src/xemaclite.c
new file mode 100644
index 000000000..5b5381159
--- /dev/null
+++ b/FreeRTOS/Demo/MicroBlaze_Kintex7_EthernetLite/BSP/microblaze_0/libsrc/emaclite_v4_0/src/xemaclite.c
@@ -0,0 +1,967 @@
+/******************************************************************************
+*
+* Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* Use of the Software is limited solely to applications:
+* (a) running on a Xilinx device, or
+* (b) that interact with a Xilinx device through a bus or interconnect.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in
+* this Software without prior written authorization from Xilinx.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xemaclite.c
+*
+* Functions in this file are the minimum required functions for the EmacLite
+* driver. See xemaclite.h for a detailed description of the driver.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ---- -------- --------------------------------------------------------
+* 1.01a ecm 01/31/04 First release
+* 1.11a mta 03/21/07 Updated to new coding style
+* 1.11a ecm 05/18/07 Updated the TxBufferAvailable routine to look at both
+* the active and busy bits
+* 1.13a sv 02/1/08 Updated the TxBufferAvailable routine to return
+* busy status properly
+* 2.00a ktn 02/16/09 Added support for MDIO
+* 2.01a ktn 07/20/09 Modified XEmacLite_Send function to use Ping buffers
+* Interrupt enable bit since this alone is used to enable
+* the interrupts for both Ping and Pong Buffers.
+* 3.00a ktn 10/22/09 Updated driver to use the HAL APIs/macros.
+* The macros have been renamed to remove _m from the name.
+* 3.01a ktn 07/08/10 The macro XEmacLite_GetReceiveDataLength is changed to
+* a static function.
+* Updated the XEmacLite_GetReceiveDataLength and
+* XEmacLite_Recv functions to support little endian
+* MicroBlaze.
+* 3.02a sdm 07/22/11 Removed redundant code in XEmacLite_Recv functions for
+* CR617290
+* 3.04a srt 04/13/13 Removed warnings (CR 705000).
+*
+* </pre>
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xil_io.h"
+#include "xenv.h"
+#include "xemaclite.h"
+#include "xemaclite_i.h"
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+static u16 XEmacLite_GetReceiveDataLength(u32 BaseAddress);
+
+/************************** Variable Definitions *****************************/
+
+/*****************************************************************************/
+/**
+*
+* Initialize a specific XEmacLite instance/driver. The initialization entails:
+* - Initialize fields of the XEmacLite instance structure.
+*
+* The driver defaults to polled mode operation.
+*
+* @param InstancePtr is a pointer to the XEmacLite instance.
+* @param EmacLiteConfigPtr points to the XEmacLite device configuration
+* structure.
+* @param EffectiveAddr is the device base address in the virtual memory
+* address space. If the address translation is not used then the
+* physical address is passed.
+* Unexpected errors may occur if the address mapping is changed
+* after this function is invoked.
+*
+* @return
+* - XST_SUCCESS if initialization was successful.
+*
+* @note The initialization of the PHY device is not done in this
+* function. The user needs to use XEmacLite_PhyRead and
+* XEmacLite_PhyWrite functions to access the PHY device.
+*
+******************************************************************************/
+int XEmacLite_CfgInitialize(XEmacLite *InstancePtr,
+ XEmacLite_Config *EmacLiteConfigPtr,
+ u32 EffectiveAddr)
+{
+
+ /*
+ * Verify that each of the inputs are valid.
+ */
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(EmacLiteConfigPtr != NULL);
+
+ /*
+ * Zero the provided instance memory.
+ */
+ memset(InstancePtr, 0, sizeof(XEmacLite));
+
+ /*
+ * Set some default values for instance data, don't indicate the device
+ * is ready to use until everything has been initialized successfully.
+ */
+ InstancePtr->EmacLiteConfig.BaseAddress = EffectiveAddr;
+ InstancePtr->EmacLiteConfig.DeviceId = EmacLiteConfigPtr->DeviceId;
+ InstancePtr->EmacLiteConfig.TxPingPong = EmacLiteConfigPtr->TxPingPong;
+ InstancePtr->EmacLiteConfig.RxPingPong = EmacLiteConfigPtr->RxPingPong;
+ InstancePtr->EmacLiteConfig.MdioInclude = EmacLiteConfigPtr->MdioInclude;
+ InstancePtr->EmacLiteConfig.Loopback = EmacLiteConfigPtr->Loopback;
+
+ InstancePtr->NextTxBufferToUse = 0x0;
+ InstancePtr->NextRxBufferToUse = 0x0;
+ InstancePtr->RecvHandler = (XEmacLite_Handler) StubHandler;
+ InstancePtr->SendHandler = (XEmacLite_Handler) StubHandler;
+
+ /*
+ * Clear the TX CSR's in case this is a restart.
+ */
+ XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
+ XEL_TSR_OFFSET, 0);
+ XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
+ XEL_BUFFER_OFFSET + XEL_TSR_OFFSET, 0);
+
+ /*
+ * Since there were no failures, indicate the device is ready to use.
+ */
+ InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Send an Ethernet frame. The ByteCount is the total frame size, including
+* header.
+*
+* @param InstancePtr is a pointer to the XEmacLite instance.
+* @param FramePtr is a pointer to frame. For optimal performance, a
+* 32-bit aligned buffer should be used but it is not required, the
+* function will align the data if necessary.
+* @param ByteCount is the size, in bytes, of the frame
+*
+* @return
+* - XST_SUCCESS if data was transmitted.
+* - XST_FAILURE if buffer(s) was (were) full and no valid data was
+* transmitted.
+*
+* @note
+*
+* This function call is not blocking in nature, i.e. it will not wait until the
+* frame is transmitted.
+*
+******************************************************************************/
+int XEmacLite_Send(XEmacLite *InstancePtr, u8 *FramePtr, unsigned ByteCount)
+{
+ u32 Register;
+ u32 BaseAddress;
+ u32 EmacBaseAddress;
+ u32 IntrEnableStatus;
+
+ /*
+ * Verify that each of the inputs are valid.
+ */
+ Xil_AssertNonvoid(InstancePtr != NULL);
+
+ /*
+ * Determine the expected TX buffer address.
+ */
+ BaseAddress = XEmacLite_NextTransmitAddr(InstancePtr);
+ EmacBaseAddress = InstancePtr->EmacLiteConfig.BaseAddress;
+
+ /*
+ * Check the Length if it is too large, truncate it.
+ * The maximum Tx packet size is
+ * Ethernet header (14 Bytes) + Maximum MTU (1500 bytes).
+ */
+ if (ByteCount > XEL_MAX_TX_FRAME_SIZE) {
+
+ ByteCount = XEL_MAX_TX_FRAME_SIZE;
+ }
+
+ /*
+ * Determine if the expected buffer address is empty.
+ */
+ Register = XEmacLite_GetTxStatus(BaseAddress);
+
+ /*
+ * If the expected buffer is available, fill it with the provided data
+ * Align if necessary.
+ */
+ if ((Register & (XEL_TSR_XMIT_BUSY_MASK |
+ XEL_TSR_XMIT_ACTIVE_MASK)) == 0) {
+
+ /*
+ * Switch to next buffer if configured.
+ */
+ if (InstancePtr->EmacLiteConfig.TxPingPong != 0) {
+ InstancePtr->NextTxBufferToUse ^= XEL_BUFFER_OFFSET;
+ }
+
+ /*
+ * Write the frame to the buffer.
+ */
+ XEmacLite_AlignedWrite(FramePtr, (u32 *) BaseAddress,
+ ByteCount);
+
+
+ /*
+ * The frame is in the buffer, now send it.
+ */
+ XEmacLite_WriteReg(BaseAddress, XEL_TPLR_OFFSET,
+ (ByteCount & (XEL_TPLR_LENGTH_MASK_HI |
+ XEL_TPLR_LENGTH_MASK_LO)));
+
+ /*
+ * Update the Tx Status Register to indicate that there is a
+ * frame to send.
+ * If the interrupt enable bit of Ping buffer(since this
+ * controls both the buffers) is enabled then set the
+ * XEL_TSR_XMIT_ACTIVE_MASK flag which is used by the interrupt
+ * handler to call the callback function provided by the user
+ * to indicate that the frame has been transmitted.
+ */
+ Register = XEmacLite_GetTxStatus(BaseAddress);
+ Register |= XEL_TSR_XMIT_BUSY_MASK;
+ IntrEnableStatus = XEmacLite_GetTxStatus(EmacBaseAddress);
+ if ((IntrEnableStatus & XEL_TSR_XMIT_IE_MASK) != 0) {
+ Register |= XEL_TSR_XMIT_ACTIVE_MASK;
+ }
+ XEmacLite_SetTxStatus(BaseAddress, Register);
+
+ return XST_SUCCESS;
+ }
+
+ /*
+ * If the expected buffer was full, try the other buffer if configured.
+ */
+ if (InstancePtr->EmacLiteConfig.TxPingPong != 0) {
+
+ BaseAddress ^= XEL_BUFFER_OFFSET;
+
+ /*
+ * Determine if the expected buffer address is empty.
+ */
+ Register = XEmacLite_GetTxStatus(BaseAddress);
+
+ /*
+ * If the next buffer is available, fill it with the provided
+ * data.
+ */
+ if ((Register & (XEL_TSR_XMIT_BUSY_MASK |
+ XEL_TSR_XMIT_ACTIVE_MASK)) == 0) {
+
+ /*
+ * Write the frame to the buffer.
+ */
+ XEmacLite_AlignedWrite(FramePtr, (u32 *) BaseAddress,
+ ByteCount);
+
+ /*
+ * The frame is in the buffer, now send it.
+ */
+ XEmacLite_WriteReg(BaseAddress, XEL_TPLR_OFFSET,
+ (ByteCount & (XEL_TPLR_LENGTH_MASK_HI |
+ XEL_TPLR_LENGTH_MASK_LO)));
+
+ /*
+ * Update the Tx Status Register to indicate that there
+ * is a frame to send.
+ * If the interrupt enable bit of Ping buffer(since this
+ * controls both the buffers) is enabled then set the
+ * XEL_TSR_XMIT_ACTIVE_MASK flag which is used by the
+ * interrupt handler to call the callback function
+ * provided by the user to indicate that the frame has
+ * been transmitted.
+ */
+ Register = XEmacLite_GetTxStatus(BaseAddress);
+ Register |= XEL_TSR_XMIT_BUSY_MASK;
+ IntrEnableStatus =
+ XEmacLite_GetTxStatus(EmacBaseAddress);
+ if ((IntrEnableStatus & XEL_TSR_XMIT_IE_MASK) != 0) {
+ Register |= XEL_TSR_XMIT_ACTIVE_MASK;
+ }
+ XEmacLite_SetTxStatus(BaseAddress, Register);
+
+ /*
+ * Do not switch to next buffer, there is a sync problem
+ * and the expected buffer should not change.
+ */
+ return XST_SUCCESS;
+ }
+ }
+
+
+ /*
+ * Buffer(s) was(were) full, return failure to allow for polling usage.
+ */
+ return XST_FAILURE;
+}
+
+/*****************************************************************************/
+/**
+*
+* Receive a frame. Intended to be called from the interrupt context or
+* with a wrapper which waits for the receive frame to be available.
+*
+* @param InstancePtr is a pointer to the XEmacLite instance.
+* @param FramePtr is a pointer to a buffer where the frame will
+* be stored. The buffer must be at least XEL_MAX_FRAME_SIZE bytes.
+* For optimal performance, a 32-bit aligned buffer should be used
+* but it is not required, the function will align the data if
+* necessary.
+*
+* @return
+*
+* The type/length field of the frame received. When the type/length field
+* contains the type, XEL_MAX_FRAME_SIZE bytes will be copied out of the
+* buffer and it is up to the higher layers to sort out the frame.
+* Function returns 0 if there is no data waiting in the receive buffer or
+* the pong buffer if configured.
+*
+* @note
+*
+* This function call is not blocking in nature, i.e. it will not wait until
+* a frame arrives.
+*
+******************************************************************************/
+u16 XEmacLite_Recv(XEmacLite *InstancePtr, u8 *FramePtr)
+{
+ u16 LengthType;
+ u16 Length;
+ u32 Register;
+ u32 BaseAddress;
+
+ /*
+ * Verify that each of the inputs are valid.
+ */
+
+ Xil_AssertNonvoid(InstancePtr != NULL);
+
+ /*
+ * Determine the expected buffer address.
+ */
+ BaseAddress = XEmacLite_NextReceiveAddr(InstancePtr);
+
+ /*
+ * Verify which buffer has valid data.
+ */
+ Register = XEmacLite_GetRxStatus(BaseAddress);
+
+ if ((Register & XEL_RSR_RECV_DONE_MASK) == XEL_RSR_RECV_DONE_MASK) {
+
+ /*
+ * The driver is in sync, update the next expected buffer if
+ * configured.
+ */
+
+ if (InstancePtr->EmacLiteConfig.RxPingPong != 0) {
+ InstancePtr->NextRxBufferToUse ^= XEL_BUFFER_OFFSET;
+ }
+ }
+ else {
+ /*
+ * The instance is out of sync, try other buffer if other
+ * buffer is configured, return 0 otherwise. If the instance is
+ * out of sync, do not update the 'NextRxBufferToUse' since it
+ * will correct on subsequent calls.
+ */
+ if (InstancePtr->EmacLiteConfig.RxPingPong != 0) {
+ BaseAddress ^= XEL_BUFFER_OFFSET;
+ }
+ else {
+ return 0; /* No data was available */
+ }
+
+ /*
+ * Verify that buffer has valid data.
+ */
+ Register = XEmacLite_GetRxStatus(BaseAddress);
+ if ((Register & XEL_RSR_RECV_DONE_MASK) !=
+ XEL_RSR_RECV_DONE_MASK) {
+ return 0; /* No data was available */
+ }
+ }
+
+ /*
+ * Get the length of the frame that arrived.
+ */
+ LengthType = XEmacLite_GetReceiveDataLength(BaseAddress);
+
+ /*
+ * Check if length is valid.
+ */
+ if (LengthType > XEL_MAX_FRAME_SIZE) {
+
+
+ if (LengthType == XEL_ETHER_PROTO_TYPE_IP) {
+
+ /*
+ * The packet is a an IP Packet.
+ */
+#ifdef __LITTLE_ENDIAN__
+ Length = (XEmacLite_ReadReg((BaseAddress),
+ XEL_HEADER_IP_LENGTH_OFFSET +
+ XEL_RXBUFF_OFFSET) &
+ (XEL_RPLR_LENGTH_MASK_HI |
+ XEL_RPLR_LENGTH_MASK_LO));
+ Length = (u16) (((Length & 0xFF00) >> 8) | ((Length & 0x00FF) << 8));
+#else
+ Length = ((XEmacLite_ReadReg((BaseAddress),
+ XEL_HEADER_IP_LENGTH_OFFSET +
+ XEL_RXBUFF_OFFSET) >>
+ XEL_HEADER_SHIFT) &
+ (XEL_RPLR_LENGTH_MASK_HI |
+ XEL_RPLR_LENGTH_MASK_LO));
+#endif
+
+ Length += XEL_HEADER_SIZE + XEL_FCS_SIZE;
+
+ } else if (LengthType == XEL_ETHER_PROTO_TYPE_ARP) {
+
+ /*
+ * The packet is an ARP Packet.
+ */
+ Length = XEL_ARP_PACKET_SIZE + XEL_HEADER_SIZE +
+ XEL_FCS_SIZE;
+
+ } else {
+ /*
+ * Field contains type other than IP or ARP, use max
+ * frame size and let user parse it.
+ */
+ Length = XEL_MAX_FRAME_SIZE;
+
+ }
+ } else {
+
+ /*
+ * Use the length in the frame, plus the header and trailer.
+ */
+ Length = LengthType + XEL_HEADER_SIZE + XEL_FCS_SIZE;
+ }
+
+ /*
+ * Read from the EmacLite.
+ */
+ XEmacLite_AlignedRead(((u32 *) (BaseAddress + XEL_RXBUFF_OFFSET)),
+ FramePtr, Length);
+
+ /*
+ * Acknowledge the frame.
+ */
+ Register = XEmacLite_GetRxStatus(BaseAddress);
+ Register &= ~XEL_RSR_RECV_DONE_MASK;
+ XEmacLite_SetRxStatus(BaseAddress, Register);
+
+ return Length;
+}
+
+/*****************************************************************************/
+/**
+*
+* Set the MAC address for this device. The address is a 48-bit value.
+*
+* @param InstancePtr is a pointer to the XEmacLite instance.
+* @param AddressPtr is a pointer to a 6-byte MAC address.
+* the format of the MAC address is major octet to minor octet
+*
+* @return None.
+*
+* @note
+*
+* - TX must be idle and RX should be idle for deterministic results.
+* It is recommended that this function should be called after the
+* initialization and before transmission of any packets from the device.
+* - Function will not return if hardware is absent or not functioning
+* properly.
+* - The MAC address can be programmed using any of the two transmit
+* buffers (if configured).
+*
+******************************************************************************/
+void XEmacLite_SetMacAddress(XEmacLite *InstancePtr, u8 *AddressPtr)
+{
+ u32 BaseAddress;
+
+ /*
+ * Verify that each of the inputs are valid.
+ */
+ Xil_AssertVoid(InstancePtr != NULL);
+
+ /*
+ * Determine the expected TX buffer address.
+ */
+ BaseAddress = XEmacLite_NextTransmitAddr(InstancePtr);
+
+ /*
+ * Copy the MAC address to the Transmit buffer.
+ */
+ XEmacLite_AlignedWrite(AddressPtr,
+ (u32 *) BaseAddress,
+ XEL_MAC_ADDR_SIZE);
+
+ /*
+ * Set the length.
+ */
+ XEmacLite_WriteReg(BaseAddress,
+ XEL_TPLR_OFFSET,
+ XEL_MAC_ADDR_SIZE);
+
+ /*
+ * Update the MAC address in the EmacLite.
+ */
+ XEmacLite_SetTxStatus(BaseAddress, XEL_TSR_PROG_MAC_ADDR);
+
+
+ /*
+ * Wait for EmacLite to finish with the MAC address update.
+ */
+ while ((XEmacLite_GetTxStatus(BaseAddress) &
+ XEL_TSR_PROG_MAC_ADDR) != 0);
+
+}
+
+/******************************************************************************/
+/**
+*
+* This is a stub for the send and receive callbacks. The stub
+* is here in case the upper layers forget to set the handlers.
+*
+* @param CallBackRef is a pointer to the upper layer callback reference.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void StubHandler(void *CallBackRef)
+{
+ (void)(CallBackRef);
+ Xil_AssertVoidAlways();
+}
+
+
+/****************************************************************************/
+/**
+*
+* Determine if there is a transmit buffer available.
+*
+* @param InstancePtr is the pointer to the instance of the driver to
+* be worked on.
+*
+* @return
+* - TRUE if there is a TX buffer available for data to be written
+* - FALSE if Tx Buffer is not available.
+*
+* @note None.
+*
+*****************************************************************************/
+int XEmacLite_TxBufferAvailable(XEmacLite *InstancePtr)
+{
+
+ u32 Register;
+ int TxPingBusy;
+ int TxPongBusy;
+
+ /*
+ * Verify that each of the inputs are valid.
+ */
+ Xil_AssertNonvoid(InstancePtr != NULL);
+
+ /*
+ * Read the Tx Status and determine if the buffer is available.
+ */
+ Register = XEmacLite_GetTxStatus(InstancePtr->EmacLiteConfig.
+ BaseAddress);
+
+ TxPingBusy = (Register & (XEL_TSR_XMIT_BUSY_MASK |
+ XEL_TSR_XMIT_ACTIVE_MASK));
+
+
+ /*
+ * Read the Tx Status of the second buffer register and determine if the
+ * buffer is available.
+ */
+ if (InstancePtr->EmacLiteConfig.TxPingPong != 0) {
+ Register = XEmacLite_GetTxStatus(InstancePtr->EmacLiteConfig.
+ BaseAddress +
+ XEL_BUFFER_OFFSET);
+
+ TxPongBusy = (Register & (XEL_TSR_XMIT_BUSY_MASK |
+ XEL_TSR_XMIT_ACTIVE_MASK));
+
+ return (!(TxPingBusy && TxPongBusy));
+ }
+
+ return (!TxPingBusy);
+
+
+}
+
+/****************************************************************************/
+/**
+*
+* Flush the Receive buffers. All data will be lost.
+*
+* @param InstancePtr is the pointer to the instance of the driver to
+* be worked on.
+*
+* @return None.
+*
+* @note None.
+*
+*****************************************************************************/
+void XEmacLite_FlushReceive(XEmacLite *InstancePtr)
+{
+
+ u32 Register;
+
+ /*
+ * Verify that each of the inputs are valid.
+ */
+ Xil_AssertVoid(InstancePtr != NULL);
+
+ /*
+ * Read the current buffer register and determine if the buffer is
+ * available.
+ */
+ Register = XEmacLite_GetRxStatus(InstancePtr->EmacLiteConfig.
+ BaseAddress);
+
+ /*
+ * Preserve the IE bit.
+ */
+ Register &= XEL_RSR_RECV_IE_MASK;
+
+ /*
+ * Write out the value to flush the RX buffer.
+ */
+ XEmacLite_SetRxStatus(InstancePtr->EmacLiteConfig.BaseAddress,
+ Register);
+
+ /*
+ * If the pong buffer is available, flush it also.
+ */
+ if (InstancePtr->EmacLiteConfig.RxPingPong != 0) {
+ /*
+ * Read the current buffer register and determine if the buffer
+ * is available.
+ */
+ Register = XEmacLite_GetRxStatus(InstancePtr->EmacLiteConfig.
+ BaseAddress +
+ XEL_BUFFER_OFFSET);
+
+ /*
+ * Preserve the IE bit.
+ */
+ Register &= XEL_RSR_RECV_IE_MASK;
+
+ /*
+ * Write out the value to flush the RX buffer.
+ */
+ XEmacLite_SetRxStatus(InstancePtr->EmacLiteConfig.BaseAddress +
+ XEL_BUFFER_OFFSET, Register);
+
+ }
+
+}
+
+/******************************************************************************/
+/**
+*
+* Read the specified PHY register.
+*
+* @param InstancePtr is the pointer to the instance of the driver.
+* @param PhyAddress is the address of the PHY device. The valid range is
+* is from 0 to 31.
+* @param RegNum is the register number in the PHY device which
+* is to be read. The valid range is is from 0 to 31.
+* @param PhyDataPtr is a pointer to the data in which the data read
+* from the PHY device is returned.
+*
+* @return
+* - XST_SUCCESS if the data is read from the PHY.
+* - XST_DEVICE_BUSY if MDIO is busy.
+*
+* @note This function waits for the completion of MDIO data transfer.
+*
+*****************************************************************************/
+int XEmacLite_PhyRead(XEmacLite *InstancePtr, u32 PhyAddress, u32 RegNum,
+ u16 *PhyDataPtr)
+{
+ u32 PhyAddrReg;
+ u32 MdioCtrlReg;
+
+ /*
+ * Verify that each of the inputs are valid.
+ */
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(InstancePtr->EmacLiteConfig.MdioInclude == TRUE);
+ Xil_AssertNonvoid(PhyAddress <= 31);
+ Xil_AssertNonvoid(RegNum <= 31);
+ Xil_AssertNonvoid(PhyDataPtr != NULL);
+
+ /*
+ * Verify MDIO master status.
+ */
+ if (XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
+ XEL_MDIOCNTR_OFFSET) &
+ XEL_MDIOCNTR_STATUS_MASK) {
+ return XST_DEVICE_BUSY;
+ }
+
+ PhyAddrReg = ((((PhyAddress << XEL_MDIO_ADDRESS_SHIFT) &
+ XEL_MDIO_ADDRESS_MASK) | RegNum) | XEL_MDIO_OP_MASK);
+ XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
+ XEL_MDIOADDR_OFFSET, PhyAddrReg);
+
+ /*
+ * Enable MDIO and start the transfer.
+ */
+ MdioCtrlReg =
+ XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
+ XEL_MDIOCNTR_OFFSET);
+ XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
+ XEL_MDIOCNTR_OFFSET,
+ MdioCtrlReg |
+ XEL_MDIOCNTR_STATUS_MASK |
+ XEL_MDIOCNTR_ENABLE_MASK);
+
+ /*
+ * Wait till the completion of transfer.
+ */
+ while ((XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
+ XEL_MDIOCNTR_OFFSET) &
+ XEL_MDIOCNTR_STATUS_MASK));
+
+ /*
+ * Read data from MDIO read data register.
+ */
+ *PhyDataPtr = (u16)XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
+ XEL_MDIORD_OFFSET);
+
+ /*
+ * Disable the MDIO.
+ */
+ MdioCtrlReg =
+ XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
+ XEL_MDIOCNTR_OFFSET);
+
+ XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
+ XEL_MDIOCNTR_OFFSET,
+ MdioCtrlReg & ~XEL_MDIOCNTR_ENABLE_MASK);
+
+
+ return XST_SUCCESS;
+}
+
+/******************************************************************************/
+/**
+*
+* Write the given data to the specified register in the PHY device.
+*
+* @param InstancePtr is the pointer to the instance of the driver.
+* @param PhyAddress is the address of the PHY device. The valid range is
+* is from 0 to 31.
+* @param RegNum is the register number in the PHY device which
+* is to be written. The valid range is is from 0 to 31.
+* @param PhyData is the data to be written to the specified register in
+* the PHY device.
+*
+* @return
+* - XST_SUCCESS if the data is written to the PHY.
+* - XST_DEVICE_BUSY if MDIO is busy.
+*
+* @note This function waits for the completion of MDIO data transfer.
+*
+*******************************************************************************/
+int XEmacLite_PhyWrite(XEmacLite *InstancePtr, u32 PhyAddress, u32 RegNum,
+ u16 PhyData)
+{
+ u32 PhyAddrReg;
+ u32 MdioCtrlReg;
+
+ /*
+ * Verify that each of the inputs are valid.
+ */
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(InstancePtr->EmacLiteConfig.MdioInclude == TRUE);
+ Xil_AssertNonvoid(PhyAddress <= 31);
+ Xil_AssertNonvoid(RegNum <= 31);
+
+ /*
+ * Verify MDIO master status.
+ */
+ if (XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
+ XEL_MDIOCNTR_OFFSET) &
+ XEL_MDIOCNTR_STATUS_MASK) {
+ return XST_DEVICE_BUSY;
+ }
+
+
+
+ PhyAddrReg = ((((PhyAddress << XEL_MDIO_ADDRESS_SHIFT) &
+ XEL_MDIO_ADDRESS_MASK) | RegNum) & ~XEL_MDIO_OP_MASK);
+ XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
+ XEL_MDIOADDR_OFFSET, PhyAddrReg);
+
+ /*
+ * Write data to MDIO write data register.
+ */
+ XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
+ XEL_MDIOWR_OFFSET, (u32)PhyData);
+
+ /*
+ * Enable MDIO and start the transfer.
+ */
+ MdioCtrlReg =
+ XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
+ XEL_MDIOCNTR_OFFSET);
+ XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
+ XEL_MDIOCNTR_OFFSET,
+ MdioCtrlReg | XEL_MDIOCNTR_STATUS_MASK |
+ XEL_MDIOCNTR_ENABLE_MASK);
+
+ /*
+ * Wait till the completion of transfer.
+ */
+ while ((XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
+ XEL_MDIOCNTR_OFFSET) & XEL_MDIOCNTR_STATUS_MASK));
+
+
+ /*
+ * Disable the MDIO.
+ */
+ MdioCtrlReg =
+ XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
+ XEL_MDIOCNTR_OFFSET);
+ XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
+ XEL_MDIOCNTR_OFFSET,
+ MdioCtrlReg & ~XEL_MDIOCNTR_ENABLE_MASK);
+
+
+
+ return XST_SUCCESS;
+}
+
+
+
+/****************************************************************************/
+/**
+*
+* Enable Internal loop back functionality.
+*
+* @param InstancePtr is the pointer to the instance of the driver.
+*
+* @return None.
+*
+* @note None.
+*
+*****************************************************************************/
+void XEmacLite_EnableLoopBack(XEmacLite *InstancePtr)
+{
+ u32 TsrReg;
+
+ /*
+ * Verify that each of the inputs are valid.
+ */
+ Xil_AssertVoid(InstancePtr != NULL);
+ Xil_AssertVoid(InstancePtr->EmacLiteConfig.Loopback == TRUE);
+
+ TsrReg = XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
+ XEL_TSR_OFFSET);
+ XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
+ XEL_TSR_OFFSET, TsrReg | XEL_TSR_LOOPBACK_MASK);
+}
+
+/****************************************************************************/
+/**
+*
+* Disable Internal loop back functionality.
+*
+* @param InstancePtr is the pointer to the instance of the driver.
+*
+* @return None.
+*
+* @note None.
+*
+*****************************************************************************/
+void XEmacLite_DisableLoopBack(XEmacLite *InstancePtr)
+{
+ u32 TsrReg;
+
+ /*
+ * Verify that each of the inputs are valid.
+ */
+ Xil_AssertVoid(InstancePtr != NULL);
+ Xil_AssertVoid(InstancePtr->EmacLiteConfig.Loopback == TRUE);
+
+ TsrReg = XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
+ XEL_TSR_OFFSET);
+ XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
+ XEL_TSR_OFFSET, TsrReg & (~XEL_TSR_LOOPBACK_MASK));
+}
+
+
+/*****************************************************************************/
+/**
+*
+* Return the length of the data in the Receive Buffer.
+*
+* @param BaseAddress contains the base address of the device.
+*
+* @return The type/length field of the frame received.
+*
+* @note None.
+*
+******************************************************************************/
+static u16 XEmacLite_GetReceiveDataLength(u32 BaseAddress)
+{
+ u16 Length;
+
+#ifdef __LITTLE_ENDIAN__
+ Length = (XEmacLite_ReadReg((BaseAddress),
+ XEL_HEADER_OFFSET + XEL_RXBUFF_OFFSET) &
+ (XEL_RPLR_LENGTH_MASK_HI | XEL_RPLR_LENGTH_MASK_LO));
+ Length = (u16) (((Length & 0xFF00) >> 8) | ((Length & 0x00FF) << 8));
+#else
+ Length = ((XEmacLite_ReadReg((BaseAddress),
+ XEL_HEADER_OFFSET + XEL_RXBUFF_OFFSET) >>
+ XEL_HEADER_SHIFT) &
+ (XEL_RPLR_LENGTH_MASK_HI | XEL_RPLR_LENGTH_MASK_LO));
+#endif
+
+ return Length;
+}
+