diff --git a/XilinxProcessorIPLib/drivers/emaclite/data/dependencies.props b/XilinxProcessorIPLib/drivers/emaclite/data/dependencies.props new file mode 100644 index 00000000..d5ea2da8 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/emaclite/data/dependencies.props @@ -0,0 +1,7 @@ +xemaclite_selftest_example.c=xemaclite_example.h,xemaclite_example_util.c +xemaclite_polled_example.c=xemaclite_example.h,xemaclite_example_util.c +xemaclite_intr_example.c=xemaclite_example.h,xemaclite_example_util.c +xemaclite_phy_loopback_example.c=xemaclite_example.h,xemaclite_example_util.c +xemaclite_ping_req_example.c=xemaclite_example.h,xemaclite_example_util.c +xemaclite_ping_reply_example.c=xemaclite_example.h,xemaclite_example_util.c +xemaclite_internal_loopback_example=xemaclite_example.h,xemaclite_example_util.c diff --git a/XilinxProcessorIPLib/drivers/emaclite/data/emaclite.mdd b/XilinxProcessorIPLib/drivers/emaclite/data/emaclite.mdd new file mode 100755 index 00000000..cc7ef038 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/emaclite/data/emaclite.mdd @@ -0,0 +1,47 @@ +############################################################################### +# +# 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. +# +# MODIFICATION HISTORY: +# +# Ver Who Date Changes +# -------- ------ -------- -------------------------------------------------- +# 4.0 adk 10/12/13 Removed support for xps emaclite +############################################################################## +OPTION psf_version = 2.1; + +BEGIN driver emaclite + + OPTION supported_peripherals = (axi_ethernetlite); + OPTION driver_state = ACTIVE; + OPTION copyfiles = all; + OPTION VERSION = 4.1; + OPTION NAME = emaclite; + +END driver diff --git a/XilinxProcessorIPLib/drivers/emaclite/data/emaclite.tcl b/XilinxProcessorIPLib/drivers/emaclite/data/emaclite.tcl new file mode 100755 index 00000000..68c0cb47 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/emaclite/data/emaclite.tcl @@ -0,0 +1,57 @@ +############################################################################### +# +# 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. +# +# Modification History +# +# Ver Who Date Changes +# ----- ---- -------- ----------------------------------------------- +# 4.0 adk 10/12/13 Updated as per the New Tcl API's +##################################################################### + +## @BEGIN_CHANGELOG EDK_M +## Removed the local ::hsi::utils::define_canonical_xpars API as there is +## a common API in the tcl of the tools +## +## @END_CHANGELOG + +## @BEGIN_CHANGELOG EDK_LS3 +## Updated to handle the corner cases described in CR #518193 while +## generating canonical definitions +## +## @END_CHANGELOG + +#uses "xillib.tcl" + +proc generate {drv_handle} { + ::hsi::utils::define_include_file $drv_handle "xparameters.h" "XEmacLite" "NUM_INSTANCES" "DEVICE_ID" "C_BASEADDR" "C_HIGHADDR" "C_TX_PING_PONG" "C_RX_PING_PONG" "C_INCLUDE_MDIO" "C_INCLUDE_INTERNAL_LOOPBACK" + ::hsi::utils::define_config_file $drv_handle "xemaclite_g.c" "XEmacLite" "DEVICE_ID" "C_BASEADDR" "C_TX_PING_PONG" "C_RX_PING_PONG" "C_INCLUDE_MDIO" "C_INCLUDE_INTERNAL_LOOPBACK" + + ::hsi::utils::define_canonical_xpars $drv_handle "xparameters.h" "EmacLite" "DEVICE_ID" "C_BASEADDR" "C_HIGHADDR" "C_TX_PING_PONG" "C_RX_PING_PONG" "C_INCLUDE_MDIO" "C_INCLUDE_INTERNAL_LOOPBACK" +} diff --git a/XilinxProcessorIPLib/drivers/emaclite/data/emaclite_header.h b/XilinxProcessorIPLib/drivers/emaclite/data/emaclite_header.h new file mode 100644 index 00000000..927f25a5 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/emaclite/data/emaclite_header.h @@ -0,0 +1,42 @@ +/****************************************************************************** +* +* Copyright (C) 2003 - 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. +* +******************************************************************************/ +#ifndef EMACLITE_HEADER_H /* prevent circular inclusions */ +#define EMACLITE_HEADER_H /* by using protection macros */ + + +#include "xil_types.h" +#include "xil_assert.h" +#include "xstatus.h" + +int EmacLitePolledExample(u16 DeviceId); + +#endif diff --git a/XilinxProcessorIPLib/drivers/emaclite/data/emaclite_intr_header.h b/XilinxProcessorIPLib/drivers/emaclite/data/emaclite_intr_header.h new file mode 100644 index 00000000..5f3e0b45 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/emaclite/data/emaclite_intr_header.h @@ -0,0 +1,52 @@ +/****************************************************************************** +* +* Copyright (C) 2003 - 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. +* +******************************************************************************/ +#ifndef EMACLITE_INTR_HEADER_H /* prevent circular inclusions */ +#define EMACLITE_INTR_HEADER_H /* by using protection macros */ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xstatus.h" + + +#ifdef XPAR_INTC_0_DEVICE_ID +int EmacLiteIntrExample(XIntc* IntcInstancePtr, + XEmacLite* EmacLiteInstPtr, + u16 EmacLiteDeviceId, + u16 EmacLiteIntrId); +#else +int EmacLiteIntrExample(XScuGic* IntcInstancePtr, + XEmacLite* EmacLiteInstPtr, + u16 EmacLiteDeviceId, + u16 EmacLiteIntrId); + +#endif +#endif diff --git a/XilinxProcessorIPLib/drivers/emaclite/data/emaclite_tapp.tcl b/XilinxProcessorIPLib/drivers/emaclite/data/emaclite_tapp.tcl new file mode 100755 index 00000000..6b451b79 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/emaclite/data/emaclite_tapp.tcl @@ -0,0 +1,227 @@ +############################################################################### +# +# Copyright (C) 2005 - 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. +# +# +# Ver Who Date Changes +# ----- ---- -------- ----------------------------------------------- +# 4.0 adk 10/12/13 Updated as per the New Tcl API's +############################################################################## + + +## @BEGIN_CHANGELOG EDK_I +## +## - include header files +## +## @END_CHANGELOG + +## @BEGIN_CHANGELOG EDK_H +## +## - Initial Revision +## +## @END_CHANGELOG + +## @BEGIN_CHANGELOG EDK_LS2 +## +## - Updated the tcl to use additional files provided with the examples +## +## @END_CHANGELOG + +# Uses $XILINX_EDK/bin/lib/xillib_sw.tcl + +# ----------------------------------------------------------------- +# Software Project Types (swproj): +# 0 : MemoryTest - Calls basic memorytest routines from common driver dir +# 1 : PeripheralTest - Calls any existing polled_example and/or selftest +# ----------------------------------------------------------------- + +# ----------------------------------------------------------------- +# TCL Procedures: +# ----------------------------------------------------------------- + +proc gen_include_files {swproj mhsinst} { + if {$swproj == 0} { + return "" + } + if {$swproj == 1} { + set ifemacliteintr [::hsi::utils::is_ip_interrupting_current_proc $mhsinst] + if {$ifemacliteintr == 1} { + set inc_file_lines {xemaclite.h xemaclite_example.h emaclite_header.h emaclite_intr_header.h} + } else { + set inc_file_lines {xemaclite.h xemaclite_example.h emaclite_header.h} + } + return $inc_file_lines + } +} + +proc gen_src_files {swproj mhsinst} { + if {$swproj == 0} { + return "" + } + if {$swproj == 1} { + set ifemacliteintr [::hsi::utils::is_ip_interrupting_current_proc $mhsinst] + if {$ifemacliteintr == 1} { + set inc_file_lines {examples/xemaclite_example.h examples/xemaclite_polled_example.c examples/xemaclite_intr_example.c examples/xemaclite_example_util.c data/emaclite_header.h data/emaclite_intr_header.h} + } else { + set inc_file_lines {examples/xemaclite_example.h examples/xemaclite_polled_example.c examples/xemaclite_example_util.c data/emaclite_header.h} + } + return $inc_file_lines + } +} + +proc gen_testfunc_def {swproj mhsinst} { + return "" +} + +proc gen_init_code {swproj mhsinst} { + if {$swproj == 0} { + return "" + } + if {$swproj == 1} { + + set ipname [common::get_property NAME $mhsinst] + set ifemacliteintr [::hsi::utils::is_ip_interrupting_current_proc $mhsinst] + if {$ifemacliteintr == 1} { + set decl " static XEmacLite ${ipname}_EmacLite;" + set inc_file_lines $decl + return $inc_file_lines + } else { + return "" + } + } + +} + +proc gen_testfunc_call {swproj mhsinst} { + + if {$swproj == 0} { + return "" + } + + set ifemacliteintr [::hsi::utils::is_ip_interrupting_current_proc $mhsinst] + set ipname [common::get_property NAME $mhsinst] + set deviceid [::hsi::utils::get_ip_param_name $mhsinst "DEVICE_ID"] + set stdout [common::get_property CONFIG.STDOUT [hsi::get_os]] + if { $stdout == "" || $stdout == "none" } { + set hasStdout 0 + } else { + set hasStdout 1 + } + + + if {$ifemacliteintr == 1} { + set intr_pin_name [hsi::get_pins -of_objects [hsi::get_cells $ipname] -filter "TYPE==INTERRUPT"] + set intcname [::hsi::utils::get_connected_intr_cntrl $ipname $intr_pin_name] + set intcvar intc + set proc [common::get_property IP_NAME [hsi::get_cells [hsi::get_sw_processor]]] + } + + set testfunc_call "" + + if {${hasStdout} == 0} { + + append testfunc_call " + + { + int status; + + status = EmacLitePolledExample(${deviceid}); + }" + + if {$ifemacliteintr == 1} { + if { + $proc == "microblaze" + } then { + set intr_id "XPAR_${intcname}_${ipname}_${intr_pin_name}_INTR" + } else { + set intr_id "XPAR_FABRIC_${ipname}_${intr_pin_name}_INTR" + } + set intr_id [string toupper $intr_id] + + append testfunc_call " + + { + int Status; + Status = EmacLiteIntrExample(&${intcvar}, &${ipname}_EmacLite, \\ + ${deviceid}, \\ + ${intr_id}); + }" + + } + + } else { + + append testfunc_call " + + { + int status; + + print(\"\\r\\nRunning EmacLitePolledExample() for ${ipname}...\\r\\n\"); + status = EmacLitePolledExample(${deviceid}); + if (status == 0) { + print(\"EmacLite Polled Example PASSED\\r\\n\"); + } + else { + print(\"EmacLite Polled Example FAILED\\r\\n\"); + } + }" + + if {$ifemacliteintr == 1} { + if { + $proc == "microblaze" + } then { + set intr_id "XPAR_${intcname}_${ipname}_${intr_pin_name}_INTR" + } else { + set intr_id "XPAR_FABRIC_${ipname}_${intr_pin_name}_INTR" + } + set intr_id [string toupper $intr_id] + + append testfunc_call " + { + int Status; + + print(\"\\r\\n Running Interrupt Test for ${ipname}...\\r\\n\"); + + Status = EmacLiteIntrExample(&${intcvar}, &${ipname}_EmacLite, \\ + ${deviceid}, \\ + ${intr_id}); + + if (Status == 0) { + print(\"EmacLite Interrupt Test PASSED\\r\\n\"); + } + else { + print(\"EmacLite Interrupt Test FAILED\\r\\n\"); + } + + }" + + } + } + return $testfunc_call +} diff --git a/XilinxProcessorIPLib/drivers/emaclite/examples/index.html b/XilinxProcessorIPLib/drivers/emaclite/examples/index.html new file mode 100755 index 00000000..85e91870 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/emaclite/examples/index.html @@ -0,0 +1,24 @@ + + + + + +Driver example applications + + + +

Example Applications for the driver emaclite_v4_0

+
+ +

Copyright � 1995-2014 Xilinx, Inc. All rights reserved.

+ + diff --git a/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_example.h b/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_example.h new file mode 100644 index 00000000..3eb673df --- /dev/null +++ b/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_example.h @@ -0,0 +1,134 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 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_example.h +* +* Defines common data types, prototypes, and includes the proper headers +* for use with the EmacLite example code residing in this directory. +* +* This file along with xemaclite_example_util.c are utilized with the specific +* example code in the other source code files provided. +* +* These examples are designed to be compiled and utilized within the EDK +* standalone BSP development environment. The readme file contains more +* information on build requirements needed by these examples. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 2.00a ktn  04/13/09 First release
+* 3.03a bss  09/01/12 Moved the declarations of RecvFrameLength
+*		      TransmitComplete, EmacLiteInstance,
+*		      TxFrame[XEL_MAX_FRAME_SIZE], RxFrame[XEL_MAX_FRAME_SIZE];
+* 		      to xemaclite_example_util.c for fixing C++ compilation
+*		      errors
+* 
+* +******************************************************************************/ +#ifndef XEMACLITE_EXAMPLE_H +#define XEMACLITE_EXAMPLE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xparameters.h" +#include "xemaclite.h" + +/************************** Constant Definitions ****************************/ + +#define PHY_REG0_OFFSET 0 /* Register 0 of PHY device */ +#define PHY_REG1_OFFSET 1 /* Register 1 of PHY device */ + +#define PHY_REG0_RESET_MASK 0x8000 /* Reset Phy device */ +#define PHY_REG0_LOOPBACK_MASK 0x4000 /* Loopback Enable in Phy */ +#define PHY_REG0_SPD_100_MASK 0x2000 /* Speed of 100Mbps for Phy */ + +#define PHY_REG1_DETECT_MASK 0x1808 /* Mask to detect PHY device */ + +#define EMACLITE_PHY_DELAY_SEC 4 /* Amount of time to delay waiting on + * PHY to reset. + */ + +/* + * The following constants map to the XPAR parameters created in the + * xparameters.h file. They are defined here such that a user can easily + * change all the needed parameters in one place. + */ +#define EMAC_DEVICE_ID XPAR_EMACLITE_0_DEVICE_ID + +/***************** Macros (Inline Functions) Definitions *********************/ + +/**************************** Type Definitions ******************************/ + +/************************** Function Prototypes *****************************/ + +/* + * Utility functions implemented in xemaclite_example_util.c + */ +void EmacLitePhyDelay(unsigned int Seconds); +u32 EmacLitePhyDetect(XEmacLite *InstancePtr); +int EmacLiteEnablePhyLoopBack(XEmacLite *InstancePtr, u32 PhyAddress); +int EmacLiteDisablePhyLoopBack(XEmacLite *InstancePtr, u32 PhyAddress); + +/************************** Variable Definitions ****************************/ +/* + * Set up valid local MAC addresses. This loop back test uses the LocalAddress + * both as a source and destination MAC address. + */ + +extern XEmacLite EmacLiteInstance; /* Instance of the EmacLite */ + +/* + * Buffers used for Transmission and Reception of Packets. These are declared + * as global so that they are not a part of the stack. + */ +extern u8 TxFrame[XEL_MAX_FRAME_SIZE]; +extern u8 RxFrame[XEL_MAX_FRAME_SIZE]; + +extern volatile u32 RecvFrameLength; /* Indicates the length of the + * Received packet + */ +extern volatile int TransmitComplete; /* Flag to indicate that the + * Transmission is complete + */ +#ifdef __cplusplus +} +#endif + +#endif /* XEMACLITE_EXAMPLE_H */ diff --git a/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_example_readme.txt b/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_example_readme.txt new file mode 100755 index 00000000..084a3c04 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_example_readme.txt @@ -0,0 +1,60 @@ +xemaclite_example_readme.txt +------------------------- + +The examples in this directory are provided to give the user some idea of +how the EmacLite and its driver/examples are intended to be used. + +SYSTEM REQUIREMENTS + +The system containing the EmacLite should have the following capabilities: + + - Processor based system + - At least one EmacLite core + - An interrupt controller + - An external memory controller with at least 200KB of RAM available + - A UART to display messages + +FILES + +1. xemaclite_example.h - Top level include for all examples. + This file needs to be included in xemaclite_phy_loopback_example, + xemaclite_polled_example, xemaclite_intr_example and + xemaclite_internal_loopback_example.c + +2. xemaclite_example_util.c - Provide various functions for Phy setup. + This file needs to be used with xemaclite_phy_loopback_example, + xemaclite_polled_example, xemaclite_intr_example and + xemaclite_internal_loopback_example.c + +3. xemaclite_polled_example.c - Example using the emaclite driver + in polled mode. + +4. xemaclite_intr_example.c - Example using the emaclite driver + in interrupt mode. + +5. xemaclite_phy_loopback_example.c - Example using the emaclite driver + in interrupt mode using the MAC loop back in the PHY. This example can + be run only when the MDIO interface is configured in the EmacLite core. + +6. xemaclite_ping_rq_example.c - This is a polled mode example generating a + ping request for a specified IP address. + +7. xemaclite_ping_reply_example.c - This is a polled mode example generating a + ping reply when it receives a ping packet from the external world. + +8. xemaclite_selftest_example.c - This is a example based on the self test. + +9.xemaclite_internal_loopback_example.c - + This file contains an interrupt example outlining the use of interrupts and + callbacks in the transmission/reception of Ethernet frames using internal + loop back with an incrementing payload from 1 byte to 1500 bytes (excluding + Ethernet Header and FCS). + + + +INCLUDING EXAMPLES IN EDK/SDK + +Each example is independent from the others except for common code found in +xemaclite_example_util.c. When including source code files in an EDK/SDK SW +application, select xemaclite_example_util.c along with one other example +source code file. diff --git a/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_example_util.c b/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_example_util.c new file mode 100644 index 00000000..ae9d871a --- /dev/null +++ b/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_example_util.c @@ -0,0 +1,272 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 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_example_util.c +* +* This file implements the utility functions for the EmacLite example code. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 2.00a  ktn 04/13/09 First release
+* 2.00a  ktn 06/13/09 Changed the EmacLitePhyDetect function so that
+*		      the function is not in an infinite loop in case of a
+*		      faulty Phy device.
+* 3.03a  bss 09/01/12 Moved the declarations of RecvFrameLength,
+*                     TransmitComplete, EmacLiteInstance
+*		      TxFrame[XEL_MAX_FRAME_SIZE], RxFrame[XEL_MAX_FRAME_SIZE]
+*		      from the xemaclite_example.h
+*		      to this file for fixing C++ compilation errors
+*
+******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xemaclite_example.h" +#include "stdio.h" + +/************************** Variable Definitions ****************************/ + +/* + * Set up valid local MAC addresses. This loop back test uses the LocalAddress + * both as a source and destination MAC address. + */ + +XEmacLite EmacLiteInstance; /* Instance of the EmacLite */ + +/* + * Buffers used for Transmission and Reception of Packets. These are declared + * as global so that they are not a part of the stack. + */ +u8 TxFrame[XEL_MAX_FRAME_SIZE]; +u8 RxFrame[XEL_MAX_FRAME_SIZE]; + +volatile u32 RecvFrameLength; /* Indicates the length of the Received packet + */ +volatile int TransmitComplete; /* Flag to indicate that the Transmission + * is complete + */ + +/******************************************************************************/ +/** +* +* This function detects the PHY address by looking for successful MII status +* register contents (PHY register 1). It looks for a PHY that supports +* auto-negotiation and 10Mbps full-duplex and half-duplex. So, this code +* won't work for PHYs that don't support those features, but it's a bit more +* general purpose than matching a specific PHY manufacturer ID. +* +* Note also that on some (older) Xilinx ML4xx boards, PHY address 0 does not +* properly respond to this query. But, since the default is 0 and assuming +* no other address responds, then it seems to work OK. +* +* @param InstancePtr is the pointer to the instance of EmacLite driver. +* +* @return The address of the PHY device detected (returns 0 if not +* detected). +* +* @note +* The bit mask (0x1808) of the MII status register +* (PHY Register 1) used in this function are: +* 0x1000: 10Mbps full duplex support. +* 0x0800: 10Mbps half duplex support. +* 0x0008: Auto-negotiation support. +* +******************************************************************************/ +u32 EmacLitePhyDetect(XEmacLite *InstancePtr) +{ + u16 PhyData; + int PhyAddr; + + /* + * Verify all 32 MDIO ports. + */ + for (PhyAddr = 31; PhyAddr >= 0; PhyAddr--) { + XEmacLite_PhyRead(InstancePtr, PhyAddr, PHY_REG1_OFFSET, + &PhyData); + + if (PhyData != 0xFFFF) { + if ((PhyData & PHY_REG1_DETECT_MASK) == + PHY_REG1_DETECT_MASK) { + return PhyAddr; /* Found a valid PHY device */ + } + } + } + /* + * Unable to detect PHY device returning the default address of 0. + */ + return 0; +} + +/******************************************************************************/ +/** +* +* This function enables the MAC loopback on the PHY. +* +* @param InstancePtr is the pointer to the instance of EmacLite driver. +* @param PhyAddress is the address of the Phy device. +* +* @return +* - XST_SUCCESS if the loop back is enabled. +* - XST_FAILURE if the loop back was not enabled. +* +* @note None. +* +******************************************************************************/ +int EmacLiteEnablePhyLoopBack(XEmacLite *InstancePtr, u32 PhyAddress) +{ + int Status; + u16 PhyData = 0; + + /* + * Set the speed and put the PHY in reset. + */ + PhyData |= PHY_REG0_SPD_100_MASK; + Status = XEmacLite_PhyWrite(InstancePtr, PhyAddress, PHY_REG0_OFFSET, + PhyData | PHY_REG0_RESET_MASK); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + /* + * Give sufficient delay for Phy Reset. + */ + EmacLitePhyDelay(EMACLITE_PHY_DELAY_SEC); + + /* + * Set the PHY in loop back. + */ + XEmacLite_PhyWrite(InstancePtr, PhyAddress, PHY_REG0_OFFSET, + PhyData | PHY_REG0_LOOPBACK_MASK); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + /* + * Give sufficient delay for Phy Loopback Enable. + */ + EmacLitePhyDelay(1); + + return XST_SUCCESS; +} + +/******************************************************************************/ +/** +* +* This function disables the MAC loopback on the PHY. +* +* @param InstancePtr is the pointer to the instance of EmacLite driver. +* @param PhyAddress is the address of the Phy device. +* +* @return +* - XST_SUCCESS if the loop back was disabled. +* - XST_FAILURE if the loop back was not disabled. +* +* @note None. +* +******************************************************************************/ +int EmacLiteDisablePhyLoopBack(XEmacLite *InstancePtr, u32 PhyAddress) +{ + int Status; + u16 PhyData; + + /* + * Disable loop back through PHY register using MDIO support. + */ + Status = XEmacLite_PhyRead(InstancePtr, PhyAddress, PHY_REG0_OFFSET, + &PhyData); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + Status = XEmacLite_PhyWrite(InstancePtr,PhyAddress, PHY_REG0_OFFSET, + PhyData & ~(PHY_REG0_LOOPBACK_MASK)); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + return XST_SUCCESS; + +} + +/******************************************************************************/ +/** +* +* For PPC we use a usleep call, for Microblaze we use an assembly loop that +* is roughly the same regardless of optimization level, although caches and +* memory access time can make the delay vary. Just keep in mind that after +* resetting or updating the PHY modes, the PHY typically needs time to recover. +* +* @return None +* +* @note None +* +******************************************************************************/ +void EmacLitePhyDelay(unsigned int Seconds) +{ +#ifdef __MICROBLAZE__ + static int WarningFlag = 0; + + /* If MB caches are disabled or do not exist, this delay loop could + * take minutes instead of seconds (e.g., 30x longer). Print a warning + * message for the user (once). If only MB had a built-in timer! + */ + if (((mfmsr() & 0x20) == 0) && (!WarningFlag)) { +#ifdef STDOUT_BASEADDRESS + xil_printf("Warning: This example will take "); + xil_printf("minutes to complete without I-cache enabled \r\n"); +#endif + WarningFlag = 1; + } + +#define ITERS_PER_SEC (XPAR_CPU_CORE_CLOCK_FREQ_HZ / 6) + asm volatile ("\n" + "1: \n\t" + "addik r7, r0, %0 \n\t" + "2: \n\t" + "addik r7, r7, -1 \n\t" + "bneid r7, 2b \n\t" + "or r0, r0, r0 \n\t" + "bneid %1, 1b \n\t" + "addik %1, %1, -1 \n\t" + :: "i"(ITERS_PER_SEC), "d" (Seconds)); + +#else + + usleep(Seconds * 1000000); + +#endif +} diff --git a/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_internal_loopback_example.c b/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_internal_loopback_example.c new file mode 100644 index 00000000..33e1c8ce --- /dev/null +++ b/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_internal_loopback_example.c @@ -0,0 +1,580 @@ +/****************************************************************************** +* +* Copyright (C) 2003 - 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_internal_loopback_example.c +* +* This file contains a example for using EmacLite hardware and driver. +* This file contains an interrupt example outlining the use of interrupts and +* callbacks in the transmission/reception of Ethernet frames using internal +* loop back with an incrementing payload from 1 byte to 1500 bytes (excluding +* Ethernet Header and FCS). +* +* This example assumes that there is an interrupt controller in the hardware +* system and the EmacLite device is connected to the interrupt controller. +* +* @note +* +* None +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.01a ecm  05/21/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 internal loop back feature
+* 2.01a ktn  07/20/09 Updated the example to wait for either Transmit complete
+*                     or Rx packet reception.
+* 3.00a ktn  10/22/09 Updated the example to use the HAL APIs/macros.
+*		      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.
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xemaclite_example.h" +#include "xintc.h" +#include "xil_exception.h" +#include "xil_io.h" + +/************************** Constant Definitions *****************************/ + +/* + * The following constants map to the XPAR parameters created in the + * xparameters.h file. They are defined here such that a user can easily + * change all the needed parameters in one place. + */ +#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID +#define INTC_EMACLITE_ID XPAR_INTC_0_EMACLITE_0_VEC_ID + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +int EmacLiteIntrLoopbackExample(u16 DeviceId); + +static int EmacLiteSendFrame(XEmacLite *InstancePtr, u32 PayloadSize); +static int EmacLiteRecvFrame(u32 PayloadSize); +static void EmacLiteRecvHandler(void *CallBackRef); +static void EmacLiteSendHandler(void *CallBackRef); +static void EmacLiteDisableIntrSystem(XIntc *IntcInstancePtr, + u16 EmacLiteIntrId); +static int EmacLiteSetupIntrSystem(XIntc *IntcInstancePtr, + XEmacLite *EmacLiteInstPtr, u16 EmacLiteIntrId); + +/************************** Variable Definitions ****************************/ + +XIntc IntcInstance; /* Instance of the Interrupt Controller */ + +/* + * Set up valid local 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 +}; + +/******************************************************************************/ +/** +* +* This function is the main function of the EmacLite example in interrupt mode. +* +* @param None. +* +* @return XST_SUCCESS to indicate success, otherwise XST_FAILURE. +* +* @note None. +* +******************************************************************************/ +int main() +{ + int Status; + + /* + * Run the EmacLite example , specify the Device ID that is + * generated in xparameters.h. + */ + Status = EmacLiteIntrLoopbackExample(EMAC_DEVICE_ID); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* The main entry point for the EmacLite driver in interrupt mode example. +* This function will transmit/receive the frame using internal loop back and +* verify the data in the received frame. +* +* @param DeviceId is device ID of the XEmacLite Device , typically +* XPAR__DEVICE_ID value from xparameters.h. +* +* @return XST_SUCCESS to indicate success, otherwise XST_FAILURE. +* +* @note None. +* +******************************************************************************/ +int EmacLiteIntrLoopbackExample(u16 DeviceId) +{ + int Status; + XIntc *IntcInstancePtr; + XEmacLite *EmacLiteInstPtr; + u32 TxLength; + XEmacLite_Config *ConfigPtr; + + RecvFrameLength = 0; + IntcInstancePtr = &IntcInstance; + EmacLiteInstPtr =&EmacLiteInstance; + + /* + * 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); + + /* + * Set up the interrupt infrastructure. + */ + Status = EmacLiteSetupIntrSystem(IntcInstancePtr, EmacLiteInstPtr, + INTC_EMACLITE_ID); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + /* + * Setup the EmacLite handlers. + */ + XEmacLite_SetRecvHandler((EmacLiteInstPtr), (void *)(EmacLiteInstPtr), + (XEmacLite_Handler)EmacLiteRecvHandler); + XEmacLite_SetSendHandler((EmacLiteInstPtr), (void *)(EmacLiteInstPtr), + (XEmacLite_Handler)EmacLiteSendHandler); + + /* + * Empty any existing receive frames. + */ + XEmacLite_FlushReceive(EmacLiteInstPtr); + + /* + * Enable the EmacLite interrupts. + */ + XEmacLite_EnableInterrupts(EmacLiteInstPtr); + + /* + * Check if there is a Tx buffer available. + */ + if (XEmacLite_TxBufferAvailable(EmacLiteInstPtr) != TRUE) { + return XST_FAILURE; + } + + /* + * Enable internal loop back. + */ + XEmacLite_EnableLoopBack(EmacLiteInstPtr); + + /* + * Send/Receive frames of varying sizes and verify the data in the + * received frames. + */ + for (TxLength = 1; TxLength <= XEL_MTU_SIZE; ) { + RecvFrameLength = 0; + + /* + * Send a frame. + */ + Status = EmacLiteSendFrame(EmacLiteInstPtr, TxLength); + if (Status != XST_SUCCESS) { + /* + * Disable internal loop back. + */ + XEmacLite_DisableLoopBack(EmacLiteInstPtr); + return XST_FAILURE; + } + + /* + * Wait for the frame to be transmitted and received back. + * As the core is in loopback the transmit interrupt and the + * receive interrupt occur simulataneously. + */ + while ((RecvFrameLength == 0) && (TransmitComplete == FALSE)); + + /* + * Check the receive frame. + */ + Status = EmacLiteRecvFrame(TxLength++); + if ((Status != XST_SUCCESS) && (Status != XST_NO_DATA)) { + /* + * Disable internal loop back. + */ + XEmacLite_DisableLoopBack(EmacLiteInstPtr); + /* + * Disable and disconnect the EmacLite Interrupts. + */ + XEmacLite_DisableInterrupts(EmacLiteInstPtr); + EmacLiteDisableIntrSystem(IntcInstancePtr, + INTC_EMACLITE_ID); + return XST_FAILURE; + } + } + + /* + * Disable internal loop back. + */ + XEmacLite_DisableLoopBack(EmacLiteInstPtr); + + /* + * Disable and disconnect the EmacLite Interrupts. + */ + XEmacLite_DisableInterrupts(EmacLiteInstPtr); + EmacLiteDisableIntrSystem(IntcInstancePtr, INTC_EMACLITE_ID); + + return XST_SUCCESS; +} + +/******************************************************************************/ +/** +* +* This function sends a frame of given size. This function assumes interrupt +* mode and sends the frame. +* +* @param XEmacInstancePtr is a pointer to the XEmacLite instance to be +* worked on. +* @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). +* @param DestAddress if the address of the remote hardware the frame is +* to be sent to. +* +* @return XST_SUCCESS if successful, a driver-specific return code if not. +* +* @note None. +* +******************************************************************************/ +static int EmacLiteSendFrame(XEmacLite *XEmacInstancePtr, u32 PayloadSize) +{ + u8 *FramePtr; + int Index; + int Status; + + /* + * Set the Complete flag to false. + */ + TransmitComplete = FALSE; + + /* + * Assemble the frame with a destination address and the source address. + */ + FramePtr = (u8 *)TxFrame; + *FramePtr++ = LocalAddress[0]; + *FramePtr++ = LocalAddress[1]; + *FramePtr++ = LocalAddress[2]; + *FramePtr++ = LocalAddress[3]; + *FramePtr++ = LocalAddress[4]; + *FramePtr++ = LocalAddress[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. + */ + Status = XEmacLite_Send(XEmacInstancePtr, (u8 *)TxFrame, + PayloadSize + XEL_HEADER_SIZE); + + return Status; +} + +/******************************************************************************/ +/** +* +* 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; +} + +/******************************************************************************/ +/** +* +* This function handles the receive callback from the EmacLite driver. +* +* @param CallBackRef is the call back reference provided to the Handler. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +static void EmacLiteRecvHandler(void *CallBackRef) +{ + XEmacLite *XEmacInstancePtr; + + /* + * Convert the argument to something useful. + */ + XEmacInstancePtr = (XEmacLite *)CallBackRef; + + /* + * Handle the Receive callback. + */ + RecvFrameLength = XEmacLite_Recv(XEmacInstancePtr, (u8 *)RxFrame); + +} + +/******************************************************************************/ +/** +* +* This function handles the transmit callback from the EmacLite driver. +* +* @param CallBackRef is the call back reference provided to the Handler. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +static void EmacLiteSendHandler(void *CallBackRef) +{ + XEmacLite *XEmacInstancePtr; + + /* + * Convert the argument to something useful. + */ + XEmacInstancePtr = (XEmacLite *)CallBackRef; + + /* + * Handle the Transmit callback. + */ + TransmitComplete = TRUE; + +} + +/*****************************************************************************/ +/** +* +* This function setups the interrupt system such that interrupts can occur +* for the EmacLite device. This function is application specific since the +* actual system may or may not have an interrupt controller. The EmacLite +* could be directly connected to a processor without an interrupt controller. +* The user should modify this function to fit the application. +* +* @param IntcInstancePtr is a pointer to the instance of the Intc. +* @param EmacLiteInstPtr is a pointer to the instance of the EmacLite. +* @param EmacLiteIntrId is the interrupt ID and is typically +* XPAR___VEC_ID +* value from xparameters.h +* +* @return XST_SUCCESS if successful, otherwise XST_FAILURE. +* +* @note None. +* +******************************************************************************/ +static int EmacLiteSetupIntrSystem(XIntc *IntcInstancePtr, + XEmacLite *EmacLiteInstPtr, u16 EmacLiteIntrId) +{ + int Status; + +#ifndef TESTAPP_GEN + /* + * Initialize the interrupt controller driver so that it is ready to + * use. + */ + Status = XIntc_Initialize(IntcInstancePtr, INTC_DEVICE_ID); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } +#endif + /* + * Connect a device driver handler that will be called when an interrupt + * for the device occurs, the device driver handler performs the + * specific interrupt processing for the device. + */ + Status = XIntc_Connect(IntcInstancePtr, + EmacLiteIntrId, + XEmacLite_InterruptHandler, + (void *)(EmacLiteInstPtr)); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + +#ifndef TESTAPP_GEN + /* + * Start the interrupt controller such that interrupts are enabled for + * all devices that cause interrupts, specific real mode so that + * the EmacLite can cause interrupts thru the interrupt controller. + */ + Status = XIntc_Start(IntcInstancePtr, XIN_REAL_MODE); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } +#endif + + /* + * Enable the interrupt for the EmacLite in the Interrupt controller. + */ + XIntc_Enable(IntcInstancePtr, EmacLiteIntrId); + +#ifndef TESTAPP_GEN + + + /* + * Initialize the exception table. + */ + Xil_ExceptionInit(); + + /* + * Register the interrupt controller handler with the exception table. + */ + Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, + (Xil_ExceptionHandler) XIntc_InterruptHandler, + IntcInstancePtr); + + /* + * Enable non-critical exceptions. + */ + Xil_ExceptionEnable(); + +#endif /* TESTAPP_GEN */ + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* This function disables the interrupts that occur for the EmacLite device. +* +* @param IntcInstancePtr is the pointer to the instance of the INTC +* component. +* @param EmacLiteIntrId is the interrupt ID and is typically +* XPAR___VEC_ID +* value from xparameters.h. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +static void EmacLiteDisableIntrSystem(XIntc *IntcInstancePtr, + u16 EmacLiteIntrId) +{ + /* + * Disconnect and disable the interrupts for the EmacLite device. + */ + XIntc_Disconnect(IntcInstancePtr, EmacLiteIntrId); + +} diff --git a/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_intr_example.c b/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_intr_example.c new file mode 100644 index 00000000..d458af9b --- /dev/null +++ b/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_intr_example.c @@ -0,0 +1,665 @@ +/****************************************************************************** +* +* Copyright (C) 2003 - 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_intr_example.c +* +* This file contains an example for using the EmacLite hardware and driver. +* This file contains an interrupt example outlining the use of interrupts and +* callbacks in 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 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 +* +* None +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.01a ecm  05/21/04 First release
+* 1.01a sv   06/06/05 Minor changes to comply to Doxygen and coding guidelines
+* 1.01a sv   06/06/06 Minor changes for supporting Test App Interrupt examples
+* 2.00a ktn  02/25/09 Updated to use PHY loop back if MDIO is configured in
+*		      core
+* 3.00a ktn  10/22/09 Updated the example to use the HAL APIs/macros.
+*		      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.
+*
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xemaclite_example.h" +#include "xintc.h" +#include "xil_exception.h" +#include "xil_io.h" + +/************************** Constant Definitions *****************************/ + +#ifndef TESTAPP_GEN +/* + * The following constants map to the XPAR parameters created in the + * xparameters.h file. They are defined here such that a user can easily + * change all the needed parameters in one place. + */ +#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID +#define INTC_EMACLITE_ID XPAR_INTC_0_EMACLITE_0_VEC_ID +#endif + +/* + * The Size of the Test Frame. + */ +#define EMACLITE_TEST_FRAME_SIZE 1000 + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +int EmacLiteIntrExample(XIntc *IntcInstancePtr, + XEmacLite *EmacLiteInstPtr, + u16 EmacLiteDeviceId, + u16 EmacLiteIntrId); + +static int EmacLiteSendFrame(XEmacLite *EmacLiteInstPtr, + u32 PayloadSize); +static int EmacLiteRecvFrame(u32 PayloadSize); +static void EmacLiteRecvHandler(void *CallBackRef); +static void EmacLiteSendHandler(void *CallBackRef); +static void EmacLiteDisableIntrSystem(XIntc *IntcInstancePtr, + u16 EmacLiteIntrId); +static int EmacLiteSetupIntrSystem(XIntc *IntcInstancePtr, + XEmacLite *EmacLiteInstPtr, u16 EmacLiteIntrId); + +/************************** Variable Definitions *****************************/ + +XIntc IntcInstance; /* Instance of the Interrupt Controller */ + +/* + * 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 RemoteAddress[XEL_MAC_ADDR_SIZE] = +{ + 0x00, 0x10, 0xa4, 0xb6, 0xfd, 0x09 +}; +static u8 LocalAddress[XEL_MAC_ADDR_SIZE] = +{ + 0x00, 0x0A, 0x35, 0x01, 0x02, 0x03 +}; + +/****************************************************************************/ +/** +* +* This function is the main function of the EmacLite interrupt example. +* +* @param None. +* +* @return XST_SUCCESS if successful, otherwise XST_FAILURE. +* +* @note None. +* +*****************************************************************************/ +#ifndef TESTAPP_GEN +int main() +{ + int Status; + + /* + * Run the EmacLite interrupt example , specify the parameters + * generated in xparameters.h. + */ + Status = EmacLiteIntrExample(&IntcInstance, + &EmacLiteInstance, + EMAC_DEVICE_ID, + INTC_EMACLITE_ID); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + return XST_SUCCESS; + +} +#endif + +/*****************************************************************************/ +/** +* +* The main entry point for the EmacLite driver example in interrupt 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 IntcInstancePtr is a pointer to the instance of the Intc. +* @param EmacLiteInstPtr is a pointer to the instance of the EmacLite. +* @param EmacLiteDeviceId is device ID of the XEmacLite Device , +* typically XPAR__DEVICE_ID value from +* xparameters.h. +* @param EmacLiteIntrId is the interrupt ID and is typically +* XPAR___VEC_ID value from +* xparameters.h. +* +* @return XST_SUCCESS if successful, otherwise XST_FAILURE. +* +* @note None. +* +******************************************************************************/ +int EmacLiteIntrExample(XIntc *IntcInstancePtr, + XEmacLite *EmacLiteInstPtr, + u16 EmacLiteDeviceId, + u16 EmacLiteIntrId) +{ + int Status; + u32 PhyAddress = 0; + XEmacLite_Config *ConfigPtr; + + /* + * Initialize the EmacLite device. + */ + ConfigPtr = XEmacLite_LookupConfig(EmacLiteDeviceId); + 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; + } + + + /* + * Set up the interrupt infrastructure. + */ + Status = EmacLiteSetupIntrSystem(IntcInstancePtr, + EmacLiteInstPtr, + EmacLiteIntrId); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + /* + * Setup the EmacLite handlers. + */ + XEmacLite_SetRecvHandler((EmacLiteInstPtr), (void *)(EmacLiteInstPtr), + (XEmacLite_Handler)EmacLiteRecvHandler); + XEmacLite_SetSendHandler((EmacLiteInstPtr), (void *)(EmacLiteInstPtr), + (XEmacLite_Handler)EmacLiteSendHandler); + + + /* + * Enable the interrupts in the EmacLite controller. + */ + XEmacLite_EnableInterrupts(EmacLiteInstPtr); + RecvFrameLength = 0; + + /* + * 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) { + XEmacLite_DisableInterrupts(EmacLiteInstPtr); + EmacLiteDisableIntrSystem(IntcInstancePtr, + EmacLiteIntrId); + return XST_FAILURE; + } + } + + /* + * Transmit an Ethernet frame. + */ + Status = EmacLiteSendFrame(EmacLiteInstPtr, + EMACLITE_TEST_FRAME_SIZE); + if (Status != XST_SUCCESS) { + if (XEmacLite_IsMdioConfigured(EmacLiteInstPtr)) { + /* + * Disable the MAC Loop back in the PHY and + * disable/disconnect the EmacLite Interrupts. + */ + EmacLiteDisablePhyLoopBack(EmacLiteInstPtr, + PhyAddress); + XEmacLite_DisableInterrupts(EmacLiteInstPtr); + EmacLiteDisableIntrSystem(IntcInstancePtr, + EmacLiteIntrId); + return XST_FAILURE; + } + } + + /* + * Wait for the frame to be transmitted. + */ + while (TransmitComplete == FALSE); + + /* + * If the MDIO is not configured in the core then return XST_SUCCESS + * as the frame has been transmitted. + */ + if (!XEmacLite_IsMdioConfigured(EmacLiteInstPtr)) { + + /* + * Disable and disconnect the EmacLite Interrupts. + */ + XEmacLite_DisableInterrupts(EmacLiteInstPtr); + EmacLiteDisableIntrSystem(IntcInstancePtr, EmacLiteIntrId); + return XST_SUCCESS; + } + + /* + * Wait for the frame to be received. + */ + while (RecvFrameLength == 0); + + /* + * Check the received frame. + */ + Status = EmacLiteRecvFrame(EMACLITE_TEST_FRAME_SIZE); + + /* + * Diasble the Loop Back. + */ + if (XEmacLite_IsMdioConfigured(EmacLiteInstPtr)) { + /* + * Disable the MAC Loop back in the PHY. + */ + Status |= EmacLiteDisablePhyLoopBack(EmacLiteInstPtr, + PhyAddress); + } + + /* + * Disable and disconnect the EmacLite Interrupts. + */ + XEmacLite_DisableInterrupts(EmacLiteInstPtr); + EmacLiteDisableIntrSystem(IntcInstancePtr, EmacLiteIntrId); + if ((Status != XST_SUCCESS) && (Status != XST_NO_DATA)) { + return XST_FAILURE; + } + + return XST_SUCCESS; +} + +/******************************************************************************/ +/** +* +* This function sends a frame of given size. This function assumes interrupt +* mode and sends the frame. +* +* @param EmacLiteInstPtr is a pointer to the EmacLite 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 XST_FAILURE. +* +* @note None. +* +******************************************************************************/ +static int EmacLiteSendFrame(XEmacLite *EmacLiteInstPtr, u32 PayloadSize) +{ + int Status; + u8 *FramePtr; + u32 Index; + + /* + * Set the Complete flag to false. + */ + TransmitComplete = FALSE; + + /* + * Assemble the frame with a destination address and the source address. + */ + FramePtr = (u8 *)TxFrame; + + /* + * Set up the destination address as the local address for + * Phy Loopback and Internal loopback. + */ + if (XEmacLite_IsMdioConfigured(EmacLiteInstPtr) || + XEmacLite_IsLoopbackConfigured(EmacLiteInstPtr)) { + + *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. + */ + for (Index = 0; Index < PayloadSize; Index++) { + *FramePtr++ = (u8)Index; + } + + /* + * Now send the frame. + */ + Status = XEmacLite_Send(EmacLiteInstPtr, (u8 *)TxFrame, + PayloadSize + XEL_HEADER_SIZE); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + return XST_SUCCESS; +} + +/******************************************************************************/ +/** +* +* 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; +} + + +/******************************************************************************/ +/** +* +* This function handles the receive callback from the EmacLite driver. +* +* @param CallBackRef is the call back reference provided to the Handler. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +static void EmacLiteRecvHandler(void *CallBackRef) +{ + XEmacLite *XEmacInstancePtr; + + /* + * Convert the argument to something useful. + */ + XEmacInstancePtr = (XEmacLite *)CallBackRef; + + /* + * Handle the Receive callback. + */ + RecvFrameLength = XEmacLite_Recv(XEmacInstancePtr, (u8 *)RxFrame); + +} + +/******************************************************************************/ +/** +* +* This function handles the transmit callback from the EmacLite driver. +* +* @param CallBackRef is the call back reference provided to the Handler. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +static void EmacLiteSendHandler(void *CallBackRef) +{ + XEmacLite *XEmacInstancePtr; + + /* + * Convert the argument to something useful. + */ + XEmacInstancePtr = (XEmacLite *)CallBackRef; + + /* + * Handle the Transmit callback. + */ + TransmitComplete = TRUE; + +} + +/*****************************************************************************/ +/** +* +* This function setups the interrupt system such that interrupts can occur +* for the EmacLite device. This function is application specific since the +* actual system may or may not have an interrupt controller. The EmacLite +* could be directly connected to a processor without an interrupt controller. +* The user should modify this function to fit the application. +* +* @param IntcInstancePtr is a pointer to the instance of the Intc. +* @param EmacLiteInstPtr is a pointer to the instance of the EmacLite. +* @param EmacLiteIntrId is the interrupt ID and is typically +* XPAR___VEC_ID +* value from xparameters.h +* +* @return XST_SUCCESS if successful, otherwise XST_FAILURE. +* +* @note None. +* +******************************************************************************/ +static int EmacLiteSetupIntrSystem(XIntc *IntcInstancePtr, + XEmacLite *EmacLiteInstPtr, u16 EmacLiteIntrId) +{ + int Status; + +#ifndef TESTAPP_GEN + /* + * Initialize the interrupt controller driver so that it is ready to + * use. + */ + Status = XIntc_Initialize(IntcInstancePtr, INTC_DEVICE_ID); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } +#endif + /* + * Connect a device driver handler that will be called when an interrupt + * for the device occurs, the device driver handler performs the + * specific interrupt processing for the device. + */ + Status = XIntc_Connect(IntcInstancePtr, + EmacLiteIntrId, + XEmacLite_InterruptHandler, + (void *)(EmacLiteInstPtr)); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + +#ifndef TESTAPP_GEN + /* + * Start the interrupt controller such that interrupts are enabled for + * all devices that cause interrupts, specific real mode so that + * the EmacLite can cause interrupts thru the interrupt controller. + */ + Status = XIntc_Start(IntcInstancePtr, XIN_REAL_MODE); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } +#endif + + /* + * Enable the interrupt for the EmacLite in the Interrupt controller. + */ + XIntc_Enable(IntcInstancePtr, EmacLiteIntrId); + +#ifndef TESTAPP_GEN + + /* + * Initialize the exception table. + */ + Xil_ExceptionInit(); + + /* + * Register the interrupt controller handler with the exception table. + */ + Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, + (Xil_ExceptionHandler) XIntc_InterruptHandler, + IntcInstancePtr); + + /* + * Enable non-critical exceptions. + */ + Xil_ExceptionEnable(); + +#endif /* TESTAPP_GEN */ + + return XST_SUCCESS; +} + + +/*****************************************************************************/ +/** +* +* This function disables the interrupts that occur for the EmacLite device. +* +* @param IntcInstancePtr is the pointer to the instance of the INTC +* component. +* @param EmacLiteIntrId is the interrupt ID and is typically +* XPAR___VEC_ID +* value from xparameters.h. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +static void EmacLiteDisableIntrSystem(XIntc *IntcInstancePtr, + u16 EmacLiteIntrId) +{ + /* + * Disconnect and disable the interrupts for the EmacLite device. + */ + XIntc_Disconnect(IntcInstancePtr, EmacLiteIntrId); + +} diff --git a/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_phy_loopback_example.c b/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_phy_loopback_example.c new file mode 100644 index 00000000..18215253 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_phy_loopback_example.c @@ -0,0 +1,596 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 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_phy_loopback_example.c +* +* This file contains a example for using EmacLite hardware and driver. +* This file contains an interrupt example outlining the use of interrupts and +* callbacks in the transmission/reception of Ethernet frames using MAC loop +* back in the PHY device with an incrementing payload from 1 byte to 1500 bytes +* (excluding Ethernet Header and FCS). +* +* This example assumes that there is an interrupt controller in the hardware +* system and the EmacLite device is connected to the interrupt controller. +* +* @note +* +* None +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 2.00a ktn  02/25/09 First release
+* 2.01a ktn  07/20/09 Updated the example to wait for either Transmit complete
+*                     or Rx packet reception.
+* 3.00a ktn  10/22/09 Updated the example to use the HAL APIs/macros.
+*		      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.
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xemaclite_example.h" +#include "xintc.h" +#include "xil_exception.h" +#include "xil_io.h" + +/************************** Constant Definitions *****************************/ + +/* + * The following constants map to the XPAR parameters created in the + * xparameters.h file. They are defined here such that a user can easily + * change all the needed parameters in one place. + */ +#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID +#define INTC_EMACLITE_ID XPAR_INTC_0_EMACLITE_0_VEC_ID + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +int EmacLitePhyLoopbackExample(u16 DeviceId); + +static int SendFrame(XEmacLite *InstancePtr, u32 PayloadSize); +static int EmacLiteRecvFrame(u32 PayloadSize); +static void EmacLiteRecvHandler(void *CallBackRef); +static void EmacLiteSendHandler(void *CallBackRef); +static void EmacLiteDisableIntrSystem(XIntc *IntcInstancePtr, + u16 EmacLiteIntrId); +static int EmacLiteSetupIntrSystem(XIntc *IntcInstancePtr, + XEmacLite *EmacLiteInstPtr, u16 EmacLiteIntrId); + +/************************** Variable Definitions *****************************/ + +XIntc IntcInstance; /* Instance of the Interrupt Controller */ + +/* + * Set up valid local 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 +}; + +/******************************************************************************/ +/** +* +* This function is the main function of the EmacLite PHY loop back example in +* interrupt mode. +* +* @param None. +* +* @return XST_SUCCESS to indicate success, otherwise XST_FAILURE. +* +* @note None. +* +******************************************************************************/ +int main() +{ + int Status; + + /* + * Run the EmacLite PHY loop back example , specify the Device ID + * that is generated in xparameters.h. + */ + Status = EmacLitePhyLoopbackExample(EMAC_DEVICE_ID); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + return XST_SUCCESS; + +} + +/*****************************************************************************/ +/** +* +* The main entry point for the EmacLite driver PHY loop back example in +* interrupt mode. This function will transmit/receive the frame using MAC +* interface loop back (in the PHY device) and verify the data in the received +* frame. +* +* @param DeviceId is device ID of the XEmacLite Device , typically +* XPAR__DEVICE_ID value from xparameters.h. +* +* @return XST_SUCCESS to indicate success, otherwise XST_FAILURE. +* +* @note None. +* +******************************************************************************/ +int EmacLitePhyLoopbackExample(u16 DeviceId) +{ + int Status; + XIntc *IntcInstancePtr; + XEmacLite *EmacLiteInstPtr; + u32 PhyAddress = 0; + u32 TxLength; + XEmacLite_Config *ConfigPtr; + + RecvFrameLength = 0; + IntcInstancePtr = &IntcInstance; + EmacLiteInstPtr =&EmacLiteInstance; + + /* + * 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; + } + + /* + * If MDIO is not configured in the core then return XST_FAILURE. + */ + if (!XEmacLite_IsMdioConfigured(EmacLiteInstPtr)) { + 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 (XEmacLite_TxBufferAvailable(EmacLiteInstPtr) != TRUE) { + return XST_FAILURE; + } + + /* + * Set up the interrupt infrastructure. + */ + Status = EmacLiteSetupIntrSystem(IntcInstancePtr, EmacLiteInstPtr, + INTC_EMACLITE_ID); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + /* + * Setup the EmacLite handlers. + */ + XEmacLite_SetRecvHandler((EmacLiteInstPtr), (void *)(EmacLiteInstPtr), + (XEmacLite_Handler)EmacLiteRecvHandler); + XEmacLite_SetSendHandler((EmacLiteInstPtr), (void *)(EmacLiteInstPtr), + (XEmacLite_Handler)EmacLiteSendHandler); + + /* + * Enable the EmacLite interrupts. + */ + XEmacLite_EnableInterrupts(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) { + XEmacLite_DisableInterrupts(EmacLiteInstPtr); + EmacLiteDisableIntrSystem(IntcInstancePtr, INTC_EMACLITE_ID); + return XST_FAILURE; + } + + /* + * Send/Receive frames of varying sizes and verify the data in the + * received frames. + */ + for (TxLength = 1; TxLength <= XEL_MTU_SIZE; ) { + RecvFrameLength = 0; + + /* + * Send a frame. + */ + Status = SendFrame(EmacLiteInstPtr, TxLength); + if (Status != XST_SUCCESS) { + /* + * Disable the MAC Loop back in the PHY and + * disable/disconnect the EmacLite Interrupts. + */ + EmacLiteDisablePhyLoopBack(EmacLiteInstPtr, PhyAddress); + XEmacLite_DisableInterrupts(EmacLiteInstPtr); + EmacLiteDisableIntrSystem(IntcInstancePtr, + INTC_EMACLITE_ID); + return XST_FAILURE; + } + + /* + * Wait for the frame to be transmitted and received back. + * As the PHY is in loopback the transmit interrupt and the + * receive interrupt occur simulataneously. + */ + while ((TransmitComplete == FALSE) && (RecvFrameLength == 0)); + + /* + * Check the receive frame. + */ + Status = EmacLiteRecvFrame(TxLength++); + if ((Status != XST_SUCCESS) && (Status != XST_NO_DATA)) { + /* + * Disable the MAC Loop back in the PHY and + * disable/disconnect the EmacLite Interrupts. + */ + EmacLiteDisablePhyLoopBack(EmacLiteInstPtr, PhyAddress); + XEmacLite_DisableInterrupts(EmacLiteInstPtr); + EmacLiteDisableIntrSystem(IntcInstancePtr, + INTC_EMACLITE_ID); + return XST_FAILURE; + } + } + + /* + * Disable the MAC Loop back in the PHY and + * disable/disconnect the EmacLite Interrupts. + */ + EmacLiteDisablePhyLoopBack(EmacLiteInstPtr, PhyAddress); + XEmacLite_DisableInterrupts(EmacLiteInstPtr); + EmacLiteDisableIntrSystem(IntcInstancePtr, INTC_EMACLITE_ID); + + return XST_SUCCESS; +} + +/******************************************************************************/ +/** +* +* This function sends a frame of given size. This function assumes interrupt +* mode and sends the frame. +* +* @param XEmacInstancePtr is a pointer to the XEmacLite instance to be +* worked on. +* @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). +* @param DestAddress if the address of the remote hardware the frame is +* to be sent to. +* +* @return XST_SUCCESS if successful, a driver-specific return code if not. +* +* @note None. +* +******************************************************************************/ +static int SendFrame(XEmacLite *XEmacInstancePtr, u32 PayloadSize) +{ + u8 *FramePtr; + int Index; + int Status; + + /* + * Set the Complete flag to false. + */ + TransmitComplete = FALSE; + + /* + * Assemble the frame with a destination address and the source address. + */ + FramePtr = (u8 *)TxFrame; + *FramePtr++ = LocalAddress[0]; + *FramePtr++ = LocalAddress[1]; + *FramePtr++ = LocalAddress[2]; + *FramePtr++ = LocalAddress[3]; + *FramePtr++ = LocalAddress[4]; + *FramePtr++ = LocalAddress[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. + */ + Status = XEmacLite_Send(XEmacInstancePtr, (u8 *)TxFrame, + PayloadSize + XEL_HEADER_SIZE); + + return Status; +} + +/******************************************************************************/ +/** +* +* 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; +} + + +/******************************************************************************/ +/** +* +* This function handles the receive callback from the EmacLite driver. +* +* @param CallBackRef is the call back reference provided to the Handler. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +static void EmacLiteRecvHandler(void *CallBackRef) +{ + XEmacLite *XEmacInstancePtr; + + /* + * Convert the argument to something useful. + */ + XEmacInstancePtr = (XEmacLite *)CallBackRef; + + /* + * Handle the Receive callback. + */ + RecvFrameLength = XEmacLite_Recv(XEmacInstancePtr, (u8 *)RxFrame); + +} + +/******************************************************************************/ +/** +* +* This function handles the transmit callback from the EmacLite driver. +* +* @param CallBackRef is the call back reference provided to the Handler. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +static void EmacLiteSendHandler(void *CallBackRef) +{ + XEmacLite *XEmacInstancePtr; + + /* + * Convert the argument to something useful. + */ + XEmacInstancePtr = (XEmacLite *)CallBackRef; + + /* + * Handle the Transmit callback. + */ + TransmitComplete = TRUE; + +} + + +/*****************************************************************************/ +/** +* +* This function setups the interrupt system such that interrupts can occur +* for the EmacLite device. This function is application specific since the +* actual system may or may not have an interrupt controller. The EmacLite +* could be directly connected to a processor without an interrupt controller. +* The user should modify this function to fit the application. +* +* @param IntcInstancePtr is a pointer to the instance of the Intc. +* @param EmacLiteInstPtr is a pointer to the instance of the EmacLite. +* @param EmacLiteIntrId is the interrupt ID and is typically +* XPAR___VEC_ID +* value from xparameters.h +* +* @return XST_SUCCESS if successful, otherwise XST_FAILURE. +* +* @note None. +* +******************************************************************************/ +static int EmacLiteSetupIntrSystem(XIntc *IntcInstancePtr, + XEmacLite *EmacLiteInstPtr, u16 EmacLiteIntrId) +{ + int Status; + +#ifndef TESTAPP_GEN + /* + * Initialize the interrupt controller driver so that it is ready to + * use. + */ + Status = XIntc_Initialize(IntcInstancePtr, INTC_DEVICE_ID); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } +#endif + /* + * Connect a device driver handler that will be called when an interrupt + * for the device occurs, the device driver handler performs the + * specific interrupt processing for the device. + */ + Status = XIntc_Connect(IntcInstancePtr, + EmacLiteIntrId, + XEmacLite_InterruptHandler, + (void *)(EmacLiteInstPtr)); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + +#ifndef TESTAPP_GEN + /* + * Start the interrupt controller such that interrupts are enabled for + * all devices that cause interrupts, specific real mode so that + * the EmacLite can cause interrupts thru the interrupt controller. + */ + Status = XIntc_Start(IntcInstancePtr, XIN_REAL_MODE); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } +#endif + + /* + * Enable the interrupt for the EmacLite in the Interrupt controller. + */ + XIntc_Enable(IntcInstancePtr, EmacLiteIntrId); + +#ifndef TESTAPP_GEN + + /* + * Initialize the exception table. + */ + Xil_ExceptionInit(); + + /* + * Register the interrupt controller handler with the exception table. + */ + Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, + (Xil_ExceptionHandler) XIntc_InterruptHandler, + IntcInstancePtr); + + /* + * Enable non-critical exceptions. + */ + Xil_ExceptionEnable(); + +#endif /* TESTAPP_GEN */ + + return XST_SUCCESS; +} + + +/*****************************************************************************/ +/** +* +* This function disables the interrupts that occur for the EmacLite device. +* +* @param IntcInstancePtr is the pointer to the instance of the INTC +* component. +* @param EmacLiteIntrId is the interrupt ID and is typically +* XPAR___VEC_ID +* value from xparameters.h. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +static void EmacLiteDisableIntrSystem(XIntc *IntcInstancePtr, + u16 EmacLiteIntrId) +{ + /* + * Disconnect and disable the interrupts for the EmacLite device. + */ + XIntc_Disconnect(IntcInstancePtr, EmacLiteIntrId); + +} diff --git a/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_ping_reply_example.c b/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_ping_reply_example.c new file mode 100644 index 00000000..9f599213 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_ping_reply_example.c @@ -0,0 +1,707 @@ +/****************************************************************************** +* +* Copyright (C) 2008 - 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_ping_reply_example.c +* +* This file contains an EmacLite ping reply example in polled mode. This example +* will generate a ping reply when it receives a ping request packet from the +* external world. +* +* @note +* +* The local IP address is set to 172.16.63.121. User needs to update +* LocalIpAddr variable with a free IP address based on the network on which +* this example is to be run. +* +* The local MAC address is set to 0x000A35030201. User can update LocalMacAddr +* variable with a valid MAC address. The first three bytes contains +* the manufacture ID. 0x000A35 is XILINX manufacture ID. +* +* This program will respond continuously to a number of ping requests as defined +* by MAX_PING_REPLIES in this file. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a ktn  20/08/08 First release
+* 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  08/06/10 Updated the example to support little endian MicroBlaze.
+*
+* 
+* +*****************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xparameters.h" +#include "xstatus.h" +#include "xemaclite.h" +#include "xil_io.h" + +/************************** Constant Definitions *****************************/ + +/* + * The following constants map to the XPAR parameters created in the + * xparameters.h file. They are defined here such that a user can easily + * change all the needed parameters in one place. + */ +#define EMAC_DEVICE_ID XPAR_EMACLITE_0_DEVICE_ID + +/* + * Change this parameter to limit the number of ping replies sent by this + * program. + */ +#define MAX_PING_REPLIES 10 /* Maximum number of ping replies */ + +#define BROADCAST_PACKET 1 /* Broadcast packet */ +#define MAC_MATCHED_PACKET 2 /* Dest MAC matched with local MAC */ +#define IP_ADDR_SIZE 4 /* IP Address size in Bytes */ +#define ARP_REQUEST 0x0001 /* ARP Request bits in Rx packet */ +#define ARP_REPLY 0x0002 /* ARP status bits indicating reply */ +#define ARP_PACKET_SIZE 0x3C /* ARP packet len 60 Bytes */ +#define ICMP_PACKET_SIZE 0x4A /* ICMP packet length 74 Bytes + * including Src and Dest MAC Address */ +#define BROADCAST_ADDR 0xFFFF /* Broadcast Address */ +#define CORRECT_CKSUM_VALUE 0xFFFF /* Correct checksum value */ +#define IDENT_FIELD_VALUE 0x9263 /* Identification field (random num) */ + +/* + * Definitions for the locations and length of some of the fields in a + * IP packet. The lengths are defined in Half-Words (2 bytes). + */ +#define ETHER_PROTO_TYPE_LEN 1 /* Ethernet protocol Type length */ +#define SRC_MAC_ADDR_LOC 3 /* Source MAC address location */ +#define MAC_ADDR_LEN 3 /* MAC address length */ +#define ETHER_PROTO_TYPE_LOC 6 /* Ethernet Proto type location */ + +#define ARP_HW_TYPE_LEN 1 /* Hardware Type length */ +#define ARP_PROTO_TYPE_LEN 1 /* Protocol Type length */ +#define ARP_HW_ADD_LEN 1 /* Hardware address length */ +#define ARP_PROTO_ADD_LEN 1 /* Protocol address length */ +#define ARP_ZEROS_LEN 9 /* Length to be filled with zeros */ +#define ARP_REQ_STATUS_LOC 10 /* ARP request location */ +#define ARP_REQ_SRC_IP_LOC 14 /* Src IP address location of ARP request */ +#define ARP_REQ_DEST_IP_LOC_1 19 /* Destination IP's 1st half word location */ +#define ARP_REQ_DEST_IP_LOC_2 20 /* Destination IP's 2nd half word location */ + +#define IP_VERSION_LEN 1 /* IP Version length */ +#define IP_PACKET_LEN 1 /* IP Packet length field */ +#define IP_FRAG_FIELD_LEN 1 /* Fragment field len in ICMP packet */ +#define IP_TTL_ICM_LEN 1 /* Time to live and ICM fields length */ +#define IP_ADDR_LEN 2 /* Size of IP address in half-words */ +#define IP_CSUM_LOC_BACK 5 /* IP checksum location from end of frame */ +#define IP_HDR_START_LOC 7 /* IP header start location */ +#define IP_HDR_LEN 10 /* IP Header length */ +#define IP_FRAG_FIELD_LOC 10 /* Fragment field location */ + +#define ICMP_TYPE_LEN 1 /* ICMP Type length */ +#define ICMP_ECHO_FIELD_LEN 2 /* Echo field length in half-words */ +#define ICMP_REQ_SRC_IP_LOC 13 /* Src IP address location of ICMP request */ +#define ICMP_ECHO_FIELD_LOC 17 /* Echo field location */ +#define ICMP_DATA_START_LOC 17 /* Data field start location */ +#define ICMP_DATA_LEN 18 /* ICMP data length */ +#define ICMP_DATA_LOC 19 /* ICMP data location including + identifier number and sequence number */ +#define ICMP_DATA_CSUM_LOC_BACK 19 /* Data checksum location from end of + frame */ +#define ICMP_DATA_FIELD_LEN 20 /* Data field length */ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +static int EmacLitePingReplyExample(u16 DeviceId); + +static void ProcessRecvFrame(XEmacLite *InstancePtr); + +static u16 CheckSumCalculation(u16 *RxFramePtr, int StartLoc, int Length); + +/************************** Variable Definitions *****************************/ + +/* + * Set up a local MAC address. + */ +static u8 LocalMacAddr[XEL_MAC_ADDR_SIZE] = +{ + 0x00, 0x0A, 0x35, 0x02, 0x22, 0x5E +}; + +/* + * The IP address was set to 172.16.63.121. User need to set a free IP address + * based on the network on which this example is to be run. + */ +static u8 LocalIpAddr[IP_ADDR_SIZE] = +{ + 172, 16, 63, 121 +}; + +static XEmacLite EmacLiteInstance; /* Instance of the EmacLite driver */ + +/* + * Buffers used for Transmission and Reception of Packets. These are declared as + * global so that they are not a part of the stack. + */ +static u8 RxFrame[XEL_MAX_FRAME_SIZE]; +static u8 TxFrame[XEL_MAX_FRAME_SIZE]; + +/* + * Variable used to indicate the length of the received frame. + */ +u32 RecvFrameLength = 0; + +/* + * Variable used to indicate the number of Ping replies sent. + */ +u32 NumOfPingReplies; + + +/****************************************************************************/ +/** +* +* This function is the main function of the Ping reply example in +* polled mode. +* +* @param None. +* +* @return XST_FAILURE to indicate failure, otherwise XST_SUCCESS +* is returned. +* +* @note None. +* +*****************************************************************************/ +int main() +{ + int Status; + + /* + * Run the EmacLite Ping reply example. + */ + Status = EmacLitePingReplyExample(EMAC_DEVICE_ID); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* The entry point for the EmacLite Ping reply example in polled mode. +* +* @param DeviceId is device ID of the XEmacLite Device. +* +* @return XST_FAILURE to indicate failure, otherwise XST_SUCCESS is +* returned. +* +* @note This is in a continuous loop generating a specified number of +* ping replies as defined by MAX_PING_REPLIES. +* +******************************************************************************/ +int EmacLitePingReplyExample(u16 DeviceId) +{ + int Status; + XEmacLite *EmacLiteInstPtr = &EmacLiteInstance; + XEmacLite_Config *ConfigPtr; + NumOfPingReplies = 0; + + /* + * 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, LocalMacAddr); + + /* + * Empty any existing receive frames. + */ + XEmacLite_FlushReceive(EmacLiteInstPtr); + + while (1) { + + /* + * Wait for a Receive packet. + */ + while (RecvFrameLength == 0) { + RecvFrameLength = XEmacLite_Recv(EmacLiteInstPtr, + (u8 *)RxFrame); + } + + /* + * Process the Receive frame. + */ + ProcessRecvFrame(EmacLiteInstPtr); + RecvFrameLength = 0; + + /* + * If the number of ping replies sent is equal to that + * specified by the user then exit out of this loop. + */ + if (NumOfPingReplies == MAX_PING_REPLIES) { + + return XST_SUCCESS; + } + + } +} + +/******************************************************************************/ +/** +* +* This function processes the received packet and generates the corresponding +* reply packets. +* +* @param InstancePtr is a pointer to the instance of the EmacLite. +* +* @return None. +* +* @note This function assumes MAC does not strip padding or CRC. +* +******************************************************************************/ +static void ProcessRecvFrame(XEmacLite *InstancePtr) +{ + u16 *RxFramePtr; + u16 *TxFramePtr; + u16 *TempPtr; + u16 CheckSum; + u32 NextTxBuffBaseAddr; + int Index; + int PacketType = 0; + + TxFramePtr = (u16 *)TxFrame; + RxFramePtr = (u16 *)RxFrame; + + /* + * Determine the next expected Tx buffer address. + */ + NextTxBuffBaseAddr = XEmacLite_NextTransmitAddr(InstancePtr); + + /* + * Check the packet type. + */ + Index = MAC_ADDR_LEN; + TempPtr = (u16 *)LocalMacAddr; + while (Index--) { + if (Xil_Ntohs((*(RxFramePtr + Index)) == BROADCAST_ADDR) && + (PacketType != MAC_MATCHED_PACKET)) { + PacketType = BROADCAST_PACKET; + } else if (Xil_Ntohs((*(RxFramePtr + Index)) == *(TempPtr + Index)) && + (PacketType != BROADCAST_PACKET)) { + PacketType = MAC_MATCHED_PACKET; + } else { + PacketType = 0; + break; + } + } + + /* + * Process broadcast packet. + */ + if (PacketType == BROADCAST_PACKET) { + + /* + * Check for an ARP Packet if so generate a reply. + */ + if (Xil_Ntohs(*(RxFramePtr + ETHER_PROTO_TYPE_LOC)) == + XEL_ETHER_PROTO_TYPE_ARP) { + + /* + * IP address of the local machine. + */ + TempPtr = (u16 *)LocalIpAddr; + + /* + * Check destination IP address of the packet with + * local IP address. + */ + if ( + ((*(RxFramePtr + ARP_REQ_DEST_IP_LOC_1)) == *TempPtr++) && + ((*(RxFramePtr + ARP_REQ_DEST_IP_LOC_2)) == *TempPtr++)) { + + /* + * Check ARP packet type(request/reply). + */ + if (Xil_Ntohs(*(RxFramePtr + ARP_REQ_STATUS_LOC)) == + ARP_REQUEST) { + + /* + * Add destination MAC address + * to the reply packet (i.e) source + * address of the received packet. + */ + Index = SRC_MAC_ADDR_LOC; + while (Index < (SRC_MAC_ADDR_LOC + + MAC_ADDR_LEN)) { + *TxFramePtr++ = + *(RxFramePtr + Index); + Index++; + } + + /* + * Add source (local) MAC address + * to the reply packet. + */ + Index = 0; + TempPtr = (u16 *)LocalMacAddr; + while (Index < MAC_ADDR_LEN) { + *TxFramePtr++ = *TempPtr++; + Index++; + } + + /* + * Add Ethernet proto type H/W + * type(10/3MBps),H/W address length and + * protocol address len (i.e)same as in + * the received packet + */ + Index = ETHER_PROTO_TYPE_LOC; + while (Index < (ETHER_PROTO_TYPE_LOC + + ETHER_PROTO_TYPE_LEN + + ARP_HW_TYPE_LEN + + ARP_HW_ADD_LEN + + ARP_PROTO_ADD_LEN)) { + *TxFramePtr++ = + *(RxFramePtr + Index); + Index++; + } + + /* + * Add ARP reply status to the reply + * packet. + */ + *TxFramePtr++ = Xil_Htons(ARP_REPLY); + + /* + * Add local MAC Address + * to the reply packet. + */ + TempPtr = (u16 *)LocalMacAddr; + Index = 0; + while (Index < MAC_ADDR_LEN) { + *TxFramePtr++ = *TempPtr++; + Index++; + } + + /* + * Add local IP Address + * to the reply packet. + */ + TempPtr = (u16 *)LocalIpAddr; + Index = 0; + while (Index < IP_ADDR_LEN) { + *TxFramePtr++ = *TempPtr++ ; + Index++; + } + + /* + * Add Destination MAC Address + * to the reply packet from the received + * packet. + */ + Index = SRC_MAC_ADDR_LOC; + while (Index < (SRC_MAC_ADDR_LOC + + MAC_ADDR_LEN)) { + *TxFramePtr++ = + *(RxFramePtr + Index); + Index++; + } + + /* + * Add Destination IP Address + * to the reply packet. + */ + Index = ARP_REQ_SRC_IP_LOC; + while (Index < (ARP_REQ_SRC_IP_LOC + + IP_ADDR_LEN)) { + *TxFramePtr++ = + *(RxFramePtr + Index); + Index++; + } + + /* + * Fill zeros as per protocol. + */ + Index = 0; + while (Index < ARP_ZEROS_LEN) { + *TxFramePtr++ = 0x0000; + Index++; + } + + /* + * Transmit the Reply Packet. + */ + XEmacLite_Send(InstancePtr, + (u8 *)&TxFrame, + ARP_PACKET_SIZE); + } + } + } + } + + /* + * Process packets whose MAC address is matched. + */ + if (PacketType == MAC_MATCHED_PACKET) { + + /* + * Check ICMP packet. + */ + if (Xil_Ntohs(*(RxFramePtr + ETHER_PROTO_TYPE_LOC)) == + XEL_ETHER_PROTO_TYPE_IP) { + + /* + * Check the IP header checksum. + */ + CheckSum = CheckSumCalculation(RxFramePtr, + IP_HDR_START_LOC, + IP_HDR_LEN); + + /* + * Check the Data field checksum. + */ + if (CheckSum == CORRECT_CKSUM_VALUE) { + CheckSum = CheckSumCalculation(RxFramePtr, + ICMP_DATA_START_LOC, + ICMP_DATA_FIELD_LEN); + if (CheckSum == CORRECT_CKSUM_VALUE) { + + /* + * Add destination address + * to the reply packet (i.e)source + * address of the received packet. + */ + Index = SRC_MAC_ADDR_LOC; + while (Index < (SRC_MAC_ADDR_LOC + + MAC_ADDR_LEN)) { + *TxFramePtr++ = + *(RxFramePtr + Index); + Index++; + } + + /* + * Add local MAC address + * to the reply packet. + */ + Index = 0; + TempPtr = (u16 *)LocalMacAddr; + while (Index < MAC_ADDR_LEN) { + *TxFramePtr++ = *TempPtr++; + Index++; + } + + /* + * Add protocol type + * header length and, packet + * length(60 Bytes) to the reply packet. + */ + Index = ETHER_PROTO_TYPE_LOC; + while (Index < (ETHER_PROTO_TYPE_LOC + + ETHER_PROTO_TYPE_LEN + + IP_VERSION_LEN + + IP_PACKET_LEN)) { + *TxFramePtr++ = + *(RxFramePtr + Index); + Index++; + } + + /* + * Identification field a random number + * which is set to IDENT_FIELD_VALUE. + */ + *TxFramePtr++ = IDENT_FIELD_VALUE; + + /* + * Add fragment type, time to live and + * ICM field. It is same as in the + * received packet. + */ + Index = IP_FRAG_FIELD_LOC; + while (Index < (IP_FRAG_FIELD_LOC + + IP_TTL_ICM_LEN + + IP_FRAG_FIELD_LEN)) { + *TxFramePtr++ = + *(RxFramePtr + Index); + Index++; + } + + /* + * Checksum first set to 0 and + * added in this field later. + */ + *TxFramePtr++ = 0x0000; + + /* + * Add Source IP address + */ + Index = 0; + TempPtr = (u16 *)LocalIpAddr; + while (Index < IP_ADDR_LEN) { + *TxFramePtr++ = *TempPtr++; + Index++; + } + + /* + * Add Destination IP address. + */ + Index = ICMP_REQ_SRC_IP_LOC; + while (Index < (ICMP_REQ_SRC_IP_LOC + + IP_ADDR_LEN)) { + *TxFramePtr++ = + *(RxFramePtr + Index); + Index++; + } + + /* + * Calculate checksum, and + * add it in the appropriate field. + */ + CheckSum = CheckSumCalculation( + (u16 *)TxFrame, + IP_HDR_START_LOC, + IP_HDR_LEN); + CheckSum = ~CheckSum; + *(TxFramePtr - IP_CSUM_LOC_BACK) = + Xil_Htons(CheckSum); + + /* + * Echo reply status & checksum. + */ + Index = ICMP_ECHO_FIELD_LOC; + while (Index < (ICMP_ECHO_FIELD_LOC + + ICMP_ECHO_FIELD_LEN)) { + *TxFramePtr++ = 0x0000; + Index++; + } + + /* + * Add data to buffer which was + * received from the packet. + */ + Index = ICMP_DATA_LOC; + while (Index < (ICMP_DATA_LOC + + ICMP_DATA_LEN)) { + *TxFramePtr++ = + (*(RxFramePtr + Index)); + Index++; + } + + /* + * Generate checksum for the data and + * add it in the appropriate field. + */ + CheckSum = CheckSumCalculation( + (u16 *)TxFrame, + ICMP_DATA_START_LOC, + ICMP_DATA_FIELD_LEN); + CheckSum = ~CheckSum; + *(TxFramePtr - ICMP_DATA_CSUM_LOC_BACK) + = Xil_Htons(CheckSum); + + /* + * Transmit the frame. + */ + XEmacLite_Send(InstancePtr, + (u8 *)&TxFrame, + ICMP_PACKET_SIZE); + + /* + * Increment the number of + * Ping replies sent. + */ + NumOfPingReplies++; + + } + } + } + } +} + +/*****************************************************************************/ +/** +* +* This function calculates the checksum and returns a 16 bit result. +* +* @param RxFramePtr is a 16 bit pointer for the data to which checksum +* is to be calculated. +* @param StartLoc is the starting location of the data from which the +* checksum has to be calculated. +* @param Length is the number of halfwords(16 bits) to which checksum is +* to be calculated. +* +* @return It returns a 16 bit checksum value. +* +* @note This can also be used for calculating checksum. The ones +* complement of this return value will give the final checksum. +* +******************************************************************************/ +static u16 CheckSumCalculation(u16 *RxFramePtr, int StartLoc, int Length) +{ + u32 Sum = 0; + u16 CheckSum = 0; + int Index; + + /* + * Add all the 16 bit data. + */ + Index = StartLoc; + while (Index < (StartLoc + Length)) { + Sum = Sum + Xil_Ntohs(*(RxFramePtr + Index)); + Index++; + } + + /* + * Add upper 16 bits to lower 16 bits. + */ + CheckSum = Sum; + Sum = Sum >> 16; + CheckSum = Sum + CheckSum; + return CheckSum; +} diff --git a/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_ping_req_example.c b/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_ping_req_example.c new file mode 100644 index 00000000..01f40c07 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_ping_req_example.c @@ -0,0 +1,804 @@ +/****************************************************************************** +* +* Copyright (C) 2008 - 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_ping_req_example.c +* +* This file contains a EmacLite Ping request example in polled mode. This +* example will generate a ping request for the specified IP address. +* +* @note +* +* The local IP address is set to 172.16.63.121. User needs to update +* LocalIpAddr variable with a free IP address based on the network on which +* this example is to be run. +* +* The Destination IP address is set to 172.16.63.61. User needs to update +* DestIpAddress variable with any valid IP address based on the network on which +* this example is to be run. +* +* The local MAC address is set to 0x000A35030201. User can update LocalMacAddr +* variable with a valid MAC address. The first three bytes contains +* the manufacture ID. 0x000A35 is XILINX manufacture ID. +* +* This program will generate the specified number of ping request packets as +* defined in "NUM_OF_PING_REQ_PKTS". +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a ktn  27/08/08 First release
+* 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  08/06/10 Updated the example to support little endian MicroBlaze.
+*
+* 
+* +*****************************************************************************/ +/***************************** Include Files *********************************/ + +#include "xparameters.h" +#include "xstatus.h" +#include "xemaclite.h" +#include "stdio.h" +#include "xil_io.h" + +/************************** Constant Definitions *****************************/ + +/* + * The following constants map to the XPAR parameters created in the + * xparameters.h file. They are defined here such that a user can easily + * change all the needed parameters in one place. + */ +#define EMAC_DEVICE_ID XPAR_EMACLITE_0_DEVICE_ID + +/* + * Change this parameter to limit the number of ping requests sent by this + * program. + */ +#define NUM_OF_PING_REQ_PKTS 100 /* Number of ping req it generates */ + +#define ECHO_REPLY 0x00 /* Echo reply */ +#define HW_TYPE 0x01 /* Hardware type (10/100 Mbps) */ +#define ARP_REQUEST 0x01 /* ARP Request bits in Rx packet */ +#define ARP_REPLY 0x02 /* ARP status bits indicating reply */ +#define IDEN_NUM 0x02 /* ICMP identifier number */ +#define IP_VERSION 0x0604 /* IP version ipv4/ipv6 */ +#define BROADCAST_ADDR 0xFFFF /* Broadcast Address */ +#define CORRECT_CHECKSUM_VALUE 0xFFFF /* Correct checksum value */ +#define ARP_REQ_PKT_SIZE 0x2A /* ARP request packet size */ +#define ICMP_PKT_SIZE 0x4A /* ICMP packet length 74 Bytes + including Src and dest MAC Add */ +#define IP_ADDR_SIZE 4 /* IP Address size in Bytes */ +#define NUM_RX_PACK_CHECK_REQ 10 /* Max num of Rx pack to be checked + before sending another request */ +#define NUM_PACK_CHECK_RX_PACK 100 /* Max number of pack to be checked + before to identify a Rx packet */ +#define DELAY 5000000 /* Used to introduce delay */ + +/* + * Definitions for the locations and length of some of the fields in a + * IP packet. The lengths are defined in Half-Words (2 bytes). + */ + +#define SRC_MAC_ADDR_LOC 3 /* Src MAC address location */ +#define MAC_ADDR_LEN 3 /* MAC address length */ +#define ETHER_PROTO_TYPE_LOC 6 /* Ethernet Proto type loc */ + +#define IP_ADDR_LEN 2 /* Size of IP address */ +#define IP_START_LOC 7 /* IP header start location */ +#define IP_HEADER_INFO_LEN 7 /* IP header information length */ +#define IP_HEADER_LEN 10 /* IP header length */ +#define IP_CHECKSUM_LOC 12 /* IP header checksum location */ +#define IP_REQ_SRC_IP_LOC 13 /* Src IP add loc of ICMP req */ +#define IP_REQ_DEST_IP_LOC 15 /* Dest IP add loc of ICMP req */ + +#define ICMP_KNOWN_DATA_LEN 16 /* ICMP known data length */ +#define ICMP_ECHO_FIELD_LOC 17 /* Echo field loc */ +#define ICMP_DATA_START_LOC 17 /* Data field start location */ +#define ICMP_DATA_LEN 18 /* ICMP data length */ +#define ICMP_DATA_CHECKSUM_LOC 18 /* ICMP data checksum location */ +#define ICMP_IDEN_FIELD_LOC 19 /* Identifier field loc */ +#define ICMP_DATA_LOC 19 /* ICMP data loc including + identifier number and sequence number */ +#define ICMP_SEQ_NO_LOC 20 /* sequence number location */ +#define ICMP_DATA_FIELD_LEN 20 /* Data field length */ +#define ICMP_KNOWN_DATA_LOC 21 /* ICMP known data start loc */ + +#define ARP_REQ_STATUS_LOC 10 /* ARP request loc */ +#define ARP_REQ_SRC_IP_LOC 14 /* Src IP add loc of ARP req Packet */ + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/************************** Function Prototypes ******************************/ + +static int EmacLitePingReqExample(u16 DeviceId); + +static void SendArpReqFrame(XEmacLite *InstancePtr); + +static void SendEchoReqFrame(XEmacLite *InstancePtr); + +static int ProcessRecvFrame(XEmacLite *InstancePtr); + +static u16 CheckSumCalculation(u16 *RxFramePtr16, int StartLoc, int Length); + +static int CompareData(u16 *LhsPtr, u16 *RhsPtr, int LhsLoc, int RhsLoc, + int Count); + +/************************** Variable Definitions *****************************/ + +/* + * Set up a local MAC address. + */ +static u8 LocalMacAddr[XEL_MAC_ADDR_SIZE] = +{ + 0x00, 0x0A, 0x35, 0x03, 0x02, 0x01 +}; + +/* + * The IP address was set to 172.16.63.121. User need to set a free IP address + * based on the network on which this example is to be run. + */ +static u8 LocalIpAddress[IP_ADDR_SIZE] = +{ + 172, 16, 63, 121 +}; + +/* + * Set up a Destination IP address. Currently it is set to 172.16.63.61. + */ +static u8 DestIpAddress[IP_ADDR_SIZE] = +{ + 172, 16, 63, 61 +}; + +static u16 DestMacAddr[MAC_ADDR_LEN]; /* Destination MAC Address */ +static XEmacLite EmacLiteInstance; /* Instance of the EmacLite driver */ + +/* + * Known data transmitted in Echo request. + */ +u16 IcmpData[ICMP_KNOWN_DATA_LEN] = +{ + 0x6162, 0x6364, 0x6566, 0x6768, 0x696A, 0x6B6C, 0x6D6E, 0x6F70, + 0x7172, 0x7374, 0x7576, 0x7761, 0x6263, 0x6465, 0x6667, 0x6869 +}; + +/* + * IP header information -- each field has its own significance. + * Icmp type, ipv4 typelength, packet length, identification field + * Fragment type, time to live and ICM, checksum. + */ +u16 IpHeaderInfo[IP_HEADER_INFO_LEN] = +{ + 0x0800, 0x4500, 0x003C, 0x5566, 0x0000, 0x8001, 0x0000 +}; + +/* + * Buffers used for Transmission and Reception of Packets. These are declared as + * global so that they are not a part of the stack. + */ +static u8 RxFrame[XEL_MAX_FRAME_SIZE]; +static u8 TxFrame[XEL_MAX_FRAME_SIZE]; + +/* + * Variable used to indicate the length of the received frame. + */ +u32 RecvFrameLength; + +/* + * Variable used to indicate the sequence number of the ICMP(echo) packet. + */ +int SeqNum; + +/* + * Variable used to indicate the number of ping request packets to be send. + */ +int NumOfPingReqPkts; + +/****************************************************************************/ +/** +* +* This function is the main function of the Ping Request example in polled mode. +* +* @param None. +* +* @return XST_FAILURE to indicate failure, otherwise it will return +* XST_SUCCESS after sending specified number of packets as +* defined in "NUM_OF_PING_REQ_PKTS" . +* +* @note None. +* +*****************************************************************************/ +int main() +{ + int Status; + + /* + * Run the EmacLite Ping request example. + */ + Status = EmacLitePingReqExample(EMAC_DEVICE_ID); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* The entry point for the EmacLite driver to ping request example in polled +* mode. This function will generate specified number of request packets as +* defined in "NUM_OF_PING_REQ_PKTS. +* +* @param DeviceId is device ID of the XEmacLite Device. +* +* @return XST_FAILURE to indicate failure, otherwise it will return +* XST_SUCCESS. +* +* @note None. +* +******************************************************************************/ +static int EmacLitePingReqExample(u16 DeviceId) +{ + int Status; + int Index; + int Count; + int EchoReplyStatus; + XEmacLite_Config *ConfigPtr; + XEmacLite *EmacLiteInstPtr = &EmacLiteInstance; + SeqNum = 0; + RecvFrameLength = 0; + EchoReplyStatus = XST_FAILURE; + NumOfPingReqPkts = NUM_OF_PING_REQ_PKTS; + + /* + * 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, LocalMacAddr); + + /* + * Empty any existing receive frames. + */ + XEmacLite_FlushReceive(EmacLiteInstPtr); + while (NumOfPingReqPkts--) { + + /* + * Introduce delay. + */ + Count = DELAY; + while (Count--) { + } + + /* + * Send an ARP or an ICMP packet based on receive packet. + */ + if (SeqNum == 0) { + SendArpReqFrame(EmacLiteInstPtr); + } else { + SendEchoReqFrame(EmacLiteInstPtr); + } + + /* + * Check next 10 packets for the correct reply. + */ + Index = NUM_RX_PACK_CHECK_REQ; + while (Index--) { + + /* + * Wait for a Receive packet. + */ + Count = NUM_PACK_CHECK_RX_PACK; + while (RecvFrameLength == 0) { + RecvFrameLength = XEmacLite_Recv( + EmacLiteInstPtr, + (u8 *)RxFrame); + + /* + * To avoid infinite loop when no packet is + * received. + */ + if (Count-- == 0) { + break; + } + } + + /* + * Process the Receive frame. + */ + if (RecvFrameLength != 0) { + EchoReplyStatus = ProcessRecvFrame( + EmacLiteInstPtr); + } + RecvFrameLength = 0; + + /* + * Comes out of loop when an echo reply packet is + * received. + */ + if (EchoReplyStatus == XST_SUCCESS) { + break; + } + } + + /* + * If no echo reply packet is received, it reports + * request timed out. + */ + if (EchoReplyStatus == XST_FAILURE) { + xil_printf("Packet No: %d", + NUM_OF_PING_REQ_PKTS - NumOfPingReqPkts); + xil_printf(" Seq NO %d Request timed out\r\n", + SeqNum); + } + } + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* This function will send a ARP request packet. +* +* @param InstancePtr is a pointer to the instance of the EmacLite. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +static void SendArpReqFrame(XEmacLite *InstancePtr) +{ + u16 *TempPtr; + u16 *TxFramePtr; + u32 NextTxBuffBaseAddr; + int Index; + + TxFramePtr = (u16 *)TxFrame; + + /* + * Determine the next expected transmit buffer base address. + */ + NextTxBuffBaseAddr = XEmacLite_NextTransmitAddr(InstancePtr); + + /* + * Add broadcast address. + */ + Index = MAC_ADDR_LEN; + while (Index--) { + *TxFramePtr++ = BROADCAST_ADDR; + } + + /* + * Add local MAC address. + */ + Index = 0; + TempPtr = (u16 *)LocalMacAddr; + while (Index < MAC_ADDR_LEN) { + *TxFramePtr++ = *(TempPtr + Index); + Index++; + } + + /* + * Add + * - Ethernet proto type. + * - Hardware Type + * - Protocol IP Type + * - IP version (IPv6/IPv4) + * - ARP Request + */ + *TxFramePtr++ = Xil_Htons(XEL_ETHER_PROTO_TYPE_ARP); + *TxFramePtr++ = Xil_Htons(HW_TYPE); + *TxFramePtr++ = Xil_Htons(XEL_ETHER_PROTO_TYPE_IP); + *TxFramePtr++ = Xil_Htons(IP_VERSION); + *TxFramePtr++ = Xil_Htons(ARP_REQUEST); + + /* + * Add local MAC address. + */ + Index = 0; + TempPtr = (u16 *)LocalMacAddr; + while (Index < MAC_ADDR_LEN) { + *TxFramePtr++ = *(TempPtr + Index); + Index++; + } + + /* + * Add local IP address. + */ + Index = 0; + TempPtr = (u16 *)LocalIpAddress; + while (Index < IP_ADDR_LEN) { + *TxFramePtr++ = *(TempPtr + Index); + Index++; + } + + /* + * Fills 6 bytes of information with zeros as per protocol. + */ + Index = 0; + while (Index < 3) { + *TxFramePtr++ = 0x0000; + Index++; + } + + /* + * Add Destination IP address. + */ + Index = 0; + TempPtr = (u16 *)DestIpAddress; + while (Index < IP_ADDR_LEN) { + *TxFramePtr++ = *(TempPtr + Index); + Index++; + } + + /* + * Transmit the Frame. + */ + XEmacLite_Send(InstancePtr, (u8 *)&TxFrame, ARP_REQ_PKT_SIZE); +} + +/*****************************************************************************/ +/** +* +* This function will send a Echo request packet. +* +* @param InstancePtr is a pointer to the instance of the EmacLite. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +static void SendEchoReqFrame(XEmacLite *InstancePtr) +{ + u16 *TempPtr; + u16 *TxFramePtr; + u16 *RxFramePtr; + u16 CheckSum; + u32 NextTxBuffBaseAddr; + int Index; + + TxFramePtr = (u16 *)TxFrame; + RxFramePtr = (u16 *)RxFrame; + + /* + * Determine the next expected transmit buffer base address. + */ + NextTxBuffBaseAddr = XEmacLite_NextTransmitAddr(InstancePtr); + + /* + * Add Destination MAC Address. + */ + Index = MAC_ADDR_LEN; + while (Index--) { + *(TxFramePtr + Index) = *(DestMacAddr + Index); + } + + /* + * Add Source MAC Address. + */ + Index = MAC_ADDR_LEN; + TempPtr = (u16 *)LocalMacAddr; + while (Index--) { + *(TxFramePtr + (Index + SRC_MAC_ADDR_LOC )) = + *(TempPtr + Index); + } + + /* + * Add IP header information. + */ + Index = IP_START_LOC; + while (Index--) { + *(TxFramePtr + (Index + ETHER_PROTO_TYPE_LOC )) = + Xil_Htons(*(IpHeaderInfo + Index)); + } + + /* + * Add Source IP address. + */ + Index = IP_ADDR_LEN; + TempPtr = (u16 *)LocalIpAddress; + while (Index--) { + *(TxFramePtr + (Index + IP_REQ_SRC_IP_LOC )) = + *(TempPtr + Index); + } + + /* + * Add Destination IP address. + */ + Index = IP_ADDR_LEN; + TempPtr = (u16 *)DestIpAddress; + while (Index--) { + *(TxFramePtr + (Index + IP_REQ_DEST_IP_LOC )) = + *(TempPtr + Index); + } + + /* + * Checksum is calculated for IP field and added in the frame. + */ + CheckSum = CheckSumCalculation((u16 *)TxFrame, IP_START_LOC, + IP_HEADER_LEN); + CheckSum = ~CheckSum; + *(TxFramePtr + IP_CHECKSUM_LOC) = Xil_Htons(CheckSum); + + /* + * Add echo field information. + */ + *(TxFramePtr + ICMP_ECHO_FIELD_LOC) = Xil_Htons(XEL_ETHER_PROTO_TYPE_IP); + + /* + * Checksum value is initialized to zeros. + */ + *(TxFramePtr + ICMP_DATA_LEN) = 0x0000; + + /* + * Add identifier and sequence number to the frame. + */ + *(TxFramePtr + ICMP_IDEN_FIELD_LOC) = (IDEN_NUM); + *(TxFramePtr + (ICMP_IDEN_FIELD_LOC + 1)) = Xil_Htons((u16)(++SeqNum)); + + /* + * Add known data to the frame. + */ + Index = ICMP_KNOWN_DATA_LEN; + while (Index--) { + *(TxFramePtr + (Index + ICMP_KNOWN_DATA_LOC)) = + Xil_Htons(*(IcmpData + Index)); + } + + /* + * Checksum is calculated for Data Field and added in the frame. + */ + CheckSum = CheckSumCalculation((u16 *)TxFrame, ICMP_DATA_START_LOC, + ICMP_DATA_FIELD_LEN ); + CheckSum = ~CheckSum; + *(TxFramePtr + ICMP_DATA_CHECKSUM_LOC) = Xil_Htons(CheckSum); + + /* + * Transmit the Frame. + */ + XEmacLite_Send(InstancePtr, (u8 *)&TxFrame, ICMP_PKT_SIZE); +} + +/*****************************************************************************/ +/** +* +* This function will process the received packet. This function sends +* the echo request packet based on the ARP reply packet. +* +* @param InstancePtr is a pointer to the instance of the EmacLite. +* +* @return XST_SUCCESS is returned when an echo reply is received. +* Otherwise, XST_FAILURE is returned. +* +* @note This assumes MAC does not strip padding or CRC. +* +******************************************************************************/ +static int ProcessRecvFrame(XEmacLite *InstancePtr) +{ + u16 *RxFramePtr; + u16 *TempPtr; + u16 CheckSum; + int Index; + int Match = 0; + int DataWrong = 0; + + RxFramePtr = (u16 *)RxFrame; + TempPtr = (u16 *)LocalMacAddr; + + /* + * Check Dest Mac address of the packet with the LocalMac address. + */ + Match = CompareData(RxFramePtr, TempPtr, 0, 0, MAC_ADDR_LEN); + if (Match == XST_SUCCESS) { + + /* + * Check ARP type. + */ + if (Xil_Ntohs(*(RxFramePtr + ETHER_PROTO_TYPE_LOC)) == + XEL_ETHER_PROTO_TYPE_ARP ) { + + /* + * Check ARP status. + */ + if (Xil_Ntohs(*(RxFramePtr + ARP_REQ_STATUS_LOC)) == ARP_REPLY) { + + /* + * Check destination IP address with + * packet's source IP address. + */ + TempPtr = (u16 *)DestIpAddress; + Match = CompareData(RxFramePtr, + TempPtr, ARP_REQ_SRC_IP_LOC, + 0, IP_ADDR_LEN); + if (Match == XST_SUCCESS) { + + /* + * Copy src Mac address of the received + * packet. + */ + Index = MAC_ADDR_LEN; + TempPtr = (u16 *)DestMacAddr; + while (Index--) { + *(TempPtr + Index) = + *(RxFramePtr + + (SRC_MAC_ADDR_LOC + + Index)); + } + + /* + * Send Echo request packet. + */ + SendEchoReqFrame(InstancePtr); + } + } + } + + /* + * Check for IP type. + */ + else if (Xil_Ntohs(*(RxFramePtr + ETHER_PROTO_TYPE_LOC)) == + XEL_ETHER_PROTO_TYPE_IP) { + + /* + * Calculate checksum. + */ + CheckSum = CheckSumCalculation(RxFramePtr, + ICMP_DATA_START_LOC, + ICMP_DATA_FIELD_LEN); + + /* + * Verify checksum, echo reply, identifier number and + * sequence number of the received packet. + */ + if ((CheckSum == CORRECT_CHECKSUM_VALUE) && + (Xil_Ntohs(*(RxFramePtr + ICMP_ECHO_FIELD_LOC)) == ECHO_REPLY) && + (Xil_Ntohs(*(RxFramePtr + ICMP_IDEN_FIELD_LOC)) == IDEN_NUM) && + (Xil_Ntohs(*(RxFramePtr + (ICMP_SEQ_NO_LOC))) == SeqNum)) { + + /* + * Verify data in the received packet with known + * data. + */ + TempPtr = IcmpData; + Match = CompareData(RxFramePtr, + TempPtr, ICMP_KNOWN_DATA_LOC, + 0, ICMP_KNOWN_DATA_LEN); + if (Match == XST_FAILURE) { + DataWrong = 1; + } + } + if (DataWrong != 1) { + xil_printf("Packet No: %d ", + NUM_OF_PING_REQ_PKTS - NumOfPingReqPkts); + xil_printf("Seq NO %d Echo Packet received\r\n", + SeqNum); + return XST_SUCCESS; + } + } + } + return XST_FAILURE; +} +/*****************************************************************************/ +/** +* +* This function calculates the checksum and returns a 16 bit result. +* +* @param RxFramePtr is a 16 bit pointer for the data to which checksum +* is to be calculated. +* @param StartLoc is the starting location of the data from which the +* checksum has to be calculated. +* @param Length is the number of halfwords(16 bits) to which checksum is +* to be calculated. +* +* @return It returns a 16 bit checksum value. +* +* @note This can also be used for calculating checksum. The ones +* complement of this return value will give the final checksum. +* +******************************************************************************/ +static u16 CheckSumCalculation(u16 *RxFramePtr, int StartLoc, int Length) +{ + u32 Sum = 0; + u16 CheckSum = 0; + int Index; + + /* + * Add all the 16 bit data. + */ + Index = StartLoc; + while (Index < (StartLoc + Length)) { + Sum = Sum + Xil_Htons(*(RxFramePtr + Index)); + Index++; + } + + /* + * Add upper 16 bits to lower 16 bits. + */ + CheckSum = Sum; + Sum = Sum>>16; + CheckSum = Sum + CheckSum; + return CheckSum; +} +/*****************************************************************************/ +/** +* +* This function checks the match for the specified number of half words. +* +* @param LhsPtr is a LHS entity pointer. +* @param RhsPtr is a RHS entity pointer. +* @param LhsLoc is a LHS entity location. +* @param RhsLoc is a RHS entity location. +* @param Count is the number of location which has to compared. +* +* @return XST_SUCCESS is returned when both the entities are same, +* otherwise XST_FAILURE is returned. +* +* @note None. +* +******************************************************************************/ +static int CompareData(u16 *LhsPtr, u16 *RhsPtr, int LhsLoc, int RhsLoc, + int Count) +{ + int Result; + while (Count--) { + if (*(LhsPtr + LhsLoc + Count) == *(RhsPtr + RhsLoc + Count)) { + Result = XST_SUCCESS; + } else { + Result = XST_FAILURE; + break; + } + } + return Result; +} diff --git a/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_polled_example.c b/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_polled_example.c new file mode 100644 index 00000000..762b5a4c --- /dev/null +++ b/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_polled_example.c @@ -0,0 +1,390 @@ +/****************************************************************************** +* +* 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_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 +* +*
+* 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.
+*
+* 
+* +*****************************************************************************/ + +/***************************** 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__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; +} diff --git a/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_selftest_example.c b/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_selftest_example.c new file mode 100644 index 00000000..5e8bc46b --- /dev/null +++ b/XilinxProcessorIPLib/drivers/emaclite/examples/xemaclite_selftest_example.c @@ -0,0 +1,152 @@ +/****************************************************************************** +* +* 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_selftest_example.c +* +* This file contains a design example using the EmacLite driver. +* +* @note +* +* None. +* +* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ----------------------------------------------- +* 1.00a ecm 01/25/05 Initial release for TestApp integration. +* 1.00a sv 06/06/05 Minor changes to comply to Doxygen and coding guidelines +* 2.00a ktn 04/14/09 Removed support for TestApp +* +******************************************************************************/ +/***************************** Include Files *********************************/ + +#include "xparameters.h" +#include "xemaclite.h" + +/************************** Constant Definitions *****************************/ + +/* + * The following constants map to the XPAR parameters created in the + * xparameters.h file. They are defined here such that a user can easily + * change all the needed parameters in one place. + */ +#define EMAC_DEVICE_ID XPAR_EMACLITE_0_DEVICE_ID + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +int EMACLiteSelfTestExample(u16 DeviceId); + +/************************** Variable Definitions *****************************/ + +/* + * Instance of the driver + */ +static XEmacLite EmacLite; + +/****************************************************************************/ +/** +* +* This function is the main function of the EmacLite selftest example. +* +* @param None +* +* @return XST_SUCCESS to indicate success, else XST_FAILURE. +* +* @note None +* +*****************************************************************************/ +int main(void) +{ + int Status; + + /* + * Run the EmacLite Self test example, specify the Device ID that is + * generated in xparameters.h + */ + Status = EMACLiteSelfTestExample(EMAC_DEVICE_ID); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + return XST_SUCCESS; + +} + +/*****************************************************************************/ +/** +* +* The main entry point for the EmacLite driver selftest example. +* +* @param DeviceId is the XPAR__DEVICE_ID value from +* xparameters.h +* +* @return XST_SUCCESS to indicate success, else XST_FAILURE. +* +* @note None. +* +******************************************************************************/ +int EMACLiteSelfTestExample(u16 DeviceId) +{ + int Status; + XEmacLite_Config *ConfigPtr; + XEmacLite *InstancePtr = &EmacLite; + + /* + * Initialize the EmacLite device. + */ + ConfigPtr = XEmacLite_LookupConfig(DeviceId); + if (ConfigPtr == NULL) { + return XST_FAILURE; + } + Status = XEmacLite_CfgInitialize(InstancePtr, + ConfigPtr, + ConfigPtr->BaseAddress); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + /* + * Run the Self Test + */ + Status = XEmacLite_SelfTest(InstancePtr); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + return XST_SUCCESS; +} diff --git a/XilinxProcessorIPLib/drivers/emaclite/src/Makefile b/XilinxProcessorIPLib/drivers/emaclite/src/Makefile new file mode 100644 index 00000000..1822ca81 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/emaclite/src/Makefile @@ -0,0 +1,26 @@ +COMPILER= +ARCHIVER= +CP=cp +COMPILER_FLAGS= +EXTRA_COMPILER_FLAGS= +LIB=libxil.a + +RELEASEDIR=../../../lib +INCLUDEDIR=../../../include +INCLUDES=-I./. -I${INCLUDEDIR} + +INCLUDEFILES=*.h +LIBSOURCES=*.c +OUTS = *.o + +libs: + echo "Compiling emaclite" + $(COMPILER) $(COMPILER_FLAGS) $(EXTRA_COMPILER_FLAGS) $(INCLUDES) $(LIBSOURCES) + $(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OUTS} + make clean + +include: + ${CP} $(INCLUDEFILES) $(INCLUDEDIR) + +clean: + rm -rf ${OUTS} diff --git a/XilinxProcessorIPLib/drivers/emaclite/src/xemaclite.c b/XilinxProcessorIPLib/drivers/emaclite/src/xemaclite.c new file mode 100644 index 00000000..8df885b2 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/emaclite/src/xemaclite.c @@ -0,0 +1,971 @@ +/****************************************************************************** +* +* 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 +* @addtogroup emaclite_v4_0 +* @{ +* @details +* +* Functions in this file are the minimum required functions for the EmacLite +* driver. See xemaclite.h for a detailed description of the driver. +* +*
+* 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).
+*
+* 
+******************************************************************************/ + +/***************************** 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; +} + +/** @} */ diff --git a/XilinxProcessorIPLib/drivers/emaclite/src/xemaclite.h b/XilinxProcessorIPLib/drivers/emaclite/src/xemaclite.h new file mode 100644 index 00000000..448af472 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/emaclite/src/xemaclite.h @@ -0,0 +1,408 @@ +/****************************************************************************** +* +* 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.h +* @addtogroup emaclite_v4_0 +* @{ +* @details +* +* The Xilinx Ethernet Lite (EmacLite) driver. This driver supports the Xilinx +* Ethernet Lite 10/100 MAC (EmacLite). +* +* The Xilinx Ethernet Lite 10/100 MAC supports the following features: +* - Media Independent Interface (MII) for connection to external +* 10/100 Mbps PHY transceivers +* - Independent internal transmit and receive buffers +* - CSMA/CD compliant operations for half-duplex modes +* - Unicast and broadcast +* - Automatic FCS insertion +* - Automatic pad insertion on transmit +* - Configurable ping/pong buffers for either/both transmit and receive +* buffer areas +* - Interrupt driven mode +* - Internal loop back +* - MDIO Support to access PHY Registers +* +* The Xilinx Ethernet Lite 10/100 MAC does not support the following features: +* - multi-frame buffering +* only 1 transmit frame is allowed into each transmit buffer, +* only 1 receive frame is allowed into each receive buffer. +* the hardware blocks reception until buffer is emptied +* - Pause frame (flow control) detection in full-duplex mode +* - Programmable inter frame gap +* - Multicast and promiscuous address filtering +* - Automatic source address insertion or overwrite +* +* Driver Description +* +* The device driver enables higher layer software (e.g., an application) to +* communicate to the EmacLite. The driver handles transmission and reception +* of Ethernet frames, as well as configuration of the controller. It does not +* handle protocol stack functionality such as Link Layer Control (LLC) or the +* Address Resolution Protocol (ARP). The protocol stack that makes use of the +* driver handles this functionality. This implies that the driver is simply a +* pass-through mechanism between a protocol stack and the EmacLite. +* +* Since the driver is a simple pass-through mechanism between a protocol stack +* and the EmacLite, no assembly or disassembly of Ethernet frames is done at +* the driver-level. This assumes that the protocol stack passes a correctly +* formatted Ethernet frame to the driver for transmission, and that the driver +* does not validate the contents of an incoming frame. A single device driver +* can support multiple EmacLite devices. +* +* The driver supports interrupt driven mode and the default mode of operation +* is polled mode. If interrupts are desired, XEmacLite_InterruptEnable() must +* be called. +* +* Device Configuration +* +* The device can be configured in various ways during the FPGA implementation +* process. Configuration parameters are stored in the xemaclite_g.c file. +* A table is defined where each entry contains configuration information for an +* EmacLite device. This information includes such things as the base address +* of the memory-mapped device and the number of buffers. +* +* Interrupt Processing +* +* After _Initialize is called, _InterruptEnable can be called to enable the +* interrupt driven functionality. If polled operation is desired, just call +* _Send and check the return code. If XST_FAILURE is returned, call _Send with +* the same data until XST_SUCCESS is returned. The same idea applies to _Recv. +* Call _Recv until the returned length is non-zero at which point the received +* data is in the buffer provided in the function call. +* +* The Transmit and Receive interrupts are enabled within the _InterruptEnable +* function and disabled in the _InterruptDisable function. The _Send and _Recv +* functions acknowledge the EmacLite generated interrupts associated with each +* function. +* It is the application's responsibility to acknowledge any associated Interrupt +* Controller interrupts if it is used in the system. +* +* Memory Buffer Alignment +* +* The alignment of the input/output buffers for the _Send and _Recv routine is +* not required to be 32 bits. If the buffer is not aligned on a 32-bit boundary +* there will be a performance impact while the driver aligns the data for +* transmission or upon reception. +* +* For optimum performance, the user should provide a 32-bit aligned buffer +* to the _Send and _Recv routines. +* +* Asserts +* +* Asserts are used within all Xilinx drivers to enforce constraints on argument +* values. Asserts can be turned off on a system-wide basis by defining, at +* compile time, the NDEBUG identifier. By default, asserts are turned on and it +* is recommended that application developers leave asserts on during +* development. +* +* @note +* +* This driver requires EmacLite hardware version 1.01a and higher. It is not +* compatible with earlier versions of the EmacLite hardware. Use version 1.00a +* software driver for hardware version 1.00a/b. +* +* The RX hardware is enabled from powerup and there is no disable. It is +* possible that frames have been received prior to the initialization +* of the driver. If this situation is possible, call XEmacLite_FlushReceive() +* to empty the receive buffers after initialization. +* +* This driver is intended to be RTOS and processor independent. It works +* with physical addresses only. Any needs for dynamic memory management, +* threads or thread mutual exclusion, virtual memory, or cache control must +* be satisfied by the layer above this driver. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.01a ecm  01/30/04 First release
+* 1.11a mta  03/21/07 Updated to new coding style
+* 1.12a mta  11/28/07 Added the function XEmacLite_CfgInitialize,
+*		      moved the functions XEmacLite_LookupConfig and
+*		      XEmacLite_Initialize to xemaclite_sinit.c for removing
+*		      the dependency on the static config table and
+*		      xparameters.h from the driver initialization
+* 1.13a sv   02/1/08  Updated the TxBufferAvailable routine to return
+*		      busy status properly and added macros for Tx/Rx status
+* 1.14a sdm  08/22/08 Removed support for static interrupt handlers from the MDD
+*		      file
+* 2.00a ktn  02/16/09 Added support for MDIO and internal loop back
+* 2.01a ktn  07/20/09 Updated the XEmacLite_AlignedWrite and
+*                     XEmacLite_AlignedRead functions to use volatile
+*                     variables so that they are not optimized.
+*                     Modified the XEmacLite_EnableInterrupts and
+*                     XEmacLite_DisableInterrupts functions to enable/disable
+*                     the interrupt in the Ping buffer as this is used to enable
+*                     the interrupts for both Ping and Pong Buffers.
+*                     The interrupt enable bit in the Pong buffer is not used by
+*                     the HW.
+*                     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 Processor APIs/macros.
+*		      The macros have been renamed to remove _m from the name in
+*		      all the driver files.
+*		      The macros changed in this file are
+*		      XEmacLite_mNextTransmitAddr is XEmacLite_NextTransmitAddr,
+*		      XEmacLite_mNextReceiveAddr is XEmacLite_NextReceiveAddr,
+*		      XEmacLite_mIsMdioConfigured is XEmacLite_IsMdioConfigured,
+*		      XEmacLite_mIsLoopbackConfigured is
+*		      XEmacLite_IsLoopbackConfigured.
+*		      See xemaclite_i.h for the macros which have changed.
+* 3.01a ktn  07/08/10 The macro XEmacLite_GetReceiveDataLength in the
+*		      xemaclite.c file is changed to a static function.
+*		      XEmacLite_GetReceiveDataLength and XEmacLite_Recv
+*		      functions  are updated to support little endian
+*		      MicroBlaze.
+* 3.02a sdm  07/22/11 Removed redundant code in XEmacLite_Recv functions for
+*		      CR617290
+* 3.03a asa  04/05/12 Defined the flag __LITTLE_ENDIAN__ for cases where the
+*		      driver is compiled with ARM toolchain.
+* 3.04a srt  04/13/13 Removed warnings (CR 705000).
+* 4.0   adk  19/12/13 Updated as per the New Tcl API's
+*
+* 
+* +* +******************************************************************************/ +#ifndef XEMACLITE_H /* prevent circular inclusions */ +#define XEMACLITE_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xenv.h" +#include "xil_types.h" +#include "xil_assert.h" +#include "xstatus.h" +#include "xemaclite_l.h" + +#ifdef __ARMEL__ +#ifndef __LITTLE_ENDIAN__ +#define __LITTLE_ENDIAN__ +#endif +#endif +/************************** Constant Definitions *****************************/ +/* + * Device information + */ +#define XEL_DEVICE_NAME "xemaclite" +#define XEL_DEVICE_DESC "Xilinx Ethernet Lite 10/100 MAC" + +/**************************** Type Definitions *******************************/ + +/** + * This typedef contains configuration information for a device. + */ +typedef struct { + u16 DeviceId; /**< Unique ID of device */ + u32 BaseAddress; /**< Device base address */ + u8 TxPingPong; /**< 1 if TX Pong buffer configured, 0 otherwise */ + u8 RxPingPong; /**< 1 if RX Pong buffer configured, 0 otherwise */ + u8 MdioInclude; /**< 1 if MDIO is enabled, 0 otherwise */ + u8 Loopback; /**< 1 if internal loopback is enabled, 0 otherwise */ +} XEmacLite_Config; + + +/* + * Callback when data is sent or received . + * @param CallBackRef is a callback reference passed in by the upper layer + * when setting the callback functions, and passed back to the + * upper layer when the callback is invoked. + */ +typedef void (*XEmacLite_Handler) (void *CallBackRef); + +/** + * The XEmacLite driver instance data. The user is required to allocate a + * variable of this type for every EmacLite device in the system. A pointer + * to a variable of this type is then passed to the driver API functions. + */ +typedef struct { + XEmacLite_Config EmacLiteConfig; /* Device configuration */ + u32 IsReady; /* Device is initialized and ready */ + + u32 NextTxBufferToUse; /* Next TX buffer to write to */ + u32 NextRxBufferToUse; /* Next RX buffer to read from */ + + /* + * Callbacks + */ + XEmacLite_Handler RecvHandler; + void *RecvRef; + XEmacLite_Handler SendHandler; + void *SendRef; + +} XEmacLite; + +/***************** Macros (Inline Functions) Definitions *********************/ + +/****************************************************************************/ +/** +* +* Return the next expected Transmit Buffer's address. +* +* @param InstancePtr is the pointer to the instance of the driver to +* be worked on +* +* @note C-Style signature: +* u32 XEmacLite_NextTransmitAddr(XEmacLite *InstancePtr); +* +* This macro returns the address of the next transmit buffer to put data into. +* This is used to determine the destination of the next transmit data frame. +* +*****************************************************************************/ +#define XEmacLite_NextTransmitAddr(InstancePtr) \ + ((InstancePtr)->EmacLiteConfig.BaseAddress + \ + (InstancePtr)->NextTxBufferToUse) + XEL_TXBUFF_OFFSET + +/****************************************************************************/ +/** +* +* Return the next expected Receive Buffer's address. +* +* @param InstancePtr is the pointer to the instance of the driver to +* be worked on +* +* @note C-Style signature: +* u32 XEmacLite_NextReceiveAddr(XEmacLite *InstancePtr); +* +* This macro returns the address of the next receive buffer to read data from. +* This is the expected receive buffer address if the driver is in sync. +* +*****************************************************************************/ +#define XEmacLite_NextReceiveAddr(InstancePtr) \ + ((InstancePtr)->EmacLiteConfig.BaseAddress + \ + (InstancePtr)->NextRxBufferToUse) + +/*****************************************************************************/ +/** +* +* This macro determines if the device is currently configured for MDIO. +* +* @param InstancePtr is the pointer to the instance of the +* EmacLite driver. +* +* @return +* - TRUE if the device is configured for MDIO. +* - FALSE if the device is NOT configured for MDIO. +* +* @note C-Style signature: +* int XEmacLite_IsMdioConfigured(XEmacLite *InstancePtr) +* +******************************************************************************/ +#define XEmacLite_IsMdioConfigured(InstancePtr) \ + ((InstancePtr)->EmacLiteConfig.MdioInclude == 1) + +/*****************************************************************************/ +/** +* +* This macro determines if the device is currently configured for internal +* loopback. +* +* @param InstancePtr is the pointer to the instance of the +* EmacLite driver. +* +* @return +* - TRUE if the device is configured for internal loopback. +* - FALSE if the device is NOT configured for internal loopback. +* +* @note C-Style signature: +* int XEmacLite_IsLoopbackConfigured(XEmacLite *InstancePtr) +* +******************************************************************************/ +#define XEmacLite_IsLoopbackConfigured(InstancePtr) \ + ((InstancePtr)->EmacLiteConfig.Loopback == 1) + +/************************** Variable Definitions *****************************/ + +/************************** Function Prototypes ******************************/ + +/* + * Functions in xemaclite.c + */ +int XEmacLite_CfgInitialize(XEmacLite *InstancePtr, + XEmacLite_Config *EmacLiteConfigPtr, + u32 EffectiveAddr); +void XEmacLite_SetMacAddress(XEmacLite *InstancePtr, u8 *AddressPtr); +int XEmacLite_TxBufferAvailable(XEmacLite *InstancePtr); +void XEmacLite_FlushReceive(XEmacLite *InstancePtr); + +int XEmacLite_Send(XEmacLite *InstancePtr, u8 *FramePtr, unsigned ByteCount); +u16 XEmacLite_Recv(XEmacLite *InstancePtr, u8 *FramePtr); + +int XEmacLite_PhyRead(XEmacLite *InstancePtr, u32 PhyAddress, u32 RegNum, + u16 *PhyDataPtr); +int XEmacLite_PhyWrite(XEmacLite *InstancePtr, u32 PhyAddress, u32 RegNum, + u16 PhyData); + +void XEmacLite_EnableLoopBack(XEmacLite *InstancePtr); +void XEmacLite_DisableLoopBack(XEmacLite *InstancePtr); + +/* + * Initialization functions in xemaclite_sinit.c + */ +XEmacLite_Config *XEmacLite_LookupConfig(u16 DeviceId); +int XEmacLite_Initialize(XEmacLite *InstancePtr, u16 DeviceId); + +/* + * Interrupt driven functions in xemaclite_intr.c + */ +int XEmacLite_EnableInterrupts(XEmacLite *InstancePtr); +void XEmacLite_DisableInterrupts(XEmacLite *InstancePtr); + +void XEmacLite_InterruptHandler(void *InstancePtr); + +void XEmacLite_SetRecvHandler(XEmacLite *InstancePtr, void *CallBackRef, + XEmacLite_Handler FuncPtr); +void XEmacLite_SetSendHandler(XEmacLite *InstancePtr, void *CallBackRef, + XEmacLite_Handler FuncPtr); + +/* + * Selftest function in xemaclite_selftest.c + */ +int XEmacLite_SelfTest(XEmacLite *InstancePtr); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ + + +/** @} */ diff --git a/XilinxProcessorIPLib/drivers/emaclite/src/xemaclite_g.c b/XilinxProcessorIPLib/drivers/emaclite/src/xemaclite_g.c new file mode 100644 index 00000000..52abbb74 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/emaclite/src/xemaclite_g.c @@ -0,0 +1,85 @@ +/****************************************************************************** +* +* 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_g.c +* @addtogroup emaclite_v4_0 +* @{ +* @details +* +* This file contains a configuration table that specifies the configuration +* of EmacLite devices in the system. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.01a ecm  02/16/04 First release
+* 1.11a mta  03/21/07 Updated to new coding style
+* 2.00a ktn  02/16/09 Added support for MDIO
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xparameters.h" +#include "xemaclite.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Prototypes ******************************/ + +/** + * This table contains configuration information for each EmacLite device + * in the system. + */ +XEmacLite_Config XEmacLite_ConfigTable[XPAR_XEMACLITE_NUM_INSTANCES] = { + { + XPAR_EMACLITE_0_DEVICE_ID, /* Unique ID of device */ + XPAR_EMACLITE_0_BASEADDR, /* Device base address */ + XPAR_EMACLITE_0_TX_PING_PONG, /* Include TX Ping Pong buffers */ + XPAR_EMACLITE_0_RX_PING_PONG, /* Include RX Ping Pong buffers */ + XPAR_EMACLITE_0_INCLUDE_MDIO /* Include MDIO support */ + XPAR_EMACLITE_0_INCLUDE_INTERNAL_LOOPBACK /* Include Internal + * loop back support */ + } +}; +/** @} */ diff --git a/XilinxProcessorIPLib/drivers/emaclite/src/xemaclite_i.h b/XilinxProcessorIPLib/drivers/emaclite/src/xemaclite_i.h new file mode 100644 index 00000000..52ed6bb5 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/emaclite/src/xemaclite_i.h @@ -0,0 +1,140 @@ +/****************************************************************************** +* +* 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_i.h +* @addtogroup emaclite_v4_0 +* @{ +* @details +* +* This header file contains internal identifiers, which are those shared +* between the files of the driver. It is intended for internal use only. +* +* NOTES: +* +* None. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.01a ecm  05/21/04 First release
+* 1.11a mta  03/21/07 Updated to new coding style
+* 1.13a sv   02/1/08  Added macros to Get/Set Tx/Rx status
+* 3.00a ktn  10/22/09 The macros have been renamed to remove _m from the name.
+*		      The macros changed in this file are
+*		      XEmacLite_mGetTxActive changed to XEmacLite_GetTxActive,
+*		      XEmacLite_mSetTxActive changed to XEmacLite_SetTxActive.
+*
+* 
+******************************************************************************/ + +#ifndef XEMACLITE_I_H /* prevent circular inclusions */ +#define XEMACLITE_I_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/***************************** Include Files *********************************/ + +#include "xemaclite.h" + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/****************************************************************************/ +/** +* +* Get the TX active location to check status. This is used to check if +* the TX buffer is currently active. There isn't any way in the hardware +* to implement this but the register is fully populated so the driver can +* set the bit in the send routine and the ISR can clear the bit when +* the handler is complete. This mimics the correct operation of the hardware +* if it was possible to do this in hardware. +* +* @param BaseAddress is the base address of the device +* +* @return Contents of active bit in register. +* +* @note C-Style signature: +* u32 XEmacLite_GetTxActive(u32 BaseAddress) +* +*****************************************************************************/ +#define XEmacLite_GetTxActive(BaseAddress) \ + (XEmacLite_ReadReg((BaseAddress), XEL_TSR_OFFSET)) + +/****************************************************************************/ +/** +* +* Set the TX active location to update status. This is used to set the bit +* indicating which TX buffer is currently active. There isn't any way in the +* hardware to implement this but the register is fully populated so the driver +* can set the bit in the send routine and the ISR can clear the bit when +* the handler is complete. This mimics the correct operation of the hardware +* if it was possible to do this in hardware. +* +* @param BaseAddress is the base address of the device +* @param Mask is the data to be written +* +* @return None +* +* @note C-Style signature: +* void XEmacLite_SetTxActive(u32 BaseAddress, u32 Mask) +* +*****************************************************************************/ +#define XEmacLite_SetTxActive(BaseAddress, Mask) \ + (XEmacLite_WriteReg((BaseAddress), XEL_TSR_OFFSET, (Mask))) + +/************************** Variable Definitions ****************************/ + +extern XEmacLite_Config XEmacLite_ConfigTable[]; + +/************************** Function Prototypes ******************************/ + +void XEmacLite_AlignedWrite(void *SrcPtr, u32 *DestPtr, unsigned ByteCount); +void XEmacLite_AlignedRead(u32 *SrcPtr, void *DestPtr, unsigned ByteCount); + +void StubHandler(void *CallBackRef); + + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/XilinxProcessorIPLib/drivers/emaclite/src/xemaclite_intr.c b/XilinxProcessorIPLib/drivers/emaclite/src/xemaclite_intr.c new file mode 100644 index 00000000..6309efe3 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/emaclite/src/xemaclite_intr.c @@ -0,0 +1,363 @@ +/****************************************************************************** +* +* 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_intr.c +* @addtogroup emaclite_v4_0 +* @{ +* @details +* +* Functions in this file are for the interrupt driven processing functionality. +* See xemaclite.h for a detailed description of the driver. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- --------------------------------------------------------
+* 1.01a ecm  03/31/04 First release
+* 1.11a mta  03/21/07 Updated to new coding style
+* 2.01a ktn  07/20/09 Modified the XEmacLite_EnableInterrupts and
+*                     XEmacLite_DisableInterrupts functions to enable/disable
+*                     the interrupt in the Ping buffer as this is used to enable
+*                     the interrupts for both Ping and Pong Buffers.
+*                     The interrupt enable bit in the Pong buffer is not used by
+*                     the HW.
+* 3.00a ktn  10/22/09 Updated file to use the HAL Processor APIs/macros.
+*		      The macros have been renamed to remove _m from the name.
+*
+* 
+******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xemaclite_i.h" +#include "xil_io.h" +#include "xemaclite.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ +/*****************************************************************************/ +/** +* +* Enable the EmacLite Interrupts. +* +* This function must be called before other functions to send or receive data +* in interrupt driven mode. The user should have connected the +* interrupt handler of the driver to an interrupt source such as an interrupt +* controller or the processor interrupt prior to this function being called. +* +* @param InstancePtr is a pointer to the XEmacLite instance. +* +* @return +* - XST_SUCCESS if the device interrupts were enabled +* successfully. +* - XST_NO_CALLBACK if the callbacks were not set. +* +* @note None. +* +******************************************************************************/ +int XEmacLite_EnableInterrupts(XEmacLite *InstancePtr) +{ + u32 Register; + u32 BaseAddress; + + /* + * Verify that each of the inputs are valid. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + BaseAddress = InstancePtr->EmacLiteConfig.BaseAddress; + + /* + * Verify that the handlers are in place. + */ + if ((InstancePtr->RecvHandler == (XEmacLite_Handler) StubHandler) || + (InstancePtr->SendHandler == (XEmacLite_Handler) StubHandler)) { + return XST_NO_CALLBACK; + } + + /* + * Enable the TX interrupts for both the buffers, the Interrupt Enable + * is common for the both the buffers and is defined in the + * Ping buffer. + */ + Register = XEmacLite_GetTxStatus(BaseAddress); + Register |= XEL_TSR_XMIT_IE_MASK; + XEmacLite_SetTxStatus(BaseAddress, Register); + + /* + * Enable the RX interrupts for both the buffers, the Interrupt Enable + * is common for the both the buffers and is defined in the + * Ping buffer. + */ + Register = XEmacLite_GetRxStatus(BaseAddress); + Register |= XEL_RSR_RECV_IE_MASK; + XEmacLite_SetRxStatus(BaseAddress, Register); + + /* + * Enable the global interrupt output. + */ + XEmacLite_WriteReg(BaseAddress, XEL_GIER_OFFSET, XEL_GIER_GIE_MASK); + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* Disables the interrupts from the device (the higher layer software is +* responsible for disabling interrupts at the interrupt controller). +* +* To start using the device again, _EnableInterrupts must be called. +* +* @param InstancePtr is a pointer to the XEmacLite instance . +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XEmacLite_DisableInterrupts(XEmacLite *InstancePtr) +{ + u32 Register; + u32 BaseAddress; + + /* + * Verify that each of the inputs are valid. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + + BaseAddress = InstancePtr->EmacLiteConfig.BaseAddress; + + /* + * Disable the global interrupt output. + */ + XEmacLite_WriteReg(BaseAddress, XEL_GIER_OFFSET, 0); + + /* + * Disable the TX interrupts for both the buffers, the Interrupt Enable + * is common for the both the buffers and is defined in the + * Ping buffer. + */ + Register = XEmacLite_GetTxStatus(BaseAddress); + Register &= ~XEL_TSR_XMIT_IE_MASK; + XEmacLite_SetTxStatus(BaseAddress, Register); + + /* + * Disable the RX interrupts for both the buffers, the Interrupt Enable + * is common for the both the buffers and is defined in the + * Ping buffer. + */ + Register = XEmacLite_GetRxStatus(BaseAddress); + Register &= ~XEL_RSR_RECV_IE_MASK; + XEmacLite_SetRxStatus(BaseAddress, Register); + +} + +/*****************************************************************************/ +/** +* +* Interrupt handler for the EmacLite driver. It performs the following +* processing: +* +* - Get the interrupt status from the registers to determine the source +* of the interrupt. +* - Call the appropriate handler based on the source of the interrupt. +* +* @param InstancePtr contains a pointer to the EmacLite device instance +* for the interrupt. +* +* @return None. +* +* @note None. +* +* +******************************************************************************/ +void XEmacLite_InterruptHandler(void *InstancePtr) +{ + + XEmacLite *EmacLitePtr; + int TxCompleteIntr = FALSE; + u32 BaseAddress; + u32 TxStatus; + + /* + * Verify that each of the inputs are valid. + */ + Xil_AssertVoid(InstancePtr != NULL); + + /* + * Convert the non-typed pointer to an EmacLite instance pointer + * such that there is access to the device. + */ + EmacLitePtr = (XEmacLite *) InstancePtr; + BaseAddress = EmacLitePtr->EmacLiteConfig.BaseAddress; + + if ((XEmacLite_IsRxEmpty(BaseAddress) != TRUE) || + (XEmacLite_IsRxEmpty(BaseAddress + + XEL_BUFFER_OFFSET) != TRUE)) { + /* + * Call the RX callback. + */ + EmacLitePtr->RecvHandler(EmacLitePtr->RecvRef); + + } + + TxStatus = XEmacLite_GetTxStatus(BaseAddress); + if (((TxStatus & XEL_TSR_XMIT_BUSY_MASK) == 0) && + (TxStatus & XEL_TSR_XMIT_ACTIVE_MASK) != 0) { + + /* + * Clear the Tx Active bit in the Tx Status Register. + */ + TxStatus &= ~XEL_TSR_XMIT_ACTIVE_MASK; + XEmacLite_SetTxStatus(BaseAddress, TxStatus); + + /* + * Update the flag indicating that there was a Tx Interrupt. + */ + TxCompleteIntr = TRUE; + + } + + TxStatus = XEmacLite_GetTxStatus(BaseAddress + XEL_BUFFER_OFFSET); + if (((TxStatus & XEL_TSR_XMIT_BUSY_MASK) == 0) && + (TxStatus & XEL_TSR_XMIT_ACTIVE_MASK) != 0) { + + /* + * Clear the Tx Active bit in the Tx Status Register. + */ + TxStatus &= ~XEL_TSR_XMIT_ACTIVE_MASK; + XEmacLite_SetTxStatus(BaseAddress + XEL_BUFFER_OFFSET, + TxStatus); + /* + * Update the flag indicating that there was a Tx Interrupt. + */ + TxCompleteIntr = TRUE; + } + + /* + * If there was a TX interrupt, call the callback. + */ + if (TxCompleteIntr == TRUE) { + + /* + * Call the TX callback. + */ + EmacLitePtr->SendHandler(EmacLitePtr->SendRef); + + } +} + +/*****************************************************************************/ +/** +* +* Sets the callback function for handling received frames in interrupt mode. +* The upper layer software should call this function during initialization. +* The callback is called when a frame is received. The callback function +* should communicate the data to a thread such that the processing is not +* performed in an interrupt context. +* +* The callback is invoked by the driver within interrupt context, so it needs +* to do its job quickly. If there are other potentially slow operations +* within the callback, these should be done at task-level. +* +* @param InstancePtr is a pointer to the XEmacLite instance.. +* @param CallBackRef is a reference pointer to be passed back to the +* application in the callback. This helps the application +* correlate the callback to a particular driver. +* @param FuncPtr is the pointer to the callback function. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XEmacLite_SetRecvHandler(XEmacLite *InstancePtr, void *CallBackRef, + XEmacLite_Handler FuncPtr) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(FuncPtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + InstancePtr->RecvHandler = FuncPtr; + InstancePtr->RecvRef = CallBackRef; +} + + +/*****************************************************************************/ +/** +* +* Sets the callback function for handling transmitted frames in interrupt mode. +* The upper layer software should call this function during initialization. +* The callback is called when a frame is transmitted. The callback function +* should communicate the data to a thread such that the processing is not +* performed in an interrupt context. +* +* The callback is invoked by the driver within interrupt context, so it needs +* to do its job quickly. If there are other potentially slow operations +* within the callback, these should be done at task-level. +* +* @param InstancePtr is a pointer to the XEmacLite instance. +* @param CallBackRef is a reference pointer to be passed back to the +* application in the callback. This helps the application +* correlate the callback to a particular driver. +* @param FuncPtr is the pointer to the callback function. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XEmacLite_SetSendHandler(XEmacLite *InstancePtr, void *CallBackRef, + XEmacLite_Handler FuncPtr) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(FuncPtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + InstancePtr->SendHandler = FuncPtr; + InstancePtr->SendRef = CallBackRef; +} +/** @} */ diff --git a/XilinxProcessorIPLib/drivers/emaclite/src/xemaclite_l.c b/XilinxProcessorIPLib/drivers/emaclite/src/xemaclite_l.c new file mode 100644 index 00000000..430dbe70 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/emaclite/src/xemaclite_l.c @@ -0,0 +1,507 @@ +/****************************************************************************** +* +* 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_l.c +* @addtogroup emaclite_v4_0 +* @{ +* @details +* +* This file contains the minimal, polled functions to send and receive Ethernet +* frames. +* +* Refer to xemaclite.h for more details. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a ecm  06/01/02 First release
+* 1.01a ecm  03/31/04 Additional functionality and the _AlignedRead and
+*                     _AlignedWrite functions.
+* 1.11a mta  03/21/07 Updated to new coding style
+* 2.01a ktn  07/20/09 Updated the XEmacLite_AlignedWrite and
+*                     XEmacLite_AlignedRead functions to use volatile
+*                     variables so that they are not optimized.
+* 3.00a ktn  10/22/09 The macros have been renamed to remove _m from the name.
+*
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xemaclite_l.h" +#include "xemaclite_i.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ +void XEmacLite_AlignedWrite(void *SrcPtr, u32 *DestPtr, unsigned ByteCount); +void XEmacLite_AlignedRead(u32 *SrcPtr, void *DestPtr, unsigned ByteCount); + +/************************** Variable Definitions *****************************/ + +/*****************************************************************************/ +/** +* +* Send an Ethernet frame. The size is the total frame size, including header. +* This function blocks waiting for the frame to be transmitted. +* +* @param BaseAddress is the base address of the device +* @param FramePtr is a pointer to frame +* @param ByteCount is the size, in bytes, of the frame +* +* @return None. +* +* @note +* +* This function call is blocking in nature, i.e. it will wait until the +* frame is transmitted. This function can hang and not exit if the +* hardware is not configured properly. +* +* If the ping buffer is the destination of the data, the argument should be +* DeviceAddress + XEL_TXBUFF_OFFSET. +* If the pong buffer is the destination of the data, the argument should be +* DeviceAddress + XEL_TXBUFF_OFFSET + XEL_BUFFER_OFFSET. +* The function does not take the different buffers into consideration. +* +******************************************************************************/ +void XEmacLite_SendFrame(u32 BaseAddress, u8 *FramePtr, unsigned ByteCount) +{ + u32 Register; + + /* + * Write data to the EmacLite + */ + 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))); + + + Register = XEmacLite_GetTxStatus(BaseAddress); + XEmacLite_SetTxStatus(BaseAddress, Register | XEL_TSR_XMIT_BUSY_MASK); + + /* + * Loop on the status waiting for the transmit to be complete. + */ + while (!XEmacLite_IsTxDone(BaseAddress)); + +} + + +/*****************************************************************************/ +/** +* +* Receive a frame. Wait for a frame to arrive. +* +* @param BaseAddress is the base address of the device +* @param FramePtr is a pointer to a buffer where the frame will +* be stored. +* +* @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. +* +* @note +* +* This function call is blocking in nature, i.e. it will wait until a +* frame arrives. +* +* If the ping buffer is the source of the data, the argument should be +* DeviceAddress + XEL_RXBUFF_OFFSET. +* If the pong buffer is the source of the data, the argument should be +* DeviceAddress + XEL_RXBUFF_OFFSET + XEL_BUFFER_OFFSET. +* The function does not take the different buffers into consideration. +* +******************************************************************************/ +u16 XEmacLite_RecvFrame(u32 BaseAddress, u8 *FramePtr) +{ + u16 LengthType; + u16 Length; + u32 Register; + + /* + * Wait for a frame to arrive - this is a blocking call + */ + while (XEmacLite_IsRxEmpty(BaseAddress)); + + /* + * Get the length of the frame that arrived, only 32-bit reads are + * allowed LengthType is in the upper half of the 32-bit word. + */ + Register = XEmacLite_ReadReg(BaseAddress, XEL_RPLR_OFFSET); + LengthType = (u16) ((Register >> 16) & + (XEL_RPLR_LENGTH_MASK_HI | + XEL_RPLR_LENGTH_MASK_LO)); + + /* + * Check if length is valid + */ + if (LengthType > XEL_MAX_FRAME_SIZE) { + /* + * Field contain type, 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 each byte 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 LengthType; +} + +/******************************************************************************/ +/** +* +* This function aligns the incoming data and writes it out to a 32-bit +* aligned destination address range. +* +* @param SrcPtr is a pointer to incoming data of any alignment. +* @param DestPtr is a pointer to outgoing data of 32-bit alignment. +* @param ByteCount is the number of bytes to write. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XEmacLite_AlignedWrite(void *SrcPtr, u32 *DestPtr, unsigned ByteCount) +{ + unsigned Index; + unsigned Length = ByteCount; + volatile u32 AlignBuffer; + volatile u32 *To32Ptr; + u32 *From32Ptr; + volatile u16 *To16Ptr; + u16 *From16Ptr; + volatile u8 *To8Ptr; + u8 *From8Ptr; + + To32Ptr = DestPtr; + + if ((((u32) SrcPtr) & 0x00000003) == 0) { + + /* + * Word aligned buffer, no correction needed. + */ + From32Ptr = (u32 *) SrcPtr; + + while (Length > 3) { + /* + * Output each word destination. + */ + *To32Ptr++ = *From32Ptr++; + + /* + * Adjust length accordingly + */ + Length -= 4; + } + + /* + * Set up to output the remaining data, zero the temp buffer + first. + */ + AlignBuffer = 0; + To8Ptr = (u8 *) &AlignBuffer; + From8Ptr = (u8 *) From32Ptr; + + } + else if ((((u32) SrcPtr) & 0x00000001) != 0) { + /* + * Byte aligned buffer, correct. + */ + AlignBuffer = 0; + To8Ptr = (u8 *) &AlignBuffer; + From8Ptr = (u8 *) SrcPtr; + + while (Length > 3) { + /* + * Copy each byte into the temporary buffer. + */ + for (Index = 0; Index < 4; Index++) { + *To8Ptr++ = *From8Ptr++; + } + + /* + * Output the buffer + */ + *To32Ptr++ = AlignBuffer; + + /*. + * Reset the temporary buffer pointer and adjust length. + */ + To8Ptr = (u8 *) &AlignBuffer; + Length -= 4; + } + + /* + * Set up to output the remaining data, zero the temp buffer + * first. + */ + AlignBuffer = 0; + To8Ptr = (u8 *) &AlignBuffer; + + } + else { + /* + * Half-Word aligned buffer, correct. + */ + AlignBuffer = 0; + + /* + * This is a funny looking cast. The new gcc, version 3.3.x has + * a strict cast check for 16 bit pointers, aka short pointers. + * The following warning is issued if the initial 'void *' cast + * is not used: + * 'dereferencing type-punned pointer will break strict-aliasing + * rules' + */ + + To16Ptr = (u16 *) ((void *) &AlignBuffer); + From16Ptr = (u16 *) SrcPtr; + + while (Length > 3) { + /* + * Copy each half word into the temporary buffer. + */ + for (Index = 0; Index < 2; Index++) { + *To16Ptr++ = *From16Ptr++; + } + + /* + * Output the buffer. + */ + *To32Ptr++ = AlignBuffer; + + /* + * Reset the temporary buffer pointer and adjust length. + */ + + /* + * This is a funny looking cast. The new gcc, version + * 3.3.x has a strict cast check for 16 bit pointers, + * aka short pointers. The following warning is issued + * if the initial 'void *' cast is not used: + * 'dereferencing type-punned pointer will break + * strict-aliasing rules' + */ + To16Ptr = (u16 *) ((void *) &AlignBuffer); + Length -= 4; + } + + /* + * Set up to output the remaining data, zero the temp buffer + * first. + */ + AlignBuffer = 0; + To8Ptr = (u8 *) &AlignBuffer; + From8Ptr = (u8 *) From16Ptr; + } + + /* + * Output the remaining data, zero the temp buffer first. + */ + for (Index = 0; Index < Length; Index++) { + *To8Ptr++ = *From8Ptr++; + } + + *To32Ptr++ = AlignBuffer; + +} + +/******************************************************************************/ +/** +* +* This function reads from a 32-bit aligned source address range and aligns +* the writes to the provided destination pointer alignment. +* +* @param SrcPtr is a pointer to incoming data of 32-bit alignment. +* @param DestPtr is a pointer to outgoing data of any alignment. +* @param ByteCount is the number of bytes to read. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XEmacLite_AlignedRead(u32 *SrcPtr, void *DestPtr, unsigned ByteCount) +{ + unsigned Index; + unsigned Length = ByteCount; + volatile u32 AlignBuffer; + u32 *To32Ptr; + volatile u32 *From32Ptr; + u16 *To16Ptr; + volatile u16 *From16Ptr; + u8 *To8Ptr; + volatile u8 *From8Ptr; + + From32Ptr = (u32 *) SrcPtr; + + if ((((u32) DestPtr) & 0x00000003) == 0) { + + /* + * Word aligned buffer, no correction needed. + */ + To32Ptr = (u32 *) DestPtr; + + while (Length > 3) { + /* + * Output each word. + */ + *To32Ptr++ = *From32Ptr++; + + /* + * Adjust length accordingly. + */ + Length -= 4; + } + + /* + * Set up to read the remaining data. + */ + To8Ptr = (u8 *) To32Ptr; + + } + else if ((((u32) DestPtr) & 0x00000001) != 0) { + /* + * Byte aligned buffer, correct. + */ + To8Ptr = (u8 *) DestPtr; + + while (Length > 3) { + /* + * Copy each word into the temporary buffer. + */ + AlignBuffer = *From32Ptr++; + From8Ptr = (u8 *) &AlignBuffer; + + /* + * Write data to destination. + */ + for (Index = 0; Index < 4; Index++) { + *To8Ptr++ = *From8Ptr++; + } + + /* + * Adjust length + */ + Length -= 4; + } + + } + else { + /* + * Half-Word aligned buffer, correct. + */ + To16Ptr = (u16 *) DestPtr; + + while (Length > 3) { + /* + * Copy each word into the temporary buffer. + */ + AlignBuffer = *From32Ptr++; + + /* + * This is a funny looking cast. The new gcc, version + * 3.3.x has a strict cast check for 16 bit pointers, + * aka short pointers. The following warning is issued + * if the initial 'void *' cast is not used: + * 'dereferencing type-punned pointer will break + * strict-aliasing rules' + */ + From16Ptr = (u16 *) ((void *) &AlignBuffer); + + /* + * Write data to destination. + */ + for (Index = 0; Index < 2; Index++) { + *To16Ptr++ = *From16Ptr++; + } + + /* + * Adjust length. + */ + Length -= 4; + } + + /* + * Set up to read the remaining data. + */ + To8Ptr = (u8 *) To16Ptr; + } + + /* + * Read the remaining data. + */ + AlignBuffer = *From32Ptr++; + From8Ptr = (u8 *) &AlignBuffer; + + for (Index = 0; Index < Length; Index++) { + *To8Ptr++ = *From8Ptr++; + } +} +/** @} */ diff --git a/XilinxProcessorIPLib/drivers/emaclite/src/xemaclite_l.h b/XilinxProcessorIPLib/drivers/emaclite/src/xemaclite_l.h new file mode 100644 index 00000000..29469610 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/emaclite/src/xemaclite_l.h @@ -0,0 +1,375 @@ +/****************************************************************************** +* +* 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_l.h +* @addtogroup emaclite_v4_0 +* @{ +* @details +* +* This header file contains identifiers and basic driver functions and macros +* that can be used to access the Xilinx Ethernet Lite 10/100 MAC (EmacLite). +* +* Refer to xemaclite.h for more details. +* +* @note +* +* The functions and macros in this file assume that the proper device address is +* provided in the argument. If the ping buffer is the source or destination, +* the argument should be DeviceAddress + XEL_(T/R)XBUFF_OFFSET. If the pong +* buffer is the source or destination, the argument should be +* DeviceAddress + XEL_(T/R)XBUFF_OFFSET + XEL_BUFFER_OFFSET. The driver does +* not take the different buffers into consideration. +* For more details on the ping/pong buffer configuration please refer to the +* Ethernet Lite 10/100 Media Access Controller hardware specification. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a ecm  06/01/02 First release
+* 1.01a ecm  03/31/04 Additional functionality and the _AlignedRead and
+*                     AlignedWrite functions.
+*                     Moved the bulk of description to xemaclite.h
+* 1.11a mta  03/21/07 Updated to new coding style
+* 2.00a ktn  02/16/09 Added support for MDIO and internal loop back
+* 3.00a ktn  10/22/09 The macros have been renamed to remove _m from the name.
+*		      The macros changed in this file are
+*		      XEmacLite_mReadReg changed to XEmacLite_mReadReg,
+*		      XEmacLite_mWriteReg changed to XEmacLite_mWriteReg,
+*		      XEmacLite_mGetTxStatus changed to XEmacLite_GetTxStatus,
+*		      XEmacLite_mSetTxStatus changed to XEmacLite_SetTxStatus,
+*		      XEmacLite_mGetRxStatus changed to XEmacLite_GetRxStatus,
+*		      XEmacLite_mSetRxStatus changed to XEmacLite_SetRxStatus,
+*		      XEmacLite_mIsTxDone changed to XEmacLite_IsTxDone and
+*		      XEmacLite_mIsRxEmpty changed to XEmacLite_IsRxEmpty.
+* 
+* +******************************************************************************/ + +#ifndef XEMAC_LITE_L_H /* prevent circular inclusions */ +#define XEMAC_LITE_L_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xil_io.h" + +/************************** Constant Definitions *****************************/ +/** + * Register offsets for the Ethernet MAC. + */ +#define XEL_TXBUFF_OFFSET (0x00000000) /**< Transmit Buffer */ +#define XEL_MDIOADDR_OFFSET (XEL_TXBUFF_OFFSET + 0x07E4)/**< MDIO Address offset + register */ +#define XEL_MDIOWR_OFFSET (XEL_TXBUFF_OFFSET + 0x07E8) /**< MDIO write data + register offset */ +#define XEL_MDIORD_OFFSET (XEL_TXBUFF_OFFSET + 0x07EC) /**< MDIO read data + register offset*/ +#define XEL_MDIOCNTR_OFFSET (XEL_TXBUFF_OFFSET + 0x07F0)/**< MDIO Control + Register offset */ +#define XEL_GIER_OFFSET (XEL_TXBUFF_OFFSET + 0x07F8) /**< Offset for the GIE + Register */ +#define XEL_TSR_OFFSET (XEL_TXBUFF_OFFSET + 0x07FC) /**< Tx status */ +#define XEL_TPLR_OFFSET (XEL_TXBUFF_OFFSET + 0x07F4) /**< Tx packet length */ + +#define XEL_RXBUFF_OFFSET (0x00001000) /**< Receive Buffer */ +#define XEL_RSR_OFFSET (XEL_RXBUFF_OFFSET + 0x07FC) /**< Rx status */ +#define XEL_RPLR_OFFSET (XEL_RXBUFF_OFFSET + 0x0C) /**< Rx packet length */ + +#define XEL_MAC_HI_OFFSET (XEL_TXBUFF_OFFSET + 0x14) /**< MAC address hi + offset */ +#define XEL_MAC_LO_OFFSET (XEL_TXBUFF_OFFSET) /**< MAC address lo + offset */ + +#define XEL_BUFFER_OFFSET (0x00000800) /**< Next buffer's + offset same for + both TX and RX */ +/** + * MDIO Address/Write Data/Read Data Register Bit Masks + */ +#define XEL_MDIO_ADDRESS_MASK 0x00003E0 /**< PHY Address mask */ +#define XEL_MDIO_ADDRESS_SHIFT 0x5 /**< PHY Address shift*/ +#define XEL_MDIO_OP_MASK 0x00000400 /**< PHY read access */ + +/** + * MDIO Control Register Bit Masks + */ +#define XEL_MDIOCNTR_STATUS_MASK 0x00000001 /**< MDIO transfer in + Progress */ +#define XEL_MDIOCNTR_ENABLE_MASK 0x00000008 /**< MDIO Enable */ + +/** + * Global Interrupt Enable Register (GIER) Bit Masks + */ +#define XEL_GIER_GIE_MASK 0x80000000 /**< Global Enable */ + +/** + * Transmit Status Register (TSR) Bit Masks + */ +#define XEL_TSR_XMIT_BUSY_MASK 0x00000001 /**< Xmit complete */ +#define XEL_TSR_PROGRAM_MASK 0x00000002 /**< Program the MAC + address */ +#define XEL_TSR_XMIT_IE_MASK 0x00000008 /**< Xmit interrupt + enable bit */ +#define XEL_TSR_LOOPBACK_MASK 0x00000010 /**< Loop back enable + bit */ +#define XEL_TSR_XMIT_ACTIVE_MASK 0x80000000 /**< Buffer is active, + SW bit only. This + is not documented + in the HW spec */ + +/** + * define for programming the MAC address into the EmacLite + */ +#define XEL_TSR_PROG_MAC_ADDR (XEL_TSR_XMIT_BUSY_MASK | XEL_TSR_PROGRAM_MASK) + +/** + * Receive Status Register (RSR) + */ +#define XEL_RSR_RECV_DONE_MASK 0x00000001 /**< Recv complete */ +#define XEL_RSR_RECV_IE_MASK 0x00000008 /**< Recv interrupt + enable bit */ + +/** + * Transmit Packet Length Register (TPLR) + */ +#define XEL_TPLR_LENGTH_MASK_HI 0x0000FF00 /**< Transmit packet length + upper byte */ +#define XEL_TPLR_LENGTH_MASK_LO 0x000000FF /**< Transmit packet length + lower byte */ + +/** + * Receive Packet Length Register (RPLR) + */ +#define XEL_RPLR_LENGTH_MASK_HI 0x0000FF00 /**< Receive packet length + upper byte */ +#define XEL_RPLR_LENGTH_MASK_LO 0x000000FF /**< Receive packet length + lower byte */ + +#define XEL_HEADER_SIZE 14 /**< Size of header in bytes */ +#define XEL_MTU_SIZE 1500 /**< Max size of data in frame */ +#define XEL_FCS_SIZE 4 /**< Size of CRC */ + +#define XEL_HEADER_OFFSET 12 /**< Offset to length field */ +#define XEL_HEADER_SHIFT 16 /**< Right shift value to align + length */ + + +#define XEL_MAX_FRAME_SIZE (XEL_HEADER_SIZE+XEL_MTU_SIZE+ XEL_FCS_SIZE) /**< Max + length of Rx frame used if + length/type field + contains the type (> 1500) */ + +#define XEL_MAX_TX_FRAME_SIZE (XEL_HEADER_SIZE + XEL_MTU_SIZE) /**< Max + length of Tx frame */ + + +#define XEL_MAC_ADDR_SIZE 6 /**< length of MAC address */ + + +/* + * General Ethernet Definitions + */ +#define XEL_ETHER_PROTO_TYPE_IP 0x0800 /**< IP Protocol */ +#define XEL_ETHER_PROTO_TYPE_ARP 0x0806 /**< ARP Protocol */ +#define XEL_ETHER_PROTO_TYPE_VLAN 0x8100 /**< VLAN Tagged */ +#define XEL_ARP_PACKET_SIZE 28 /**< Max ARP packet size */ +#define XEL_HEADER_IP_LENGTH_OFFSET 16 /**< IP Length Offset */ +#define XEL_VLAN_TAG_SIZE 4 /**< VLAN Tag Size */ + +/***************** Macros (Inline Functions) Definitions *********************/ + +#define XEmacLite_In32 Xil_In32 +#define XEmacLite_Out32 Xil_Out32 + +/****************************************************************************/ +/** +* +* Read from the specified EmacLite device register. +* +* @param BaseAddress contains the base address of the device. +* @param RegOffset contains the offset from the 1st register of the +* device to select the specific register. +* +* @return The value read from the register. +* +* @note C-Style signature: +* u32 XEmacLite_ReadReg(u32 BaseAddress, u32 RegOffset); +* +******************************************************************************/ +#define XEmacLite_ReadReg(BaseAddress, RegOffset) \ + XEmacLite_In32((BaseAddress) + (RegOffset)) + +/***************************************************************************/ +/** +* +* Write to the specified EmacLite device register. +* +* @param BaseAddress contains the base address of the device. +* @param RegOffset contains the offset from the 1st register of the +* device to select the specific register. +* @param RegisterValue is the value to be written to the register. +* +* @return None. +* +* @note C-Style signature: +* void XEmacLite_WriteReg(u32 BaseAddress, u32 RegOffset, +* u32 RegisterValue); +******************************************************************************/ +#define XEmacLite_WriteReg(BaseAddress, RegOffset, RegisterValue) \ + XEmacLite_Out32((BaseAddress) + (RegOffset), (RegisterValue)) + + +/****************************************************************************/ +/** +* +* Get the Tx Status Register Contents. +* +* @param BaseAddress is the base address of the device +* +* @return The contents of the Tx Status Register. +* +* @note C-Style signature: +* u32 XEmacLite_GetTxStatus(u32 BaseAddress) +* +*****************************************************************************/ +#define XEmacLite_GetTxStatus(BaseAddress) \ + (XEmacLite_ReadReg((BaseAddress), XEL_TSR_OFFSET)) + + +/****************************************************************************/ +/** +* +* Set the Tx Status Register Contents. +* +* @param BaseAddress is the base address of the device +* @param Data is the value to be written to the Register. +* +* @return None. +* +* @note C-Style signature: +* u32 XEmacLite_SetTxStatus(u32 BaseAddress, u32 Data) +* +*****************************************************************************/ +#define XEmacLite_SetTxStatus(BaseAddress, Data) \ + (XEmacLite_WriteReg((BaseAddress), XEL_TSR_OFFSET, (Data))) + + +/****************************************************************************/ +/** +* +* Get the Rx Status Register Contents. +* +* @param BaseAddress is the base address of the device +* +* @return The contents of the Rx Status Register. +* +* @note C-Style signature: +* u32 XEmacLite_GetRxStatus(u32 BaseAddress) +* +*****************************************************************************/ +#define XEmacLite_GetRxStatus(BaseAddress) \ + (XEmacLite_ReadReg((BaseAddress), XEL_RSR_OFFSET)) + + +/****************************************************************************/ +/** +* +* Set the Rx Status Register Contents. +* +* @param BaseAddress is the base address of the device +* @param Data is the value to be written to the Register. +* +* @return None. +* +* @note C-Style signature: +* u32 XEmacLite_SetRxStatus(u32 BaseAddress, u32 Data) +* +*****************************************************************************/ +#define XEmacLite_SetRxStatus(BaseAddress, Data) \ + (XEmacLite_WriteReg((BaseAddress), XEL_RSR_OFFSET, (Data))) + + +/****************************************************************************/ +/** +* +* Check to see if the transmission is complete. +* +* @param BaseAddress is the base address of the device +* +* @return TRUE if it is done, or FALSE if it is not. +* +* @note C-Style signature: +* int XEmacLite_IsTxDone(u32 BaseAddress) +* +*****************************************************************************/ +#define XEmacLite_IsTxDone(BaseAddress) \ + ((XEmacLite_ReadReg((BaseAddress), XEL_TSR_OFFSET) & \ + XEL_TSR_XMIT_BUSY_MASK) != XEL_TSR_XMIT_BUSY_MASK) + + +/****************************************************************************/ +/** +* +* Check to see if the receive is empty. +* +* @param BaseAddress is the base address of the device +* +* @return TRUE if it is empty, or FALSE if it is not. +* +* @note C-Style signature: +* int XEmacLite_IsRxEmpty(u32 BaseAddress) +* +*****************************************************************************/ +#define XEmacLite_IsRxEmpty(BaseAddress) \ + ((XEmacLite_ReadReg((BaseAddress), XEL_RSR_OFFSET) & \ + XEL_RSR_RECV_DONE_MASK) != XEL_RSR_RECV_DONE_MASK) + +/************************** Function Prototypes ******************************/ + +void XEmacLite_SendFrame(u32 BaseAddress, u8 *FramePtr, unsigned ByteCount); +u16 XEmacLite_RecvFrame(u32 BaseAddress, u8 *FramePtr); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/XilinxProcessorIPLib/drivers/emaclite/src/xemaclite_selftest.c b/XilinxProcessorIPLib/drivers/emaclite/src/xemaclite_selftest.c new file mode 100644 index 00000000..0b5f0737 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/emaclite/src/xemaclite_selftest.c @@ -0,0 +1,212 @@ +/****************************************************************************** +* +* 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_selftest.c +* @addtogroup emaclite_v4_0 +* @{ +* @details +* +* Function(s) in this file are the required functions for the EMAC Lite +* driver sefftest for the hardware. +* See xemaclite.h for a detailed description of the driver. +* +*
+* 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
+* 3.00a ktn  10/22/09 Updated driver to use the HAL Processor APIs/macros.
+* 
+******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xil_io.h" +#include "xemaclite.h" +#include "xemaclite_i.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +/*****************************************************************************/ +/** +* +* Performs a SelfTest on the EmacLite device as follows: +* - Writes to the mandatory TX buffer and reads back to verify. +* - If configured, writes to the secondary TX buffer and reads back to verify. +* - Writes to the mandatory RX buffer and reads back to verify. +* - If configured, writes to the secondary RX buffer and reads back to verify. +* +* +* @param InstancePtr is a pointer to the XEmacLite instance . +* +* @return +* - XST_SUCCESS if the device Passed the Self Test. +* - XST_FAILURE if any of the data read backs fail. +* +* @note None. +* +******************************************************************************/ +int XEmacLite_SelfTest(XEmacLite * InstancePtr) +{ + u32 BaseAddress; + u8 Index; + u8 TestString[4] = { 0xDE, 0xAD, 0xBE, 0xEF }; + u8 ReturnString[4] = { 0x0, 0x0, 0x0, 0x0 }; + + /* + * Verify that each of the inputs are valid. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + + /* + * Determine the TX buffer address + */ + BaseAddress = InstancePtr->EmacLiteConfig.BaseAddress + + XEL_TXBUFF_OFFSET; + + /* + * Write the TestString to the TX buffer in EMAC Lite then + * back from the EMAC Lite and verify + */ + XEmacLite_AlignedWrite(TestString, (u32 *) BaseAddress, + sizeof(TestString)); + XEmacLite_AlignedRead((u32 *) BaseAddress, ReturnString, + sizeof(ReturnString)); + + for (Index = 0; Index < 4; Index++) { + + if (ReturnString[Index] != TestString[Index]) { + return XST_FAILURE; + } + + /* + * Zero the return string for the next test + */ + ReturnString[Index] = 0; + } + + /* + * If the second buffer is configured, test it also + */ + if (InstancePtr->EmacLiteConfig.TxPingPong != 0) { + BaseAddress += XEL_BUFFER_OFFSET; + /* + * Write the TestString to the optional TX buffer in EMAC Lite + * then back from the EMAC Lite and verify + */ + XEmacLite_AlignedWrite(TestString, (u32 *) BaseAddress, + sizeof(TestString)); + XEmacLite_AlignedRead((u32 *) BaseAddress, ReturnString, + sizeof(ReturnString)); + + for (Index = 0; Index < 4; Index++) { + + if (ReturnString[Index] != TestString[Index]) { + return XST_FAILURE; + } + + /* + * Zero the return string for the next test + */ + ReturnString[Index] = 0; + } + } + + /* + * Determine the RX buffer address + */ + BaseAddress = InstancePtr->EmacLiteConfig.BaseAddress + + XEL_RXBUFF_OFFSET; + + /* + * Write the TestString to the RX buffer in EMAC Lite then + * back from the EMAC Lite and verify + */ + XEmacLite_AlignedWrite(TestString, (u32 *) (BaseAddress), + sizeof(TestString)); + XEmacLite_AlignedRead((u32 *) (BaseAddress), ReturnString, + sizeof(ReturnString)); + + for (Index = 0; Index < 4; Index++) { + + if (ReturnString[Index] != TestString[Index]) { + return XST_FAILURE; + } + + /* + * Zero the return string for the next test + */ + ReturnString[Index] = 0; + } + + /* + * If the second buffer is configured, test it also + */ + if (InstancePtr->EmacLiteConfig.RxPingPong != 0) { + BaseAddress += XEL_BUFFER_OFFSET; + /* + * Write the TestString to the optional RX buffer in EMAC Lite + * then back from the EMAC Lite and verify + */ + XEmacLite_AlignedWrite(TestString, (u32 *) BaseAddress, + sizeof(TestString)); + XEmacLite_AlignedRead((u32 *) BaseAddress, ReturnString, + sizeof(ReturnString)); + + for (Index = 0; Index < 4; Index++) { + + if (ReturnString[Index] != TestString[Index]) { + return XST_FAILURE; + } + + /* + * Zero the return string for the next test + */ + ReturnString[Index] = 0; + } + } + + return XST_SUCCESS; +} +/** @} */ diff --git a/XilinxProcessorIPLib/drivers/emaclite/src/xemaclite_sinit.c b/XilinxProcessorIPLib/drivers/emaclite/src/xemaclite_sinit.c new file mode 100644 index 00000000..9594cc75 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/emaclite/src/xemaclite_sinit.c @@ -0,0 +1,157 @@ +/****************************************************************************** +* +* Copyright (C) 2007 - 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_sinit.c +* @addtogroup emaclite_v4_0 +* @{ +* @details +* +* This file contains the implementation of the XEmacLite driver's static +* initialization functionality. +* +* @note None. +* +*
+*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.12a sv   11/28/07 First release
+*
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xparameters.h" +#include "xemaclite.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ +extern XEmacLite_Config XEmacLite_ConfigTable[]; + +/*****************************************************************************/ +/** +* +* Lookup the device configuration based on the unique device ID. The table +* XEmacLite_ConfigTable contains the configuration info for each device in the +* system. +* +* @param DeviceId is the unique device ID of the device being looked up. +* +* @return A pointer to the configuration table entry corresponding to the +* given device ID, or NULL if no match is found. +* +* @note None. +* +******************************************************************************/ +XEmacLite_Config *XEmacLite_LookupConfig(u16 DeviceId) +{ + XEmacLite_Config *CfgPtr = NULL; + u32 Index; + + for (Index = 0; Index < XPAR_XEMACLITE_NUM_INSTANCES; Index++) { + if (XEmacLite_ConfigTable[Index].DeviceId == DeviceId) { + CfgPtr = &XEmacLite_ConfigTable[Index]; + break; + } + } + + return CfgPtr; +} + + +/*****************************************************************************/ +/** +* +* 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 DeviceId is the unique id of the device controlled by this +* XEmacLite instance. Passing in a device id associates the +* generic XEmacLite instance to a specific device, as chosen by +* the caller or application developer. +* +* @return +* - XST_SUCCESS if initialization was successful. +* - XST_DEVICE_NOT_FOUND/XST_FAILURE if device configuration +* information was not found for a device with the supplied +* device ID. +* +* @note None +* +******************************************************************************/ +int XEmacLite_Initialize(XEmacLite *InstancePtr, u16 DeviceId) +{ + int Status; + XEmacLite_Config *EmacLiteConfigPtr;/* Pointer to Configuration data. */ + + /* + * Verify that each of the inputs are valid. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + + /* + * Lookup the device configuration in the configuration table. Use this + * configuration info down below when initializing this driver. + */ + EmacLiteConfigPtr = XEmacLite_LookupConfig(DeviceId); + if (EmacLiteConfigPtr == NULL) { + return XST_DEVICE_NOT_FOUND; + } + + Status = XEmacLite_CfgInitialize(InstancePtr, + EmacLiteConfigPtr, + EmacLiteConfigPtr->BaseAddress); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + return XST_SUCCESS; +} + + +/** @} */