diff options
Diffstat (limited to 'board/xilinx/xilinx_enet/xemac_options.c')
-rw-r--r-- | board/xilinx/xilinx_enet/xemac_options.c | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/board/xilinx/xilinx_enet/xemac_options.c b/board/xilinx/xilinx_enet/xemac_options.c new file mode 100644 index 0000000..1f225f8 --- /dev/null +++ b/board/xilinx/xilinx_enet/xemac_options.c @@ -0,0 +1,318 @@ +/****************************************************************************** +* +* Author: Xilinx, Inc. +* +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at your +* option) any later version. +* +* +* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A +* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS +* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, +* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE +* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING +* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. +* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO +* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY +* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM +* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND +* FITNESS FOR A PARTICULAR PURPOSE. +* +* +* Xilinx hardware products are not intended for use in life support +* appliances, devices, or systems. Use in such applications is +* expressly prohibited. +* +* +* (c) Copyright 2002-2004 Xilinx Inc. +* All rights reserved. +* +* +* You should have received a copy of the GNU General Public License along +* with this program; if not, write to the Free Software Foundation, Inc., +* 675 Mass Ave, Cambridge, MA 02139, USA. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xemac_options.c +* +* Functions in this file handle configuration of the XEmac driver. +* +* <pre> +* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ----------------------------------------------- +* 1.00a rpm 07/31/01 First release +* 1.00b rpm 02/20/02 Repartitioned files and functions +* 1.00c rpm 12/05/02 New version includes support for simple DMA +* </pre> +* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xbasic_types.h" +#include "xemac_i.h" +#include "xio.h" + +/************************** Constant Definitions *****************************/ + +#define XEM_MAX_IFG 32 /* Maximum Interframe gap value */ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +/* + * A table of options and masks. This table maps the user-visible options with + * the control register masks. It is used in Set/GetOptions as an alternative + * to a series of if/else pairs. Note that the polled options does not have a + * corresponding entry in the control register, so it does not exist in the + * table. + */ +typedef struct { + u32 Option; + u32 Mask; +} OptionMap; + +static OptionMap OptionsTable[] = { + {XEM_UNICAST_OPTION, XEM_ECR_UNICAST_ENABLE_MASK}, + {XEM_BROADCAST_OPTION, XEM_ECR_BROAD_ENABLE_MASK}, + {XEM_PROMISC_OPTION, XEM_ECR_PROMISC_ENABLE_MASK}, + {XEM_FDUPLEX_OPTION, XEM_ECR_FULL_DUPLEX_MASK}, + {XEM_LOOPBACK_OPTION, XEM_ECR_LOOPBACK_MASK}, + {XEM_MULTICAST_OPTION, XEM_ECR_MULTI_ENABLE_MASK}, + {XEM_FLOW_CONTROL_OPTION, XEM_ECR_PAUSE_FRAME_MASK}, + {XEM_INSERT_PAD_OPTION, XEM_ECR_XMIT_PAD_ENABLE_MASK}, + {XEM_INSERT_FCS_OPTION, XEM_ECR_XMIT_FCS_ENABLE_MASK}, + {XEM_INSERT_ADDR_OPTION, XEM_ECR_XMIT_ADDR_INSERT_MASK}, + {XEM_OVWRT_ADDR_OPTION, XEM_ECR_XMIT_ADDR_OVWRT_MASK}, + {XEM_STRIP_PAD_FCS_OPTION, XEM_ECR_RECV_STRIP_ENABLE_MASK} +}; + +#define XEM_NUM_OPTIONS (sizeof(OptionsTable) / sizeof(OptionMap)) + +/*****************************************************************************/ +/** +* +* Set Ethernet driver/device options. The device must be stopped before +* calling this function. The options are contained within a bit-mask with each +* bit representing an option (i.e., you can OR the options together). A one (1) +* in the bit-mask turns an option on, and a zero (0) turns the option off. +* +* @param InstancePtr is a pointer to the XEmac instance to be worked on. +* @param OptionsFlag is a bit-mask representing the Ethernet options to turn on +* or off. See xemac.h for a description of the available options. +* +* @return +* +* - XST_SUCCESS if the options were set successfully +* - XST_DEVICE_IS_STARTED if the device has not yet been stopped +* +* @note +* +* This function is not thread-safe and makes use of internal resources that are +* shared between the Start, Stop, and SetOptions functions, so if one task +* might be setting device options while another is trying to start the device, +* protection of this shared data (typically using a semaphore) is required. +* +******************************************************************************/ +XStatus +XEmac_SetOptions(XEmac * InstancePtr, u32 OptionsFlag) +{ + u32 ControlReg; + int Index; + + XASSERT_NONVOID(InstancePtr != NULL); + XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); + + if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) { + return XST_DEVICE_IS_STARTED; + } + + ControlReg = XIo_In32(InstancePtr->BaseAddress + XEM_ECR_OFFSET); + + /* + * Loop through the options table, turning the option on or off + * depending on whether the bit is set in the incoming options flag. + */ + for (Index = 0; Index < XEM_NUM_OPTIONS; Index++) { + if (OptionsFlag & OptionsTable[Index].Option) { + ControlReg |= OptionsTable[Index].Mask; /* turn it on */ + } else { + ControlReg &= ~OptionsTable[Index].Mask; /* turn it off */ + } + } + + /* + * TODO: need to validate addr-overwrite only if addr-insert? + */ + + /* + * Now write the control register. Leave it to the upper layers + * to restart the device. + */ + XIo_Out32(InstancePtr->BaseAddress + XEM_ECR_OFFSET, ControlReg); + + /* + * Check the polled option + */ + if (OptionsFlag & XEM_POLLED_OPTION) { + InstancePtr->IsPolled = TRUE; + } else { + InstancePtr->IsPolled = FALSE; + } + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* Get Ethernet driver/device options. The 32-bit value returned is a bit-mask +* representing the options. A one (1) in the bit-mask means the option is on, +* and a zero (0) means the option is off. +* +* @param InstancePtr is a pointer to the XEmac instance to be worked on. +* +* @return +* +* The 32-bit value of the Ethernet options. The value is a bit-mask +* representing all options that are currently enabled. See xemac.h for a +* description of the available options. +* +* @note +* +* None. +* +******************************************************************************/ +u32 +XEmac_GetOptions(XEmac * InstancePtr) +{ + u32 OptionsFlag = 0; + u32 ControlReg; + int Index; + + XASSERT_NONVOID(InstancePtr != NULL); + XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); + + /* + * Get the control register to determine which options are currently set. + */ + ControlReg = XIo_In32(InstancePtr->BaseAddress + XEM_ECR_OFFSET); + + /* + * Loop through the options table to determine which options are set + */ + for (Index = 0; Index < XEM_NUM_OPTIONS; Index++) { + if (ControlReg & OptionsTable[Index].Mask) { + OptionsFlag |= OptionsTable[Index].Option; + } + } + + if (InstancePtr->IsPolled) { + OptionsFlag |= XEM_POLLED_OPTION; + } + + return OptionsFlag; +} + +/*****************************************************************************/ +/** +* +* Set the Interframe Gap (IFG), which is the time the MAC delays between +* transmitting frames. There are two parts required. The total interframe gap +* is the total of the two parts. The values provided for the Part1 and Part2 +* parameters are multiplied by 4 to obtain the bit-time interval. The first +* part should be the first 2/3 of the total interframe gap. The MAC will reset +* the interframe gap timer if carrier sense becomes true during the period +* defined by interframe gap Part1. Part1 may be shorter than 2/3 the total and +* can be as small as zero. The second part should be the last 1/3 of the total +* interframe gap, but can be as large as the total interframe gap. The MAC +* will not reset the interframe gap timer if carrier sense becomes true during +* the period defined by interframe gap Part2. +* +* The device must be stopped before setting the interframe gap. +* +* @param InstancePtr is a pointer to the XEmac instance to be worked on. +* @param Part1 is the interframe gap part 1 (which will be multiplied by 4 to +* get the bit-time interval). +* @param Part2 is the interframe gap part 2 (which will be multiplied by 4 to +* get the bit-time interval). +* +* @return +* +* - XST_SUCCESS if the interframe gap was set successfully +* - XST_DEVICE_IS_STARTED if the device has not been stopped +* +* @note +* +* None. +* +******************************************************************************/ +XStatus +XEmac_SetInterframeGap(XEmac * InstancePtr, u8 Part1, u8 Part2) +{ + u32 Ifg; + + XASSERT_NONVOID(InstancePtr != NULL); + XASSERT_NONVOID(Part1 < XEM_MAX_IFG); + XASSERT_NONVOID(Part2 < XEM_MAX_IFG); + XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); + + /* + * Be sure device has been stopped + */ + if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) { + return XST_DEVICE_IS_STARTED; + } + + Ifg = Part1 << XEM_IFGP_PART1_SHIFT; + Ifg |= (Part2 << XEM_IFGP_PART2_SHIFT); + XIo_Out32(InstancePtr->BaseAddress + XEM_IFGP_OFFSET, Ifg); + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* Get the interframe gap, parts 1 and 2. See the description of interframe gap +* above in XEmac_SetInterframeGap(). +* +* @param InstancePtr is a pointer to the XEmac instance to be worked on. +* @param Part1Ptr is a pointer to an 8-bit buffer into which the interframe gap +* part 1 value will be copied. +* @param Part2Ptr is a pointer to an 8-bit buffer into which the interframe gap +* part 2 value will be copied. +* +* @return +* +* None. The values of the interframe gap parts are copied into the +* output parameters. +* +******************************************************************************/ +void +XEmac_GetInterframeGap(XEmac * InstancePtr, u8 * Part1Ptr, u8 * Part2Ptr) +{ + u32 Ifg; + + XASSERT_VOID(InstancePtr != NULL); + XASSERT_VOID(Part1Ptr != NULL); + XASSERT_VOID(Part2Ptr != NULL); + XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); + + Ifg = XIo_In32(InstancePtr->BaseAddress + XEM_IFGP_OFFSET); + *Part1Ptr = (Ifg & XEM_IFGP_PART1_MASK) >> XEM_IFGP_PART1_SHIFT; + *Part2Ptr = (Ifg & XEM_IFGP_PART2_MASK) >> XEM_IFGP_PART2_SHIFT; +} |