📄 eth_ep93xx.c
字号:
#include <ep93xx/ioregs.h>#include <ep93xx/regs_eth.h>#include <ep93xx/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_armadillo2x0.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", ð_info->QueTxDesc); _DEBUG("QueTxSts : %p\n", ð_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(ð_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(ð_info->QueTxSts, 0, sizeof(TxStatus) * LEN_QueTxSts); eth_info->idxQueTxSts = 0; IO_MAC_TXSBA = (unsigned long)ð_info->QueTxSts; IO_MAC_TXSCA = (unsigned long)ð_info->QueTxSts; IO_MAC_TXSBL = sizeof(TxStatus) * LEN_QueTxSts; IO_MAC_TXSCL = sizeof(TxStatus) * LEN_QueTxSts; safe_memset(ð_info->QueTxDesc, 0, sizeof(TxDescriptor) * LEN_QueTxDesc); eth_info->idxQueTxDesc = 0; IO_MAC_TXDBA = (unsigned long)ð_info->QueTxDesc; IO_MAC_TXDCA = (unsigned long)ð_info->QueTxDesc; IO_MAC_TXDBL = sizeof(TxDescriptor) * LEN_QueTxDesc; IO_MAC_TXDCL = sizeof(TxDescriptor) * LEN_QueTxDesc; safe_memset(ð_info->QueRxSts, 0, sizeof(RxStatus) * LEN_QueRxSts); eth_info->idxQueRxSts = 0; IO_MAC_RXSBA = (unsigned long)ð_info->QueRxSts; IO_MAC_RXSCA = (unsigned long)ð_info->QueRxSts; IO_MAC_RXSBL = sizeof(RxStatus) * LEN_QueRxSts; IO_MAC_RXSCL = sizeof(RxStatus) * LEN_QueRxSts; safe_memset(ð_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)ð_info->QueRxDesc; IO_MAC_RXDCA = (unsigned long)ð_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", ð_info->QueRxDesc); _DEBUG("QueRxSts: %p\n", ð_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 + -