mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-29 16:10:58 +00:00
319 lines
11 KiB
C
319 lines
11 KiB
C
|
/******************************************************************************
|
||
|
*
|
||
|
* 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;
|
||
|
}
|