| /****************************************************************************** |
| * |
| * 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; |
| } |