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

📄 ns83902end.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    NS83902_REG_SET (pDrvCtrl, NS83902_CR, CR_ABORT | CR_STA, CR_RPAGE0);    NS83902_REG_SET (pDrvCtrl, NS83902_TCR, TCR_MODE0, CR_RPAGE0);    }/********************************************************************************* ns83902EnetAddrGet - get the Ethernet address.** Get ethernet address from the BSP.** RETURNS: N/A.*/LOCAL void ns83902EnetAddrGet    (    NS83902_END_DEVICE*	pDrvCtrl,     char*		addr    )    {#if _BYTE_ORDER == _BIG_ENDIAN    /* For big endian we need to swap byte order */    int			i;    char 		bytes[6];    SYS_ENET_ADDR_GET (pDrvCtrl, bytes);    for (i=0; i<6; i++)	*addr++ = bytes[5-i];#else  /* _BYTE_ORDER == _LITTLE_ENDIAN  */    /* Little endian is in correct order */    SYS_ENET_ADDR_GET (pDrvCtrl, addr);#endif /* _BYTE_ORDER == _BIG_ENDIAN */    }/********************************************************************************* ns83902WritePort - write to the DMA port** RETURNS: N/A.*/LOCAL void ns83902WritePort    (    NS83902_END_DEVICE*	pDrvCtrl,        char *		pBuf,    int			len    )    {    int			ix;    UINT16 * 		pWide;    if (pDrvCtrl->wide == TRUE)	{	len = (++len) >> 1;	pWide = (UINT16 *) pBuf;	for (ix = 0 ; ix < len; ix++)	    {	    SYS_OUT_SHORT (pDrvCtrl, pDrvCtrl->ioPort, *pWide++);	    SYS_NS83902_DELAY();	    }	}    else	{	for (ix = 0 ; ix < len; ix++)	    {	    SYS_OUT_BYTE (pDrvCtrl, pDrvCtrl->ioPort, *pBuf++);	    SYS_NS83902_DELAY();	    }	}    }    /********************************************************************************* ns83902ReadPort - read the DMA port** RETURNS: N/A.*/LOCAL void ns83902ReadPort    (    NS83902_END_DEVICE*	pDrvCtrl,        char *		pBuf,    int			len    )    {    int 		ix;    UINT16 * 		pWide;    if (pDrvCtrl->wide == TRUE)	{	len = (++len) >> 1;	pWide = (UINT16 *) pBuf;	for (ix = 0 ; ix < len; ix++)	    {	    SYS_IN_SHORT (pDrvCtrl, pDrvCtrl->ioPort, *pWide++);	    }	}    else	{	for (ix = 0 ; ix < len; ix++)	    {	    SYS_IN_BYTE (pDrvCtrl, pDrvCtrl->ioPort, *pBuf++);	    }	}    }    /********************************************************************************* ns83902PktBufRead - read data from the NIC receive ring buffer** This routine gets exclusive access to the remote DMA, and gets data from * the NIC's receive ring buffer.** RETURNS: OK, or ERROR if obtaining the requested bytes encountered an error.*/LOCAL STATUS ns83902PktBufRead    (    NS83902_END_DEVICE*	pDrvCtrl,    UINT32		ns83902BufAddr,    UINT32		len,    char*		pData    )    {    /* Exclusive DMA access */    if (!NS83902_IS_IN_POLL_MODE())	NS83902_SEM_TAKE (pDrvCtrl, WAIT_FOREVER);    DRV_LOG (NS83902_DEBUG_RX, 	     "ns83902Receive: ns83902BufAddr:%u pData:%p len:%d\n",             ns83902BufAddr, (int)pData, len, 4, 5, 6);                /* Set up remote read DMA transfer */    NS83902_REG_SET (pDrvCtrl, NS83902_RBCR0, LSB(len), CR_RPAGE0);    NS83902_REG_SET (pDrvCtrl, NS83902_RBCR1, MSB(len), CR_RPAGE0);    NS83902_REG_SET (pDrvCtrl, NS83902_RSAR0, LSB(ns83902BufAddr), CR_RPAGE0);    NS83902_REG_SET (pDrvCtrl, NS83902_RSAR1, MSB(ns83902BufAddr), CR_RPAGE0);    NS83902_REG_SET (pDrvCtrl, NS83902_CR, CR_RREAD, CR_RPAGE0);    /* Get data through DMA port */    ns83902ReadPort (pDrvCtrl, pData, len);    if (!NS83902_IS_IN_POLL_MODE())	NS83902_SEM_GIVE (pDrvCtrl);    return (OK);    }/********************************************************************************* ns83902ReadFrame - read a packet off the interface ring buffer into a cluster** Allocates a new cluster from the cluster pool, and reads the frame from the* device into the cluster.** RETURNS: a cluster or NULL if any error*/LOCAL NS83902_CLUSTER ns83902ReadFrame    (    NS83902_END_DEVICE*	pDrvCtrl    )    {    NS83902_RX_FRAME*	pRx;    NS83902_CLUSTER	pRetCluster = NULL;    UINT32		frameAddress;    UINT16		len;			/* len of Rx pkt */    UINT8		bnry;    UINT8		rsr;    UINT8		cur;    /* Check receive status */    NS83902_REG_GET (pDrvCtrl, NS83902_RSR, rsr, CR_RPAGE0);    if ((rsr & RSR_PRX) != RSR_PRX)        return (pRetCluster);    NS83902_REG_GET (pDrvCtrl, NS83902_CURR, cur, CR_RPAGE1);    if (!(END_FLAGS_GET(&pDrvCtrl->endObj) & (IFF_UP | IFF_RUNNING)) ||        (pDrvCtrl->nextPage == cur))        return (pRetCluster);    DRV_LOG (NS83902_DEBUG_RX, "Start Read!\n", 1, 2, 3, 4, 5, 6);    /*     * There is work to be done.     * First we copy the NIC receive status header from the NIC buffer     * into our local area. This is done so that we can obtain the length     * of the packet before copying out the rest of it. Note that the length     * field in the NIC header includes the Ethernet header, the data, and     * the 4 byte FCS field.     */    /* Get a cluster */    if ((pRx = (NS83902_RX_FRAME*) netClusterGet (pDrvCtrl->endObj.pNetPool,                                           pDrvCtrl->pClPoolId)) == NULL)        {	pDrvCtrl->lastError.errCode = END_ERR_NO_BUF;	muxError (&pDrvCtrl->endObj, &pDrvCtrl->lastError);        DRV_LOG (NS83902_DEBUG_RX, "Cannot loan!\n", 1, 2, 3, 4, 5, 6);        END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);        return (pRetCluster);        }        /* read header */    DRV_LOG (NS83902_DEBUG_RX, "ns83902PktBufRead : Reading Header\n", 	     1, 2, 3, 4, 5, 6);    if (ns83902PktBufRead (pDrvCtrl, pDrvCtrl->nextPage << 8,                          (NS83902_RX_HDR_SZ), (char *) &pRx->rxHdr) == ERROR)        {        DRV_LOG (NS83902_DEBUG_RX,                 "ns83902PktBufRead could not read packet header\n",                 0, 0, 0, 0, 0, 0);	netClFree (pDrvCtrl->endObj.pNetPool, (UCHAR *)pRx);        return (pRetCluster);        }    /* Calculate real length */    len = pRx->rxHdr.count;#if (_BYTE_ORDER == _BIG_ENDIAN)    len = ((len >> 8) & 0x00ff) + ((len << 8) & 0xff00) - NS83902_ETH_CRC_LEN;#else    len = len - NS83902_ETH_CRC_LEN;#endif    /* write back value to rxHdr */    pRx->rxHdr.count = len;    /* Current frame address and next page */    frameAddress = (pDrvCtrl->nextPage << 8) + NS83902_RX_HDR_SZ;    pDrvCtrl->nextPage = pRx->rxHdr.nextRxPage;       /* valid frame checks */#ifdef	NS83902_INSTRUMENT    ns83902Len = len;    ns83902HdrStat = pRx->rxHdr.status;    ns83902NextPage = pRx->rxHdr.nextRxPage;    ns83902CurrentPage = cur;#endif    /* check for critical error; should never happen */    if (pDrvCtrl->nextPage < pDrvCtrl->rxStartPage || 	pDrvCtrl->nextPage >= pDrvCtrl->rxStopPage )	{	/* Can't recover, restart */#ifdef	NS83902_INSTRUMENT    	ns83902InitNb++;#endif	ns83902Config (pDrvCtrl);	pDrvCtrl->nextPage = pDrvCtrl->rxStartPage;	/* mark the interface up */	END_FLAGS_SET (&pDrvCtrl->endObj,		(IFF_UP | IFF_RUNNING | IFF_MULTICAST | IFF_BROADCAST));	netClFree (pDrvCtrl->endObj.pNetPool, (UCHAR *)pRx);	return (pRetCluster);	}    /*     * If the packet's receive status byte indicates an error the packet is      * discarded and the receive page pointers are updated to point to the      * next packet.     */    if ((len < 60) || (len > 1514) || 	((pRx->rxHdr.status & ~RSR_PHY) != RSR_PRX))	{        DRV_LOG (NS83902_DEBUG_RX,                 "ns83902Rcv receive error: statusHeader=0x%x nextRxPage=%d \                           currentPage=%d len=%d IntNb=%d\n",                 pRx->rxHdr.status, pRx->rxHdr.nextRxPage, cur, len,		 ns83902IntNb, 0);                END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);	/* update boundary pointer */	if (pDrvCtrl->nextPage == pDrvCtrl->rxStartPage)	    bnry = pDrvCtrl->rxStopPage;	else	    bnry = pDrvCtrl->nextPage - 1;	NS83902_REG_SET (pDrvCtrl, NS83902_BNRY, bnry, CR_RPAGE0);	netClFree (pDrvCtrl->endObj.pNetPool, (UCHAR *)pRx);	return (pRetCluster);	}    /* copy Ethernet packet section of the frame */        DRV_LOG (NS83902_DEBUG_RX, "ns83902PktBufRead : Reading Frame\n",	     1, 2, 3, 4, 5, 6);        if (ns83902PktBufRead (pDrvCtrl, frameAddress, len,			   (char *) &pRx->enetHdr) == ERROR)	{	DRV_LOG (NS83902_DEBUG_RX, "ns83902Recv: Could not read packet data\n",		 1, 2, 3, 4, 5, 6);	END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);	netClFree (pDrvCtrl->endObj.pNetPool, (UCHAR *)pRx);	}    else	{	/* Successfully got a frame */	pRetCluster = (NS83902_CLUSTER) pRx;	END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1);	}    /* update boundary pointer */    if (pDrvCtrl->nextPage == pDrvCtrl->rxStartPage)	bnry = pDrvCtrl->rxStopPage;    else	bnry = pDrvCtrl->nextPage - 1;    NS83902_REG_SET (pDrvCtrl, NS83902_BNRY, bnry, CR_RPAGE0);    DRV_LOG (NS83902_DEBUG_RX, "End Read!\n", 1, 2, 3, 4, 5, 6);    return (pRetCluster);    }/********************************************************************************* ns83902Recv - read a packet off the interface ring buffer** ns83902Recv copies packets from local memory into an mbuf and hands it to* the next higher layer (IP or etherInputHook).** RETURNS: TRUE, or FALSE if the packet reception encountered errors.*/LOCAL void ns83902Recv    (    NS83902_END_DEVICE*	pDrvCtrl,    NS83902_CLUSTER	pCluster    )    {    NS83902_RX_FRAME*	pRx = (NS83902_RX_FRAME*) pCluster;        CL_BLK_ID		pClBlk;    M_BLK_ID		pMblk;    UINT32		len = pRx->rxHdr.count;    /* Process frame received */    if ((pClBlk = netClBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT)) == NULL)        {	pDrvCtrl->lastError.errCode = END_ERR_NO_BUF;	muxError (&pDrvCtrl->endObj, &pDrvCtrl->lastError);        DRV_LOG (NS83902_DEBUG_RX, "Out of Cluster Blocks!\n", 1, 2, 3, 4, 5, 6);        netClFree (pDrvCtrl->endObj.pNetPool, (UCHAR *)pCluster);                END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);        goto cleanRXD;        }    /*     * OK we've got a spare, let's get an M_BLK_ID and marry it to the     * one in the ring.     */    if ((pMblk = mBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT, MT_DATA)) ==        NULL)        {        netClBlkFree (pDrvCtrl->endObj.pNetPool, pClBlk);        netClFree (pDrvCtrl->endObj.pNetPool, (UCHAR *)pCluster);        DRV_LOG (NS83902_DEBUG_MB, "Out of M Blocks!\n", 1, 2, 3, 4, 5, 6);        END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);        goto cleanRXD;        }    END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1);    /* Join the cluster to the MBlock */    netClBlkJoin (pClBlk, (char*)pCluster, len, NULL, 0, 0, 0);    netMblkClJoin (pMblk, pClBlk);    pMblk->mBlkHdr.mData 	= (char *)&pRx->enetHdr;    pMblk->mBlkHdr.mFlags 	|= M_PKTHDR;	/* set the packet header */    pMblk->mBlkHdr.mLen		= len;		/* set the data len */    pMblk->mBlkPktHdr.len 	= len;		/* set the total len */    /* Call the upper layer's receive routine. */    END_RCV_RTN_CALL (&pDrvCtrl->endObj, pMblk);cleanRXD:    return;    }/********************************************************************************* ns83902Restart - restart chip after receive ring buffer overflow** This routine is called from an isr handler that deals with a receive DMA* overflow condition.  It gets access to the remote DMA, cleans up NIC* registers and defers work to task context to empty the receive ring buffers.** RETURNS: N/A.*/LOCAL void ns83902Restart    (    NS83902_END_DEVICE*	pDrvCtrl,    UINT8		cr    )    {    UINT8		isr;#ifdef	NS83902_INSTRUMENT    ns83902RestartNb++;#endif    /* Buffer ring overflow algorithm */    NS83902_REG_SET (pDrvCtrl, NS83902_CR, CR_STP | CR_ABORT, CR_RPAGE0);    /* wait at least 1.6 mSec */    SYS_MS_DELAY (2);    /* Remove packets from buffer */    NS83902_REG_SET (pDrvCtrl, NS83902_RBCR0, 0, CR_RPAGE0);    NS83902_REG_SET (pDrvCtrl, NS83902_RBCR1, 0, CR_RPAGE0);    NS83902_REG_GET (pDrvCtrl, NS83902_ISR, isr, CR_RPAGE0);    if ((cr & CR_TXP) && (!(isr & (ISR_TXE | ISR_PTX))))    	pDrvCtrl->txResend = TRUE;    NS83902_REG_SET (pDrvCtrl, NS83902_TCR, TCR_MODE1, CR_RPAGE0);    NS83902_REG_SET (pDrvCtrl, NS83902_CR, CR_ABORT | CR_STA, CR_RPAGE0);    END_FLAGS_SET (&pDrvCtrl->endObj, IFF_UP | IFF_RUNNING | IFF_NOTRAILERS);    pDrvCtrl->rxOvw = TRUE;    if (pDrvCtrl->rxHandling == FALSE)	{	pDrvCtrl->rxHandling = TRUE;	netJobAdd ((FUNCPTR) ns83902HandleInt, (int) pDrvCtrl, 0, 0, 0, 0);	}    }/********************************************************************************* ns83902HandleInt - deferred receive interrupt handler** This function handles the received frames from the device.  It runs in the* context of the netTask, which was triggered by a received packet interrupt.* It resends any packet that was in the midst of transmission when the overflow* hit.* Actual processing of the packet is done by calling ns83902Recv().

⌨️ 快捷键说明

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