📄 sed.c
字号:
rcb_pending = 0; rcb_array=(struct rcb_s *)UNCACHED(&rcb_array_i[0]); for(i=0;i<RCB_ENTRIES;i++) { pTmp=sys_malloc(size); if (!pTmp) sys_printf("Error: sys_malloc\n"); rcb_array[i].size=0; rcb_array[i].BufPtr=PHYS(pTmp); rcb_array[i].Res1=0; rcb_array[i].Res2=0; rcb_array[i].DatPtr=(int *)UNCACHED(pTmp); } SAVE4=(int)rcb_array; }void init_txcomp(int num) { int *pTmp,iTmp,i,j; /*Make num power of two*/ num*=2; num--; for(i=0,j=0x80000000;i<32;i++,j>>=1) if (j&num) num&=j; txcompring_size=num; /*Allocate so that it is on a power of size alignment*/ iTmp=num*16*2; pTmp=sys_malloc(iTmp); if (!pTmp) sys_printf("Error: sys_malloc\n"); iTmp=(int)UNCACHED(pTmp); iTmp+=((num*16)-1); iTmp&=~((num*16)-1); SAVE2=iTmp; pTmp=(int *)iTmp; TxCompPtr=(struct txcompring_s *)pTmp; for(i=0;i<num;i++) { *pTmp++=0; *pTmp++=0; *pTmp++=0; *pTmp++=0; } /* allocate Tx completion ring (num entries) */ TCRPTR = PHYS(TxCompPtr); TCRSIZE = num-1; TCRTOTENT = num; TCRENTINC = num; TxCompRingMask=(num-1)<<4; TxCompRingBase=(~(((num-1)<<4)|0xf))&((int)TxCompPtr); }void init_rxcomp(int num) { int *pTmp,iTmp,i,j; /*Make num power of two*/ num*=2; num--; for(i=0,j=0x80000000;i<32;i++,j>>=1) if (j&num) num&=j; rxcompring_size=num; /*Allocate so that it is on a power of size alignment*/ iTmp=num*16*2; pTmp=sys_malloc(iTmp); if (!pTmp) sys_printf("Error: sys_malloc\n"); iTmp=(int)UNCACHED(pTmp); iTmp+=((num*16)-1); iTmp&=~((num*16)-1); SAVE3=iTmp; pTmp=(int *)iTmp; RxCompPtr=(struct rxcompring_s *)pTmp; for(i=0;i<num;i++) { *pTmp++=0; *pTmp++=0; *pTmp++=0; *pTmp++=0; } /* allocate Tx completion ring (num entries) */ RCRPTR = PHYS(RxCompPtr); RCRSIZE = num-1; RCRTOTENT = num; RCRENTINC = num; RxCompRingMask=(num-1)<<4; RxCompRingBase=(~(((num-1)<<4)|0xf))&((int)RxCompPtr); }void RxFree(struct rcb_s *rcb) { rcb->Res1=0; rcb->Res2=0; rcb_pending++; while((FBLADDCNT&0x80000000)==0) { } FBLADDCNT = 1; FBLADDSTART = PHYS(rcb); FBLADDEND = PHYS(rcb); }void clockwait(unsigned int et) { unsigned int ct; et/=2; t_clear(); do { ct=t_get(); }while(ct<et); }void InitTcb(void) { int i; tcb_index=0; tcb_array=(struct tcb_s *)UNCACHED(&tcb_array_i[0]); for(i=0;i<TCB_ENTRIES;i++) { tcb_array[i].mode=0; tcb_array[i].BufPtr=0; tcb_array[i].Res1=0; tcb_array[i].DO_FBLID=0; tcb_array[i].RcbPtr=0; } SAVE1=(int)tcb_array; }void IssueSend(volatile int *buffer,int size, int pass_crc) { int itmp; struct tcb_s *tcb_ptr; size+=4; /*Deal with CRC padding*/ itmp=tcb_index++; if (tcb_index>=TCB_ENTRIES) tcb_index=0; tcb_array[itmp].mode=(size+4)|0xc0000000; if (pass_crc) tcb_array[itmp].mode|=0x20000000; tcb_array[itmp].BufPtr=PHYS((int *)buffer); tcb_array[itmp].DO_FBLID=(((bit32u)buffer)&3)<<16; tcb_pending++; tcb_ptr=&tcb_array[itmp]; while((TXPADDCNT&0x80000000)==0) { } TXPADDCNT = 1; TXPADDSTART = PHYS(tcb_ptr); TXPADDEND = PHYS(tcb_ptr); }void sed_shutdown(void) { /* Take the MAC out of reset */ if(emacbase == EMACA_BASE) { RESET_PRCR &= ~EMACA_RESET; } else { RESET_PRCR &= ~EMACB_RESET; }#ifdef ACPEP /* Put the PHY in reset */ if(emacbase == EMACA_BASE) { ACPEP_EPLD_RESET_CTRL_REG &= ~ACPEP_EPLD_RESET_MIIA; } else { ACPEP_EPLD_RESET_CTRL_REG &= ~ACPEP_EPLD_RESET_MIIB; }#endif }int sed_Init(int loopback) { register int i,EmacDuplex = 0,EmacSpeed = 0, PhyNum = 0; bit32u uitmp, linktimeout; char *cp; unsigned int timeoutvalue; bit32u tempPhyState = 0; /* * and initialize the exported variable which gives the Eth broadcast * address, for everyone else to use. */ for (i=0; i<3; i++) sed_ethBcastAddr[i] = 0xFFFF;#ifdef ACPEP /* Take the PHY out of reset */ if(emacbase == EMACA_BASE) { ACPEP_EPLD_RESET_CTRL_REG |= ACPEP_EPLD_RESET_MIIA; } else { ACPEP_EPLD_RESET_CTRL_REG |= ACPEP_EPLD_RESET_MIIB; }#endif /* accept packets addressed for us and broadcast packets */ InitTcb(); InitRcb(BUFFER_SIZE); /*Initialize RCB with 1518 byte buffers*/ /* Take the MAC out of reset */ if(emacbase == EMACA_BASE) { RESET_PRCR &= ~EMACA_RESET; clockwait(64); RESET_PRCR |= EMACA_RESET; clockwait(64); } else { RESET_PRCR &= ~EMACB_RESET; clockwait(64); RESET_PRCR |= EMACB_RESET; clockwait(64); } /*Reset the mac*/ DMACONFIG = 0x80000000; DMACONFIG = 0x00000000; /* allocate Tx completion ring (TX_COMP_ENTRIES entries) */ init_txcomp(TX_COMP_ENTRIES); /* Set DMA burst length to 16 words */ TDMASTATE7 = 0x00100000; /* allocate Rx completion ring (four entries) */ init_rxcomp(RX_COMP_ENTRIES); /* Set Rx DMA state stuff */ RDMASTATE0 = 0x00000200; /* Set Rx Buffer Size */ FBL0BUFSIZE = BUFFER_SIZE; /*Initialize MDIO Phy State machine*/ PhyState = 0; EmacMdioInit(emacbase,(int *)&PhyState,av_cpufreq); clockwait((av_cpufreq/1000000)*32*64*4); /* Wait for a pool loop */ if (av_cpufreq >= 75000000) tempPhyState = NWAY_FD100|NWAY_HD100|NWAY_FD10|NWAY_HD10; /* Phy 100 and Full Duplex */ else tempPhyState = NWAY_FD100|NWAY_FD10; /* Full Duplex */ if (loopback == EXTERNAL_LOOP) tempPhyState |= PHY_LOOP; /* external phy loop */ else if (loopback == NORMAL) tempPhyState |= NWAY_AUTO; /* auto negotiation */ EmacMdioSetPhyMode(emacbase, (int *)&PhyState, tempPhyState); if (loopback == EXTERNAL_LOOP) { for (i = 0; i < 5; i++) EmacMdioTic(emacbase,(int *)&PhyState); } else if (loopback == NORMAL) { /*Call EmacMdioTic every 10mS until EmacMdioGetLinked returns TRUE;*/ /*This can be called every 10 mS forever so that cable un-plugs and re-plugs are delt with.*/ timeoutvalue = (cp = sys_getenv("link_timeout")) ? atoui(cp) : LINK_TIMEOUT; t_clear(); linktimeout = t_get() + GetTicks(timeoutvalue); sys_printf("Waiting for %d secs to detect the EMAC link...\n", timeoutvalue); while((!EmacMdioGetLinked(emacbase,(int *)&PhyState)) && (t_get() < linktimeout)) { /*clockwait(av_cpufreq/100);*/ /* Commented as the above timer gets reset */ EmacMdioTic(emacbase,(int *)&PhyState); } if (!EmacMdioGetLinked(emacbase,(int *)&PhyState)) { sys_printf("EMAC Link DOWN.\n"); return 1; } else sys_printf("EMAC Link UP.\n"); } /*The Below section is done any time the EmacMdioTic returns TRUE!*/ /*Retreive Duplex and Speed and the Phy Number*/ EmacDuplex = EmacMdioGetDuplex(emacbase,(int *)&PhyState); EmacSpeed = EmacMdioGetSpeed(emacbase,(int *)&PhyState); PhyNum = EmacMdioGetPhyNum(emacbase,(int *)&PhyState); /* Set mode of the MAC */ MDIOMACPHY = PhyNum | (((loopback == WIRE_LOOP) || (loopback == NORMAL))?0x80:0x00); if (loopback == EXTERNAL_LOOP) { WRAPCLK |= 0x80000000; /*Force MII link in External WRAP*/ clockwait((av_cpufreq/1000000)*64*2*4); /*Wait for the write to happen*/ } MACCONTROL = ((EmacDuplex)?FULL_DUPLEX:0) | ((EmacSpeed)?SPEED_100:0) | ((loopback == INTERNAL_LOOP)?0:NO_LOOP) | TXPACE | CLRP | ((loopback != NORMAL)?(PEFCE|CAF):0); /* Enable Rx and Tx DMA, and unreset MAC */ DMACONFIG = 0x00000003; if (loopback == NORMAL) { /* Set Copy All Frames mode */ INTSTS = 0x1ff; /* Clear all pending interrupts */ /* Set the MAC address for the PHY */ cp = (char *)sed_lclEthAddr; uitmp =(((bit32u)*cp++)&0x0ff); uitmp|=(((bit32u)*cp++)&0x0ff)<<8; uitmp|=(((bit32u)*cp++)&0x0ff)<<16; uitmp|=(((bit32u)*cp++)&0x0ff)<<24; MACADDRHI=uitmp; uitmp =(((bit32u)*cp++)&0x0ff); uitmp|=(((bit32u)*cp++)&0x0ff)<<8; MACADDRLO=uitmp; } for(i = 0; i < RCB_ENTRIES; i++) RxFree(&rcb_array[i]); /* Now put some data in Tx buffer */ return(0); }/* * Format an ethernet header in the transmit buffer, and say where it is. * Note that because of the way the 3Com interface works, we need to know * how long the packet is before we know where to put it. The solution is * that we format the packet at the BEGINNING of the transmit buffer, and * later copy it (carefully) to where it belongs. Another hack would be * to be inefficient about the size of the packet to be sent (always send * a larger ethernet packet than you need to, but copying should be ok for * now.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -