396 lines
11 KiB
C
396 lines
11 KiB
C
![]() |
/******************************************************************************
|
||
|
*
|
||
|
* 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 THE
|
||
|
* XILINX CONSORTIUM 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_polled_example.c
|
||
|
*
|
||
|
* This file contains an example for using the EmacLite hardware and driver.
|
||
|
* This file contains an polled mode example outlining the transmission/reception
|
||
|
* of an Ethernet frame of 1000 bytes of payload.
|
||
|
*
|
||
|
* If the MDIO interface is NOT configured in the EmacLite core then this example
|
||
|
* will only transmit a frame.
|
||
|
* If the MDIO interface is configured in the EmacLite core then this example
|
||
|
* will enable the MAC loopback in the PHY device, then transmit the frame and
|
||
|
* compare the received frame.
|
||
|
*
|
||
|
* @note
|
||
|
*
|
||
|
* <pre>
|
||
|
* MODIFICATION HISTORY:
|
||
|
*
|
||
|
* Ver Who Date Changes
|
||
|
* ----- ---- -------- -----------------------------------------------
|
||
|
* 1.01a ecm 21/05/04 First release
|
||
|
* 1.01a sv 06/06/05 Minor changes to comply to Doxygen and coding guidelines
|
||
|
* 2.00a ktn 02/25/09 Updated to use PHY loop back if MDIO is configured in
|
||
|
* core and updated to be used in Test App
|
||
|
* 3.00a ktn 10/22/09 Updated example to use the macros that have been changed
|
||
|
* in the driver to remove _m from the name of the macro.
|
||
|
* 3.01a ktn 07/08/10 Updated example to support Little Endian MicroBlaze.
|
||
|
*
|
||
|
* </pre>
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
/***************************** Include Files *********************************/
|
||
|
|
||
|
#include "xemaclite_example.h"
|
||
|
|
||
|
/************************** Constant Definitions *****************************/
|
||
|
|
||
|
/*
|
||
|
* The Size of the Test Frame.
|
||
|
*/
|
||
|
#define EMACLITE_TEST_FRAME_SIZE 1000
|
||
|
|
||
|
/**************************** Type Definitions *******************************/
|
||
|
|
||
|
/***************** Macros (Inline Functions) Definitions *********************/
|
||
|
|
||
|
/************************** Function Prototypes ******************************/
|
||
|
|
||
|
int EmacLitePolledExample(u16 DeviceId);
|
||
|
|
||
|
static int EmacLiteSendFrame(XEmacLite *InstancePtr, u32 PayloadSize);
|
||
|
|
||
|
static int EmacLiteRecvFrame(u32 PayloadSize);
|
||
|
|
||
|
/************************** Variable Definitions *****************************/
|
||
|
|
||
|
/*
|
||
|
* Set up valid local and remote MAC addresses. This loop back test uses the
|
||
|
* LocalAddress both as a source and destination MAC address.
|
||
|
*/
|
||
|
static u8 LocalAddress[XEL_MAC_ADDR_SIZE] =
|
||
|
{
|
||
|
0x00, 0x0A, 0x35, 0x01, 0x02, 0x03
|
||
|
};
|
||
|
static u8 RemoteAddress[XEL_MAC_ADDR_SIZE] =
|
||
|
{
|
||
|
0x00, 0x10, 0xa4, 0xb6, 0xfd, 0x09
|
||
|
};
|
||
|
|
||
|
/****************************************************************************/
|
||
|
/**
|
||
|
*
|
||
|
* This function is the main function of the EmacLite polled example.
|
||
|
*
|
||
|
* @param None.
|
||
|
*
|
||
|
* @return XST_SUCCESS to indicate success, otherwise XST_FAILURE .
|
||
|
*
|
||
|
* @note None.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
#ifndef TESTAPP_GEN
|
||
|
int main()
|
||
|
{
|
||
|
int Status;
|
||
|
|
||
|
/*
|
||
|
* Run the EmacLite Polled example, specify the Device ID that is
|
||
|
* generated in xparameters.h.
|
||
|
*/
|
||
|
Status = EmacLitePolledExample(EMAC_DEVICE_ID);
|
||
|
if (Status != XST_SUCCESS) {
|
||
|
return XST_FAILURE;
|
||
|
}
|
||
|
|
||
|
return XST_SUCCESS;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/*****************************************************************************/
|
||
|
/**
|
||
|
*
|
||
|
* The main entry point for the EmacLite driver example in polled mode.
|
||
|
*
|
||
|
* This function will transmit/receive the Ethernet frames and verify the
|
||
|
* data in the received frame (if the MDIO interface is configured in the
|
||
|
* EmacLite core).
|
||
|
* This function simply transmits a frame if the MDIO interface is not
|
||
|
* configured in the EmacLite core.
|
||
|
*
|
||
|
* @param DeviceId is device ID of the XEmacLite Device , typically
|
||
|
* XPAR_<EMAC_instance>_DEVICE_ID value from xparameters.h.
|
||
|
*
|
||
|
* @return XST_SUCCESS to indicate success, XST_FAILURE otherwise.
|
||
|
*
|
||
|
* @note None.
|
||
|
*
|
||
|
******************************************************************************/
|
||
|
int EmacLitePolledExample(u16 DeviceId)
|
||
|
{
|
||
|
int Status;
|
||
|
XEmacLite *EmacLiteInstPtr = &EmacLiteInstance;
|
||
|
u32 PhyAddress = 0;
|
||
|
RecvFrameLength = 0;
|
||
|
XEmacLite_Config *ConfigPtr;
|
||
|
|
||
|
/*
|
||
|
* Initialize the EmacLite device.
|
||
|
*/
|
||
|
ConfigPtr = XEmacLite_LookupConfig(DeviceId);
|
||
|
if (ConfigPtr == NULL) {
|
||
|
return XST_FAILURE;
|
||
|
}
|
||
|
Status = XEmacLite_CfgInitialize(EmacLiteInstPtr,
|
||
|
ConfigPtr,
|
||
|
ConfigPtr->BaseAddress);
|
||
|
if (Status != XST_SUCCESS) {
|
||
|
return XST_FAILURE;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Set the MAC address.
|
||
|
*/
|
||
|
XEmacLite_SetMacAddress(EmacLiteInstPtr, LocalAddress);
|
||
|
|
||
|
/*
|
||
|
* Empty any existing receive frames.
|
||
|
*/
|
||
|
XEmacLite_FlushReceive(EmacLiteInstPtr);
|
||
|
|
||
|
/*
|
||
|
* Check if there is a TX buffer available, if there isn't it is an
|
||
|
* error.
|
||
|
*/
|
||
|
if (XEmacLite_TxBufferAvailable(EmacLiteInstPtr) != TRUE) {
|
||
|
return XST_FAILURE;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* If the MDIO is configured in the device.
|
||
|
*/
|
||
|
if (XEmacLite_IsMdioConfigured(EmacLiteInstPtr)) {
|
||
|
/*
|
||
|
* Detect the PHY device and enable the MAC Loop back
|
||
|
* in the PHY.
|
||
|
*/
|
||
|
PhyAddress = EmacLitePhyDetect(EmacLiteInstPtr);
|
||
|
Status = EmacLiteEnablePhyLoopBack(EmacLiteInstPtr,
|
||
|
PhyAddress);
|
||
|
if (Status != XST_SUCCESS) {
|
||
|
return XST_FAILURE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Reset the receive frame length to zero.
|
||
|
*/
|
||
|
RecvFrameLength = 0;
|
||
|
Status = EmacLiteSendFrame(EmacLiteInstPtr, EMACLITE_TEST_FRAME_SIZE);
|
||
|
if (Status != XST_SUCCESS) {
|
||
|
if (XEmacLite_IsMdioConfigured(EmacLiteInstPtr)) {
|
||
|
/*
|
||
|
* Disable the MAC Loop back in the PHY.
|
||
|
*/
|
||
|
EmacLiteDisablePhyLoopBack(EmacLiteInstPtr,
|
||
|
PhyAddress);
|
||
|
return XST_FAILURE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* If the MDIO is not configured in the core then return XST_SUCCESS
|
||
|
* as the frame has been transmitted.
|
||
|
*/
|
||
|
if (!XEmacLite_IsMdioConfigured(EmacLiteInstPtr)) {
|
||
|
return XST_SUCCESS;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Poll for receive packet.
|
||
|
*/
|
||
|
while ((volatile u32)RecvFrameLength == 0) {
|
||
|
RecvFrameLength = XEmacLite_Recv(EmacLiteInstPtr,
|
||
|
(u8 *)RxFrame);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Check the received frame.
|
||
|
*/
|
||
|
Status = EmacLiteRecvFrame(EMACLITE_TEST_FRAME_SIZE);
|
||
|
if ((Status != XST_SUCCESS) && (Status != XST_NO_DATA)) {
|
||
|
/*
|
||
|
* Disable the MAC Loop back in the PHY.
|
||
|
*/
|
||
|
EmacLiteDisablePhyLoopBack(EmacLiteInstPtr, PhyAddress);
|
||
|
return XST_FAILURE;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Disable the MAC Loop back in the PHY.
|
||
|
*/
|
||
|
EmacLiteDisablePhyLoopBack(EmacLiteInstPtr, PhyAddress);
|
||
|
|
||
|
return XST_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/******************************************************************************/
|
||
|
/**
|
||
|
*
|
||
|
* This function sends a frame of given size.
|
||
|
*
|
||
|
* @param XEmacInstancePtr is a pointer to the XEmacLite instance.
|
||
|
* @param PayloadSize is the size of the frame to create. The size only
|
||
|
* reflects the payload size, it does not include the Ethernet
|
||
|
* header size (14 bytes) nor the Ethernet CRC size (4 bytes).
|
||
|
*
|
||
|
* @return XST_SUCCESS if successful, else a driver-specific return code.
|
||
|
*
|
||
|
* @note None.
|
||
|
*
|
||
|
******************************************************************************/
|
||
|
static int EmacLiteSendFrame(XEmacLite *InstancePtr, u32 PayloadSize)
|
||
|
{
|
||
|
u8 *FramePtr;
|
||
|
int Index;
|
||
|
FramePtr = (u8 *)TxFrame;
|
||
|
|
||
|
/*
|
||
|
* Set up the destination address as the local address for
|
||
|
* Phy Loopback.
|
||
|
*/
|
||
|
if (XEmacLite_IsMdioConfigured(InstancePtr)) {
|
||
|
|
||
|
*FramePtr++ = LocalAddress[0];
|
||
|
*FramePtr++ = LocalAddress[1];
|
||
|
*FramePtr++ = LocalAddress[2];
|
||
|
*FramePtr++ = LocalAddress[3];
|
||
|
*FramePtr++ = LocalAddress[4];
|
||
|
*FramePtr++ = LocalAddress[5];
|
||
|
} else {
|
||
|
/*
|
||
|
* Fill in the valid Destination MAC address if
|
||
|
* the Loopback is not enabled.
|
||
|
*/
|
||
|
*FramePtr++ = RemoteAddress[0];
|
||
|
*FramePtr++ = RemoteAddress[1];
|
||
|
*FramePtr++ = RemoteAddress[2];
|
||
|
*FramePtr++ = RemoteAddress[3];
|
||
|
*FramePtr++ = RemoteAddress[4];
|
||
|
*FramePtr++ = RemoteAddress[5];
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Fill in the source MAC address.
|
||
|
*/
|
||
|
*FramePtr++ = LocalAddress[0];
|
||
|
*FramePtr++ = LocalAddress[1];
|
||
|
*FramePtr++ = LocalAddress[2];
|
||
|
*FramePtr++ = LocalAddress[3];
|
||
|
*FramePtr++ = LocalAddress[4];
|
||
|
*FramePtr++ = LocalAddress[5];
|
||
|
|
||
|
/*
|
||
|
* Set up the type/length field - be sure its in network order.
|
||
|
*/
|
||
|
*((u16 *)FramePtr) = Xil_Htons(PayloadSize);
|
||
|
FramePtr++;
|
||
|
FramePtr++;
|
||
|
|
||
|
/*
|
||
|
* Now fill in the data field with known values so we can verify them
|
||
|
* on receive.
|
||
|
*/
|
||
|
for (Index = 0; Index < PayloadSize; Index++) {
|
||
|
*FramePtr++ = (u8)Index;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Now send the frame.
|
||
|
*/
|
||
|
return XEmacLite_Send(InstancePtr, (u8 *)TxFrame,
|
||
|
PayloadSize + XEL_HEADER_SIZE);
|
||
|
|
||
|
}
|
||
|
|
||
|
/******************************************************************************/
|
||
|
/**
|
||
|
*
|
||
|
* This function receives a frame of given size. This function assumes interrupt
|
||
|
* mode, receives the frame and verifies its contents.
|
||
|
*
|
||
|
* @param PayloadSize is the size of the frame to receive.
|
||
|
* The size only reflects the payload size, it does not include the
|
||
|
* Ethernet header size (14 bytes) nor the Ethernet CRC size (4
|
||
|
* bytes).
|
||
|
*
|
||
|
* @return XST_SUCCESS if successful, a driver-specific return code if not.
|
||
|
*
|
||
|
* @note None.
|
||
|
*
|
||
|
******************************************************************************/
|
||
|
static int EmacLiteRecvFrame(u32 PayloadSize)
|
||
|
{
|
||
|
u8 *FramePtr;
|
||
|
|
||
|
/*
|
||
|
* This assumes MAC does not strip padding or CRC.
|
||
|
*/
|
||
|
if (RecvFrameLength != 0) {
|
||
|
int Index;
|
||
|
|
||
|
/*
|
||
|
* Verify length, which should be the payload size.
|
||
|
*/
|
||
|
if ((RecvFrameLength- (XEL_HEADER_SIZE + XEL_FCS_SIZE)) !=
|
||
|
PayloadSize) {
|
||
|
return XST_LOOPBACK_ERROR;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Verify the contents of the Received Frame.
|
||
|
*/
|
||
|
FramePtr = (u8 *)RxFrame;
|
||
|
FramePtr += XEL_HEADER_SIZE; /* Get past the header */
|
||
|
|
||
|
for (Index = 0; Index < PayloadSize; Index++) {
|
||
|
if (*FramePtr++ != (u8)Index) {
|
||
|
return XST_LOOPBACK_ERROR;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return XST_SUCCESS;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|