📄 ne2000end.c
字号:
recvLen = (pDrvCtrl->current-pDrvCtrl->nextPacket)*RECV_PAGE_SIZE; } else { recvLen = ((NE2000_PSTOP-pDrvCtrl->nextPacket)+(pDrvCtrl->current-NE2000_PSTART))*RECV_PAGE_SIZE; } ne2000DmaRecv(pDrvCtrl , (((UINT)pDrvCtrl->nextPacket << 8) & 0x0000ffff) , recvLen); #else (void)netJobAdd ((FUNCPTR)ne2000HandleRcvInt, (int)pDrvCtrl, 0,0,0,0); #endif } } if ((intStat & (ISTAT_TXE | ISTAT_PTX)) != 0) { #ifndef _USE_SND_DMA_ pDrvCtrl->flags &= ~END_TX_IN_PROGRESS; ENDLOGMSG (("ne2000Int: Tx complete, blocked=%d\n", (pDrvCtrl->flags & END_TX_BLOCKED) ? 1 : 0,0,0,0,0,0)); #else if(pDrvCtrl->bufCount< SAVE_SND_NUM) { ne2000DmaSend(pDrvCtrl , (NE2000_TSTART << 8)); } else { pDrvCtrl->flags &= ~END_TX_IN_PROGRESS; } #endif if (pDrvCtrl->flags & END_TX_BLOCKED) { pDrvCtrl->imask &= ~(IM_TXEE | IM_PTXE); SYS_OUT_CHAR (pDrvCtrl, ENE_INTMASK, pDrvCtrl->imask); pDrvCtrl->flags &= ~END_TX_BLOCKED; netJobAdd ((FUNCPTR)muxTxRestart, (int)&pDrvCtrl->endObj, 0, 0, 0, 0); } } /* Flush the write pipe */ CACHE_PIPE_FLUSH ();}/********************************************************************************* ne2000HandleRcvInt - task level interrupt service for input packets** This routine is called at task level indirectly by the interrupt* service routine to do any message received processing.** RETURNS: N/A.*/LOCAL void ne2000HandleRcvInt ( NE2000END_DEVICE *pDrvCtrl ) { int oldLevel; char *pBuf; UCHAR currNo ; UCHAR bnry ; UCHAR stat; int errFlag = FALSE; ENDLOGMSG (("ne2000HandleRcvInt(%x): enter (flags=%x)\n", pDrvCtrl,pDrvCtrl->flags,0,0,0,0)); pBuf = NULL; while ((pDrvCtrl->flags & END_RECV_HANDLING_FLAG) || (pDrvCtrl->flags &END_OVERWRITE2)) { int len; CL_BLK_ID pClBlk; M_BLK_ID pMblk; /* MBLK to send upstream */ SYS_IN_CHAR (pDrvCtrl, ENE_BOUND , &bnry); if (pDrvCtrl->nextPacket == pDrvCtrl->current) break; if (pDrvCtrl->flags & END_OVERWRITE) break; if (!pBuf) { pBuf = netClusterGet (pDrvCtrl->endObj.pNetPool, pDrvCtrl->clPoolId); if (!pBuf) { errFlag = TRUE; break; } } len = ne2000PacketGet (pDrvCtrl, pBuf + pDrvCtrl->offset); if (len <= 0) { END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1); errFlag = TRUE; break; } pMblk = mBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT, MT_DATA); if (!pMblk) { END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1); errFlag = TRUE; break; } pClBlk = netClBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT); if (!pClBlk) { netMblkFree (pDrvCtrl->endObj.pNetPool, (M_BLK_ID)pMblk); errFlag = TRUE; break; } netClBlkJoin (pClBlk, pBuf, NE2000_BUFSIZ, NULL, 0, 0, 0); netMblkClJoin (pMblk, pClBlk); pMblk->mBlkHdr.mFlags |= M_PKTHDR; pMblk->mBlkHdr.mLen = len; pMblk->mBlkPktHdr.len = len; pMblk->mBlkHdr.mData += pDrvCtrl->offset; END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1); END_RCV_RTN_CALL (&pDrvCtrl->endObj, pMblk); pBuf = NULL; } if (pBuf) netClFree (pDrvCtrl->endObj.pNetPool, (UCHAR *) pBuf); oldLevel = intLock (); pDrvCtrl->flags &= ~END_RECV_HANDLING_FLAG; pDrvCtrl->imask |= IM_PRXE; SYS_OUT_CHAR (pDrvCtrl, ENE_INTMASK, pDrvCtrl->imask); if(pDrvCtrl->flags &END_OVERWRITE2 ) { currNo = ne2000GetCurr(pDrvCtrl); SYS_IN_CHAR (pDrvCtrl, ENE_BOUND , &bnry); if(TRUE == errFlag) { if(NE2000_PSTART ==currNo ) { bnry = NE2000_PSTOP-1; } else { bnry = currNo-1; } SYS_OUT_CHAR (pDrvCtrl, ENE_BOUND , bnry); } SYS_IN_CHAR (pDrvCtrl, ENE_INTSTAT, &stat); SYS_OUT_CHAR (pDrvCtrl, ENE_INTSTAT, stat); SYS_OUT_CHAR (pDrvCtrl, ENE_TCON, 0x00); pDrvCtrl->imask = NE2000_ALL_INTS; SYS_OUT_CHAR (pDrvCtrl, ENE_INTMASK, pDrvCtrl->imask); pDrvCtrl->flags &= ~END_OVERWRITE2; } intUnlock (oldLevel); }/********************************************************************************* ne2000DataIn - input bytes from NE2000 memory** NOMANUAL*/LOCAL void ne2000DataIn ( NE2000END_DEVICE * pDrvCtrl, int eneAddress, int len, char * pData ) { if (len == 0) { return; } SYS_OUT_CHAR (pDrvCtrl, ENE_INTMASK, 0); SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_NODMA | CMD_PAGE0 | CMD_START); SYS_OUT_CHAR (pDrvCtrl, ENE_RSAR0, eneAddress & 0xff); SYS_OUT_CHAR (pDrvCtrl, ENE_RSAR1, eneAddress >> 8); SYS_OUT_CHAR (pDrvCtrl, ENE_RBCR0, len & 0xff); SYS_OUT_CHAR (pDrvCtrl, ENE_RBCR1, len >> 8); SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_RREAD | CMD_START); SYS_IN_WORD_STRING (pDrvCtrl, ENE_DATA, pData, len/2); if (len & 1) SYS_IN_CHAR (pDrvCtrl, ENE_DATA, (pData + (len - 1))); SYS_OUT_CHAR (pDrvCtrl, ENE_INTMASK, pDrvCtrl->imask); }/********************************************************************************* ne2000DataOut - output bytes to NE2000 memory** NOMANUAL*/void ne2000DmaInit(){ #ifdef _USE_SND_DMA_ (void) intConnect (INUM_TO_IVEC(INT_VEC_DMA3),ne2000DmaSendInt, (int)0); intEnable (INT_LVL_DMA3); #endif #ifdef _USE_RECV_DMA_ (void) intConnect (INUM_TO_IVEC(INT_VEC_DMA0),ne2000DmaRecvInt, (int)0); intEnable (INT_LVL_DMA0); #endif}#ifdef _USE_SND_DMA_void ne2000DmaSendInt(){ ENDLOGMSG (("into ne2000DmaSendInt.\n", 0, 0, 0, 0, 0, 0)); SYS_OUT_CHAR (gpDeviceCtrl, ENE_TSTART, NE2000_TSTART); SYS_OUT_CHAR (gpDeviceCtrl, ENE_TCNTH, gpDeviceCtrl->packetLen[gpDeviceCtrl->useHead] >> 8); SYS_OUT_CHAR (gpDeviceCtrl, ENE_TCNTL, gpDeviceCtrl->packetLen[gpDeviceCtrl->useHead] & 0xff); if(gpDeviceCtrl->bufCount >=(SAVE_SND_NUM-1) ) { gpDeviceCtrl->useHead = 0x5a; gpDeviceCtrl->bufCount = SAVE_SND_NUM; } else { if(gpDeviceCtrl->useHead >= (SAVE_SND_NUM-1)) { gpDeviceCtrl->useHead = 0; } else { gpDeviceCtrl->useHead++; } gpDeviceCtrl->bufCount++; } CACHE_PIPE_FLUSH (); SYS_OUT_CHAR (gpDeviceCtrl, ENE_CMD, CMD_TXP | CMD_START); }void ne2000DmaSend(NE2000END_DEVICE* pDrvCtrl , int eneAddress){ char *sndBuf = NULL; int sndLen = 0; ENDLOGMSG (("into ne2000DmaSend.\n", 0, 0, 0, 0, 0, 0)); sndBuf = pDrvCtrl->packetBuf[pDrvCtrl->useHead]; sndLen = pDrvCtrl->packetLen[pDrvCtrl->useHead]; if (sndLen == 0) { ENDLOGMSG (("ne2000DmaSend:send len is 0.\n", 0, 0, 0, 0, 0, 0)); return; } if(rNE2000_DSTAT3 & 0xfffff) { ENDLOGMSG (("ne2000DmaSend:dma can not op.\n", 0, 0, 0, 0, 0, 0)); return ; } pDrvCtrl->flags |= END_TX_IN_PROGRESS; SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_NODMA | CMD_PAGE0 | CMD_START); SYS_OUT_CHAR (pDrvCtrl, ENE_RSAR0, eneAddress & 0xff); SYS_OUT_CHAR (pDrvCtrl, ENE_RSAR1, eneAddress >> 8); SYS_OUT_CHAR (pDrvCtrl, ENE_RBCR0, sndLen & 0xff); SYS_OUT_CHAR (pDrvCtrl, ENE_RBCR1, sndLen >> 8); SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_RWRITE | CMD_START); rNE2000_DISRC3 = (int)sndBuf; rNE2000_DISRCC3 = (0x0<<1) + 0x0; rNE2000_DIDST3 = ((U32)(pDrvCtrl)->base+ (int)ENE_DATA); rNE2000_DIDSTC3 = (0x0<<1)+0x1; rNE2000_DCON3 = ((unsigned)1<<31)+(1<<30)+(1<<29)+(0<<28)+(1<<27)+(0<<23)+(1<<22)+(0<<20)+sndLen;/*((len-0x30)/2);*/ rNE2000_DMASKTRIG3 = (0x0<<2) + (0x1<<1) + (0x1<<0); }#elsevoid ne2000DmaSendInt(){}void ne2000DmaSend(NE2000END_DEVICE* pDev , char *srcBuf , int sndLen){ if(rNE2000_DSTAT3 & 0xfffff) { return ; } rNE2000_DISRC3 = (int)srcBuf; rNE2000_DISRCC3 = (0x0<<1) + 0x0; rNE2000_DIDST3 = ((U32)(pDev)->base+ (int)ENE_DATA); rNE2000_DIDSTC3 = (0x0<<1)+0x1; rNE2000_DCON3 = ((unsigned)1<<31)+(1<<30)+(1<<29)+(0<<28)+(1<<27)+(0<<23)+(1<<22)+(0<<20)+sndLen;/*((len-0x30)/2);*/ rNE2000_DMASKTRIG3 = (0x0<<2) + (0x1<<1) + (0x1<<0); }#endif#ifdef _USE_RECV_DMA_void ne2000DmaRecvInt(){ gpDeviceCtrl->nextMapPage = 0; (void)netJobAdd ((FUNCPTR)ne2000HandleRcvInt, (int)gpDeviceCtrl, 0,0,0,0); }void ne2000DmaRecv(NE2000END_DEVICE *pDrvCtrl,int eneAddress,int len){ ENDLOGMSG (("into ne2000DmaRecv.\n", 0, 0, 0, 0, 0, 0)); if (len == 0) { pDrvCtrl->flags &= ~END_RECV_HANDLING_FLAG; pDrvCtrl->imask |= IM_PRXE; SYS_OUT_CHAR (pDrvCtrl, ENE_INTMASK, pDrvCtrl->imask); return; } SYS_OUT_CHAR (pDrvCtrl, ENE_INTMASK, 0); SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_NODMA | CMD_PAGE0 | CMD_START); SYS_OUT_CHAR (pDrvCtrl, ENE_RSAR0, eneAddress & 0xff); SYS_OUT_CHAR (pDrvCtrl, ENE_RSAR1, eneAddress >> 8); SYS_OUT_CHAR (pDrvCtrl, ENE_RBCR0, len & 0xff); SYS_OUT_CHAR (pDrvCtrl, ENE_RBCR1, len >> 8); SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_RREAD | CMD_START); rNE2000_DISRC0 = ((U32)(pDrvCtrl)->base+ (int)ENE_DATA); rNE2000_DISRCC0 = (0x0<<1) + 0x1; rNE2000_DIDST0 = ((U32)pDrvCtrl->recvMapBuf[0]); rNE2000_DIDSTC0 = (0x0<<1)+0x0; rNE2000_DCON0 = ((unsigned)1<<31)+(1<<30)+(1<<29)+(0<<28)+(1<<27)+(0<<23)+(1<<22)+(0<<20)+len;/*((len-0x30)/2);*/ rNE2000_DMASKTRIG0 = (0x0<<2) + (0x1<<1) + (0x1<<0);}#endif/********************************************************************************* ne2000OpenRecvIntLog - output bytes to NE2000 memory** NOMANUAL*/void ne2000OpenRecvIntLog(){ recvIntLog = TRUE;}/********************************************************************************* ne2000DataOut - output bytes to NE2000 memory** NOMANUAL*/LOCAL void ne2000DataOut ( NE2000END_DEVICE * pDrvCtrl, char * pData, int len, int eneAddress ) { ENDLOGMSG (("into ne2000DataOut.\n", 0, 0, 0, 0, 0, 0)); if (len == 0) return; SYS_OUT_CHAR (pDrvCtrl, ENE_RBCR0, (char)0xff); SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_NODMA | CMD_PAGE0 | CMD_START); SYS_OUT_CHAR (pDrvCtrl, ENE_RSAR0, eneAddress & 0xff); SYS_OUT_CHAR (pDrvCtrl, ENE_RSAR1, eneAddress >> 8); SYS_OUT_CHAR (pDrvCtrl, ENE_RBCR0, len & 0xff); SYS_OUT_CHAR (pDrvCtrl, ENE_RBCR1, len >> 8); SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_RWRITE | CMD_START); #ifndef _USE_SND_DMA_ #ifndef _UNUSE_SND_DMA_ ne2000DmaSend(pDrvCtrl , pData , len); #else SYS_OUT_WORD_STRING (pDrvCtrl, ENE_DATA, pData, len/2); if (len & 1) SYS_OUT_CHAR (pDrvCtrl, ENE_DATA, *(pData + (len - 1))); #endif #endif }/********************************************************************************* RETURNS: OK or ERROR.*/LOCAL STATUS ne2000Send ( void* pCookie, M_BLK_ID pMblk ) { int len; UCHAR cmdStat; int level = 0; NE2000END_DEVICE* pDrvCtrl = (NE2000END_DEVICE *) pCookie; ENDLOGMSG (("ne2000Send: enter: (flags=%x, imask=%x)\n", pDrvCtrl->flags, pDrvCtrl->imask, 0, 0, 0, 0)); if (pDrvCtrl->flags & (END_OVERWRITE | END_OVERWRITE2)) { return (END_ERR_BLOCK); } END_TX_SEM_TAKE (&pDrvCtrl->endObj, WAIT_FOREVER); #ifndef _USE_SND_DMA_ pDrvCtrl->flags |= END_TX_BLOCKED; #endif #ifndef _USE_SND_DMA_ if (pDrvCtrl->flags & END_TX_IN_PROGRESS) { int cnt; ENDLOGMSG (("ne2000Send: waiting for TX_IN_PROGRESS\n", 0,0,0,0,0,0)); cnt = sysClkRateGet (); while ((pDrvCtrl->flags & END_TX_IN_PROGRESS) && (cnt-- > 0)) { taskDelay (1); } } #endif #ifndef _USE_SND_DMA_ SYS_OUT_CHAR (pDrvCtrl, ENE_INTMASK, 0); if (pDrvCtrl->flags & (END_OVERWRITE | END_OVERWRITE2)) { ENDLOGMSG (("ne2000Send: overwrite detected (timeout)\n", 0, 0, 0, 0, 0, 0)); pDrvCtrl->flags &= ~END_TX_BLOCKED; END_TX_SEM_GIVE (&pDrvCtrl->endObj); return (END_ERR_BLOCK); } #endif #ifndef _USE_SND_DMA_ if (pDrvCtrl->flags & END_TX_IN_PROGRESS) { UCHAR tstat; SYS_IN_CHAR (pDrvCtrl, ENE_TSTAT, &tstat); SYS_IN_CHAR (pDrvCtrl, ENE_CMD, &cmdStat); ENDLOGMSG (("ne2000Send: timeout: flags=%x cmd=%02x stat=%02x\n", pDrvCtrl->flags, cmdStat, tstat, 0, 0, 0)); ne2000Config (pDrvCtrl, FALSE); } #endif #ifndef _USE_SND_DMA_ len = netMblkToBufCopy (pMblk, pDrvCtrl->packetBuf, NULL); netMblkClChainFree (pMblk); len = max (len, ETHERSMALL); SYS_OUT_CHAR (pDrvCtrl, ENE_INTMASK, 0x00); ne2000DataOut (pDrvCtrl, pDrvCtrl->packetBuf, len, (NE2000_TSTART << 8)); CACHE_PIPE_FLUSH (); SYS_OUT_CHAR (pDrvCtrl, ENE_TSTART, NE2000_TSTART); SYS_OUT_CHAR (pDrvCtrl, ENE_TCNTH, len >> 8); SYS_OUT_CHAR (pDrvCtrl, ENE_TCNTL, len & 0xff); SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_TXP | CMD_START); pDrvCtrl->flags |= END_TX_IN_PROGRESS; pDrvCtrl->imask |= (IM_TXEE | IM_PTXE); SYS_OUT_CHAR (pDrvCtrl, ENE_INTMASK, pDrvCtrl->imask); #else level = intLock (); if(pDrvCtrl->bufCount>0) { len = netMblkToBufCopy (pMblk, pDrvCtrl->packetBuf[pDrvCtrl->freeHead], NULL); len = max (len, ETHERSMALL); pDrvCtrl->packetLen[pDrvCtrl->freeHead] = len; if(0x5a == pDrvCtrl->useHead ) { pDrvCtrl->useHead = pDrvCtrl->freeHead; } if(pDrvCtrl->freeHead>= (SAVE_SND_NUM -1)) { pDrvCtrl->freeHead =0; } else { pDrvCtrl->freeHead++; } pDrvCtrl->bufCount--; intUnlock(level); } else { intUnlock(level); return (END_ERR_BLOCK); } netMblkClChainFree (pMblk); if (!(pDrvCtrl->flags & END_TX_IN_PROGRESS)) { ne2000DmaSend(pDrvCtrl , (NE2000_TSTART << 8)); } #endif END_TX_SEM_GIVE (&pDrvCtrl->endObj); END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, +1); ENDLOGMSG (("ne2000Send: done: imask=%02x\n", pDrvCtrl->imask, 0, 0, 0, 0, 0)); return (OK); }/********************************************************************************** RETURNS: ptr to next packet, or NULL if none ready.*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -