⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 at91rm9200_ether.c

📁 ecos在9200上redboot实现
💻 C
📖 第 1 页 / 共 2 页
字号:
//==========================================================================////      at91rm9200_ether.c////////==========================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.//// eCos 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 or (at your option) any later version.//// eCos is distributed in the hope that it will be useful, but WITHOUT ANY// WARRANTY; without even the implied warranty of MERCHANTABILITY or// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License// for more details.//// You should have received a copy of the GNU General Public License along// with eCos; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.//// As a special exception, if other files instantiate templates or use macros// or inline functions from this file, or you compile this file and link it// with other works to produce a work based on this file, this file does not// by itself cause the resulting work to be covered by the GNU General Public// License. However the source code for this file must still be made available// in accordance with section (3) of the GNU General Public License.//// This exception does not invalidate any other reasons why a work based on// this file might be covered by the GNU General Public License.//// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.// at http://sources.redhat.com/ecos/ecos-license/// -------------------------------------------//####ECOSGPLCOPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s):    Jiun-Shian H. <asky@syncom.com.tw>// Contributors: Jiun-Shian H. <asky@syncom.com.tw>// Date:         2005-08-10// Purpose:// Description:////####DESCRIPTIONEND####////========================================================================*/#include <pkgconf/hal.h>#include <pkgconf/system.h>#include <cyg/hal/hal_io.h>             // IO macros#include <pkgconf/devs_eth_arm_at91rm9200.h>#include <pkgconf/io_eth_drivers.h>#include <errno.h>#if defined(CYGPKG_IO)#include <pkgconf/io.h>#include <cyg/io/io.h>#include <cyg/io/devtab.h>#endif// need to provide fake values for errno?#ifndef EIO# define EIO 1#endif#ifndef EINVAL# define EINVAL 2#endif#include <cyg/infra/cyg_type.h>  // Common type definitions and support                                 // including endian-ness#include <cyg/infra/diag.h>#include <cyg/io/eth/netdev.h>#include <cyg/io/eth/eth_drv.h>#include <cyg/io/eth/eth_drv_stats.h>#include <cyg/hal/hal_intr.h>#include <cyg/hal/hal_arch.h>#include <cyg/hal/drv_api.h>#if defined(CYGPKG_REDBOOT)#include <pkgconf/redboot.h>#endif#ifndef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED#define cyg_drv_interrupt_unmask(v) /* noop */#define cyg_drv_interrupt_mask(v)   /* noop */#define cyg_drv_isr_lock()          /* noop */#define cyg_drv_isr_unlock()        /* noop */#define cyg_drv_mutex_init(m)       /* noop */#define cyg_drv_mutex_lock(m)       /* noop */#define cyg_drv_mutex_unlock(m)     /* noop */#define cyg_drv_dsr_lock()          /* noop */#define cyg_drv_dsr_unlock()        /* noop */#endif#define HavePHYinterrupt 0#include "std.h"#include "at91rm9200_regs.h"#include "at91rm9200_ether.h"#if CYGINT_DEVS_ETH_ARM_AT91RM9200_PHY#include "phy.h"#endif// Set up the level of debug output#if CYGPKG_DEVS_ETH_ARM_AT91RM9200_DEBUG_LEVEL > 0#define debug1_printf(args...) diag_printf(args)#else#define debug1_printf(args...) /* noop */#endif#if CYGPKG_DEVS_ETH_ARM_AT91RM9200_DEBUG_LEVEL > 1#define debug2_printf(args...) diag_printf(args)#else#define debug2_printf(args...) /* noop */#endif#define Bit(n) (1<<(n))// enable/disable software verification of rx CRC// should be moved to user-controlled valud in CDL file#if defined(CYG_HAL_CPUTYPE_AT91RM9200A)#define SoftwareCRC 1#include <cyg/crc/crc.h>#else#define SoftwareCRC 0#endif// --------------------------------------------------------------// RedBoot configuration options for managing ESAs for us// Decide whether to have redboot config vars for it...#if defined(CYGSEM_REDBOOT_FLASH_CONFIG) && defined(CYGPKG_REDBOOT_NETWORKING)#include <redboot.h>#include <flash_config.h>#ifdef CYGSEM_DEVS_ETH_ARM_AT91RM9200_REDBOOT_HOLDS_ESA_ETH0RedBoot_config_option("Network hardware address [MAC] for eth0",                      eth0_esa_data,                      ALWAYS_ENABLED, true,                      CONFIG_ESA, 0);#endif#endif  // CYGPKG_REDBOOT_NETWORKING && CYGSEM_REDBOOT_FLASH_CONFIG// and initialization code to read them// - independent of whether we are building RedBoot right now:#ifdef CYGPKG_DEVS_ETH_ARM_AT91RM9200_REDBOOT_HOLDS_ESA#include <cyg/hal/hal_if.h>#ifndef CONFIG_ESA#define CONFIG_ESA (6)#endif#define CYGHWR_DEVS_ETH_ARM_AT91RM9200_GET_ESA( mac_address, ok )                 \CYG_MACRO_START                                                                  \    ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET,              \                                      "eth0_esa_data", mac_address, CONFIG_ESA); \CYG_MACRO_END#endif // CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA//============================================================================// Private Datatypedef struct{  cyg_uint32 phy_type;}at91rm9200_priv_data_t;at91rm9200_priv_data_t at91rm9200_priv_data;#define eth_drv_tx_done(sc,key,retval) \          (sc)->funs->eth_drv->tx_done(sc,key,retval)#define eth_drv_init(sc,enaddr) \          ((sc)->funs->eth_drv->init)(sc, enaddr)#define eth_drv_recv(sc,len)  \          ((sc)->funs->eth_drv->recv)(sc, len)#define ETH_HEADER_SIZE   (14)/* cf. Table 30-4. Received Buffer Descriptor List */#if 0typedef struct  {    unsigned long   owner : 1,    /* Ownership bit.                                     1 indicates software owns the pointer,                                     0 indicates that the DMA owns the buffer.                                  */                    wrap : 1,     /* Wrap bit. ... */                    addr : 30;    /* 31:2 Base address of receive buffer */    unsigned long   len : 11,     /* Length of frame including FCS */                    reserved : 12,                    sa4 : 1,      /* Local address match (Specific address 4 match) */                    sa3 : 1,      /* Local address match (Specific address 3 match) */                    sa2 : 1,      /* Local address match (Specific address 2 match) */                    sa1 : 1,      /* Local address match (Specific address 1 match) */                    unknown: 1,   /* Unknown source address  */                    ext_addr : 1, /* External Address */                    uc : 1,       /* Unicast */                    mc : 1,       /* Multicast */                    bc : 1;       /* Broadcast */  } rbf_t;#elsetypedef struct  {    unsigned int addr;    unsigned long len;  } rbf_t;#endif /* 0/1 *//* Word 0 */#define RBF_OWNER     (0x01 << 0)#define RBF_WRAP      (0x01 << 1)/* Word 1 */#define RBF_LEN       (0x7FF)#define RBF_SA4       (0x01 << 23)#define RBF_SA3       (0x01 << 24)#define RBF_SA2       (0x01 << 25)#define RBF_SA1       (0x01 << 26)#define RBF_UNKOWN    (0x01 << 27)#define RBF_EXTERNAL  (0x01 << 28)#define RBF_UNICAST   (0x01 << 29)#define RBF_MULTICAST (0x01 << 30)#define RBF_BROADCAST (0x01 << 31)#if _SDRAM_64M_/* 0x23F00000 - 0x23FFFFFF */#define START_RXBUFF    (0x23F00000)#define STOP_RXBUFF     (0x24000000 )#else /* _SDRAM_32M_ *//* 0x21F00000 - 0x21FFFFFF */#define START_RXBUFF    (0x21F00000)#define STOP_RXBUFF     (0x22000000)#endif /* _SDRAM_SIZE_ *//* Root of Rx buffer descriptor */#define RXBUFF_DES    (START_RXBUFF)#define RXBUFF_SIZE   (0x600)//#define RXBUF_NUM     ((STOP_RXBUFF - START_RXBUFF) / RXBUFF_SIZE)#define RXBUF_NUM     (12)#define BASE_RXBUFF   (START_RXBUFF + 0x2000)/* Root of Rx Buffer descriptor */rbf_t *rbf_des;/* Current pointer of Rx Buffer */rbf_t *rbf_ptr;//============================================================================#if CYGINT_DEVS_ETH_ARM_AT91RM9200_PHY// functions to read/write Phy chip registers via MII/RMII interfacevoidwrite_phy(cyg_uint32 phy_addr, cyg_uint32 reg_addr, cyg_uint32 Data){  cyg_uint32 val;  val = C_EMAC_HIGH | C_EMAC_CODE_802_3 | C_EMAC_RW_W        | ((phy_addr & 0x1F) << 23) | (reg_addr << 18) | (Data & 0xFFFF);  HAL_WRITE_UINT32((BASE_EMAC+EMAC_MAN), val);  /* FixMe */#if 1  for (val = 0; val < 0x5000; val++)    {;}#else  /* Wait until IDLE bit in Network Status register is cleared */  // TODO: Enforce some maximum loop-count?  while (1)    {      HAL_READ_UINT32((BASE_EMAC+EMAC_SR), val);      if (!(val & C_EMAC_IDLE))        break;    }#endif /* 0/1 */  //debug1_printf("PHY Wr %x:%02x := %04x\n",PhyAddr, RegAddr, PhyWrData) ;}cyg_uint32read_phy(cyg_uint32 phy_addr, cyg_uint32 reg_addr){  cyg_uint32 val;  val = C_EMAC_HIGH | C_EMAC_CODE_802_3 | C_EMAC_RW_R        | ((phy_addr & 0x1F) << 23) | (reg_addr << 18);  HAL_WRITE_UINT32((BASE_EMAC+EMAC_MAN), val);  /* FixMe */#if 1  for (val = 0; val < 0x5000; val++)    {;}#else  /* Wait until IDLE bit in Network Status register is cleared */  // TODO: Enforce some maximum loop-count?  while (1)    {      HAL_READ_UINT32((BASE_EMAC+EMAC_SR), val);      if (!(val & C_EMAC_IDLE))        break;    }#endif /* 0/1 */  HAL_READ_UINT32((BASE_EMAC+EMAC_MAN), val);  val &= 0x0000FFFF;  //debug1_printf("PHY Rd %x:%02x  %04x\n",PhyAddr,RegAddr,PhyRdData) ;  return val ;}#endif/* * Enable the MDIO bit in MAC control register * When not called from an interrupt-handler, access to the PHY must be *  protected by a spinlock. */static void enable_mdi(void){  cyg_uint32 val;  HAL_READ_UINT32((BASE_EMAC+EMAC_CTL), val);  val |= C_EMAC_MPE;    /* enable management port */  HAL_WRITE_UINT32((BASE_EMAC+EMAC_CTL), val);}/* * Disable the MDIO bit in the MAC control register */static void disable_mdi(void){  cyg_uint32 val;  HAL_READ_UINT32((BASE_EMAC+EMAC_CTL), val);  val &= ~C_EMAC_MPE;    /* disable management port */  HAL_WRITE_UINT32((BASE_EMAC+EMAC_CTL), val);}// miscellaneous data structures#if defined(CYGPKG_NET)struct ether_drv_stats ifStats;#endif#if defined(CYGINT_IO_ETH_INT_SUPPORT_REQUIRED)static cyg_drv_mutex_t txMutex;#endifstatic cyg_drv_mutex_t oldRxMutex;static cyg_drv_cond_t  oldRxCond;static bool configDone;/*---------------------------------------------------------------------- * Data structures used to manage ethernet buffers */#ifdef  _CFG_BIG_#define MAX_ETH_FRAME_SIZE  (1522)#else#define MAX_ETH_FRAME_SIZE  (1518)#endif  /* _CFG_BIG_ *///======================================================================voidinit_phy (void){  cyg_uint32  val;  enable_mdi();  if (at91rm9200_priv_data.phy_type == MII_DM9161_ID)    {/* Codes from U-Boot */#define DM9161_MDINTR           21      /* Specified Interrupt Register *//*--Bit definitions: DM9161_MDINTR */#define DM9161_INTR_PEND       (1 << 15)#define DM9161_FDX_MASK        (1 << 11)#define DM9161_SPD_MASK        (1 << 10)#define DM9161_LINK_MASK       (1 << 9)#define DM9161_INTR_MASK       (1 << 8)#define DM9161_FDX_CHANGE      (1 << 4)#define DM9161_SPD_CHANGE      (1 << 3)#define DM9161_LINK_CHANGE     (1 << 2)#define DM9161_INTR_STATUS     (1 << 0)      /* Disable PHY Interrupts */      val = read_phy(0, DM9161_MDINTR);#if 0      /* Unmask/Clear FDX, SPD, Link, INTR masks */      val &= ~(DM9161_FDX_MASK |               DM9161_SPD_MASK |               DM9161_LINK_MASK |               DM9161_INTR_MASK);#else      /* Mask/Set FDX, SPD, Link, INTR masks */      val |= (DM9161_FDX_MASK |              DM9161_SPD_MASK |              DM9161_LINK_MASK |              DM9161_INTR_MASK);#endif /* 0/1 */      write_phy(0, DM9161_MDINTR, val);    }  else    {      /* More PHY type */    }  disable_mdi();}//----------------------------------------------------------------------//======================================================================//======================================================================static int EthInit(U08* mac_address){#if CYGINT_DEVS_ETH_ARM_AT91RM9200_PHY && defined(CYGPKG_NET)  unsigned linkStatus;#endif  if (mac_address)    debug2_printf("EthInit(%02x:%02x:%02x:%02x:%02x:%02x)\n",                mac_address[0],mac_address[1],mac_address[2],                mac_address[3],mac_address[4],mac_address[5]);  else    debug2_printf("EthInit(NULL)\n");#if CYGINT_DEVS_ETH_ARM_AT91RM9200_PHY//  PhyReset();#endif  // set up our MAC address, FIXME: SA2 work  if (mac_address)    {      HAL_WRITE_UINT32((BASE_EMAC+EMAC_SA1L),                       ((mac_address[0] << 24) |                        (mac_address[1] << 16) |                        (mac_address[2] <<  8) |                        (mac_address[3])));      HAL_WRITE_UINT32((BASE_EMAC+EMAC_SA1H),                       ((mac_address[4] <<  8) |                        (mac_address[5])));#if 0      HAL_WRITE_UINT32((BASE_EMAC+EMAC_SA2L), 0);      HAL_WRITE_UINT32((BASE_EMAC+EMAC_SA2H), 0);#else      HAL_WRITE_UINT32((BASE_EMAC+EMAC_SA2L),                       ((mac_address[3] << 24) |                        (mac_address[2] << 16) |                        (mac_address[1] <<  8) |                        (mac_address[0])));      HAL_WRITE_UINT32((BASE_EMAC+EMAC_SA2H),                       ((mac_address[5] <<  8) |                        (mac_address[4])));#endif /* 0/1 */    }#if CYGINT_DEVS_ETH_ARM_AT91RM9200_PHY && defined(CYGPKG_NET)// FIXME#endif  return 0;}//======================================================================#if CYGINT_DEVS_ETH_ARM_AT91RM9200_PHY#if HavePHYinterrupt// FIXME: PHY ISR#endif#endifstatic void at91rm9200_handle_tx_complete(void){//  diag_printf("at91rm9200_handle_tx_complete().......\n");#if 0#if defined(CYGPKG_NET)#endif#endif /* 0/1 */}//======================================================================static cyg_uint32at91rm9200_eth_isr (cyg_vector_t vector, cyg_addrword_t data){  /* Interrupt Status Register, read and clear */  cyg_uint32 int_status;  cyg_uint32 val;//  diag_printf("at91rm9200_eth_isr().......\n");  HAL_READ_UINT32((BASE_PMC+EMAC_ISR), int_status);  /* Receive complete */  if (int_status & C_EMAC_RCOM)    {//      diag_printf("Receive complete.......\n");    }  /* Transmit complete */  if (int_status & C_EMAC_TCOM)    {      diag_printf("Transmit complete.......\n");    }  /* Work-around for Errata #11 */  if (int_status & C_EMAC_RBNA)    {      /* Receive Buffer Not Available, Reset "Receive Enabl" */      HAL_READ_UINT32((BASE_PMC+EMAC_CTL), val);      val &= ~C_EMAC_RE;      HAL_WRITE_UINT32((BASE_PMC+EMAC_CTL), val);      val |= C_EMAC_RE;      HAL_WRITE_UINT32((BASE_PMC+EMAC_CTL), val);    }  /* RX Overrun */  if (int_status & C_EMAC_ROVR)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -