xemacif.c
来自「Keil下移植好的lwip基于c166」· C语言 代码 · 共 512 行 · 第 1/2 页
C
512 行
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Copyright (c) 2001, 2002 Xilinx, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS".
* 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 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.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Chris Borrelli <chris.borrelli@xilinx.com>
*
* Based on example ethernetif.c, Adam Dunkels <adam@sics.se>
*
*/
/*---------------------------------------------------------------------------*/
/* V2PDK Include Files */
/*---------------------------------------------------------------------------*/
#include "xemac.h"
#include "xparameters.h"
#include "xstatus.h"
#include "xintc.h"
#include "exception.h"
/*---------------------------------------------------------------------------*/
/* LWIP Include Files */
/*---------------------------------------------------------------------------*/
#include "lwip/debug.h"
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include "lwip/netif.h"
#include "netif/etharp.h"
#include "netif/xemacif.h"
/*---------------------------------------------------------------------------*/
/* Describe network interface */
/*---------------------------------------------------------------------------*/
#define IFNAME0 'e'
#define IFNAME1 '0'
/*---------------------------------------------------------------------------*/
/* Constant Definitions */
/*---------------------------------------------------------------------------*/
#define EMAC_INTR_ID 28 /* Interrupt ID for EMAC */
#define XEM_MAX_FRAME_SIZE_IN_WORDS ((XEM_MAX_FRAME_SIZE/sizeof(Xuint32))+1)
/*---------------------------------------------------------------------------*/
/* xemacif structure */
/* contains the ethernet address and the */
/* pointer to the instance of the Xilinx */
/* EMAC driver. */
/*---------------------------------------------------------------------------*/
struct xemacif {
struct eth_addr *ethaddr;
XEmac *instance_ptr;
};
static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
static struct eth_addr mymac = {{0x00,0x0A,0x35,0x00,0x22,0x20}};
/*---------------------------------------------------------------------------*/
/* Forward declarations */
/*---------------------------------------------------------------------------*/
static err_t xemacif_output(struct netif *netif, struct pbuf *p,
struct ip_addr *ipaddr);
#ifdef LWIP_XEMAC_USE_INTMODE
static void FifoSendHandler(void *CallBackRef);
static void ErrorHandler(void *CallBackRef, XStatus Code);
#endif /* LWIP_XEMAC_USE_INTMODE */
/*---------------------------------------------------------------------------*/
/* low_level_init function */
/* - hooks up the data structures and sets the mac options and mac */
/*---------------------------------------------------------------------------*/
static err_t
low_level_init(struct netif *netif_ptr)
{
XIntc *IntcInstancePtr;
XEmac * InstancePtr;
Xuint16 DeviceId = XPAR_EMAC_0_DEVICE_ID; /* from xparameters.h */
#ifdef LWIP_XEMAC_USE_INTMODE
Xuint16 IntcDeviceId = XPAR_INTC_0_DEVICE_ID;
#endif /* LWIP_XEMAC_USE_INTMODE */
XStatus Result;
Xuint32 Options;
struct xemacif *xemacif_ptr;
xemacif_ptr = netif_ptr->state;
/* Get Instance of EMAC Driver */
xemacif_ptr->instance_ptr = InstancePtr = XEmac_GetInstance(0);
#ifdef LWIP_XEMAC_USE_INTMODE
/* Get Instance of Interrupt Controller Driver */
IntcInstancePtr = XIntc_GetInstance(0);
#endif /* LWIP_XEMAC_USE_INTMODE */
/* Call Initialize Function of EMAC driver */
Result = XEmac_Initialize(InstancePtr, DeviceId);
if (Result != XST_SUCCESS) {
return ERR_MEM;
}
#ifdef LWIP_XEMAC_USE_INTMODE
if (XIntc_Initialize(IntcInstancePtr, IntcDeviceId) != XST_SUCCESS) {
return ERR_MEM;
}
#endif /* LWIP_XEMAC_USE_INTMODE */
if (XEmac_IsSgDma(InstancePtr)) {
/* not configured for direct FIFO access */
return ERR_MEM;
}
Result = XEmac_SelfTest(InstancePtr);
if (Result != XST_SUCCESS && Result != XST_DEVICE_IS_STARTED) {
return ERR_MEM;
}
#ifdef LWIP_XEMAC_USE_INTMODE
Result = XIntc_SelfTest(IntcInstancePtr);
if (Result != XST_SUCCESS && Result != XST_DEVICE_IS_STARTED) {
return ERR_MEM;
}
#endif /* LWIP_XEMAC_USE_INTMODE */
/* Stop the EMAC hardware */
(void) XEmac_Stop(InstancePtr);
/* Set MAC Address of EMAC */
Result = XEmac_SetMacAddress(InstancePtr, (Xuint8*) netif_ptr->hwaddr);
if (Result != XST_SUCCESS) return ERR_MEM;
/* Set MAC Options - UNICAST and BROADCAST */
#ifdef LWIP_XEMAC_USE_INTMODE
Options = (XEM_UNICAST_OPTION | XEM_BROADCAST_OPTION);
#else /* LWIP_XEMAC_USE_INTMODE */
Options = (XEM_UNICAST_OPTION | XEM_BROADCAST_OPTION | XEM_POLLED_OPTION);
#endif /* LWIP_XEMAC_USE_INTMODE */
Result = XEmac_SetOptions(InstancePtr, Options);
if (Result != XST_SUCCESS) return ERR_MEM;
#ifdef LWIP_XEMAC_USE_INTMODE
/* Set Callbacks and error handler */
XEmac_SetFifoSendHandler(InstancePtr, netif_ptr, FifoSendHandler);
XEmac_SetFifoRecvHandler(InstancePtr, netif_ptr, xemacif_input);
XEmac_SetErrorHandler(InstancePtr, netif_ptr, ErrorHandler);
/* Connect to the interrupt controller and enable interrupts */
XIntc_Connect(IntcInstancePtr, EMAC_INTR_ID,
XEmac_GetIntrHandler(InstancePtr), InstancePtr);
#endif /* LWIP_XEMAC_USE_INTMODE */
/* Start the EMAC hardware */
Result = XEmac_Start(InstancePtr);
if (Result != XST_SUCCESS)
return ERR_MEM;
#ifdef LWIP_XEMAC_USE_INTMODE
if (XST_SUCCESS != XIntc_Start(IntcInstancePtr))
return ERR_MEM;
XIntc_Enable(IntcInstancePtr, EMAC_INTR_ID);
#endif /* LWIP_XEMAC_USE_INTMODE */
return ERR_OK;
}
#ifdef LWIP_XEMAC_USE_INTMODE
/*---------------------------------------------------------------------------*/
/* FifoSendHandler() */
/* */
/* Checks for Tx Errors */
/* TODO: Add actions. Nothing happens if an error is found. */
/* */
/*---------------------------------------------------------------------------*/
static void FifoSendHandler(void *CallBackRef)
{
struct netif *netif_ptr = (struct netif *) CallBackRef;
XEmac *EmacPtr = ((struct xemacif*) netif_ptr->state)->instance_ptr;
XEmacStats Stats;
/*
* Check stats for transmission errors (overrun or underrun errors are
* caught by the asynchronous error handler).
*/
XEmac_GetStats(EmacPtr, &Stats);
if (Stats.XmitLateCollisionErrors || Stats.XmitExcessDeferral)
;
}
/*---------------------------------------------------------------------------*/
/* ErrorHandler() */
/* */
/* Resets the MAC hardware is an error occurs */
/*---------------------------------------------------------------------------*/
static void ErrorHandler(void *CallBackRef, XStatus Code)
{
struct netif *netif_ptr = (struct netif *) CallBackRef;
XEmac *EmacPtr = ((struct xemacif*) netif_ptr->state)->instance_ptr;
if (Code == XST_RESET_ERROR) {
/*
* A reset error means the application should reset the device because
* it encountered a reset condition (most likely a FIFO overrun, but
* can be other reasons). You can look at the XEmac statistics to
* see what the error is.
*/
XEmac_Reset(EmacPtr);
(void)XEmac_SetMacAddress(EmacPtr, (Xuint8*) netif_ptr->hwaddr);
(void)XEmac_SetOptions(EmacPtr,XEM_UNICAST_OPTION|XEM_BROADCAST_OPTION);
(void)XEmac_Start(EmacPtr);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?