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

📄 eth_ep93xx.c

📁 Hermit-at-1.1.3,一款bootloader
💻 C
字号:
#include <ep93xx/ioregs.h>#include <ep93xx/regs_eth.h>#include <target/io.h>#include <target/mem.h>#include <target/net/eth.h>#include <target/net/eth_util.h>#include "eth_ep93xx.h"#include "board.h"#include "i2c_armadillo9.h"static unsigned char *RxBuf = (char *)0xc4900000;static unsigned char *TxBuf = (char *)0xc4a00000;static ep93xxEth_info *eth_info = (ep93xxEth_info *)0xc4800000;//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++void ep93xx_enable_phy_module(void){  IO_GPIO_PGDDR |= BIT(2);  IO_GPIO_PGDR  &= ~BIT(2);}//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++void ep93xx_disable_phy_module(void){  IO_GPIO_PGDDR |= BIT(2);  IO_GPIO_PGDR  |= BIT(2);}//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++static void phy_write(int reg, unsigned short val){}//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++static unsigned short phy_read(int reg){  unsigned short val;  IO_MAC_SELFCTL &= ~(1<<8);    while(IO_MAC_MIISTS & (1<<0));  IO_MAC_MIICMD = (0x8000 | reg);  while(IO_MAC_MIISTS & (1<<0));  val = IO_MAC_MIIDATA;  IO_MAC_SELFCTL |= (1<<8);  return val;}//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++static int phy_auto_negotiation(void){  unsigned short val;  phy_write(4, 0x01e1);  phy_write(0, 0x1200);  while(1){    val = phy_read(1);    if(val & 0x0020){      break;    }else{      mdelay(100);      continue;    }  }  val = phy_read(5);  if(val & 0x0140){    IO_MAC_TESTCTL |= TESTCTL_MFDX;  }  return 0;}//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++static int phy_init(void){  unsigned short val;  int ret;  val = phy_read(1);  if(val & 0x0004){    ret = phy_auto_negotiation();    return ret;  }  return -1;}//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++int ep93xx_eth_send(const eth_frame *ethfr,		    const void *pfr, const unsigned int pfrlen){  int idx;  unsigned char *txBuf;  int txLen;  idx = eth_info->idxQueTxDesc;  txBuf = (unsigned char *)(TxBuf + LEN_TxBuf * idx);  if(pfrlen + ETH_FRAME_LEN < 60){    safe_memset(txBuf, 0, 60);    txLen = 60;  }else{    txLen = pfrlen + ETH_FRAME_LEN;  }  if(txLen > LEN_TxBuf){    _DEBUG("not imprement\n");    return -1;  }  eth_info->QueTxDesc[idx].bl = txLen;  eth_info->QueTxDesc[idx].ba = (unsigned long)txBuf;  eth_info->QueTxDesc[idx].bi = idx;  eth_info->QueTxDesc[idx].af = 0;  eth_info->QueTxDesc[idx].eof = 1;  safe_memcpy(&txBuf[0], ethfr, ETH_FRAME_LEN);  safe_memcpy(&txBuf[ETH_FRAME_LEN], pfr, pfrlen);#ifdef DEBUG_ETH  _DEBUG("QueTxDesc: %p\n", &eth_info->QueTxDesc);  _DEBUG("QueTxSts : %p\n", &eth_info->QueTxSts);  _DEBUG("Desc.ba: %p\n", eth_info->QueTxDesc[idx].ba);  _DEBUG("Desc.bl: %p\n", eth_info->QueTxDesc[idx].bl);  _DEBUG("Desc.af: %p\n", eth_info->QueTxDesc[idx].af);  _DEBUG("Desc.bi: %p\n", eth_info->QueTxDesc[idx].bi);  _DEBUG("Desc.eof: %p\n", eth_info->QueTxDesc[idx].eof);#endif  safe_memset(&eth_info->QueTxSts[idx], 0, sizeof(TxStatus));  IO_MAC_TXDEQ = 1;  eth_info->idxQueTxDesc = ((eth_info->idxQueTxDesc + 1) % LEN_QueTxDesc);    while(!(eth_info->QueTxSts[idx].txfp)){    mdelay(1);  }#ifdef DEBUG_ETH  _DEBUG("Sts.bi: %p\n", eth_info->QueTxSts[idx].bi);  _DEBUG("Sts.ncoll: %p\n", eth_info->QueTxSts[idx].ncoll);  _DEBUG("Sts.ecoll: %p\n", eth_info->QueTxSts[idx].ecoll);  _DEBUG("Sts.txu: %p\n", eth_info->QueTxSts[idx].txu);  _DEBUG("Sts.ow: %p\n", eth_info->QueTxSts[idx].ow);  _DEBUG("Sts.lcrs: %p\n", eth_info->QueTxSts[idx].lcrs);  _DEBUG("Sts.fa: %p\n", eth_info->QueTxSts[idx].fa);  _DEBUG("Sts.txwe: %p\n", eth_info->QueTxSts[idx].txwe);  _DEBUG("Sts.txfp: %p\n", eth_info->QueTxSts[idx].txfp);#endif  return 0;}//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++int ep93xx_eth_recv(const unsigned char *mac, eth_frame **ethfr,		    void **pbuf, unsigned int *pbuflen, int *timeout){  int idx;  for(;;){    idx = eth_info->idxQueRxSts;    while(!(eth_info->QueRxSts[idx].rfp1)){      *timeout -= 1;      if(*timeout < 0){	return -1;      }      mdelay(1);    }    eth_info->idxQueRxSts = ((eth_info->idxQueRxSts + 1) % LEN_QueRxSts);        //operated    eth_info->QueRxSts[idx].rfp1 = 0;    eth_info->QueRxSts[idx].rfp2 = 0;    //    *ethfr = (eth_frame *)eth_info->QueRxDesc[idx].ba;    *pbuf  = (void *)(eth_info->QueRxDesc[idx].ba + ETH_FRAME_LEN);    *pbuflen = eth_info->QueRxSts[idx].fl - ETH_FRAME_LEN;    //    if(safe_memcmp((*ethfr)->dmac, broadcast_mac, 6) == 0){      _DEBUG("broadcast packet detect\n");    }else if(safe_memcmp((*ethfr)->dmac, mac, 6) == 0){      _DEBUG("packet detect\n");    }else{      IO_MAC_RXSEQ = idx;      IO_MAC_RXDEQ = idx;      continue;    }    return idx;  }  return 0;}//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++int ep93xx_eth_rxbuf_free(const int idx){  IO_MAC_RXSEQ = idx;  IO_MAC_RXDEQ = idx;    return 0;}//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++static int eth_enable(void){  IO_MAC_RXCTL |= RXCTL_SRxON | RXCTL_RCRCA;  return 0;}//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++static int eth_reset(int timeout){  unsigned short val;  int i;  IO_MAC_SELFCTL = SELFCTL_RESET;  while((IO_MAC_SELFCTL & SELFCTL_RESET));  IO_MAC_SELFCTL = ((IO_MAC_SELFCTL & ~0x7f00) | 0x2900);  for(i=0;i<timeout;i++){    val = phy_read(1);    if(val & 0x0004){      break;    }    mdelay(50);  }  return 0;}//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++static int queue_init(void){  int i;  IO_MAC_BMCTL |= (BMCTL_RxDis | BMCTL_TxDis);  while((IO_MAC_BMSTS & BMSTS_TxAct)){    mdelay(1000);  }  while((IO_MAC_BMSTS & BMSTS_RxAct));  safe_memset(&eth_info->QueTxSts, 0, sizeof(TxStatus) * LEN_QueTxSts);  eth_info->idxQueTxSts = 0;  IO_MAC_TXSBA = (unsigned long)&eth_info->QueTxSts;  IO_MAC_TXSCA = (unsigned long)&eth_info->QueTxSts;  IO_MAC_TXSBL = sizeof(TxStatus) * LEN_QueTxSts;  IO_MAC_TXSCL = sizeof(TxStatus) * LEN_QueTxSts;  safe_memset(&eth_info->QueTxDesc, 0, sizeof(TxDescriptor) * LEN_QueTxDesc);  eth_info->idxQueTxDesc = 0;  IO_MAC_TXDBA = (unsigned long)&eth_info->QueTxDesc;  IO_MAC_TXDCA = (unsigned long)&eth_info->QueTxDesc;  IO_MAC_TXDBL = sizeof(TxDescriptor) * LEN_QueTxDesc;  IO_MAC_TXDCL = sizeof(TxDescriptor) * LEN_QueTxDesc;  safe_memset(&eth_info->QueRxSts, 0, sizeof(RxStatus) * LEN_QueRxSts);  eth_info->idxQueRxSts = 0;  IO_MAC_RXSBA = (unsigned long)&eth_info->QueRxSts;  IO_MAC_RXSCA = (unsigned long)&eth_info->QueRxSts;  IO_MAC_RXSBL = sizeof(RxStatus) * LEN_QueRxSts;  IO_MAC_RXSCL = sizeof(RxStatus) * LEN_QueRxSts;  safe_memset(&eth_info->QueRxDesc, 0, sizeof(RxDescriptor) * LEN_QueRxDesc);  for(i=0; i<LEN_QueRxDesc; i++){    eth_info->QueRxDesc[i].bi = i;    eth_info->QueRxDesc[i].ba = (unsigned long)(RxBuf + LEN_RxBuf * i);    eth_info->QueRxDesc[i].bl = LEN_RxBuf;  }  eth_info->idxQueRxDesc = 0;  IO_MAC_RXDBA = (unsigned long)&eth_info->QueRxDesc;  IO_MAC_RXDCA = (unsigned long)&eth_info->QueRxDesc;  IO_MAC_RXDBL = sizeof(RxDescriptor) * LEN_QueRxDesc;  IO_MAC_RXDCL = sizeof(RxDescriptor) * LEN_QueRxDesc;  IO_MAC_BMCTL |= (BMCTL_TxEn | BMCTL_RxEn);  while(!(IO_MAC_BMSTS & BMSTS_TxAct)){    mdelay(1000);  }  while(!(IO_MAC_BMSTS & BMSTS_RxAct)){    mdelay(1000);  }  IO_MAC_RXSEQ = LEN_QueRxSts;  IO_MAC_RXDEQ = LEN_QueRxDesc;  return 0;}//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++static int eth_indaddr_write(const unsigned char *mac){  unsigned long tmp;  tmp = IO_MAC_RXCTL;  IO_MAC_RXCTL &= ~RXCTL_SRxON;  IO_MAC_AFP = 0;    IO_MAC_INDAD0 = mac[0];  IO_MAC_INDAD1 = mac[1];  IO_MAC_INDAD2 = mac[2];  IO_MAC_INDAD3 = mac[3];  IO_MAC_INDAD4 = mac[4];  IO_MAC_INDAD5 = mac[5];  IO_MAC_RXCTL = tmp;  return 0;}//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//int ep93xx_eth_init(const unsigned char *ipaddr,const unsigned char *mac){int ep93xx_eth_init(const unsigned char *ipaddr){  int ret;  unsigned long tmp;  hwif_eth hwif;  #ifdef DEBUG_ETH  _DEBUG("eth_info: %p\n", eth_info);  _DEBUG("QueRxDesc: %p\n", &eth_info->QueRxDesc);  _DEBUG("QueRxSts: %p\n", &eth_info->QueRxSts);  _DEBUG("RxBuf: %p\n", RxBuf);  _DEBUG("TxBuf: %p\n", TxBuf);#endif  safe_memset(&hwif, 0, sizeof(hwif_eth));  hwif.enable_phy_module = ep93xx_enable_phy_module;  hwif.disable_phy_module = ep93xx_disable_phy_module;  hwif.eth_send = ep93xx_eth_send;  hwif.eth_recv = ep93xx_eth_recv;  hwif.eth_rxbuf_free = ep93xx_eth_rxbuf_free;  safe_memcpy(&hwif.eth_ipaddr, ipaddr, 4);  arch_get_mac(hwif.eth_mac);  register_hwif_eth(&hwif);      enable_phy_module();  eth_reset(100);  ret = phy_init();  if(ret == -1){    hprintf("Link is down\n");    return -1;  }  IO_MAC_GLINTMSK = 0x00;  IO_MAC_RXCTL = RXCTL_BA | RXCTL_IA0;  IO_MAC_TXCTL = 0x00;  IO_MAC_GT = 0x00;  IO_MAC_BMCTL = 0x00;  IO_MAC_RXBTH = 0x00800040;  IO_MAC_TXBTH = 0x00800040;  IO_MAC_RXSTH = 0x00040002;  IO_MAC_TXSTH = 0x00040002;  IO_MAC_RXDTH = 0x00040002;  IO_MAC_TXDTH = 0x00040002;  IO_MAC_MAXFL = (((1518 + 1) << 16) | (944 << 0));  tmp = IO_MAC_TXCOLLCNT;  tmp = IO_MAC_RXMISSCNT;  tmp = IO_MAC_RXRUNTCNT;  tmp = IO_MAC_INTSTSC;  IO_MAC_TXCTL |= TXCTL_STxON;  eth_indaddr_write(hwif.eth_mac);  queue_init();    eth_enable();    return 0;}

⌨️ 快捷键说明

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