mirror of
https://github.com/u-boot/u-boot.git
synced 2024-11-26 05:34:30 +08:00
net: xilinx_enet: drop unused !NET_MULTI driver
This driver doesn't support the NET_MULTI framework, and I can't find any boards/configs/files that reference this subdir, so punt it all. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
This commit is contained in:
parent
5de78b17f0
commit
daaaf0285d
@ -1,165 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <net.h>
|
||||
#include "xemac.h"
|
||||
|
||||
#if defined(XPAR_EMAC_0_DEVICE_ID)
|
||||
/*
|
||||
* ENET_MAX_MTU and ENET_MAX_MTU_ALIGNED are set from
|
||||
* PKTSIZE and PKTSIZE_ALIGN (include/net.h)
|
||||
*/
|
||||
|
||||
#define ENET_MAX_MTU PKTSIZE
|
||||
#define ENET_MAX_MTU_ALIGNED PKTSIZE_ALIGN
|
||||
#define ENET_ADDR_LENGTH 6
|
||||
|
||||
static XEmac Emac;
|
||||
static char etherrxbuff[PKTSIZE_ALIGN]; /* Receive buffer */
|
||||
|
||||
/* hardcoded MAC address for the Xilinx EMAC Core when env is nowhere*/
|
||||
#ifdef CONFIG_ENV_IS_NOWHERE
|
||||
static u8 EMACAddr[ENET_ADDR_LENGTH] = { 0x00, 0x0a, 0x35, 0x00, 0x22, 0x01 };
|
||||
#endif
|
||||
|
||||
static int initialized = 0;
|
||||
|
||||
void
|
||||
eth_halt(void)
|
||||
{
|
||||
if (initialized)
|
||||
(void) XEmac_Stop(&Emac);
|
||||
}
|
||||
|
||||
int
|
||||
eth_init(bd_t * bis)
|
||||
{
|
||||
u32 Options;
|
||||
XStatus Result;
|
||||
uchar enetaddr[6];
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("EMAC Initialization Started\n\r");
|
||||
#endif
|
||||
|
||||
Result = XEmac_Initialize(&Emac, XPAR_EMAC_0_DEVICE_ID);
|
||||
if (Result != XST_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* make sure the Emac is stopped before it is started */
|
||||
(void) XEmac_Stop(&Emac);
|
||||
|
||||
if (!eth_getenv_enetaddr("ethaddr", enetaddr)) {
|
||||
#ifdef CONFIG_ENV_IS_NOWHERE
|
||||
memcpy(enetaddr, EMACAddr, 6);
|
||||
eth_setenv_enetaddr("ethaddr", enetaddr);
|
||||
#endif
|
||||
}
|
||||
|
||||
Result = XEmac_SetMacAddress(&Emac, enetaddr);
|
||||
if (Result != XST_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Options =
|
||||
(XEM_POLLED_OPTION | XEM_UNICAST_OPTION | XEM_BROADCAST_OPTION |
|
||||
XEM_FDUPLEX_OPTION | XEM_INSERT_FCS_OPTION |
|
||||
XEM_INSERT_PAD_OPTION);
|
||||
Result = XEmac_SetOptions(&Emac, Options);
|
||||
if (Result != XST_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result = XEmac_Start(&Emac);
|
||||
if (Result != XST_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf("EMAC Initialization complete\n\r");
|
||||
#endif
|
||||
|
||||
initialized = 1;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------+
|
||||
+-----------------------------------------------------------------------------*/
|
||||
int
|
||||
eth_send(volatile void *ptr, int len)
|
||||
{
|
||||
XStatus Result;
|
||||
|
||||
if (len > ENET_MAX_MTU)
|
||||
len = ENET_MAX_MTU;
|
||||
|
||||
Result = XEmac_PollSend(&Emac, (u8 *) ptr, len);
|
||||
if (Result == XST_SUCCESS) {
|
||||
return (1);
|
||||
} else {
|
||||
printf("Error while sending frame\n\r");
|
||||
return (0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
eth_rx(void)
|
||||
{
|
||||
u32 RecvFrameLength;
|
||||
XStatus Result;
|
||||
|
||||
RecvFrameLength = PKTSIZE;
|
||||
Result = XEmac_PollRecv(&Emac, (u8 *) etherrxbuff, &RecvFrameLength);
|
||||
if (Result == XST_SUCCESS) {
|
||||
#ifndef CONFIG_EMACLITE
|
||||
NetReceive((uchar *)etherrxbuff, RecvFrameLength);
|
||||
#else
|
||||
NetReceive(etherrxbuff, RecvFrameLength);
|
||||
#endif
|
||||
return (1);
|
||||
} else {
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,844 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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.c
|
||||
*
|
||||
* The XEmac driver. Functions in this file are the minimum required functions
|
||||
* for this driver. See xemac.h for a detailed description of the 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.00b rpm 07/23/02 Removed the PHY reset from Initialize()
|
||||
* 1.00b rmm 09/23/02 Removed commented code in Initialize(). Recycled as
|
||||
* XEmac_mPhyReset macro in xemac_l.h.
|
||||
* 1.00c rpm 12/05/02 New version includes support for simple DMA
|
||||
* 1.00c rpm 12/12/02 Changed location of IsStarted assignment in XEmac_Start
|
||||
* to be sure the flag is set before the device and
|
||||
* interrupts are enabled.
|
||||
* 1.00c rpm 02/03/03 SelfTest was not clearing polled mode. Take driver out
|
||||
* of polled mode in XEmac_Reset() to fix this problem.
|
||||
* 1.00c rmm 05/13/03 Fixed diab compiler warnings relating to asserts.
|
||||
* </pre>
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xbasic_types.h"
|
||||
#include "xemac_i.h"
|
||||
#include "xio.h"
|
||||
#include "xipif_v1_23_b.h" /* Uses v1.23b of the IPIF */
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
static XStatus ConfigureDma(XEmac * InstancePtr);
|
||||
static XStatus ConfigureFifo(XEmac * InstancePtr);
|
||||
static void StubFifoHandler(void *CallBackRef);
|
||||
static void StubErrorHandler(void *CallBackRef, XStatus ErrorCode);
|
||||
static void StubSgHandler(void *CallBackRef, XBufDescriptor * BdPtr,
|
||||
u32 NumBds);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Initialize a specific XEmac instance/driver. The initialization entails:
|
||||
* - Initialize fields of the XEmac structure
|
||||
* - Clear the Ethernet statistics for this device
|
||||
* - Initialize the IPIF component with its register base address
|
||||
* - Configure the FIFO components with their register base addresses.
|
||||
* - If the device is configured with DMA, configure the DMA channel components
|
||||
* with their register base addresses. At some later time, memory pools for
|
||||
* the scatter-gather descriptor lists may be passed to the driver.
|
||||
* - Reset the Ethernet MAC
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
* @param DeviceId is the unique id of the device controlled by this XEmac
|
||||
* instance. Passing in a device id associates the generic XEmac
|
||||
* instance to a specific device, as chosen by the caller or application
|
||||
* developer.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* - XST_SUCCESS if initialization was successful
|
||||
* - XST_DEVICE_IS_STARTED if the device has already been started
|
||||
* - XST_DEVICE_NOT_FOUND if device configuration information was not found for
|
||||
* a device with the supplied device ID.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
XStatus
|
||||
XEmac_Initialize(XEmac * InstancePtr, u16 DeviceId)
|
||||
{
|
||||
XStatus Result;
|
||||
XEmac_Config *ConfigPtr; /* configuration information */
|
||||
|
||||
XASSERT_NONVOID(InstancePtr != NULL);
|
||||
|
||||
/*
|
||||
* If the device is started, disallow the initialize and return a status
|
||||
* indicating it is started. This allows the user to stop the device
|
||||
* and reinitialize, but prevents a user from inadvertently initializing
|
||||
*/
|
||||
if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
|
||||
return XST_DEVICE_IS_STARTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Lookup the device configuration in the temporary CROM table. Use this
|
||||
* configuration info down below when initializing this component.
|
||||
*/
|
||||
ConfigPtr = XEmac_LookupConfig(DeviceId);
|
||||
if (ConfigPtr == NULL) {
|
||||
return XST_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set some default values
|
||||
*/
|
||||
InstancePtr->IsReady = 0;
|
||||
InstancePtr->IsStarted = 0;
|
||||
InstancePtr->IpIfDmaConfig = ConfigPtr->IpIfDmaConfig;
|
||||
InstancePtr->HasMii = ConfigPtr->HasMii;
|
||||
InstancePtr->HasMulticastHash = FALSE;
|
||||
|
||||
/* Always default polled to false, let user configure this mode */
|
||||
InstancePtr->IsPolled = FALSE;
|
||||
InstancePtr->FifoRecvHandler = StubFifoHandler;
|
||||
InstancePtr->FifoSendHandler = StubFifoHandler;
|
||||
InstancePtr->ErrorHandler = StubErrorHandler;
|
||||
InstancePtr->SgRecvHandler = StubSgHandler;
|
||||
InstancePtr->SgSendHandler = StubSgHandler;
|
||||
|
||||
/*
|
||||
* Clear the statistics for this driver
|
||||
*/
|
||||
XEmac_mClearStruct((u8 *) & InstancePtr->Stats, sizeof (XEmac_Stats));
|
||||
|
||||
/*
|
||||
* Initialize the device register base addresses
|
||||
*/
|
||||
InstancePtr->BaseAddress = ConfigPtr->BaseAddress;
|
||||
|
||||
/*
|
||||
* Configure the send and receive FIFOs in the MAC
|
||||
*/
|
||||
Result = ConfigureFifo(InstancePtr);
|
||||
if (Result != XST_SUCCESS) {
|
||||
return Result;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the device is configured for DMA, configure the send and receive DMA
|
||||
* channels in the MAC.
|
||||
*/
|
||||
if (XEmac_mIsDma(InstancePtr)) {
|
||||
Result = ConfigureDma(InstancePtr);
|
||||
if (Result != XST_SUCCESS) {
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Indicate the component is now ready to use. Note that this is done before
|
||||
* we reset the device and the PHY below, which may seem a bit odd. The
|
||||
* choice was made to move it here rather than remove the asserts in various
|
||||
* functions (e.g., Reset() and all functions that it calls). Applications
|
||||
* that use multiple threads, one to initialize the XEmac driver and one
|
||||
* waiting on the IsReady condition could have a problem with this sequence.
|
||||
*/
|
||||
InstancePtr->IsReady = XCOMPONENT_IS_READY;
|
||||
|
||||
/*
|
||||
* Reset the MAC to get it into its initial state. It is expected that
|
||||
* device configuration by the user will take place after this
|
||||
* initialization is done, but before the device is started.
|
||||
*/
|
||||
XEmac_Reset(InstancePtr);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Start the Ethernet controller as follows:
|
||||
* - If not in polled mode
|
||||
* - Set the internal interrupt enable registers appropriately
|
||||
* - Enable interrupts within the device itself. Note that connection of
|
||||
* the driver's interrupt handler to the interrupt source (typically
|
||||
* done using the interrupt controller component) is done by the higher
|
||||
* layer software.
|
||||
* - If the device is configured with scatter-gather DMA, start the DMA
|
||||
* channels if the descriptor lists are not empty
|
||||
* - Enable the transmitter
|
||||
* - Enable the receiver
|
||||
*
|
||||
* The PHY is enabled after driver initialization. We assume the upper layer
|
||||
* software has configured it and the EMAC appropriately before this function
|
||||
* is called.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* - XST_SUCCESS if the device was started successfully
|
||||
* - XST_NO_CALLBACK if a callback function has not yet been registered using
|
||||
* the SetxxxHandler function. This is required if in interrupt mode.
|
||||
* - XST_DEVICE_IS_STARTED if the device is already started
|
||||
* - XST_DMA_SG_NO_LIST if configured for scatter-gather DMA and a descriptor
|
||||
* list has not yet been created for the send or receive channel.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* The driver tries to match the hardware configuration. So if the hardware
|
||||
* is configured with scatter-gather DMA, the driver expects to start the
|
||||
* scatter-gather channels and expects that the user has set up the buffer
|
||||
* descriptor lists already. If the user expects to use the driver in a mode
|
||||
* different than how the hardware is configured, the user should modify the
|
||||
* configuration table to reflect the mode to be used. Modifying the config
|
||||
* table is a workaround for now until we get some experience with how users
|
||||
* are intending to use the hardware in its different configurations. For
|
||||
* example, if the hardware is built with scatter-gather DMA but the user is
|
||||
* intending to use only simple DMA, the user either needs to modify the config
|
||||
* table as a workaround or rebuild the hardware with only simple DMA.
|
||||
*
|
||||
* This function 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, the user is required to
|
||||
* provide protection of this shared data (typically using a semaphore).
|
||||
*
|
||||
******************************************************************************/
|
||||
XStatus
|
||||
XEmac_Start(XEmac * InstancePtr)
|
||||
{
|
||||
u32 ControlReg;
|
||||
XStatus Result;
|
||||
|
||||
XASSERT_NONVOID(InstancePtr != NULL);
|
||||
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* If it is already started, return a status indicating so
|
||||
*/
|
||||
if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
|
||||
return XST_DEVICE_IS_STARTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* If not polled, enable interrupts
|
||||
*/
|
||||
if (!InstancePtr->IsPolled) {
|
||||
/*
|
||||
* Verify that the callbacks have been registered, then enable
|
||||
* interrupts
|
||||
*/
|
||||
if (XEmac_mIsSgDma(InstancePtr)) {
|
||||
if ((InstancePtr->SgRecvHandler == StubSgHandler) ||
|
||||
(InstancePtr->SgSendHandler == StubSgHandler)) {
|
||||
return XST_NO_CALLBACK;
|
||||
}
|
||||
|
||||
/* Enable IPIF interrupts */
|
||||
XIIF_V123B_WRITE_DIER(InstancePtr->BaseAddress,
|
||||
XEM_IPIF_DMA_DFT_MASK |
|
||||
XIIF_V123B_ERROR_MASK);
|
||||
XIIF_V123B_WRITE_IIER(InstancePtr->BaseAddress,
|
||||
XEM_EIR_DFT_SG_MASK);
|
||||
|
||||
/* Enable scatter-gather DMA interrupts */
|
||||
XDmaChannel_SetIntrEnable(&InstancePtr->RecvChannel,
|
||||
XEM_DMA_SG_INTR_MASK);
|
||||
XDmaChannel_SetIntrEnable(&InstancePtr->SendChannel,
|
||||
XEM_DMA_SG_INTR_MASK);
|
||||
} else {
|
||||
if ((InstancePtr->FifoRecvHandler == StubFifoHandler) ||
|
||||
(InstancePtr->FifoSendHandler == StubFifoHandler)) {
|
||||
return XST_NO_CALLBACK;
|
||||
}
|
||||
|
||||
/* Enable IPIF interrupts (used by simple DMA also) */
|
||||
XIIF_V123B_WRITE_DIER(InstancePtr->BaseAddress,
|
||||
XEM_IPIF_FIFO_DFT_MASK |
|
||||
XIIF_V123B_ERROR_MASK);
|
||||
XIIF_V123B_WRITE_IIER(InstancePtr->BaseAddress,
|
||||
XEM_EIR_DFT_FIFO_MASK);
|
||||
}
|
||||
|
||||
/* Enable the global IPIF interrupt output */
|
||||
XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
|
||||
}
|
||||
|
||||
/*
|
||||
* Indicate that the device is started before we enable the transmitter
|
||||
* or receiver. This needs to be done before because as soon as the
|
||||
* receiver is enabled we may get an interrupt, and there are functions
|
||||
* in the interrupt handling path that rely on the IsStarted flag.
|
||||
*/
|
||||
InstancePtr->IsStarted = XCOMPONENT_IS_STARTED;
|
||||
|
||||
/*
|
||||
* Enable the transmitter, and receiver (do a read/modify/write to preserve
|
||||
* current settings). There is no critical section here since this register
|
||||
* is not modified during interrupt context.
|
||||
*/
|
||||
ControlReg = XIo_In32(InstancePtr->BaseAddress + XEM_ECR_OFFSET);
|
||||
ControlReg &= ~(XEM_ECR_XMIT_RESET_MASK | XEM_ECR_RECV_RESET_MASK);
|
||||
ControlReg |= (XEM_ECR_XMIT_ENABLE_MASK | XEM_ECR_RECV_ENABLE_MASK);
|
||||
|
||||
XIo_Out32(InstancePtr->BaseAddress + XEM_ECR_OFFSET, ControlReg);
|
||||
|
||||
/*
|
||||
* If configured with scatter-gather DMA and not polled, restart the
|
||||
* DMA channels in case there are buffers ready to be sent or received into.
|
||||
* The DMA SgStart function uses data that can be modified during interrupt
|
||||
* context, so a critical section is required here.
|
||||
*/
|
||||
if ((XEmac_mIsSgDma(InstancePtr)) && (!InstancePtr->IsPolled)) {
|
||||
XIIF_V123B_GINTR_DISABLE(InstancePtr->BaseAddress);
|
||||
|
||||
/*
|
||||
* The only error we care about is if the list has not yet been
|
||||
* created, or on receive, if no buffer descriptors have been
|
||||
* added yet (the list is empty). Other errors are benign at this point.
|
||||
*/
|
||||
Result = XDmaChannel_SgStart(&InstancePtr->RecvChannel);
|
||||
if ((Result == XST_DMA_SG_NO_LIST)
|
||||
|| (Result == XST_DMA_SG_LIST_EMPTY)) {
|
||||
XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
|
||||
return Result;
|
||||
}
|
||||
|
||||
Result = XDmaChannel_SgStart(&InstancePtr->SendChannel);
|
||||
if (Result == XST_DMA_SG_NO_LIST) {
|
||||
XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
|
||||
return Result;
|
||||
}
|
||||
|
||||
XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Stop the Ethernet MAC as follows:
|
||||
* - If the device is configured with scatter-gather DMA, stop the DMA
|
||||
* channels (wait for acknowledgment of stop)
|
||||
* - Disable the transmitter and receiver
|
||||
* - Disable interrupts if not in polled mode (the higher layer software is
|
||||
* responsible for disabling interrupts at the interrupt controller)
|
||||
*
|
||||
* The PHY is left enabled after a Stop is called.
|
||||
*
|
||||
* If the device is configured for scatter-gather DMA, the DMA engine stops at
|
||||
* the next buffer descriptor in its list. The remaining descriptors in the list
|
||||
* are not removed, so anything in the list will be transmitted or received when
|
||||
* the device is restarted. The side effect of doing this is that the last
|
||||
* buffer descriptor processed by the DMA engine before stopping may not be the
|
||||
* last descriptor in the Ethernet frame. So when the device is restarted, a
|
||||
* partial frame (i.e., a bad frame) may be transmitted/received. This is only a
|
||||
* concern if a frame can span multiple buffer descriptors, which is dependent
|
||||
* on the size of the network buffers.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* - XST_SUCCESS if the device was stopped successfully
|
||||
* - XST_DEVICE_IS_STOPPED if the device is already stopped
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* This function 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, the user is required to
|
||||
* provide protection of this shared data (typically using a semaphore).
|
||||
*
|
||||
******************************************************************************/
|
||||
XStatus
|
||||
XEmac_Stop(XEmac * InstancePtr)
|
||||
{
|
||||
u32 ControlReg;
|
||||
|
||||
XASSERT_NONVOID(InstancePtr != NULL);
|
||||
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* If the device is already stopped, do nothing but return a status
|
||||
* indicating so
|
||||
*/
|
||||
if (InstancePtr->IsStarted != XCOMPONENT_IS_STARTED) {
|
||||
return XST_DEVICE_IS_STOPPED;
|
||||
}
|
||||
|
||||
/*
|
||||
* If configured for scatter-gather DMA, stop the DMA channels. Ignore
|
||||
* the XST_DMA_SG_IS_STOPPED return code. There is a critical section
|
||||
* here between SgStart and SgStop, and SgStart can be called in interrupt
|
||||
* context, so disable interrupts while calling SgStop.
|
||||
*/
|
||||
if (XEmac_mIsSgDma(InstancePtr)) {
|
||||
XBufDescriptor *BdTemp; /* temporary descriptor pointer */
|
||||
|
||||
XIIF_V123B_GINTR_DISABLE(InstancePtr->BaseAddress);
|
||||
|
||||
(void) XDmaChannel_SgStop(&InstancePtr->SendChannel, &BdTemp);
|
||||
(void) XDmaChannel_SgStop(&InstancePtr->RecvChannel, &BdTemp);
|
||||
|
||||
XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable the transmitter and receiver. There is no critical section
|
||||
* here since this register is not modified during interrupt context.
|
||||
*/
|
||||
ControlReg = XIo_In32(InstancePtr->BaseAddress + XEM_ECR_OFFSET);
|
||||
ControlReg &= ~(XEM_ECR_XMIT_ENABLE_MASK | XEM_ECR_RECV_ENABLE_MASK);
|
||||
XIo_Out32(InstancePtr->BaseAddress + XEM_ECR_OFFSET, ControlReg);
|
||||
|
||||
/*
|
||||
* If not in polled mode, disable interrupts for IPIF (includes MAC and
|
||||
* DMAs)
|
||||
*/
|
||||
if (!InstancePtr->IsPolled) {
|
||||
XIIF_V123B_GINTR_DISABLE(InstancePtr->BaseAddress);
|
||||
}
|
||||
|
||||
InstancePtr->IsStarted = 0;
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Reset the Ethernet MAC. This is a graceful reset in that the device is stopped
|
||||
* first. Resets the DMA channels, the FIFOs, the transmitter, and the receiver.
|
||||
* The PHY is not reset. Any frames in the scatter-gather descriptor lists will
|
||||
* remain in the lists. The side effect of doing this is that after a reset and
|
||||
* following a restart of the device, frames that were in the list before the
|
||||
* reset may be transmitted or received. Reset must only be called after the
|
||||
* driver has been initialized.
|
||||
*
|
||||
* The driver is also taken out of polled mode if polled mode was set. The user
|
||||
* is responsbile for re-configuring the driver into polled mode after the
|
||||
* reset if desired.
|
||||
*
|
||||
* The configuration after this reset is as follows:
|
||||
* - Half duplex
|
||||
* - Disabled transmitter and receiver
|
||||
* - Enabled PHY (the PHY is not reset)
|
||||
* - MAC transmitter does pad insertion, FCS insertion, and source address
|
||||
* overwrite.
|
||||
* - MAC receiver does not strip padding or FCS
|
||||
* - Interframe Gap as recommended by IEEE Std. 802.3 (96 bit times)
|
||||
* - Unicast addressing enabled
|
||||
* - Broadcast addressing enabled
|
||||
* - Multicast addressing disabled (addresses are preserved)
|
||||
* - Promiscuous addressing disabled
|
||||
* - Default packet threshold and packet wait bound register values for
|
||||
* scatter-gather DMA operation
|
||||
* - MAC address of all zeros
|
||||
* - Non-polled mode
|
||||
*
|
||||
* The upper layer software is responsible for re-configuring (if necessary)
|
||||
* and restarting the MAC after the reset. Note that the PHY is not reset. PHY
|
||||
* control is left to the upper layer software. Note also that driver statistics
|
||||
* are not cleared on reset. It is up to the upper layer software to clear the
|
||||
* statistics if needed.
|
||||
*
|
||||
* When a reset is required due to an internal error, the driver notifies the
|
||||
* upper layer software of this need through the ErrorHandler callback and
|
||||
* specific status codes. The upper layer software is responsible for calling
|
||||
* this Reset function and then re-configuring the device.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* The reset is accomplished by setting the IPIF reset register. This takes
|
||||
* care of resetting all hardware blocks, including the MAC.
|
||||
*
|
||||
******************************************************************************/
|
||||
void
|
||||
XEmac_Reset(XEmac * InstancePtr)
|
||||
{
|
||||
XASSERT_VOID(InstancePtr != NULL);
|
||||
XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Stop the device first
|
||||
*/
|
||||
(void) XEmac_Stop(InstancePtr);
|
||||
|
||||
/*
|
||||
* Take the driver out of polled mode
|
||||
*/
|
||||
InstancePtr->IsPolled = FALSE;
|
||||
|
||||
/*
|
||||
* Reset the entire IPIF at once. If we choose someday to reset each
|
||||
* hardware block separately, the reset should occur in the direction of
|
||||
* data flow. For example, for the send direction the reset order is DMA
|
||||
* first, then FIFO, then the MAC transmitter.
|
||||
*/
|
||||
XIIF_V123B_RESET(InstancePtr->BaseAddress);
|
||||
|
||||
if (XEmac_mIsSgDma(InstancePtr)) {
|
||||
/*
|
||||
* After reset, configure the scatter-gather DMA packet threshold and
|
||||
* packet wait bound registers to default values. Ignore the return
|
||||
* values of these functions since they only return error if the device
|
||||
* is not stopped.
|
||||
*/
|
||||
(void) XEmac_SetPktThreshold(InstancePtr, XEM_SEND,
|
||||
XEM_SGDMA_DFT_THRESHOLD);
|
||||
(void) XEmac_SetPktThreshold(InstancePtr, XEM_RECV,
|
||||
XEM_SGDMA_DFT_THRESHOLD);
|
||||
(void) XEmac_SetPktWaitBound(InstancePtr, XEM_SEND,
|
||||
XEM_SGDMA_DFT_WAITBOUND);
|
||||
(void) XEmac_SetPktWaitBound(InstancePtr, XEM_RECV,
|
||||
XEM_SGDMA_DFT_WAITBOUND);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Set the MAC address for this driver/device. The address is a 48-bit value.
|
||||
* The device must be stopped before calling this function.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
* @param AddressPtr is a pointer to a 6-byte MAC address.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* - XST_SUCCESS if the MAC address was set successfully
|
||||
* - XST_DEVICE_IS_STARTED if the device has not yet been stopped
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
XStatus
|
||||
XEmac_SetMacAddress(XEmac * InstancePtr, u8 * AddressPtr)
|
||||
{
|
||||
u32 MacAddr = 0;
|
||||
|
||||
XASSERT_NONVOID(InstancePtr != NULL);
|
||||
XASSERT_NONVOID(AddressPtr != NULL);
|
||||
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* The device must be stopped before setting the MAC address
|
||||
*/
|
||||
if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
|
||||
return XST_DEVICE_IS_STARTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the device station address high and low registers
|
||||
*/
|
||||
MacAddr = (AddressPtr[0] << 8) | AddressPtr[1];
|
||||
XIo_Out32(InstancePtr->BaseAddress + XEM_SAH_OFFSET, MacAddr);
|
||||
|
||||
MacAddr = (AddressPtr[2] << 24) | (AddressPtr[3] << 16) |
|
||||
(AddressPtr[4] << 8) | AddressPtr[5];
|
||||
|
||||
XIo_Out32(InstancePtr->BaseAddress + XEM_SAL_OFFSET, MacAddr);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Get the MAC address for this driver/device.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
* @param BufferPtr is an output parameter, and is a pointer to a buffer into
|
||||
* which the current MAC address will be copied. The buffer must be at
|
||||
* least 6 bytes.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void
|
||||
XEmac_GetMacAddress(XEmac * InstancePtr, u8 * BufferPtr)
|
||||
{
|
||||
u32 MacAddrHi;
|
||||
u32 MacAddrLo;
|
||||
|
||||
XASSERT_VOID(InstancePtr != NULL);
|
||||
XASSERT_VOID(BufferPtr != NULL);
|
||||
XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
MacAddrHi = XIo_In32(InstancePtr->BaseAddress + XEM_SAH_OFFSET);
|
||||
MacAddrLo = XIo_In32(InstancePtr->BaseAddress + XEM_SAL_OFFSET);
|
||||
|
||||
BufferPtr[0] = (u8) (MacAddrHi >> 8);
|
||||
BufferPtr[1] = (u8) MacAddrHi;
|
||||
BufferPtr[2] = (u8) (MacAddrLo >> 24);
|
||||
BufferPtr[3] = (u8) (MacAddrLo >> 16);
|
||||
BufferPtr[4] = (u8) (MacAddrLo >> 8);
|
||||
BufferPtr[5] = (u8) MacAddrLo;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Configure DMA capabilities.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* - XST_SUCCESS if successful initialization of DMA
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static XStatus
|
||||
ConfigureDma(XEmac * InstancePtr)
|
||||
{
|
||||
XStatus Result;
|
||||
|
||||
/*
|
||||
* Initialize the DMA channels with their base addresses. We assume
|
||||
* scatter-gather DMA is the only possible configuration. Descriptor space
|
||||
* will need to be set later by the upper layer.
|
||||
*/
|
||||
Result = XDmaChannel_Initialize(&InstancePtr->RecvChannel,
|
||||
InstancePtr->BaseAddress +
|
||||
XEM_DMA_RECV_OFFSET);
|
||||
if (Result != XST_SUCCESS) {
|
||||
return Result;
|
||||
}
|
||||
|
||||
Result = XDmaChannel_Initialize(&InstancePtr->SendChannel,
|
||||
InstancePtr->BaseAddress +
|
||||
XEM_DMA_SEND_OFFSET);
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Configure the send and receive FIFO components with their base addresses
|
||||
* and interrupt masks. Currently the base addresses are defined constants.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* XST_SUCCESS if successful initialization of the packet FIFOs
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static XStatus
|
||||
ConfigureFifo(XEmac * InstancePtr)
|
||||
{
|
||||
XStatus Result;
|
||||
|
||||
/*
|
||||
* Return status from the packet FIFOs initialization is ignored since
|
||||
* they always return success.
|
||||
*/
|
||||
Result = XPacketFifoV100b_Initialize(&InstancePtr->RecvFifo,
|
||||
InstancePtr->BaseAddress +
|
||||
XEM_PFIFO_RXREG_OFFSET,
|
||||
InstancePtr->BaseAddress +
|
||||
XEM_PFIFO_RXDATA_OFFSET);
|
||||
if (Result != XST_SUCCESS) {
|
||||
return Result;
|
||||
}
|
||||
|
||||
Result = XPacketFifoV100b_Initialize(&InstancePtr->SendFifo,
|
||||
InstancePtr->BaseAddress +
|
||||
XEM_PFIFO_TXREG_OFFSET,
|
||||
InstancePtr->BaseAddress +
|
||||
XEM_PFIFO_TXDATA_OFFSET);
|
||||
return Result;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This is a stub for the scatter-gather send and recv 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
|
||||
* @param BdPtr is a pointer to the first buffer descriptor in a list
|
||||
* @param NumBds is the number of descriptors in the list.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void
|
||||
StubSgHandler(void *CallBackRef, XBufDescriptor * BdPtr, u32 NumBds)
|
||||
{
|
||||
XASSERT_VOID_ALWAYS();
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This is a stub for the non-DMA send and recv 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void
|
||||
StubFifoHandler(void *CallBackRef)
|
||||
{
|
||||
XASSERT_VOID_ALWAYS();
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This is a stub for the asynchronous error callback. The stub is here in
|
||||
* case the upper layers forget to set the handler.
|
||||
*
|
||||
* @param CallBackRef is a pointer to the upper layer callback reference
|
||||
* @param ErrorCode is the Xilinx error code, indicating the cause of the error
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void
|
||||
StubErrorHandler(void *CallBackRef, XStatus ErrorCode)
|
||||
{
|
||||
XASSERT_VOID_ALWAYS();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Lookup the device configuration based on the unique device ID. The table
|
||||
* EmacConfigTable 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
XEmac_Config *
|
||||
XEmac_LookupConfig(u16 DeviceId)
|
||||
{
|
||||
XEmac_Config *CfgPtr = NULL;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < XPAR_XEMAC_NUM_INSTANCES; i++) {
|
||||
if (XEmac_ConfigTable[i].DeviceId == DeviceId) {
|
||||
CfgPtr = &XEmac_ConfigTable[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return CfgPtr;
|
||||
}
|
@ -1,673 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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.h
|
||||
*
|
||||
* The Xilinx Ethernet driver component. This component supports the Xilinx
|
||||
* Ethernet 10/100 MAC (EMAC).
|
||||
*
|
||||
* The Xilinx Ethernet 10/100 MAC supports the following features:
|
||||
* - Simple and scatter-gather DMA operations, as well as simple memory
|
||||
* mapped direct I/O interface (FIFOs).
|
||||
* - Media Independent Interface (MII) for connection to external
|
||||
* 10/100 Mbps PHY transceivers.
|
||||
* - MII management control reads and writes with MII PHYs
|
||||
* - Independent internal transmit and receive FIFOs
|
||||
* - CSMA/CD compliant operations for half-duplex modes
|
||||
* - Programmable PHY reset signal
|
||||
* - Unicast, broadcast, and promiscuous address filtering (no multicast yet)
|
||||
* - Internal loopback
|
||||
* - Automatic source address insertion or overwrite (programmable)
|
||||
* - Automatic FCS insertion and stripping (programmable)
|
||||
* - Automatic pad insertion and stripping (programmable)
|
||||
* - Pause frame (flow control) detection in full-duplex mode
|
||||
* - Programmable interframe gap
|
||||
* - VLAN frame support.
|
||||
* - Pause frame support
|
||||
*
|
||||
* The device driver supports all the features listed above.
|
||||
*
|
||||
* <b>Driver Description</b>
|
||||
*
|
||||
* The device driver enables higher layer software (e.g., an application) to
|
||||
* communicate to the EMAC. 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 EMAC. A single device
|
||||
* driver can support multiple EMACs.
|
||||
*
|
||||
* The driver is designed for a zero-copy buffer scheme. That is, the driver will
|
||||
* not copy buffers. This avoids potential throughput bottlenecks within the
|
||||
* driver.
|
||||
*
|
||||
* Since the driver is a simple pass-through mechanism between a protocol stack
|
||||
* and the EMAC, 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
|
||||
*
|
||||
* <b>PHY Communication</b>
|
||||
*
|
||||
* The driver provides rudimentary read and write functions to allow the higher
|
||||
* layer software to access the PHY. The EMAC provides MII registers for the
|
||||
* driver to access. This management interface can be parameterized away in the
|
||||
* FPGA implementation process. If this is the case, the PHY read and write
|
||||
* functions of the driver return XST_NO_FEATURE.
|
||||
*
|
||||
* External loopback is usually supported at the PHY. It is up to the user to
|
||||
* turn external loopback on or off at the PHY. The driver simply provides pass-
|
||||
* through functions for configuring the PHY. The driver does not read, write,
|
||||
* or reset the PHY on its own. All control of the PHY must be done by the user.
|
||||
*
|
||||
* <b>Asynchronous Callbacks</b>
|
||||
*
|
||||
* The driver services interrupts and passes Ethernet frames to the higher layer
|
||||
* software through asynchronous callback functions. When using the driver
|
||||
* directly (i.e., not with the RTOS protocol stack), the higher layer
|
||||
* software must register its callback functions during initialization. The
|
||||
* driver requires callback functions for received frames, for confirmation of
|
||||
* transmitted frames, and for asynchronous errors.
|
||||
*
|
||||
* <b>Interrupts</b>
|
||||
*
|
||||
* The driver has no dependencies on the interrupt controller. The driver
|
||||
* provides two interrupt handlers. XEmac_IntrHandlerDma() handles interrupts
|
||||
* when the EMAC is configured with scatter-gather DMA. XEmac_IntrHandlerFifo()
|
||||
* handles interrupts when the EMAC is configured for direct FIFO I/O or simple
|
||||
* DMA. Either of these routines can be connected to the system interrupt
|
||||
* controller by the user.
|
||||
*
|
||||
* <b>Interrupt Frequency</b>
|
||||
*
|
||||
* When the EMAC is configured with scatter-gather DMA, the frequency of
|
||||
* interrupts can be controlled with the interrupt coalescing features of the
|
||||
* scatter-gather DMA engine. The frequency of interrupts can be adjusted using
|
||||
* the driver API functions for setting the packet count threshold and the packet
|
||||
* wait bound values.
|
||||
*
|
||||
* The scatter-gather DMA engine only interrupts when the packet count threshold
|
||||
* is reached, instead of interrupting for each packet. A packet is a generic
|
||||
* term used by the scatter-gather DMA engine, and is equivalent to an Ethernet
|
||||
* frame in our case.
|
||||
*
|
||||
* The packet wait bound is a timer value used during interrupt coalescing to
|
||||
* trigger an interrupt when not enough packets have been received to reach the
|
||||
* packet count threshold.
|
||||
*
|
||||
* These values can be tuned by the user to meet their needs. If there appear to
|
||||
* be interrupt latency problems or delays in packet arrival that are longer than
|
||||
* might be expected, the user should verify that the packet count threshold is
|
||||
* set low enough to receive interrupts before the wait bound timer goes off.
|
||||
*
|
||||
* <b>Device Reset</b>
|
||||
*
|
||||
* Some errors that can occur in the device require a device reset. These errors
|
||||
* are listed in the XEmac_SetErrorHandler() function header. The user's error
|
||||
* handler is responsible for resetting the device and re-configuring it based on
|
||||
* its needs (the driver does not save the current configuration). When
|
||||
* integrating into an RTOS, these reset and re-configure obligations are
|
||||
* taken care of by the Xilinx adapter software if it exists for that RTOS.
|
||||
*
|
||||
* <b>Device Configuration</b>
|
||||
*
|
||||
* The device can be configured in various ways during the FPGA implementation
|
||||
* process. Configuration parameters are stored in the xemac_g.c files.
|
||||
* A table is defined where each entry contains configuration information
|
||||
* for an EMAC device. This information includes such things as the base address
|
||||
* of the memory-mapped device, the base addresses of IPIF, DMA, and FIFO modules
|
||||
* within the device, and whether the device has DMA, counter registers,
|
||||
* multicast support, MII support, and flow control.
|
||||
*
|
||||
* The driver tries to use the features built into the device. So if, for
|
||||
* example, the hardware is configured with scatter-gather DMA, the driver
|
||||
* expects to start the scatter-gather channels and expects that the user has set
|
||||
* up the buffer descriptor lists already. If the user expects to use the driver
|
||||
* in a mode different than how the hardware is configured, the user should
|
||||
* modify the configuration table to reflect the mode to be used. Modifying the
|
||||
* configuration table is a workaround for now until we get some experience with
|
||||
* how users are intending to use the hardware in its different configurations.
|
||||
* For example, if the hardware is built with scatter-gather DMA but the user is
|
||||
* intending to use only simple DMA, the user either needs to modify the config
|
||||
* table as a workaround or rebuild the hardware with only simple DMA. The
|
||||
* recommendation at this point is to build the hardware with the features you
|
||||
* intend to use. If you're inclined to modify the table, do so before the call
|
||||
* to XEmac_Initialize(). Here is a snippet of code that changes a device to
|
||||
* simple DMA (the hardware needs to have DMA for this to work of course):
|
||||
* <pre>
|
||||
* XEmac_Config *ConfigPtr;
|
||||
*
|
||||
* ConfigPtr = XEmac_LookupConfig(DeviceId);
|
||||
* ConfigPtr->IpIfDmaConfig = XEM_CFG_SIMPLE_DMA;
|
||||
* </pre>
|
||||
*
|
||||
* <b>Simple DMA</b>
|
||||
*
|
||||
* Simple DMA is supported through the FIFO functions, FifoSend and FifoRecv, of
|
||||
* the driver (i.e., there is no separate interface for it). The driver makes use
|
||||
* of the DMA engine for a simple DMA transfer if the device is configured with
|
||||
* DMA, otherwise it uses the FIFOs directly. While the simple DMA interface is
|
||||
* therefore transparent to the user, the caching of network buffers is not.
|
||||
* If the device is configured with DMA and the FIFO interface is used, the user
|
||||
* must ensure that the network buffers are not cached or are cache coherent,
|
||||
* since DMA will be used to transfer to and from the Emac device. If the device
|
||||
* is configured with DMA and the user really wants to use the FIFOs directly,
|
||||
* the user should rebuild the hardware without DMA. If unable to do this, there
|
||||
* is a workaround (described above in Device Configuration) to modify the
|
||||
* configuration table of the driver to fake the driver into thinking the device
|
||||
* has no DMA. A code snippet follows:
|
||||
* <pre>
|
||||
* XEmac_Config *ConfigPtr;
|
||||
*
|
||||
* ConfigPtr = XEmac_LookupConfig(DeviceId);
|
||||
* ConfigPtr->IpIfDmaConfig = XEM_CFG_NO_DMA;
|
||||
* </pre>
|
||||
*
|
||||
* <b>Asserts</b>
|
||||
*
|
||||
* 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 users leave asserts on during development.
|
||||
*
|
||||
* <b>Building the driver</b>
|
||||
*
|
||||
* The XEmac driver is composed of several source files. Why so many? This
|
||||
* allows the user to build and link only those parts of the driver that are
|
||||
* necessary. Since the EMAC hardware can be configured in various ways (e.g.,
|
||||
* with or without DMA), the driver too can be built with varying features.
|
||||
* For the most part, this means that besides always linking in xemac.c, you
|
||||
* link in only the driver functionality you want. Some of the choices you have
|
||||
* are polled vs. interrupt, interrupt with FIFOs only vs. interrupt with DMA,
|
||||
* self-test diagnostics, and driver statistics. Note that currently the DMA code
|
||||
* must be linked in, even if you don't have DMA in the device.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Xilinx drivers are typically composed of two components, one is the driver
|
||||
* and the other is the adapter. The driver is independent of OS and processor
|
||||
* and is intended to be highly portable. The adapter is OS-specific and
|
||||
* facilitates communication between the driver and an OS.
|
||||
* <br><br>
|
||||
* 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.
|
||||
*
|
||||
* <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.00b rpm 10/08/02 Replaced HasSgDma boolean with IpifDmaConfig enumerated
|
||||
* configuration parameter
|
||||
* 1.00c rpm 12/05/02 New version includes support for simple DMA and the delay
|
||||
* argument to SgSend
|
||||
* 1.00c rpm 02/03/03 The XST_DMA_SG_COUNT_EXCEEDED return code was removed
|
||||
* from SetPktThreshold in the internal DMA driver. Also
|
||||
* avoided compiler warnings by initializing Result in the
|
||||
* DMA interrupt service routines.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XEMAC_H /* prevent circular inclusions */
|
||||
#define XEMAC_H /* by using protection macros */
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include <config.h>
|
||||
#include "xbasic_types.h"
|
||||
#include "xstatus.h"
|
||||
#include "xpacket_fifo_v1_00_b.h" /* Uses v1.00b of Packet Fifo */
|
||||
#include "xdma_channel.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/*
|
||||
* Device information
|
||||
*/
|
||||
#define XEM_DEVICE_NAME "xemac"
|
||||
#define XEM_DEVICE_DESC "Xilinx Ethernet 10/100 MAC"
|
||||
|
||||
/** @name Configuration options
|
||||
*
|
||||
* Device configuration options (see the XEmac_SetOptions() and
|
||||
* XEmac_GetOptions() for information on how to use these options)
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* <pre>
|
||||
* XEM_BROADCAST_OPTION Broadcast addressing on or off (default is on)
|
||||
* XEM_UNICAST_OPTION Unicast addressing on or off (default is on)
|
||||
* XEM_PROMISC_OPTION Promiscuous addressing on or off (default is off)
|
||||
* XEM_FDUPLEX_OPTION Full duplex on or off (default is off)
|
||||
* XEM_POLLED_OPTION Polled mode on or off (default is off)
|
||||
* XEM_LOOPBACK_OPTION Internal loopback on or off (default is off)
|
||||
* XEM_FLOW_CONTROL_OPTION Interpret pause frames in full duplex mode
|
||||
* (default is off)
|
||||
* XEM_INSERT_PAD_OPTION Pad short frames on transmit (default is on)
|
||||
* XEM_INSERT_FCS_OPTION Insert FCS (CRC) on transmit (default is on)
|
||||
* XEM_INSERT_ADDR_OPTION Insert source address on transmit (default is on)
|
||||
* XEM_OVWRT_ADDR_OPTION Overwrite source address on transmit. This is
|
||||
* only used if source address insertion is on.
|
||||
* (default is on)
|
||||
* XEM_STRIP_PAD_FCS_OPTION Strip FCS and padding from received frames
|
||||
* (default is off)
|
||||
* </pre>
|
||||
*/
|
||||
#define XEM_UNICAST_OPTION 0x00000001UL
|
||||
#define XEM_BROADCAST_OPTION 0x00000002UL
|
||||
#define XEM_PROMISC_OPTION 0x00000004UL
|
||||
#define XEM_FDUPLEX_OPTION 0x00000008UL
|
||||
#define XEM_POLLED_OPTION 0x00000010UL
|
||||
#define XEM_LOOPBACK_OPTION 0x00000020UL
|
||||
#define XEM_FLOW_CONTROL_OPTION 0x00000080UL
|
||||
#define XEM_INSERT_PAD_OPTION 0x00000100UL
|
||||
#define XEM_INSERT_FCS_OPTION 0x00000200UL
|
||||
#define XEM_INSERT_ADDR_OPTION 0x00000400UL
|
||||
#define XEM_OVWRT_ADDR_OPTION 0x00000800UL
|
||||
#define XEM_STRIP_PAD_FCS_OPTION 0x00002000UL
|
||||
/*@}*/
|
||||
/*
|
||||
* Not supported yet:
|
||||
* XEM_MULTICAST_OPTION Multicast addressing on or off (default is off)
|
||||
*/
|
||||
/* NOT SUPPORTED YET... */
|
||||
#define XEM_MULTICAST_OPTION 0x00000040UL
|
||||
|
||||
/*
|
||||
* Some default values for interrupt coalescing within the scatter-gather
|
||||
* DMA engine.
|
||||
*/
|
||||
#define XEM_SGDMA_DFT_THRESHOLD 1 /* Default pkt threshold */
|
||||
#define XEM_SGDMA_MAX_THRESHOLD 255 /* Maximum pkt theshold */
|
||||
#define XEM_SGDMA_DFT_WAITBOUND 5 /* Default pkt wait bound (msec) */
|
||||
#define XEM_SGDMA_MAX_WAITBOUND 1023 /* Maximum pkt wait bound (msec) */
|
||||
|
||||
/*
|
||||
* Direction identifiers. These are used for setting values like packet
|
||||
* thresholds and wait bound for specific channels
|
||||
*/
|
||||
#define XEM_SEND 1
|
||||
#define XEM_RECV 2
|
||||
|
||||
/*
|
||||
* Arguments to SgSend function to indicate whether to hold off starting
|
||||
* the scatter-gather engine.
|
||||
*/
|
||||
#define XEM_SGDMA_NODELAY 0 /* start SG DMA immediately */
|
||||
#define XEM_SGDMA_DELAY 1 /* do not start SG DMA */
|
||||
|
||||
/*
|
||||
* Constants to determine the configuration of the hardware device. They are
|
||||
* used to allow the driver to verify it can operate with the hardware.
|
||||
*/
|
||||
#define XEM_CFG_NO_IPIF 0 /* Not supported by the driver */
|
||||
#define XEM_CFG_NO_DMA 1 /* No DMA */
|
||||
#define XEM_CFG_SIMPLE_DMA 2 /* Simple DMA */
|
||||
#define XEM_CFG_DMA_SG 3 /* DMA scatter gather */
|
||||
|
||||
/*
|
||||
* The next few constants help upper layers determine the size of memory
|
||||
* pools used for Ethernet buffers and descriptor lists.
|
||||
*/
|
||||
#define XEM_MAC_ADDR_SIZE 6 /* six-byte MAC address */
|
||||
#define XEM_MTU 1500 /* max size of Ethernet frame */
|
||||
#define XEM_HDR_SIZE 14 /* size of Ethernet header */
|
||||
#define XEM_HDR_VLAN_SIZE 18 /* size of Ethernet header with VLAN */
|
||||
#define XEM_TRL_SIZE 4 /* size of Ethernet trailer (FCS) */
|
||||
#define XEM_MAX_FRAME_SIZE (XEM_MTU + XEM_HDR_SIZE + XEM_TRL_SIZE)
|
||||
#define XEM_MAX_VLAN_FRAME_SIZE (XEM_MTU + XEM_HDR_VLAN_SIZE + XEM_TRL_SIZE)
|
||||
|
||||
/*
|
||||
* Define a default number of send and receive buffers
|
||||
*/
|
||||
#define XEM_MIN_RECV_BUFS 32 /* minimum # of recv buffers */
|
||||
#define XEM_DFT_RECV_BUFS 64 /* default # of recv buffers */
|
||||
|
||||
#define XEM_MIN_SEND_BUFS 16 /* minimum # of send buffers */
|
||||
#define XEM_DFT_SEND_BUFS 32 /* default # of send buffers */
|
||||
|
||||
#define XEM_MIN_BUFFERS (XEM_MIN_RECV_BUFS + XEM_MIN_SEND_BUFS)
|
||||
#define XEM_DFT_BUFFERS (XEM_DFT_RECV_BUFS + XEM_DFT_SEND_BUFS)
|
||||
|
||||
/*
|
||||
* Define the number of send and receive buffer descriptors, used for
|
||||
* scatter-gather DMA
|
||||
*/
|
||||
#define XEM_MIN_RECV_DESC 16 /* minimum # of recv descriptors */
|
||||
#define XEM_DFT_RECV_DESC 32 /* default # of recv descriptors */
|
||||
|
||||
#define XEM_MIN_SEND_DESC 8 /* minimum # of send descriptors */
|
||||
#define XEM_DFT_SEND_DESC 16 /* default # of send descriptors */
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/**
|
||||
* Ethernet statistics (see XEmac_GetStats() and XEmac_ClearStats())
|
||||
*/
|
||||
typedef struct {
|
||||
u32 XmitFrames; /**< Number of frames transmitted */
|
||||
u32 XmitBytes; /**< Number of bytes transmitted */
|
||||
u32 XmitLateCollisionErrors;
|
||||
/**< Number of transmission failures
|
||||
due to late collisions */
|
||||
u32 XmitExcessDeferral; /**< Number of transmission failures
|
||||
due o excess collision deferrals */
|
||||
u32 XmitOverrunErrors; /**< Number of transmit overrun errors */
|
||||
u32 XmitUnderrunErrors; /**< Number of transmit underrun errors */
|
||||
u32 RecvFrames; /**< Number of frames received */
|
||||
u32 RecvBytes; /**< Number of bytes received */
|
||||
u32 RecvFcsErrors; /**< Number of frames discarded due
|
||||
to FCS errors */
|
||||
u32 RecvAlignmentErrors; /**< Number of frames received with
|
||||
alignment errors */
|
||||
u32 RecvOverrunErrors; /**< Number of frames discarded due
|
||||
to overrun errors */
|
||||
u32 RecvUnderrunErrors; /**< Number of recv underrun errors */
|
||||
u32 RecvMissedFrameErrors;
|
||||
/**< Number of frames missed by MAC */
|
||||
u32 RecvCollisionErrors; /**< Number of frames discarded due
|
||||
to collisions */
|
||||
u32 RecvLengthFieldErrors;
|
||||
/**< Number of frames discarded with
|
||||
invalid length field */
|
||||
u32 RecvShortErrors; /**< Number of short frames discarded */
|
||||
u32 RecvLongErrors; /**< Number of long frames discarded */
|
||||
u32 DmaErrors; /**< Number of DMA errors since init */
|
||||
u32 FifoErrors; /**< Number of FIFO errors since init */
|
||||
u32 RecvInterrupts; /**< Number of receive interrupts */
|
||||
u32 XmitInterrupts; /**< Number of transmit interrupts */
|
||||
u32 EmacInterrupts; /**< Number of MAC (device) interrupts */
|
||||
u32 TotalIntrs; /**< Total interrupts */
|
||||
} XEmac_Stats;
|
||||
|
||||
/**
|
||||
* This typedef contains configuration information for a device.
|
||||
*/
|
||||
typedef struct {
|
||||
u16 DeviceId; /**< Unique ID of device */
|
||||
u32 BaseAddress; /**< Register base address */
|
||||
u32 HasCounters; /**< Does device have counters? */
|
||||
u8 IpIfDmaConfig; /**< IPIF/DMA hardware configuration */
|
||||
u32 HasMii; /**< Does device support MII? */
|
||||
|
||||
} XEmac_Config;
|
||||
|
||||
/** @name Typedefs for callbacks
|
||||
* Callback functions.
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* Callback when data is sent or received with scatter-gather DMA.
|
||||
*
|
||||
* @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.
|
||||
* @param BdPtr is a pointer to the first buffer descriptor in a list of
|
||||
* buffer descriptors.
|
||||
* @param NumBds is the number of buffer descriptors in the list pointed
|
||||
* to by BdPtr.
|
||||
*/
|
||||
typedef void (*XEmac_SgHandler) (void *CallBackRef, XBufDescriptor * BdPtr,
|
||||
u32 NumBds);
|
||||
|
||||
/**
|
||||
* Callback when data is sent or received with direct FIFO communication or
|
||||
* simple DMA. The user typically defines two callacks, one for send and one
|
||||
* for receive.
|
||||
*
|
||||
* @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 (*XEmac_FifoHandler) (void *CallBackRef);
|
||||
|
||||
/**
|
||||
* Callback when an asynchronous error occurs.
|
||||
*
|
||||
* @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.
|
||||
* @param ErrorCode is a Xilinx error code defined in xstatus.h. Also see
|
||||
* XEmac_SetErrorHandler() for a description of possible errors.
|
||||
*/
|
||||
typedef void (*XEmac_ErrorHandler) (void *CallBackRef, XStatus ErrorCode);
|
||||
/*@}*/
|
||||
|
||||
/**
|
||||
* The XEmac driver instance data. The user is required to allocate a
|
||||
* variable of this type for every EMAC device in the system. A pointer
|
||||
* to a variable of this type is then passed to the driver API functions.
|
||||
*/
|
||||
typedef struct {
|
||||
u32 BaseAddress; /* Base address (of IPIF) */
|
||||
u32 IsStarted; /* Device is currently started */
|
||||
u32 IsReady; /* Device is initialized and ready */
|
||||
u32 IsPolled; /* Device is in polled mode */
|
||||
u8 IpIfDmaConfig; /* IPIF/DMA hardware configuration */
|
||||
u32 HasMii; /* Does device support MII? */
|
||||
u32 HasMulticastHash; /* Does device support multicast hash table? */
|
||||
|
||||
XEmac_Stats Stats;
|
||||
XPacketFifoV100b RecvFifo; /* FIFO used to receive frames */
|
||||
XPacketFifoV100b SendFifo; /* FIFO used to send frames */
|
||||
|
||||
/*
|
||||
* Callbacks
|
||||
*/
|
||||
XEmac_FifoHandler FifoRecvHandler; /* for non-DMA/simple DMA interrupts */
|
||||
void *FifoRecvRef;
|
||||
XEmac_FifoHandler FifoSendHandler; /* for non-DMA/simple DMA interrupts */
|
||||
void *FifoSendRef;
|
||||
XEmac_ErrorHandler ErrorHandler; /* for asynchronous errors */
|
||||
void *ErrorRef;
|
||||
|
||||
XDmaChannel RecvChannel; /* DMA receive channel driver */
|
||||
XDmaChannel SendChannel; /* DMA send channel driver */
|
||||
|
||||
XEmac_SgHandler SgRecvHandler; /* callback for scatter-gather DMA */
|
||||
void *SgRecvRef;
|
||||
XEmac_SgHandler SgSendHandler; /* callback for scatter-gather DMA */
|
||||
void *SgSendRef;
|
||||
} XEmac;
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro determines if the device is currently configured for
|
||||
* scatter-gather DMA.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* Boolean TRUE if the device is configured for scatter-gather DMA, or FALSE
|
||||
* if it is not.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Signature: u32 XEmac_mIsSgDma(XEmac *InstancePtr)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XEmac_mIsSgDma(InstancePtr) \
|
||||
((InstancePtr)->IpIfDmaConfig == XEM_CFG_DMA_SG)
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro determines if the device is currently configured for simple DMA.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* Boolean TRUE if the device is configured for simple DMA, or FALSE otherwise
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Signature: u32 XEmac_mIsSimpleDma(XEmac *InstancePtr)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XEmac_mIsSimpleDma(InstancePtr) \
|
||||
((InstancePtr)->IpIfDmaConfig == XEM_CFG_SIMPLE_DMA)
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro determines if the device is currently configured with DMA (either
|
||||
* simple DMA or scatter-gather DMA)
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* Boolean TRUE if the device is configured with DMA, or FALSE otherwise
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Signature: u32 XEmac_mIsDma(XEmac *InstancePtr)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XEmac_mIsDma(InstancePtr) \
|
||||
(XEmac_mIsSimpleDma(InstancePtr) || XEmac_mIsSgDma(InstancePtr))
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/*
|
||||
* Initialization functions in xemac.c
|
||||
*/
|
||||
XStatus XEmac_Initialize(XEmac * InstancePtr, u16 DeviceId);
|
||||
XStatus XEmac_Start(XEmac * InstancePtr);
|
||||
XStatus XEmac_Stop(XEmac * InstancePtr);
|
||||
void XEmac_Reset(XEmac * InstancePtr);
|
||||
XEmac_Config *XEmac_LookupConfig(u16 DeviceId);
|
||||
|
||||
/*
|
||||
* Diagnostic functions in xemac_selftest.c
|
||||
*/
|
||||
XStatus XEmac_SelfTest(XEmac * InstancePtr);
|
||||
|
||||
/*
|
||||
* Polled functions in xemac_polled.c
|
||||
*/
|
||||
XStatus XEmac_PollSend(XEmac * InstancePtr, u8 * BufPtr, u32 ByteCount);
|
||||
XStatus XEmac_PollRecv(XEmac * InstancePtr, u8 * BufPtr, u32 * ByteCountPtr);
|
||||
|
||||
/*
|
||||
* Interrupts with scatter-gather DMA functions in xemac_intr_dma.c
|
||||
*/
|
||||
XStatus XEmac_SgSend(XEmac * InstancePtr, XBufDescriptor * BdPtr, int Delay);
|
||||
XStatus XEmac_SgRecv(XEmac * InstancePtr, XBufDescriptor * BdPtr);
|
||||
XStatus XEmac_SetPktThreshold(XEmac * InstancePtr, u32 Direction, u8 Threshold);
|
||||
XStatus XEmac_GetPktThreshold(XEmac * InstancePtr, u32 Direction,
|
||||
u8 * ThreshPtr);
|
||||
XStatus XEmac_SetPktWaitBound(XEmac * InstancePtr, u32 Direction,
|
||||
u32 TimerValue);
|
||||
XStatus XEmac_GetPktWaitBound(XEmac * InstancePtr, u32 Direction,
|
||||
u32 * WaitPtr);
|
||||
XStatus XEmac_SetSgRecvSpace(XEmac * InstancePtr, u32 * MemoryPtr,
|
||||
u32 ByteCount);
|
||||
XStatus XEmac_SetSgSendSpace(XEmac * InstancePtr, u32 * MemoryPtr,
|
||||
u32 ByteCount);
|
||||
void XEmac_SetSgRecvHandler(XEmac * InstancePtr, void *CallBackRef,
|
||||
XEmac_SgHandler FuncPtr);
|
||||
void XEmac_SetSgSendHandler(XEmac * InstancePtr, void *CallBackRef,
|
||||
XEmac_SgHandler FuncPtr);
|
||||
|
||||
void XEmac_IntrHandlerDma(void *InstancePtr); /* interrupt handler */
|
||||
|
||||
/*
|
||||
* Interrupts with direct FIFO functions in xemac_intr_fifo.c. Also used
|
||||
* for simple DMA.
|
||||
*/
|
||||
XStatus XEmac_FifoSend(XEmac * InstancePtr, u8 * BufPtr, u32 ByteCount);
|
||||
XStatus XEmac_FifoRecv(XEmac * InstancePtr, u8 * BufPtr, u32 * ByteCountPtr);
|
||||
void XEmac_SetFifoRecvHandler(XEmac * InstancePtr, void *CallBackRef,
|
||||
XEmac_FifoHandler FuncPtr);
|
||||
void XEmac_SetFifoSendHandler(XEmac * InstancePtr, void *CallBackRef,
|
||||
XEmac_FifoHandler FuncPtr);
|
||||
|
||||
void XEmac_IntrHandlerFifo(void *InstancePtr); /* interrupt handler */
|
||||
|
||||
/*
|
||||
* General interrupt-related functions in xemac_intr.c
|
||||
*/
|
||||
void XEmac_SetErrorHandler(XEmac * InstancePtr, void *CallBackRef,
|
||||
XEmac_ErrorHandler FuncPtr);
|
||||
|
||||
/*
|
||||
* MAC configuration in xemac_options.c
|
||||
*/
|
||||
XStatus XEmac_SetOptions(XEmac * InstancePtr, u32 OptionFlag);
|
||||
u32 XEmac_GetOptions(XEmac * InstancePtr);
|
||||
XStatus XEmac_SetMacAddress(XEmac * InstancePtr, u8 * AddressPtr);
|
||||
void XEmac_GetMacAddress(XEmac * InstancePtr, u8 * BufferPtr);
|
||||
XStatus XEmac_SetInterframeGap(XEmac * InstancePtr, u8 Part1, u8 Part2);
|
||||
void XEmac_GetInterframeGap(XEmac * InstancePtr, u8 * Part1Ptr, u8 * Part2Ptr);
|
||||
|
||||
/*
|
||||
* Multicast functions in xemac_multicast.c (not supported by EMAC yet)
|
||||
*/
|
||||
XStatus XEmac_MulticastAdd(XEmac * InstancePtr, u8 * AddressPtr);
|
||||
XStatus XEmac_MulticastClear(XEmac * InstancePtr);
|
||||
|
||||
/*
|
||||
* PHY configuration in xemac_phy.c
|
||||
*/
|
||||
XStatus XEmac_PhyRead(XEmac * InstancePtr, u32 PhyAddress,
|
||||
u32 RegisterNum, u16 * PhyDataPtr);
|
||||
XStatus XEmac_PhyWrite(XEmac * InstancePtr, u32 PhyAddress,
|
||||
u32 RegisterNum, u16 PhyData);
|
||||
|
||||
/*
|
||||
* Statistics in xemac_stats.c
|
||||
*/
|
||||
void XEmac_GetStats(XEmac * InstancePtr, XEmac_Stats * StatsPtr);
|
||||
void XEmac_ClearStats(XEmac * InstancePtr);
|
||||
|
||||
#endif /* end of protection macro */
|
@ -1,60 +0,0 @@
|
||||
/*******************************************************************
|
||||
*
|
||||
* CAUTION: This file is automatically generated by libgen.
|
||||
* Version: Xilinx EDK 6.1.2 EDK_G.14
|
||||
* DO NOT EDIT.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Description: Driver configuration
|
||||
*
|
||||
*******************************************************************/
|
||||
|
||||
#include <config.h>
|
||||
#include "xemac.h"
|
||||
|
||||
/*
|
||||
* The configuration table for devices
|
||||
*/
|
||||
|
||||
XEmac_Config XEmac_ConfigTable[] = {
|
||||
{
|
||||
XPAR_OPB_ETHERNET_0_DEVICE_ID,
|
||||
XPAR_OPB_ETHERNET_0_BASEADDR,
|
||||
XPAR_OPB_ETHERNET_0_ERR_COUNT_EXIST,
|
||||
XPAR_OPB_ETHERNET_0_DMA_PRESENT,
|
||||
XPAR_OPB_ETHERNET_0_MII_EXIST}
|
||||
};
|
@ -1,207 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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_i.h
|
||||
*
|
||||
* This header file contains internal identifiers, which are those shared
|
||||
* between XEmac components. The identifiers in this file are not intended for
|
||||
* use external to the 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.00b rpm 04/29/02 Moved register definitions to xemac_l.h
|
||||
* 1.00c rpm 12/05/02 New version includes support for simple DMA
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XEMAC_I_H /* prevent circular inclusions */
|
||||
#define XEMAC_I_H /* by using protection macros */
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xemac.h"
|
||||
#include "xemac_l.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/*
|
||||
* Default buffer descriptor control word masks. The default send BD control
|
||||
* is set for incrementing the source address by one for each byte transferred,
|
||||
* and specify that the destination address (FIFO) is local to the device. The
|
||||
* default receive BD control is set for incrementing the destination address
|
||||
* by one for each byte transferred, and specify that the source address is
|
||||
* local to the device.
|
||||
*/
|
||||
#define XEM_DFT_SEND_BD_MASK (XDC_DMACR_SOURCE_INCR_MASK | \
|
||||
XDC_DMACR_DEST_LOCAL_MASK)
|
||||
#define XEM_DFT_RECV_BD_MASK (XDC_DMACR_DEST_INCR_MASK | \
|
||||
XDC_DMACR_SOURCE_LOCAL_MASK)
|
||||
|
||||
/*
|
||||
* Masks for the IPIF Device Interrupt enable and status registers.
|
||||
*/
|
||||
#define XEM_IPIF_EMAC_MASK 0x00000004UL /* MAC interrupt */
|
||||
#define XEM_IPIF_SEND_DMA_MASK 0x00000008UL /* Send DMA interrupt */
|
||||
#define XEM_IPIF_RECV_DMA_MASK 0x00000010UL /* Receive DMA interrupt */
|
||||
#define XEM_IPIF_RECV_FIFO_MASK 0x00000020UL /* Receive FIFO interrupt */
|
||||
#define XEM_IPIF_SEND_FIFO_MASK 0x00000040UL /* Send FIFO interrupt */
|
||||
|
||||
/*
|
||||
* Default IPIF Device Interrupt mask when configured for DMA
|
||||
*/
|
||||
#define XEM_IPIF_DMA_DFT_MASK (XEM_IPIF_SEND_DMA_MASK | \
|
||||
XEM_IPIF_RECV_DMA_MASK | \
|
||||
XEM_IPIF_EMAC_MASK | \
|
||||
XEM_IPIF_SEND_FIFO_MASK | \
|
||||
XEM_IPIF_RECV_FIFO_MASK)
|
||||
|
||||
/*
|
||||
* Default IPIF Device Interrupt mask when configured without DMA
|
||||
*/
|
||||
#define XEM_IPIF_FIFO_DFT_MASK (XEM_IPIF_EMAC_MASK | \
|
||||
XEM_IPIF_SEND_FIFO_MASK | \
|
||||
XEM_IPIF_RECV_FIFO_MASK)
|
||||
|
||||
#define XEM_IPIF_DMA_DEV_INTR_COUNT 7 /* Number of interrupt sources */
|
||||
#define XEM_IPIF_FIFO_DEV_INTR_COUNT 5 /* Number of interrupt sources */
|
||||
#define XEM_IPIF_DEVICE_INTR_COUNT 7 /* Number of interrupt sources */
|
||||
#define XEM_IPIF_IP_INTR_COUNT 22 /* Number of MAC interrupts */
|
||||
|
||||
/* a mask for all transmit interrupts, used in polled mode */
|
||||
#define XEM_EIR_XMIT_ALL_MASK (XEM_EIR_XMIT_DONE_MASK | \
|
||||
XEM_EIR_XMIT_ERROR_MASK | \
|
||||
XEM_EIR_XMIT_SFIFO_EMPTY_MASK | \
|
||||
XEM_EIR_XMIT_LFIFO_FULL_MASK)
|
||||
|
||||
/* a mask for all receive interrupts, used in polled mode */
|
||||
#define XEM_EIR_RECV_ALL_MASK (XEM_EIR_RECV_DONE_MASK | \
|
||||
XEM_EIR_RECV_ERROR_MASK | \
|
||||
XEM_EIR_RECV_LFIFO_EMPTY_MASK | \
|
||||
XEM_EIR_RECV_LFIFO_OVER_MASK | \
|
||||
XEM_EIR_RECV_LFIFO_UNDER_MASK | \
|
||||
XEM_EIR_RECV_DFIFO_OVER_MASK | \
|
||||
XEM_EIR_RECV_MISSED_FRAME_MASK | \
|
||||
XEM_EIR_RECV_COLLISION_MASK | \
|
||||
XEM_EIR_RECV_FCS_ERROR_MASK | \
|
||||
XEM_EIR_RECV_LEN_ERROR_MASK | \
|
||||
XEM_EIR_RECV_SHORT_ERROR_MASK | \
|
||||
XEM_EIR_RECV_LONG_ERROR_MASK | \
|
||||
XEM_EIR_RECV_ALIGN_ERROR_MASK)
|
||||
|
||||
/* a default interrupt mask for scatter-gather DMA operation */
|
||||
#define XEM_EIR_DFT_SG_MASK (XEM_EIR_RECV_ERROR_MASK | \
|
||||
XEM_EIR_RECV_LFIFO_OVER_MASK | \
|
||||
XEM_EIR_RECV_LFIFO_UNDER_MASK | \
|
||||
XEM_EIR_XMIT_SFIFO_OVER_MASK | \
|
||||
XEM_EIR_XMIT_SFIFO_UNDER_MASK | \
|
||||
XEM_EIR_XMIT_LFIFO_OVER_MASK | \
|
||||
XEM_EIR_XMIT_LFIFO_UNDER_MASK | \
|
||||
XEM_EIR_RECV_DFIFO_OVER_MASK | \
|
||||
XEM_EIR_RECV_MISSED_FRAME_MASK | \
|
||||
XEM_EIR_RECV_COLLISION_MASK | \
|
||||
XEM_EIR_RECV_FCS_ERROR_MASK | \
|
||||
XEM_EIR_RECV_LEN_ERROR_MASK | \
|
||||
XEM_EIR_RECV_SHORT_ERROR_MASK | \
|
||||
XEM_EIR_RECV_LONG_ERROR_MASK | \
|
||||
XEM_EIR_RECV_ALIGN_ERROR_MASK)
|
||||
|
||||
/* a default interrupt mask for non-DMA operation (direct FIFOs) */
|
||||
#define XEM_EIR_DFT_FIFO_MASK (XEM_EIR_XMIT_DONE_MASK | \
|
||||
XEM_EIR_RECV_DONE_MASK | \
|
||||
XEM_EIR_DFT_SG_MASK)
|
||||
|
||||
/*
|
||||
* Mask for the DMA interrupt enable and status registers when configured
|
||||
* for scatter-gather DMA.
|
||||
*/
|
||||
#define XEM_DMA_SG_INTR_MASK (XDC_IXR_DMA_ERROR_MASK | \
|
||||
XDC_IXR_PKT_THRESHOLD_MASK | \
|
||||
XDC_IXR_PKT_WAIT_BOUND_MASK | \
|
||||
XDC_IXR_SG_END_MASK)
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* Clears a structure of given size, in bytes, by setting each byte to 0.
|
||||
*
|
||||
* @param StructPtr is a pointer to the structure to be cleared.
|
||||
* @param NumBytes is the number of bytes in the structure.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Signature: void XEmac_mClearStruct(u8 *StructPtr, unsigned int NumBytes)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XEmac_mClearStruct(StructPtr, NumBytes) \
|
||||
{ \
|
||||
int i; \
|
||||
u8 *BytePtr = (u8 *)(StructPtr); \
|
||||
for (i=0; i < (unsigned int)(NumBytes); i++) \
|
||||
{ \
|
||||
*BytePtr++ = 0; \
|
||||
} \
|
||||
}
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
extern XEmac_Config XEmac_ConfigTable[];
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
void XEmac_CheckEmacError(XEmac * InstancePtr, u32 IntrStatus);
|
||||
void XEmac_CheckFifoRecvError(XEmac * InstancePtr);
|
||||
void XEmac_CheckFifoSendError(XEmac * InstancePtr);
|
||||
|
||||
#endif /* end of protection macro */
|
@ -1,402 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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_intr.c
|
||||
*
|
||||
* This file contains general interrupt-related functions 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
|
||||
* 1.00c rpm 03/31/03 Added comment to indicate that no Receive Length FIFO
|
||||
* overrun interrupts occur in v1.00l and later of the EMAC
|
||||
* device. This avoids the need to reset the device on
|
||||
* receive overruns.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xbasic_types.h"
|
||||
#include "xemac_i.h"
|
||||
#include "xio.h"
|
||||
#include "xipif_v1_23_b.h" /* Uses v1.23b of the IPIF */
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Set the callback function for handling asynchronous errors. The upper layer
|
||||
* software should call this function during initialization.
|
||||
*
|
||||
* The error callback is invoked by the driver within interrupt context, so it
|
||||
* needs to do its job quickly. If there are potentially slow operations within
|
||||
* the callback, these should be done at task-level.
|
||||
*
|
||||
* The Xilinx errors that must be handled by the callback are:
|
||||
* - XST_DMA_ERROR indicates an unrecoverable DMA error occurred. This is
|
||||
* typically a bus error or bus timeout. The handler must reset and
|
||||
* re-configure the device.
|
||||
* - XST_FIFO_ERROR indicates an unrecoverable FIFO error occurred. This is a
|
||||
* deadlock condition in the packet FIFO. The handler must reset and
|
||||
* re-configure the device.
|
||||
* - XST_RESET_ERROR indicates an unrecoverable MAC error occurred, usually an
|
||||
* overrun or underrun. The handler must reset and re-configure the device.
|
||||
* - XST_DMA_SG_NO_LIST indicates an attempt was made to access a scatter-gather
|
||||
* DMA list that has not yet been created.
|
||||
* - XST_DMA_SG_LIST_EMPTY indicates the driver tried to get a descriptor from
|
||||
* the receive descriptor list, but the list was empty.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
* @param CallBackRef is a reference pointer to be passed back to the adapter in
|
||||
* the callback. This helps the adapter correlate the callback to a
|
||||
* particular driver.
|
||||
* @param FuncPtr is the pointer to the callback function.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void
|
||||
XEmac_SetErrorHandler(XEmac * InstancePtr, void *CallBackRef,
|
||||
XEmac_ErrorHandler FuncPtr)
|
||||
{
|
||||
XASSERT_VOID(InstancePtr != NULL);
|
||||
XASSERT_VOID(FuncPtr != NULL);
|
||||
XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
InstancePtr->ErrorHandler = FuncPtr;
|
||||
InstancePtr->ErrorRef = CallBackRef;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* Check the interrupt status bits of the Ethernet MAC for errors. Errors
|
||||
* currently handled are:
|
||||
* - Receive length FIFO overrun. Indicates data was lost due to the receive
|
||||
* length FIFO becoming full during the reception of a packet. Only a device
|
||||
* reset clears this condition.
|
||||
* - Receive length FIFO underrun. An attempt to read an empty FIFO. Only a
|
||||
* device reset clears this condition.
|
||||
* - Transmit status FIFO overrun. Indicates data was lost due to the transmit
|
||||
* status FIFO becoming full following the transmission of a packet. Only a
|
||||
* device reset clears this condition.
|
||||
* - Transmit status FIFO underrun. An attempt to read an empty FIFO. Only a
|
||||
* device reset clears this condition.
|
||||
* - Transmit length FIFO overrun. Indicates data was lost due to the transmit
|
||||
* length FIFO becoming full following the transmission of a packet. Only a
|
||||
* device reset clears this condition.
|
||||
* - Transmit length FIFO underrun. An attempt to read an empty FIFO. Only a
|
||||
* device reset clears this condition.
|
||||
* - Receive data FIFO overrun. Indicates data was lost due to the receive data
|
||||
* FIFO becoming full during the reception of a packet.
|
||||
* - Receive data errors:
|
||||
* - Receive missed frame error. Valid data was lost by the MAC.
|
||||
* - Receive collision error. Data was lost by the MAC due to a collision.
|
||||
* - Receive FCS error. Data was dicarded by the MAC due to FCS error.
|
||||
* - Receive length field error. Data was dicarded by the MAC due to an invalid
|
||||
* length field in the packet.
|
||||
* - Receive short error. Data was dicarded by the MAC because a packet was
|
||||
* shorter than allowed.
|
||||
* - Receive long error. Data was dicarded by the MAC because a packet was
|
||||
* longer than allowed.
|
||||
* - Receive alignment error. Data was truncated by the MAC because its length
|
||||
* was not byte-aligned.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
* @param IntrStatus is the contents of the interrupt status register to be checked
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* This function is intended for internal use only.
|
||||
*
|
||||
******************************************************************************/
|
||||
void
|
||||
XEmac_CheckEmacError(XEmac * InstancePtr, u32 IntrStatus)
|
||||
{
|
||||
u32 ResetError = FALSE;
|
||||
|
||||
/*
|
||||
* First check for receive fifo overrun/underrun errors. Most require a
|
||||
* reset by the user to clear, but the data FIFO overrun error does not.
|
||||
*/
|
||||
if (IntrStatus & XEM_EIR_RECV_DFIFO_OVER_MASK) {
|
||||
InstancePtr->Stats.RecvOverrunErrors++;
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_LFIFO_OVER_MASK) {
|
||||
/*
|
||||
* Receive Length FIFO overrun interrupts no longer occur in v1.00l
|
||||
* and later of the EMAC device. Frames are just dropped by the EMAC
|
||||
* if the length FIFO is full. The user would notice the Receive Missed
|
||||
* Frame count incrementing without any other errors being reported.
|
||||
* This code is left here for backward compatibility with v1.00k and
|
||||
* older EMAC devices.
|
||||
*/
|
||||
InstancePtr->Stats.RecvOverrunErrors++;
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
ResetError = TRUE; /* requires a reset */
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_LFIFO_UNDER_MASK) {
|
||||
InstancePtr->Stats.RecvUnderrunErrors++;
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
ResetError = TRUE; /* requires a reset */
|
||||
}
|
||||
|
||||
/*
|
||||
* Now check for general receive errors. Get the latest count where
|
||||
* available, otherwise just bump the statistic so we know the interrupt
|
||||
* occurred.
|
||||
*/
|
||||
if (IntrStatus & XEM_EIR_RECV_ERROR_MASK) {
|
||||
if (IntrStatus & XEM_EIR_RECV_MISSED_FRAME_MASK) {
|
||||
/*
|
||||
* Caused by length FIFO or data FIFO overruns on receive side
|
||||
*/
|
||||
InstancePtr->Stats.RecvMissedFrameErrors =
|
||||
XIo_In32(InstancePtr->BaseAddress +
|
||||
XEM_RMFC_OFFSET);
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_COLLISION_MASK) {
|
||||
InstancePtr->Stats.RecvCollisionErrors =
|
||||
XIo_In32(InstancePtr->BaseAddress + XEM_RCC_OFFSET);
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_FCS_ERROR_MASK) {
|
||||
InstancePtr->Stats.RecvFcsErrors =
|
||||
XIo_In32(InstancePtr->BaseAddress +
|
||||
XEM_RFCSEC_OFFSET);
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_LEN_ERROR_MASK) {
|
||||
InstancePtr->Stats.RecvLengthFieldErrors++;
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_SHORT_ERROR_MASK) {
|
||||
InstancePtr->Stats.RecvShortErrors++;
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_LONG_ERROR_MASK) {
|
||||
InstancePtr->Stats.RecvLongErrors++;
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_ALIGN_ERROR_MASK) {
|
||||
InstancePtr->Stats.RecvAlignmentErrors =
|
||||
XIo_In32(InstancePtr->BaseAddress +
|
||||
XEM_RAEC_OFFSET);
|
||||
}
|
||||
|
||||
/*
|
||||
* Bump recv interrupts stats only if not scatter-gather DMA (this
|
||||
* stat gets bumped elsewhere in that case)
|
||||
*/
|
||||
if (!XEmac_mIsSgDma(InstancePtr)) {
|
||||
InstancePtr->Stats.RecvInterrupts++; /* TODO: double bump? */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for transmit errors. These apply to both DMA and non-DMA modes
|
||||
* of operation. The entire device should be reset after overruns or
|
||||
* underruns.
|
||||
*/
|
||||
if (IntrStatus & (XEM_EIR_XMIT_SFIFO_OVER_MASK |
|
||||
XEM_EIR_XMIT_LFIFO_OVER_MASK)) {
|
||||
InstancePtr->Stats.XmitOverrunErrors++;
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
ResetError = TRUE;
|
||||
}
|
||||
|
||||
if (IntrStatus & (XEM_EIR_XMIT_SFIFO_UNDER_MASK |
|
||||
XEM_EIR_XMIT_LFIFO_UNDER_MASK)) {
|
||||
InstancePtr->Stats.XmitUnderrunErrors++;
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
ResetError = TRUE;
|
||||
}
|
||||
|
||||
if (ResetError) {
|
||||
/*
|
||||
* If a reset error occurred, disable the EMAC interrupts since the
|
||||
* reset-causing interrupt(s) is latched in the EMAC - meaning it will
|
||||
* keep occurring until the device is reset. In order to give the higher
|
||||
* layer software time to reset the device, we have to disable the
|
||||
* overrun/underrun interrupts until that happens. We trust that the
|
||||
* higher layer resets the device. We are able to get away with disabling
|
||||
* all EMAC interrupts since the only interrupts it generates are for
|
||||
* error conditions, and we don't care about any more errors right now.
|
||||
*/
|
||||
XIIF_V123B_WRITE_IIER(InstancePtr->BaseAddress, 0);
|
||||
|
||||
/*
|
||||
* Invoke the error handler callback, which should result in a reset
|
||||
* of the device by the upper layer software.
|
||||
*/
|
||||
InstancePtr->ErrorHandler(InstancePtr->ErrorRef,
|
||||
XST_RESET_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* Check the receive packet FIFO for errors. FIFO error interrupts are:
|
||||
* - Deadlock. See the XPacketFifo component for a description of deadlock on a
|
||||
* FIFO.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* Although the function returns void, it can return an asynchronous error to the
|
||||
* application through the error handler. It can return XST_FIFO_ERROR if a FIFO
|
||||
* error occurred.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* This function is intended for internal use only.
|
||||
*
|
||||
******************************************************************************/
|
||||
void
|
||||
XEmac_CheckFifoRecvError(XEmac * InstancePtr)
|
||||
{
|
||||
/*
|
||||
* Although the deadlock is currently the only interrupt from a packet
|
||||
* FIFO, make sure it is deadlocked before taking action. There is no
|
||||
* need to clear this interrupt since it requires a reset of the device.
|
||||
*/
|
||||
if (XPF_V100B_IS_DEADLOCKED(&InstancePtr->RecvFifo)) {
|
||||
u32 IntrEnable;
|
||||
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
|
||||
/*
|
||||
* Invoke the error callback function, which should result in a reset
|
||||
* of the device by the upper layer software. We first need to disable
|
||||
* the FIFO interrupt, since otherwise the upper layer thread that
|
||||
* handles the reset may never run because this interrupt condition
|
||||
* doesn't go away until a reset occurs (there is no way to ack it).
|
||||
*/
|
||||
IntrEnable = XIIF_V123B_READ_DIER(InstancePtr->BaseAddress);
|
||||
XIIF_V123B_WRITE_DIER(InstancePtr->BaseAddress,
|
||||
IntrEnable & ~XEM_IPIF_RECV_FIFO_MASK);
|
||||
|
||||
InstancePtr->ErrorHandler(InstancePtr->ErrorRef,
|
||||
XST_FIFO_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* Check the send packet FIFO for errors. FIFO error interrupts are:
|
||||
* - Deadlock. See the XPacketFifo component for a description of deadlock on a
|
||||
* FIFO.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* Although the function returns void, it can return an asynchronous error to the
|
||||
* application through the error handler. It can return XST_FIFO_ERROR if a FIFO
|
||||
* error occurred.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* This function is intended for internal use only.
|
||||
*
|
||||
******************************************************************************/
|
||||
void
|
||||
XEmac_CheckFifoSendError(XEmac * InstancePtr)
|
||||
{
|
||||
/*
|
||||
* Although the deadlock is currently the only interrupt from a packet
|
||||
* FIFO, make sure it is deadlocked before taking action. There is no
|
||||
* need to clear this interrupt since it requires a reset of the device.
|
||||
*/
|
||||
if (XPF_V100B_IS_DEADLOCKED(&InstancePtr->SendFifo)) {
|
||||
u32 IntrEnable;
|
||||
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
|
||||
/*
|
||||
* Invoke the error callback function, which should result in a reset
|
||||
* of the device by the upper layer software. We first need to disable
|
||||
* the FIFO interrupt, since otherwise the upper layer thread that
|
||||
* handles the reset may never run because this interrupt condition
|
||||
* doesn't go away until a reset occurs (there is no way to ack it).
|
||||
*/
|
||||
IntrEnable = XIIF_V123B_READ_DIER(InstancePtr->BaseAddress);
|
||||
XIIF_V123B_WRITE_DIER(InstancePtr->BaseAddress,
|
||||
IntrEnable & ~XEM_IPIF_SEND_FIFO_MASK);
|
||||
|
||||
InstancePtr->ErrorHandler(InstancePtr->ErrorRef,
|
||||
XST_FIFO_ERROR);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,462 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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_l.h
|
||||
*
|
||||
* This header file contains identifiers and low-level driver functions (or
|
||||
* macros) that can be used to access the device. High-level driver functions
|
||||
* are defined in xemac.h.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00b rpm 04/26/02 First release
|
||||
* 1.00b rmm 09/23/02 Added XEmac_mPhyReset macro
|
||||
* 1.00c rpm 12/05/02 New version includes support for simple DMA
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XEMAC_L_H /* prevent circular inclusions */
|
||||
#define XEMAC_L_H /* by using protection macros */
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xbasic_types.h"
|
||||
#include "xio.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/* Offset of the MAC registers from the IPIF base address */
|
||||
#define XEM_REG_OFFSET 0x1100UL
|
||||
|
||||
/*
|
||||
* Register offsets for the Ethernet MAC. Each register is 32 bits.
|
||||
*/
|
||||
#define XEM_EMIR_OFFSET (XEM_REG_OFFSET + 0x0) /* EMAC Module ID */
|
||||
#define XEM_ECR_OFFSET (XEM_REG_OFFSET + 0x4) /* MAC Control */
|
||||
#define XEM_IFGP_OFFSET (XEM_REG_OFFSET + 0x8) /* Interframe Gap */
|
||||
#define XEM_SAH_OFFSET (XEM_REG_OFFSET + 0xC) /* Station addr, high */
|
||||
#define XEM_SAL_OFFSET (XEM_REG_OFFSET + 0x10) /* Station addr, low */
|
||||
#define XEM_MGTCR_OFFSET (XEM_REG_OFFSET + 0x14) /* MII mgmt control */
|
||||
#define XEM_MGTDR_OFFSET (XEM_REG_OFFSET + 0x18) /* MII mgmt data */
|
||||
#define XEM_RPLR_OFFSET (XEM_REG_OFFSET + 0x1C) /* Rx packet length */
|
||||
#define XEM_TPLR_OFFSET (XEM_REG_OFFSET + 0x20) /* Tx packet length */
|
||||
#define XEM_TSR_OFFSET (XEM_REG_OFFSET + 0x24) /* Tx status */
|
||||
#define XEM_RMFC_OFFSET (XEM_REG_OFFSET + 0x28) /* Rx missed frames */
|
||||
#define XEM_RCC_OFFSET (XEM_REG_OFFSET + 0x2C) /* Rx collisions */
|
||||
#define XEM_RFCSEC_OFFSET (XEM_REG_OFFSET + 0x30) /* Rx FCS errors */
|
||||
#define XEM_RAEC_OFFSET (XEM_REG_OFFSET + 0x34) /* Rx alignment errors */
|
||||
#define XEM_TEDC_OFFSET (XEM_REG_OFFSET + 0x38) /* Transmit excess
|
||||
* deferral cnt */
|
||||
|
||||
/*
|
||||
* Register offsets for the IPIF components
|
||||
*/
|
||||
#define XEM_ISR_OFFSET 0x20UL /* Interrupt status */
|
||||
|
||||
#define XEM_DMA_OFFSET 0x2300UL
|
||||
#define XEM_DMA_SEND_OFFSET (XEM_DMA_OFFSET + 0x0) /* DMA send channel */
|
||||
#define XEM_DMA_RECV_OFFSET (XEM_DMA_OFFSET + 0x40) /* DMA recv channel */
|
||||
|
||||
#define XEM_PFIFO_OFFSET 0x2000UL
|
||||
#define XEM_PFIFO_TXREG_OFFSET (XEM_PFIFO_OFFSET + 0x0) /* Tx registers */
|
||||
#define XEM_PFIFO_RXREG_OFFSET (XEM_PFIFO_OFFSET + 0x10) /* Rx registers */
|
||||
#define XEM_PFIFO_TXDATA_OFFSET (XEM_PFIFO_OFFSET + 0x100) /* Tx keyhole */
|
||||
#define XEM_PFIFO_RXDATA_OFFSET (XEM_PFIFO_OFFSET + 0x200) /* Rx keyhole */
|
||||
|
||||
/*
|
||||
* EMAC Module Identification Register (EMIR)
|
||||
*/
|
||||
#define XEM_EMIR_VERSION_MASK 0xFFFF0000UL /* Device version */
|
||||
#define XEM_EMIR_TYPE_MASK 0x0000FF00UL /* Device type */
|
||||
|
||||
/*
|
||||
* EMAC Control Register (ECR)
|
||||
*/
|
||||
#define XEM_ECR_FULL_DUPLEX_MASK 0x80000000UL /* Full duplex mode */
|
||||
#define XEM_ECR_XMIT_RESET_MASK 0x40000000UL /* Reset transmitter */
|
||||
#define XEM_ECR_XMIT_ENABLE_MASK 0x20000000UL /* Enable transmitter */
|
||||
#define XEM_ECR_RECV_RESET_MASK 0x10000000UL /* Reset receiver */
|
||||
#define XEM_ECR_RECV_ENABLE_MASK 0x08000000UL /* Enable receiver */
|
||||
#define XEM_ECR_PHY_ENABLE_MASK 0x04000000UL /* Enable PHY */
|
||||
#define XEM_ECR_XMIT_PAD_ENABLE_MASK 0x02000000UL /* Enable xmit pad insert */
|
||||
#define XEM_ECR_XMIT_FCS_ENABLE_MASK 0x01000000UL /* Enable xmit FCS insert */
|
||||
#define XEM_ECR_XMIT_ADDR_INSERT_MASK 0x00800000UL /* Enable xmit source addr
|
||||
* insertion */
|
||||
#define XEM_ECR_XMIT_ERROR_INSERT_MASK 0x00400000UL /* Insert xmit error */
|
||||
#define XEM_ECR_XMIT_ADDR_OVWRT_MASK 0x00200000UL /* Enable xmit source addr
|
||||
* overwrite */
|
||||
#define XEM_ECR_LOOPBACK_MASK 0x00100000UL /* Enable internal
|
||||
* loopback */
|
||||
#define XEM_ECR_RECV_STRIP_ENABLE_MASK 0x00080000UL /* Enable recv pad/fcs strip */
|
||||
#define XEM_ECR_UNICAST_ENABLE_MASK 0x00020000UL /* Enable unicast addr */
|
||||
#define XEM_ECR_MULTI_ENABLE_MASK 0x00010000UL /* Enable multicast addr */
|
||||
#define XEM_ECR_BROAD_ENABLE_MASK 0x00008000UL /* Enable broadcast addr */
|
||||
#define XEM_ECR_PROMISC_ENABLE_MASK 0x00004000UL /* Enable promiscuous mode */
|
||||
#define XEM_ECR_RECV_ALL_MASK 0x00002000UL /* Receive all frames */
|
||||
#define XEM_ECR_RESERVED2_MASK 0x00001000UL /* Reserved */
|
||||
#define XEM_ECR_MULTI_HASH_ENABLE_MASK 0x00000800UL /* Enable multicast hash */
|
||||
#define XEM_ECR_PAUSE_FRAME_MASK 0x00000400UL /* Interpret pause frames */
|
||||
#define XEM_ECR_CLEAR_HASH_MASK 0x00000200UL /* Clear hash table */
|
||||
#define XEM_ECR_ADD_HASH_ADDR_MASK 0x00000100UL /* Add hash table address */
|
||||
|
||||
/*
|
||||
* Interframe Gap Register (IFGR)
|
||||
*/
|
||||
#define XEM_IFGP_PART1_MASK 0xF8000000UL /* Interframe Gap Part1 */
|
||||
#define XEM_IFGP_PART1_SHIFT 27
|
||||
#define XEM_IFGP_PART2_MASK 0x07C00000UL /* Interframe Gap Part2 */
|
||||
#define XEM_IFGP_PART2_SHIFT 22
|
||||
|
||||
/*
|
||||
* Station Address High Register (SAH)
|
||||
*/
|
||||
#define XEM_SAH_ADDR_MASK 0x0000FFFFUL /* Station address high bytes */
|
||||
|
||||
/*
|
||||
* Station Address Low Register (SAL)
|
||||
*/
|
||||
#define XEM_SAL_ADDR_MASK 0xFFFFFFFFUL /* Station address low bytes */
|
||||
|
||||
/*
|
||||
* MII Management Control Register (MGTCR)
|
||||
*/
|
||||
#define XEM_MGTCR_START_MASK 0x80000000UL /* Start/Busy */
|
||||
#define XEM_MGTCR_RW_NOT_MASK 0x40000000UL /* Read/Write Not (direction) */
|
||||
#define XEM_MGTCR_PHY_ADDR_MASK 0x3E000000UL /* PHY address */
|
||||
#define XEM_MGTCR_PHY_ADDR_SHIFT 25 /* PHY address shift */
|
||||
#define XEM_MGTCR_REG_ADDR_MASK 0x01F00000UL /* Register address */
|
||||
#define XEM_MGTCR_REG_ADDR_SHIFT 20 /* Register addr shift */
|
||||
#define XEM_MGTCR_MII_ENABLE_MASK 0x00080000UL /* Enable MII from EMAC */
|
||||
#define XEM_MGTCR_RD_ERROR_MASK 0x00040000UL /* MII mgmt read error */
|
||||
|
||||
/*
|
||||
* MII Management Data Register (MGTDR)
|
||||
*/
|
||||
#define XEM_MGTDR_DATA_MASK 0x0000FFFFUL /* MII data */
|
||||
|
||||
/*
|
||||
* Receive Packet Length Register (RPLR)
|
||||
*/
|
||||
#define XEM_RPLR_LENGTH_MASK 0x0000FFFFUL /* Receive packet length */
|
||||
|
||||
/*
|
||||
* Transmit Packet Length Register (TPLR)
|
||||
*/
|
||||
#define XEM_TPLR_LENGTH_MASK 0x0000FFFFUL /* Transmit packet length */
|
||||
|
||||
/*
|
||||
* Transmit Status Register (TSR)
|
||||
*/
|
||||
#define XEM_TSR_EXCESS_DEFERRAL_MASK 0x80000000UL /* Transmit excess deferral */
|
||||
#define XEM_TSR_FIFO_UNDERRUN_MASK 0x40000000UL /* Packet FIFO underrun */
|
||||
#define XEM_TSR_ATTEMPTS_MASK 0x3E000000UL /* Transmission attempts */
|
||||
#define XEM_TSR_LATE_COLLISION_MASK 0x01000000UL /* Transmit late collision */
|
||||
|
||||
/*
|
||||
* Receive Missed Frame Count (RMFC)
|
||||
*/
|
||||
#define XEM_RMFC_DATA_MASK 0x0000FFFFUL
|
||||
|
||||
/*
|
||||
* Receive Collision Count (RCC)
|
||||
*/
|
||||
#define XEM_RCC_DATA_MASK 0x0000FFFFUL
|
||||
|
||||
/*
|
||||
* Receive FCS Error Count (RFCSEC)
|
||||
*/
|
||||
#define XEM_RFCSEC_DATA_MASK 0x0000FFFFUL
|
||||
|
||||
/*
|
||||
* Receive Alignment Error Count (RALN)
|
||||
*/
|
||||
#define XEM_RAEC_DATA_MASK 0x0000FFFFUL
|
||||
|
||||
/*
|
||||
* Transmit Excess Deferral Count (TEDC)
|
||||
*/
|
||||
#define XEM_TEDC_DATA_MASK 0x0000FFFFUL
|
||||
|
||||
/*
|
||||
* EMAC Interrupt Registers (Status and Enable) masks. These registers are
|
||||
* part of the IPIF IP Interrupt registers
|
||||
*/
|
||||
#define XEM_EIR_XMIT_DONE_MASK 0x00000001UL /* Xmit complete */
|
||||
#define XEM_EIR_RECV_DONE_MASK 0x00000002UL /* Recv complete */
|
||||
#define XEM_EIR_XMIT_ERROR_MASK 0x00000004UL /* Xmit error */
|
||||
#define XEM_EIR_RECV_ERROR_MASK 0x00000008UL /* Recv error */
|
||||
#define XEM_EIR_XMIT_SFIFO_EMPTY_MASK 0x00000010UL /* Xmit status fifo empty */
|
||||
#define XEM_EIR_RECV_LFIFO_EMPTY_MASK 0x00000020UL /* Recv length fifo empty */
|
||||
#define XEM_EIR_XMIT_LFIFO_FULL_MASK 0x00000040UL /* Xmit length fifo full */
|
||||
#define XEM_EIR_RECV_LFIFO_OVER_MASK 0x00000080UL /* Recv length fifo
|
||||
* overrun */
|
||||
#define XEM_EIR_RECV_LFIFO_UNDER_MASK 0x00000100UL /* Recv length fifo
|
||||
* underrun */
|
||||
#define XEM_EIR_XMIT_SFIFO_OVER_MASK 0x00000200UL /* Xmit status fifo
|
||||
* overrun */
|
||||
#define XEM_EIR_XMIT_SFIFO_UNDER_MASK 0x00000400UL /* Transmit status fifo
|
||||
* underrun */
|
||||
#define XEM_EIR_XMIT_LFIFO_OVER_MASK 0x00000800UL /* Transmit length fifo
|
||||
* overrun */
|
||||
#define XEM_EIR_XMIT_LFIFO_UNDER_MASK 0x00001000UL /* Transmit length fifo
|
||||
* underrun */
|
||||
#define XEM_EIR_XMIT_PAUSE_MASK 0x00002000UL /* Transmit pause pkt
|
||||
* received */
|
||||
#define XEM_EIR_RECV_DFIFO_OVER_MASK 0x00004000UL /* Receive data fifo
|
||||
* overrun */
|
||||
#define XEM_EIR_RECV_MISSED_FRAME_MASK 0x00008000UL /* Receive missed frame
|
||||
* error */
|
||||
#define XEM_EIR_RECV_COLLISION_MASK 0x00010000UL /* Receive collision
|
||||
* error */
|
||||
#define XEM_EIR_RECV_FCS_ERROR_MASK 0x00020000UL /* Receive FCS error */
|
||||
#define XEM_EIR_RECV_LEN_ERROR_MASK 0x00040000UL /* Receive length field
|
||||
* error */
|
||||
#define XEM_EIR_RECV_SHORT_ERROR_MASK 0x00080000UL /* Receive short frame
|
||||
* error */
|
||||
#define XEM_EIR_RECV_LONG_ERROR_MASK 0x00100000UL /* Receive long frame
|
||||
* error */
|
||||
#define XEM_EIR_RECV_ALIGN_ERROR_MASK 0x00200000UL /* Receive alignment
|
||||
* error */
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Low-level driver macros and functions. The list below provides signatures
|
||||
* to help the user use the macros.
|
||||
*
|
||||
* u32 XEmac_mReadReg(u32 BaseAddress, int RegOffset)
|
||||
* void XEmac_mWriteReg(u32 BaseAddress, int RegOffset, u32 Mask)
|
||||
*
|
||||
* void XEmac_mSetControlReg(u32 BaseAddress, u32 Mask)
|
||||
* void XEmac_mSetMacAddress(u32 BaseAddress, u8 *AddressPtr)
|
||||
*
|
||||
* void XEmac_mEnable(u32 BaseAddress)
|
||||
* void XEmac_mDisable(u32 BaseAddress)
|
||||
*
|
||||
* u32 XEmac_mIsTxDone(u32 BaseAddress)
|
||||
* u32 XEmac_mIsRxEmpty(u32 BaseAddress)
|
||||
*
|
||||
* void XEmac_SendFrame(u32 BaseAddress, u8 *FramePtr, int Size)
|
||||
* int XEmac_RecvFrame(u32 BaseAddress, u8 *FramePtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Read the given register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device
|
||||
* @param RegOffset is the register offset to be read
|
||||
*
|
||||
* @return The 32-bit value of the register
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmac_mReadReg(BaseAddress, RegOffset) \
|
||||
XIo_In32((BaseAddress) + (RegOffset))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Write the given register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device
|
||||
* @param RegOffset is the register offset to be written
|
||||
* @param Data is the 32-bit value to write to the register
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmac_mWriteReg(BaseAddress, RegOffset, Data) \
|
||||
XIo_Out32((BaseAddress) + (RegOffset), (Data))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Set the contents of the control register. Use the XEM_ECR_* constants
|
||||
* defined above to create the bit-mask to be written to the register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device
|
||||
* @param Mask is the 16-bit value to write to the control register
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmac_mSetControlReg(BaseAddress, Mask) \
|
||||
XIo_Out32((BaseAddress) + XEM_ECR_OFFSET, (Mask))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Set the station address of the EMAC device.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device
|
||||
* @param AddressPtr is a pointer to a 6-byte MAC address
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmac_mSetMacAddress(BaseAddress, AddressPtr) \
|
||||
{ \
|
||||
u32 MacAddr; \
|
||||
\
|
||||
MacAddr = ((AddressPtr)[0] << 8) | (AddressPtr)[1]; \
|
||||
XIo_Out32((BaseAddress) + XEM_SAH_OFFSET, MacAddr); \
|
||||
\
|
||||
MacAddr = ((AddressPtr)[2] << 24) | ((AddressPtr)[3] << 16) | \
|
||||
((AddressPtr)[4] << 8) | (AddressPtr)[5]; \
|
||||
\
|
||||
XIo_Out32((BaseAddress) + XEM_SAL_OFFSET, MacAddr); \
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Enable the transmitter and receiver. Preserve the contents of the control
|
||||
* register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmac_mEnable(BaseAddress) \
|
||||
{ \
|
||||
u32 Control; \
|
||||
Control = XIo_In32((BaseAddress) + XEM_ECR_OFFSET); \
|
||||
Control &= ~(XEM_ECR_XMIT_RESET_MASK | XEM_ECR_RECV_RESET_MASK); \
|
||||
Control |= (XEM_ECR_XMIT_ENABLE_MASK | XEM_ECR_RECV_ENABLE_MASK); \
|
||||
XIo_Out32((BaseAddress) + XEM_ECR_OFFSET, Control); \
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Disable the transmitter and receiver. Preserve the contents of the control
|
||||
* register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmac_mDisable(BaseAddress) \
|
||||
XIo_Out32((BaseAddress) + XEM_ECR_OFFSET, \
|
||||
XIo_In32((BaseAddress) + XEM_ECR_OFFSET) & \
|
||||
~(XEM_ECR_XMIT_ENABLE_MASK | XEM_ECR_RECV_ENABLE_MASK))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* 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 None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmac_mIsTxDone(BaseAddress) \
|
||||
(XIo_In32((BaseAddress) + XEM_ISR_OFFSET) & XEM_EIR_XMIT_DONE_MASK)
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Check to see if the receive FIFO is empty.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device
|
||||
*
|
||||
* @return TRUE if it is empty, or FALSE if it is not.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmac_mIsRxEmpty(BaseAddress) \
|
||||
(!(XIo_In32((BaseAddress) + XEM_ISR_OFFSET) & XEM_EIR_RECV_DONE_MASK))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Reset MII compliant PHY
|
||||
*
|
||||
* @param BaseAddress is the base address of the device
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmac_mPhyReset(BaseAddress) \
|
||||
{ \
|
||||
u32 Control; \
|
||||
Control = XIo_In32((BaseAddress) + XEM_ECR_OFFSET); \
|
||||
Control &= ~XEM_ECR_PHY_ENABLE_MASK; \
|
||||
XIo_Out32((BaseAddress) + XEM_ECR_OFFSET, Control); \
|
||||
Control |= XEM_ECR_PHY_ENABLE_MASK; \
|
||||
XIo_Out32((BaseAddress) + XEM_ECR_OFFSET, Control); \
|
||||
}
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
void XEmac_SendFrame(u32 BaseAddress, u8 * FramePtr, int Size);
|
||||
int XEmac_RecvFrame(u32 BaseAddress, u8 * FramePtr);
|
||||
|
||||
#endif /* end of protection macro */
|
@ -1,318 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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;
|
||||
}
|
@ -1,482 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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_polled.c
|
||||
*
|
||||
* Contains functions used when the driver is in polled mode. Use the
|
||||
* XEmac_SetOptions() function to put the driver into polled mode.
|
||||
*
|
||||
* <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"
|
||||
#include "xipif_v1_23_b.h" /* Uses v1.23b of the IPIF */
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Send an Ethernet frame in polled mode. The device/driver must be in polled
|
||||
* mode before calling this function. The driver writes the frame directly to
|
||||
* the MAC's packet FIFO, then enters a loop checking the device status for
|
||||
* completion or error. Statistics are updated if an error occurs. The buffer
|
||||
* to be sent must be word-aligned.
|
||||
*
|
||||
* It is assumed that the upper layer software supplies a correctly formatted
|
||||
* Ethernet frame, including the destination and source addresses, the
|
||||
* type/length field, and the data field. It is also assumed that upper layer
|
||||
* software does not append FCS at the end of the frame.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
* @param BufPtr is a pointer to a word-aligned buffer containing the Ethernet
|
||||
* frame to be sent.
|
||||
* @param ByteCount is the size of the Ethernet frame.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* - XST_SUCCESS if the frame was sent successfully
|
||||
* - XST_DEVICE_IS_STOPPED if the device has not yet been started
|
||||
* - XST_NOT_POLLED if the device is not in polled mode
|
||||
* - XST_FIFO_NO_ROOM if there is no room in the EMAC's length FIFO for this frame
|
||||
* - XST_FIFO_ERROR if the FIFO was overrun or underrun. This error is critical
|
||||
* and requires the caller to reset the device.
|
||||
* - XST_EMAC_COLLISION if the send failed due to excess deferral or late
|
||||
* collision
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* There is the possibility that this function will not return if the hardware
|
||||
* is broken (i.e., it never sets the status bit indicating that transmission is
|
||||
* done). If this is of concern to the user, the user should provide protection
|
||||
* from this problem - perhaps by using a different timer thread to monitor the
|
||||
* PollSend thread. On a 10Mbps MAC, it takes about 1.21 msecs to transmit a
|
||||
* maximum size Ethernet frame (1518 bytes). On a 100Mbps MAC, it takes about
|
||||
* 121 usecs to transmit a maximum size Ethernet frame.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* The EMAC uses FIFOs behind its length and status registers. For this reason,
|
||||
* it is important to keep the length, status, and data FIFOs in sync when
|
||||
* reading or writing to them.
|
||||
*
|
||||
******************************************************************************/
|
||||
XStatus
|
||||
XEmac_PollSend(XEmac * InstancePtr, u8 * BufPtr, u32 ByteCount)
|
||||
{
|
||||
u32 IntrStatus;
|
||||
u32 XmitStatus;
|
||||
XStatus Result;
|
||||
|
||||
XASSERT_NONVOID(InstancePtr != NULL);
|
||||
XASSERT_NONVOID(BufPtr != NULL);
|
||||
XASSERT_NONVOID(ByteCount > XEM_HDR_SIZE); /* send at least 1 byte */
|
||||
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Be sure the device is configured for polled mode and it is started
|
||||
*/
|
||||
if (!InstancePtr->IsPolled) {
|
||||
return XST_NOT_POLLED;
|
||||
}
|
||||
|
||||
if (InstancePtr->IsStarted != XCOMPONENT_IS_STARTED) {
|
||||
return XST_DEVICE_IS_STOPPED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for overruns and underruns for the transmit status and length
|
||||
* FIFOs and make sure the send packet FIFO is not deadlocked. Any of these
|
||||
* conditions is bad enough that we do not want to continue. The upper layer
|
||||
* software should reset the device to resolve the error.
|
||||
*/
|
||||
IntrStatus = XIIF_V123B_READ_IISR(InstancePtr->BaseAddress);
|
||||
|
||||
/*
|
||||
* Overrun errors
|
||||
*/
|
||||
if (IntrStatus & (XEM_EIR_XMIT_SFIFO_OVER_MASK |
|
||||
XEM_EIR_XMIT_LFIFO_OVER_MASK)) {
|
||||
InstancePtr->Stats.XmitOverrunErrors++;
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
return XST_FIFO_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Underrun errors
|
||||
*/
|
||||
if (IntrStatus & (XEM_EIR_XMIT_SFIFO_UNDER_MASK |
|
||||
XEM_EIR_XMIT_LFIFO_UNDER_MASK)) {
|
||||
InstancePtr->Stats.XmitUnderrunErrors++;
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
return XST_FIFO_ERROR;
|
||||
}
|
||||
|
||||
if (XPF_V100B_IS_DEADLOCKED(&InstancePtr->SendFifo)) {
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
return XST_FIFO_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Before writing to the data FIFO, make sure the length FIFO is not
|
||||
* full. The data FIFO might not be full yet even though the length FIFO
|
||||
* is. This avoids an overrun condition on the length FIFO and keeps the
|
||||
* FIFOs in sync.
|
||||
*/
|
||||
if (IntrStatus & XEM_EIR_XMIT_LFIFO_FULL_MASK) {
|
||||
/*
|
||||
* Clear the latched LFIFO_FULL bit so next time around the most
|
||||
* current status is represented
|
||||
*/
|
||||
XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress,
|
||||
XEM_EIR_XMIT_LFIFO_FULL_MASK);
|
||||
return XST_FIFO_NO_ROOM;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a non-blocking write. The packet FIFO returns an error if there
|
||||
* is not enough room in the FIFO for this frame.
|
||||
*/
|
||||
Result =
|
||||
XPacketFifoV100b_Write(&InstancePtr->SendFifo, BufPtr, ByteCount);
|
||||
if (Result != XST_SUCCESS) {
|
||||
return Result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Loop on the MAC's status to wait for any pause to complete.
|
||||
*/
|
||||
IntrStatus = XIIF_V123B_READ_IISR(InstancePtr->BaseAddress);
|
||||
|
||||
while ((IntrStatus & XEM_EIR_XMIT_PAUSE_MASK) != 0) {
|
||||
IntrStatus = XIIF_V123B_READ_IISR(InstancePtr->BaseAddress);
|
||||
/*
|
||||
* Clear the pause status from the transmit status register
|
||||
*/
|
||||
XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress,
|
||||
IntrStatus & XEM_EIR_XMIT_PAUSE_MASK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the MAC's transmit packet length register to tell it to transmit
|
||||
*/
|
||||
XIo_Out32(InstancePtr->BaseAddress + XEM_TPLR_OFFSET, ByteCount);
|
||||
|
||||
/*
|
||||
* Loop on the MAC's status to wait for the transmit to complete. The
|
||||
* transmit status is in the FIFO when the XMIT_DONE bit is set.
|
||||
*/
|
||||
do {
|
||||
IntrStatus = XIIF_V123B_READ_IISR(InstancePtr->BaseAddress);
|
||||
}
|
||||
while ((IntrStatus & XEM_EIR_XMIT_DONE_MASK) == 0);
|
||||
|
||||
XmitStatus = XIo_In32(InstancePtr->BaseAddress + XEM_TSR_OFFSET);
|
||||
|
||||
InstancePtr->Stats.XmitFrames++;
|
||||
InstancePtr->Stats.XmitBytes += ByteCount;
|
||||
|
||||
/*
|
||||
* Check for various errors, bump statistics, and return an error status.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Overrun errors
|
||||
*/
|
||||
if (IntrStatus & (XEM_EIR_XMIT_SFIFO_OVER_MASK |
|
||||
XEM_EIR_XMIT_LFIFO_OVER_MASK)) {
|
||||
InstancePtr->Stats.XmitOverrunErrors++;
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
return XST_FIFO_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Underrun errors
|
||||
*/
|
||||
if (IntrStatus & (XEM_EIR_XMIT_SFIFO_UNDER_MASK |
|
||||
XEM_EIR_XMIT_LFIFO_UNDER_MASK)) {
|
||||
InstancePtr->Stats.XmitUnderrunErrors++;
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
return XST_FIFO_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear the interrupt status register of transmit statuses
|
||||
*/
|
||||
XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress,
|
||||
IntrStatus & XEM_EIR_XMIT_ALL_MASK);
|
||||
|
||||
/*
|
||||
* Collision errors are stored in the transmit status register
|
||||
* instead of the interrupt status register
|
||||
*/
|
||||
if (XmitStatus & XEM_TSR_EXCESS_DEFERRAL_MASK) {
|
||||
InstancePtr->Stats.XmitExcessDeferral++;
|
||||
return XST_EMAC_COLLISION_ERROR;
|
||||
}
|
||||
|
||||
if (XmitStatus & XEM_TSR_LATE_COLLISION_MASK) {
|
||||
InstancePtr->Stats.XmitLateCollisionErrors++;
|
||||
return XST_EMAC_COLLISION_ERROR;
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Receive an Ethernet frame in polled mode. The device/driver must be in polled
|
||||
* mode before calling this function. The driver receives the frame directly
|
||||
* from the MAC's packet FIFO. This is a non-blocking receive, in that if there
|
||||
* is no frame ready to be received at the device, the function returns with an
|
||||
* error. The MAC's error status is not checked, so statistics are not updated
|
||||
* for polled receive. The buffer into which the frame will be received must be
|
||||
* word-aligned.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
* @param BufPtr is a pointer to a word-aligned buffer into which the received
|
||||
* Ethernet frame will be copied.
|
||||
* @param ByteCountPtr is both an input and an output parameter. It is a pointer
|
||||
* to a 32-bit word that contains the size of the buffer on entry into the
|
||||
* function and the size the received frame on return from the function.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* - XST_SUCCESS if the frame was sent successfully
|
||||
* - XST_DEVICE_IS_STOPPED if the device has not yet been started
|
||||
* - XST_NOT_POLLED if the device is not in polled mode
|
||||
* - XST_NO_DATA if there is no frame to be received from the FIFO
|
||||
* - XST_BUFFER_TOO_SMALL if the buffer to receive the frame is too small for
|
||||
* the frame waiting in the FIFO.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Input buffer must be big enough to hold the largest Ethernet frame. Buffer
|
||||
* must also be 32-bit aligned.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* The EMAC uses FIFOs behind its length and status registers. For this reason,
|
||||
* it is important to keep the length, status, and data FIFOs in sync when
|
||||
* reading or writing to them.
|
||||
*
|
||||
******************************************************************************/
|
||||
XStatus
|
||||
XEmac_PollRecv(XEmac * InstancePtr, u8 * BufPtr, u32 * ByteCountPtr)
|
||||
{
|
||||
XStatus Result;
|
||||
u32 PktLength;
|
||||
u32 IntrStatus;
|
||||
|
||||
XASSERT_NONVOID(InstancePtr != NULL);
|
||||
XASSERT_NONVOID(BufPtr != NULL);
|
||||
XASSERT_NONVOID(ByteCountPtr != NULL);
|
||||
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Be sure the device is configured for polled mode and it is started
|
||||
*/
|
||||
if (!InstancePtr->IsPolled) {
|
||||
return XST_NOT_POLLED;
|
||||
}
|
||||
|
||||
if (InstancePtr->IsStarted != XCOMPONENT_IS_STARTED) {
|
||||
return XST_DEVICE_IS_STOPPED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure the buffer is big enough to hold the maximum frame size.
|
||||
* We need to do this because as soon as we read the MAC's packet length
|
||||
* register, which is actually a FIFO, we remove that length from the
|
||||
* FIFO. We do not want to read the length FIFO without also reading the
|
||||
* data FIFO since this would get the FIFOs out of sync. So we have to
|
||||
* make this restriction.
|
||||
*/
|
||||
if (*ByteCountPtr < XEM_MAX_FRAME_SIZE) {
|
||||
return XST_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
/*
|
||||
* First check for packet FIFO deadlock and return an error if it has
|
||||
* occurred. A reset by the caller is necessary to correct this problem.
|
||||
*/
|
||||
if (XPF_V100B_IS_DEADLOCKED(&InstancePtr->RecvFifo)) {
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
return XST_FIFO_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the interrupt status to know what happened (whether an error occurred
|
||||
* and/or whether frames have been received successfully). When clearing the
|
||||
* intr status register, clear only statuses that pertain to receive.
|
||||
*/
|
||||
IntrStatus = XIIF_V123B_READ_IISR(InstancePtr->BaseAddress);
|
||||
XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress,
|
||||
IntrStatus & XEM_EIR_RECV_ALL_MASK);
|
||||
|
||||
/*
|
||||
* Check receive errors and bump statistics so the caller will have a clue
|
||||
* as to why data may not have been received. We continue on if an error
|
||||
* occurred since there still may be frames that were received successfully.
|
||||
*/
|
||||
if (IntrStatus & (XEM_EIR_RECV_LFIFO_OVER_MASK |
|
||||
XEM_EIR_RECV_DFIFO_OVER_MASK)) {
|
||||
InstancePtr->Stats.RecvOverrunErrors++;
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_LFIFO_UNDER_MASK) {
|
||||
InstancePtr->Stats.RecvUnderrunErrors++;
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
}
|
||||
|
||||
/*
|
||||
* General receive errors
|
||||
*/
|
||||
if (IntrStatus & XEM_EIR_RECV_ERROR_MASK) {
|
||||
if (IntrStatus & XEM_EIR_RECV_MISSED_FRAME_MASK) {
|
||||
InstancePtr->Stats.RecvMissedFrameErrors =
|
||||
XIo_In32(InstancePtr->BaseAddress +
|
||||
XEM_RMFC_OFFSET);
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_COLLISION_MASK) {
|
||||
InstancePtr->Stats.RecvCollisionErrors =
|
||||
XIo_In32(InstancePtr->BaseAddress + XEM_RCC_OFFSET);
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_FCS_ERROR_MASK) {
|
||||
InstancePtr->Stats.RecvFcsErrors =
|
||||
XIo_In32(InstancePtr->BaseAddress +
|
||||
XEM_RFCSEC_OFFSET);
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_LEN_ERROR_MASK) {
|
||||
InstancePtr->Stats.RecvLengthFieldErrors++;
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_SHORT_ERROR_MASK) {
|
||||
InstancePtr->Stats.RecvShortErrors++;
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_LONG_ERROR_MASK) {
|
||||
InstancePtr->Stats.RecvLongErrors++;
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_ALIGN_ERROR_MASK) {
|
||||
InstancePtr->Stats.RecvAlignmentErrors =
|
||||
XIo_In32(InstancePtr->BaseAddress +
|
||||
XEM_RAEC_OFFSET);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Before reading from the length FIFO, make sure the length FIFO is not
|
||||
* empty. We could cause an underrun error if we try to read from an
|
||||
* empty FIFO.
|
||||
*/
|
||||
if ((IntrStatus & XEM_EIR_RECV_DONE_MASK) == 0) {
|
||||
return XST_NO_DATA;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine, from the MAC, the length of the next packet available
|
||||
* in the data FIFO (there should be a non-zero length here)
|
||||
*/
|
||||
PktLength = XIo_In32(InstancePtr->BaseAddress + XEM_RPLR_OFFSET);
|
||||
if (PktLength == 0) {
|
||||
return XST_NO_DATA;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the RECV_DONE bit in the status register to clear it. This bit
|
||||
* indicates the RPLR is non-empty, and we know it's set at this point.
|
||||
* We clear it so that subsequent entry into this routine will reflect the
|
||||
* current status. This is done because the non-empty bit is latched in the
|
||||
* IPIF, which means it may indicate a non-empty condition even though
|
||||
* there is something in the FIFO.
|
||||
*/
|
||||
XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress, XEM_EIR_RECV_DONE_MASK);
|
||||
|
||||
/*
|
||||
* We assume that the MAC never has a length bigger than the largest
|
||||
* Ethernet frame, so no need to make another check here.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is a non-blocking read. The FIFO returns an error if there is
|
||||
* not at least the requested amount of data in the FIFO.
|
||||
*/
|
||||
Result =
|
||||
XPacketFifoV100b_Read(&InstancePtr->RecvFifo, BufPtr, PktLength);
|
||||
if (Result != XST_SUCCESS) {
|
||||
return Result;
|
||||
}
|
||||
|
||||
InstancePtr->Stats.RecvFrames++;
|
||||
InstancePtr->Stats.RecvBytes += PktLength;
|
||||
|
||||
*ByteCountPtr = PktLength;
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
Loading…
Reference in New Issue
Block a user