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

📄 at91rm9200_ether.c

📁 ecos在9200上redboot实现
💻 C
📖 第 1 页 / 共 2 页
字号:
    {      diag_printf("EMAC_ROVR!\n");    }//  return CYG_ISR_HANDLED;  return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR);}static cyg_handle_t  at91rm9200_IntHandle;static cyg_interrupt  at91rm9200_IntObject;static int ethernetRunning;#if HavePHYinterruptstatic cyg_handle_t  macPhyIntrHandle;static cyg_interrupt  macPhyIntrObject;#endifstatic void at91rm9200_eth_deliver(struct eth_drv_sc *sc){  extern struct eth_drv_sc at91rm9200_sc;  cyg_uint32 len;  cyg_uint32 val;  cyg_uint32 i;//  diag_printf("at91rm9200_eth_deliver().......\n");  if (!(rbf_ptr->addr & RBF_OWNER))    { return; }  len = rbf_ptr->len & RBF_LEN;  /* Not include Ethernet header and FCS *///  len -= (ETH_HEADER_SIZE + 2);/*  diag_printf("deliver().. len=%d\n",              len);*/  /* Call back: ((sc)->funs->eth_drv->recv)(sc, len) */  eth_drv_recv(&at91rm9200_sc, len);#if 0 /* xxx_recv() clear it */  rbf_ptr->addr &= ~RBF_OWNER;  if (rbf_ptr->addr & RBF_WRAP)    {      rbf_ptr = &rbf_des[0];    }  else    {      rbf_ptr++;    }  HAL_READ_UINT32((BASE_EMAC+EMAC_RSR), val);  val |= C_EMAC_REC;  HAL_WRITE_UINT32((BASE_EMAC+EMAC_RSR), val);#endif /* 0/1 */}static void installInterrupts(void){#if 0  extern struct eth_drv_sc at91rm9200_sc;  static bool firstTime=true;  debug1_printf("at91rm9200_ether: installInterrupts()\n");  if (!firstTime)    return;  firstTime = false;  cyg_drv_mutex_init(&txMutex);  cyg_drv_mutex_init(&oldRxMutex);  cyg_drv_cond_init(&oldRxCond, &oldRxMutex);  cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_EMAC,                           0,                           (unsigned)&at91rm9200_sc,                           at91rm9200_eth_isr,                           eth_drv_dsr,                           &at91rm9200_IntHandle,                           &at91rm9200_IntObject);#if HavePHYinterrupt  // FIXME#endif  cyg_drv_interrupt_attach(at91rm9200_IntHandle);//  cyg_drv_interrupt_attach(bdmaRxIntrHandle);//  cyg_drv_interrupt_attach(bdmaTxIntrHandle);//  cyg_drv_interrupt_attach(macRxIntrHandle);//  cyg_drv_interrupt_attach(macTxIntrHandle);#if HavePHYinterrupt//  cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_EXT0);//  cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_EXT0);#endif#endif /* 0/1 */}//======================================================================// Driver code that interfaces to the TCP/IP stack via the common// Ethernet interface.static bool at91rm9200_eth_init(struct cyg_netdevtab_entry *tab){  struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;  cyg_uint32 i;  cyg_uint32 val;  unsigned char myMacAddr[6] = { CYGPKG_DEVS_ETH_ARM_AT91RM9200_MACADDR };  bool ok;  unsigned int phyid1, phyid2;  unsigned int phy_id;  hal_interrupt_mask(CYGNUM_HAL_INTERRUPT_EMAC);#ifdef CYGHWR_DEVS_ETH_ARM_AT91RM9200_GET_ESA  // Get MAC address from RedBoot configuration variables//  CYGHWR_DEVS_ETH_ARM_AT91RM9200_GET_ESA(&myMacAddr[0], ok);  // If this call fails myMacAddr is unchanged and MAC address from CDL is used#endif//  debug1_printf("at91rm9200_eth_init()\n");  debug1_printf("  MAC address %02x:%02x:%02x:%02x:%02x:%02x\n",myMacAddr[0],myMacAddr[1],myMacAddr[2],myMacAddr[3],myMacAddr[4],myMacAddr[5]);  /* FIXME: For RMII now */  /*  ** Enable pins to be drived by peripheral,  ** PA7 ~ PA16  */  HAL_WRITE_UINT32((BASE_PIOA+PIO_ASR),                   (C_PIO_PA07 | C_PIO_PA08 | C_PIO_PA09 | C_PIO_PA10 |                    C_PIO_PA11 | C_PIO_PA12 | C_PIO_PA13 | C_PIO_PA14 |                    C_PIO_PA15 | C_PIO_PA16));  HAL_WRITE_UINT32((BASE_PIOA+PIO_BSR), 0);  /* Disables the PIO from controlling the corresponding pin    (enables peripheral control of the pin). */  HAL_WRITE_UINT32((BASE_PIOA+PIO_PDR),                   (C_PIO_PA07 | C_PIO_PA08 | C_PIO_PA09 | C_PIO_PA10 |                    C_PIO_PA11 | C_PIO_PA12 | C_PIO_PA13 | C_PIO_PA14 |                    C_PIO_PA15 | C_PIO_PA16));  /* Peripheral Clock Enable Register */  HAL_WRITE_UINT32((BASE_PMC+PMC_PCER), PID24);  /* Enable Peripheral clock in PMC for PIOA */  HAL_WRITE_UINT32((BASE_PMC+PMC_PCER), PID02);  HAL_READ_UINT32((BASE_EMAC+EMAC_CTL), val);  /* Clear statistics */  val |= C_EMAC_CSR;  /* Enable Tx/Rx */  val |= C_EMAC_RE | C_EMAC_TE;  HAL_WRITE_UINT32((BASE_EMAC+EMAC_CTL), val);  /* FIXME: config it after PHY initialization and check */#if 1  /* Set CFG as 100 Mbit/sec, Full Duplex, HCLK divided by 32, RMII*/  val = (C_EMAC_SPD | C_EMAC_FD | C_EMAC_CLK_HCLK_32 | C_EMAC_RMII);  val &= ~C_EMAC_CLK;  HAL_WRITE_UINT32((BASE_EMAC+EMAC_CFG), val);#else  /* Set CFG as 10 Mbit/sec, Half Duplex, HCLK divided by 32, RMII*//*  val = (C_EMAC_CAF |         C_EMAC_CLK_HCLK_32 |         C_EMAC_RMII);*/  val = (C_EMAC_CLK_HCLK_32 |         C_EMAC_RMII);  val &= ~C_EMAC_CLK;  HAL_WRITE_UINT32((BASE_EMAC+EMAC_CFG), val);#endif /* 0/1 */#if 0  /* Enable MAC interrupts */  HAL_WRITE_UINT32((BASE_EMAC+EMAC_IER), 0x0FFF);#else  /* Disable MAC interrupts */  HAL_WRITE_UINT32((BASE_EMAC+EMAC_IDR), 0x0FFF);#endif /* 0/1 */  /* Initialize Ehternet Rx buffers */  rbf_des = (rbf_t *)RXBUFF_DES;  for ( i = 0; i < RXBUF_NUM; i++)    {      rbf_des[i].addr = BASE_RXBUFF + RXBUFF_SIZE * i;      rbf_des[i].len = 0;    }  rbf_des[RXBUF_NUM-1].addr |= RBF_WRAP;  rbf_ptr = (rbf_t *)RXBUFF_DES;  /* Set Receive Buffer Queue Pointer */  HAL_WRITE_UINT32((BASE_EMAC+EMAC_RBQP), RXBUFF_DES);  /* Reset Receive Status Register */  HAL_WRITE_UINT32((BASE_EMAC+EMAC_RSR), (C_EMAC_BNA | C_EMAC_REC | C_EMAC_OVR));  enable_mdi();  phyid1 = read_phy(0, MII_PHYSID1);  phyid2 = read_phy(0, MII_PHYSID2);  disable_mdi();  phy_id = (phyid1 << 16) | (phyid2 & 0xFFF0);  switch (phy_id)    {      /* Davicom 9161: PHY_ID1 = 0x181, PHY_ID2 = B881 */      case MII_DM9161_ID:          debug1_printf("PHY: DM9161\n");          at91rm9200_priv_data.phy_type = MII_DM9161_ID;          break;      /* Intel LXT971A: PHY_ID1 = 0x13, PHY_ID2 = 78E0 */      case MII_LXT971A_ID:          debug1_printf("PHY: LXT971A\n");          at91rm9200_priv_data.phy_type = MII_LXT971A_ID;          break;      /* Realtek RTL8201: PHY_ID1 = 0, PHY_ID2 = 0x8201 */      case MII_RTL8201_ID:          debug1_printf("PHY: RTL8201\n");          at91rm9200_priv_data.phy_type = MII_RTL8201_ID;          break;      /* Broadcom BCM5221: PHY_ID1 = 0x40, PHY_ID2 = 0x61e0 */      case MII_BCM5221_ID:          debug1_printf("PHY: BCM5221\n");          at91rm9200_priv_data.phy_type = MII_BCM5221_ID;          break;      /* National Semiconductor DP83847:  */      case MII_DP83847_ID:          debug1_printf("PHY: DP83847\n");          at91rm9200_priv_data.phy_type = MII_DP83847_ID;          break;      default:          debug1_printf("PHY: Unknown (%d)\n", phy_id);          at91rm9200_priv_data.phy_type = 0;          break;    }  init_phy();#if defined(CYGPKG_NET)  ifStats.duplex = 1;      //unknown  ifStats.operational = 1; //unknown  ifStats.tx_queue_len = MAX_TX_FRAME_DESCRIPTORS;  strncpy(ifStats.description,"Ethernet device", sizeof(ifStats.description));  ifStats.snmp_chipset[0] = 0;  ifStats.supports_dot3 = 1; // support dot3#endif  installInterrupts();  EthInit(myMacAddr);//  cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_EMAC);  configDone = 1;  ethernetRunning = 1;  eth_drv_init(sc, myMacAddr);  return true;}static void at91rm9200_eth_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags){  debug2_printf("at91rm9200_eth_start()\n");  if (!ethernetRunning)    {      cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_EMAC);      /* FIXME: PHY IRQ */      EthInit(enaddr);      cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_EMAC);      /* FIXME: PHY IRQ */      ethernetRunning = 1;    }}static void at91rm9200_eth_stop(struct eth_drv_sc *sc){  debug1_printf("at91rm9200_eth_stop()\n");  // cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_EMAC);  ethernetRunning = 0;}static int at91rm9200_eth_control(struct eth_drv_sc *sc,                          unsigned long key,                          void *data,                          int len){#if 0  switch (key)    {#if defined(CYGPKG_NET)     case ETH_DRV_GET_IF_STATS_UD:     case ETH_DRV_GET_IF_STATS:        {          struct ether_drv_stats *p = (struct ether_drv_stats*)data;#if CYGINT_DEVS_ETH_ARM_AT91RM9200_PHY          unsigned linkStatus;          // Read link status to be up to date          linkStatus = PhyStatus();          if (linkStatus & PhyStatus_FullDuplex)            ifStats.duplex = 3;          else            ifStats.duplex = 2;          if (linkStatus & PhyStatus_LinkUp)            ifStats.operational = 3;          else            ifStats.operational = 2;          if (linkStatus & PhyStatus_100Mb)            ifStats.speed = 100000000;          else            ifStats.speed = 10000000;#endif          *p = ifStats;          return 0;        }#endif     case ETH_DRV_SET_MAC_ADDRESS: {         int act;         if (ETHER_ADDR_LEN != len)             return -1;         debug1_printf("at91rm9200_eth_control: ETH_DRV_SET_MAC_ADDRESS.\n");         act = ethernetRunning;         at91rm9200_eth_stop(sc);         at91rm9200_eth_start(sc, data, 0);         ethernetRunning = act;         return 0;     }#ifdef	ETH_DRV_GET_MAC_ADDRESS     case ETH_DRV_GET_MAC_ADDRESS: {         if (len < ETHER_ADDR_LEN)             return -1;         debug1_printf("at91rm9200_eth_control: ETH_DRV_GET_MAC_ADDRESS.\n");//         memcpy(data, (void *)CAM_BaseAddr, ETHER_ADDR_LEN);         return 0;     }#endif     default:      return -1;    }#endif /* 0/1 */  return 0;}// In case there are multiple Tx frames waiting, we should// return how many empty Tx spots we have.  For now we just// return 0 or 1.static int at91rm9200_eth_can_send(struct eth_drv_sc *sc){  cyg_uint32 val;  HAL_READ_UINT32((BASE_EMAC+EMAC_TSR), val);  if (val & C_EMAC_BNQ)    {      return 1;    }  else    {      return 0;    }}static int at91rm9200_eth_send_count=0;static voidat91rm9200_eth_send(        struct eth_drv_sc *sc,        struct eth_drv_sg *sg_list,        int sg_len,        int total_len,        unsigned long key){  cyg_uint32 val;  static cyg_uint8 buf_mem[2048];  cyg_uint32 len;  cyg_uint8 *dest;  if (total_len >= MAX_ETH_FRAME_SIZE)    {      eth_drv_tx_done(sc, key, -EINVAL);      return;    }  ++at91rm9200_eth_send_count;  while (1)    {      HAL_READ_UINT32((BASE_EMAC+EMAC_TSR), val);      if (val & C_EMAC_BNQ)        { break; }    }  /* FIXME:    * Do NOT use block mechanism    * Queue.  */  // copy data from scatter/gather list into BDMA data buffer  len = 0;  dest = buf_mem;  while (sg_len)    {      memcpy(dest, (unsigned char*)sg_list->buf, sg_list->len);      len += sg_list->len;      dest += sg_list->len;      ++sg_list;      --sg_len;    }  /* Must always be written in address-then-length order. */  HAL_WRITE_UINT32((BASE_EMAC+EMAC_TAR), buf_mem);  HAL_WRITE_UINT32((BASE_EMAC+EMAC_TCR), total_len);  /* Block/Waiting for sent */  while (1)    {      HAL_READ_UINT32((BASE_EMAC+EMAC_TCR), val);      if (!(val & 0x7FF))        { break; }    }  /* Cleared by writing a one to this bit. (Transmit complete.) */  HAL_READ_UINT32((BASE_EMAC+EMAC_TSR), val);  val |= C_EMAC_COMP;  HAL_WRITE_UINT32((BASE_EMAC+EMAC_TSR), val);  // tell upper layer that we're done with this sglist  eth_drv_tx_done(sc, key, 0);}static voidat91rm9200_eth_recv(                    struct eth_drv_sc *sc,                    struct eth_drv_sg *sg_list,                    int sg_len){  extern struct eth_drv_sc at91rm9200_sc;  cyg_uint32 len;  cyg_uint32 val;  //diag_printf("at91rm9200_eth_recv().......\n");/*  diag_printf("recv(), sg_len = %d, sg_list->len=%d\n",              sg_len, sg_list->len);*/  val = rbf_ptr->addr;  val &= ~((cyg_uint32)0x03);//  val += ETH_HEADER_SIZE;  if (!(sg_list->buf))    diag_printf("recv(), sg_list->buf is NULL\n");  while (sg_len)    {      if (sg_list->buf)        {          memcpy((unsigned char*)sg_list->buf, val, sg_list->len);        }      ++sg_list;      --sg_len;    }#if 1  rbf_ptr->addr &= ~RBF_OWNER;  if (rbf_ptr->addr & RBF_WRAP)    {      rbf_ptr = &rbf_des[0];    }  else    {      rbf_ptr++;    }  HAL_READ_UINT32((BASE_EMAC+EMAC_RSR), val);  val |= C_EMAC_REC;  HAL_WRITE_UINT32((BASE_EMAC+EMAC_RSR), val);#endif /* 0/1 */}// routine called to handle ethernet controller in polled modestatic void at91rm9200_eth_poll(struct eth_drv_sc *sc){//  diag_printf("at91rm9200_eth_poll().......\n");  // Call ISR routine  at91rm9200_eth_isr(CYGNUM_HAL_INTERRUPT_EMAC, 0);  at91rm9200_eth_deliver(sc);  // handle rx frames  at91rm9200_handle_tx_complete();/*   my_interrupt_ISR(sc);   HRDWR_deliver(struct eth_drv_sc *sc);*/}static int at91rm9200_eth_int_vector(struct eth_drv_sc *sc){  return CYGNUM_HAL_INTERRUPT_EMAC;}ETH_DRV_SC(at91rm9200_sc,           &at91rm9200_priv_data, // Driver specific data           "eth0",                // Name for this interface           at91rm9200_eth_start,           at91rm9200_eth_stop,           at91rm9200_eth_control,           at91rm9200_eth_can_send,           at91rm9200_eth_send,           at91rm9200_eth_recv,           at91rm9200_eth_deliver,           at91rm9200_eth_poll,           at91rm9200_eth_int_vector           );NETDEVTAB_ENTRY(at91rm9200_netdev,                "at91rm9200",                at91rm9200_eth_init,                &at91rm9200_sc);// EOF at91rm9200_ether.c

⌨️ 快捷键说明

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