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

📄 ne2000end.c

📁 BSP for S3C2410
💻 C
📖 第 1 页 / 共 4 页
字号:
				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 + -