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 + -
显示快捷键?