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

📄 nicevbend.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	return (pRetCluster);	}    END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1);        DRV_LOG (DRV_DEBUG_POLL, "End Read!\n", 1, 2, 3, 4, 5, 6);         return (NIC_CLUSTER)pRx;    }/********************************************************************************* nicEvbRestart - restart chip after receive ring buffer overflow** This routine is the task-level handler that deals with a receive DMA* overflow condition.  It gets access to the remote DMA, cleans up NIC* registers, empties the receive ring buffers, and then resends any* packet that was in the midst of transmission when the overflow hit.** RETURNS: N/A.*/LOCAL void nicEvbRestart    (    NICEVB_END_DEVICE*	pDrvCtrl,    UINT8		cr    )    {    NIC_DEVICE *	pNic = pDrvCtrl->pNic;	/* NIC registers */    BOOL		resend = FALSE;#ifdef	NIC_INSTRUMENT    nicRestartNb++;#endif    nicEvbWriteCr (pNic, STP);    nicEvbResetDelay ();	/* wait at least 1.6 mSec */    if(!NIC_IS_IN_POLL_MODE())        {        if (semTake(pDrvCtrl->dmaSem, 100) == ERROR)            {            DRV_LOG (DRV_DEBUG_LOAD, "nicRestart: can't obtain dmaSem\n",                     0, 0, 0, 0, 0,0);            semTake (pDrvCtrl->dmaSem, WAIT_FOREVER);            }        }    nicEvbWriteReg (pNic, &pNic->Rbcr0, 0, RPAGE0);    nicEvbWriteReg (pNic, &pNic->Rbcr1, 0, RPAGE0);    if ((cr & TXP) && (!(nicEvbReadReg (pNic, &pNic->Isr, RPAGE0) &        (TXE | PTX))))    	resend = TRUE;    nicEvbWriteReg (pNic, &pNic->Tcr, MODE1, RPAGE0);    nicEvbWriteCr (pNic, RPAGE0 | ABORT | STA);		/* back to page 0 */    END_FLAGS_SET (&pDrvCtrl->end, IFF_UP | IFF_RUNNING | IFF_NOTRAILERS);        while (nicEvbRead (pDrvCtrl))	;    nicEvbWriteReg(pNic, &pNic->Isr, OVW, RPAGE0);    nicEvbWriteReg (pNic, &pNic->Tcr, MODE0, RPAGE0);    if (resend)        nicEvbWriteCr (pNic, RPAGE0 | STA | TXP | ABORT);    if(!NIC_IS_IN_POLL_MODE())        semGive(pDrvCtrl->dmaSem);    nicEvbWriteReg (pNic, &pNic->Imr, PRXE | OVWE, RPAGE0);    }/********************************************************************************* nicEvbHandleInt - 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.* Actual processing of the packet is done by calling nicEvbRead().** RETURNS: N/A.*/LOCAL void nicEvbHandleInt    (    NICEVB_END_DEVICE*	pDrvCtrl        )    {    /* empties the receive ring buffer of its packets */    while (nicEvbRead (pDrvCtrl));    }/********************************************************************************* nicIntr - The driver's interrupt handler** This function clears the cause of the device interrupt(s) and then acts* on the individual possible causes.  The primary goal of this routine is to* minimize the time spent in it.  This is accomplished by deferring processing* to the netTask via the netJobAdd() function.** Note that in case the receiver overruns, we promptly mark the interface as* "down" and leave error handling to task-level.   This is in case netTask* is in the midst of DMA activity, we must allow it to complete.  The receive* handler will give up when it discovers the interface is down, which will* then allow netTask to run our OVW handler.  This provides a nice orderly* error recovery.** RETURNS: N/A.*/LOCAL void nicEvbInt    (    NICEVB_END_DEVICE*	pDrvCtrl    )    {    NIC_DEVICE *	pNic = pDrvCtrl->pNic;	/* NIC registers */    UINT8		isr;				/* copy of ISR */    UINT8		cr;				/* copy of CR */#ifdef	DRV_DEBUG    nicIntNb++;#endif    DRV_LOG (DRV_DEBUG_INT, "Inside INT\n", 1, 2, 3, 4, 5, 6);        isr = nicEvbReadReg(pNic, &pNic->Isr, RPAGE0);    nicEvbWriteReg(pNic, &pNic->Isr, isr, RPAGE0);    /* handle receiver overrun */    if  ((isr & OVW) && (END_FLAGS_GET(&pDrvCtrl->end) & (IFF_UP | IFF_RUNNING)))	{	cr = nicEvbReadReg (pNic, &pNic->Cr, RPAGE0);	nicEvbWriteReg(pNic, &pNic->Imr, 0, RPAGE0); /* disable all interrupts */        /* mark the interface -- down */        END_FLAGS_CLR (&pDrvCtrl->end, IFF_UP | IFF_RUNNING);        	netJobAdd ((FUNCPTR) nicEvbRestart, (int) pDrvCtrl, cr, 0, 0, 0);        return;	}    /* handle packet received */    if  ((isr & PRX) && (END_FLAGS_GET(&pDrvCtrl->end) & (IFF_UP | IFF_RUNNING)))	netJobAdd ((FUNCPTR) nicEvbHandleInt, (int) pDrvCtrl, 0, 0, 0, 0);    }/********************************************************************************* nicEvbSend - the driver's actual output routine** This routine accepts outgoing packets from the snd queue, and then * gains exclusive access to the DMA (through a mutex semaphore),* then calls nicEvbTransmit() to send the packet out onto the interface.** RETURNS: OK, or ERROR if the packet could not be transmitted.*/LOCAL STATUS nicEvbSend    (    NICEVB_END_DEVICE* pDrvCtrl,    M_BLK* pMblk    )    {    int	status = OK;    DRV_LOG(DRV_DEBUG_TX, "Begin nicEvbSend pDrvCtrl %p pMblk %p\n", pDrvCtrl,            pMblk, 0, 0, 0, 0);    if ((END_FLAGS_GET(&pDrvCtrl->end) & (IFF_UP | IFF_RUNNING)) !=        (IFF_UP | IFF_RUNNING))        {        DRV_LOG(DRV_DEBUG_TX, "Device is NOT UP and RUNNING\n", 0, 0,                0, 0, 0, 0);	if(!NIC_IS_IN_POLL_MODE())        netMblkClChainFree (pMblk); /* free the given mBlk chain */        errno = EINVAL;        return (ERROR);        }    if(!NIC_IS_IN_POLL_MODE())        {        if (semTake (pDrvCtrl->dmaSem, 100) == ERROR)	/* get DMA access */            {            DRV_LOG(DRV_DEBUG_TX, "nicTxStartup: can't obtain dmaSem\n",                      0, 0, 0, 0, 0, 0);            semTake (pDrvCtrl->dmaSem, WAIT_FOREVER);            }        }    /* update statistics */    END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1);#ifdef	NIC_INSTRUMENT    nicTxNb++;#endif    /* send packet out over interface */    if ((status = nicEvbTransmit (pDrvCtrl, pMblk, TRUE)) == ERROR)        {        DRV_LOG(DRV_DEBUG_TX, "FAILED nicEvbTransmit\n", 0, 0, 0, 0, 0, 0);                /* update statistics */        END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1);        /* TODO update error count */        }    if(!NIC_IS_IN_POLL_MODE())	{        semGive (pDrvCtrl->dmaSem);    	/* free the Mblk chain */        	netMblkClChainFree (pMblk);	}        DRV_LOG(DRV_DEBUG_TX, "End nicEvbSend \n", 0, 0, 0, 0, 0, 0);            return status;        }/********************************************************************************* nicEvbTransmit - send data over the NIC network interface** This routine transfers data to the NIC device via the remote DMA, and* then signal for a transmission.** RETURNS: OK, or ERROR if the transmitter signalled an error.*/LOCAL STATUS nicEvbTransmit    (    NICEVB_END_DEVICE* pDrvCtrl,        M_BLK*		pMblk,    BOOL		waitFlag    )    {    NIC_DEVICE *	pNic = pDrvCtrl->pNic;    UINT8		cr;    UINT8		isr;    UINT8*		pBuf;    int			status = OK;    int			count;    int			ix;    int			len;    int			tranxLen;    /* find the length of the packet */        len = nicEvbMblkDataLenGet (pMblk);        /* find the length of the packet */    tranxLen = max (len, MINPKTSIZE);    #ifdef	NIC_FASTER    nicWriteReg(pNic, &pNic->Imr, 0, RPAGE0);   /* disable all interrupts */#endif    nicEvbWriteReg (pNic, &pNic->Rbcr0, 0x10, RPAGE0);    nicEvbWriteCr (pNic, RREAD);    nicEvbWriteReg (pNic, &pNic->Rbcr0, (tranxLen & 0x00ff), RPAGE0);    nicEvbWriteReg (pNic, &pNic->Rbcr1, (tranxLen & 0xff00) >> 8, RPAGE0);    nicEvbWriteReg (pNic, &pNic->Rsar0, 0x00, RPAGE0);    nicEvbWriteReg (pNic, &pNic->Rsar1, 0x00, RPAGE0);    nicEvbWriteCr (pNic, RWRITE);        count = 0;    while (pMblk != NULL)        {        pBuf = (char *)pMblk->mBlkHdr.mData;        len  = pMblk->mBlkHdr.mLen;	for (ix = 0 ; ix < len; ix++)	    { 	    count++;	    nicEvbWritePort (*pBuf++);	    }        pMblk = pMblk->mBlkHdr.mNext;        }        for (; count < tranxLen; count ++)		/* pad out if too short */	nicEvbWritePort (0);    nicEvbWriteReg (pNic, &pNic->Tpsr, 0x00, RPAGE0);    nicEvbWriteReg (pNic, &pNic->Tbcr0, (tranxLen & 0x000000ff), RPAGE0);    nicEvbWriteReg (pNic, &pNic->Tbcr1, ((tranxLen & 0x0000ff00) >> 8), RPAGE0);    cr = nicEvbReadReg (pNic, &pNic->Cr, RPAGE0);    nicEvbWriteReg(pNic, &pNic->Isr, (PTX | TXE), RPAGE0);    nicEvbWriteCr (pNic, TXP | (cr & (RWRITE | RREAD)));	/* start Tx */    count = 0;    if (waitFlag)				/* wait for Tx to end ? */	{        while (count++ < NIC_TRANS_TIMEOUT)		/* only poll a few times */	    {            isr = nicEvbReadReg (pNic, &pNic->Isr, RPAGE0);	    if (isr & TXE)			/* error encountered */	        {                DRV_LOG(DRV_DEBUG_TX, "ERROR in Transmition\n",                           0, 0, 0, 0, 0, 0);                                                status = ERROR;	        break;	        }	    if (isr & PTX)			/* Tx done */                {                DRV_LOG(DRV_DEBUG_TX, "Transmit Done\n",                           0, 0, 0, 0, 0, 0);                	        break;                }            }        if (count >= NIC_TRANS_TIMEOUT)		/* error ? */	    {            status = ERROR;#ifdef	NIC_INSTRUMENT	    nicTxTimeout++;#endif            DRV_LOG(DRV_DEBUG_LOAD, "nicTransmit TRANS_TIMEOUT %d\n",                    nicTxTimeout,0,0,0,0,0);	    }        }#ifdef	NIC_FASTER    nicEvbWriteReg(pNic, &pNic->Imr, PRXE | OVWE, RPAGE0); /* re-enable intr. */#endif    return (status);    }/********************************************************************************* nicEvbMblkDataLenGet - gets the total len of the given Mblk chain packet** RETURNS: length of the packet.**/LOCAL int nicEvbMblkDataLenGet    (    M_BLK* pMblk    )    {    int nPktChainLen = 0;    while (pMblk != NULL)        {        nPktChainLen += pMblk->mBlkHdr.mLen;        pMblk = pMblk->mBlkHdr.mNext;        }            return (nPktChainLen);    }/********************************************************************************* nicEnetAddrGet - get the Ethernet address.** Get ethernet address from the BSP.** RETURNS: N/A.*/LOCAL void nicEvbEnetAddrGet    (    NICEVB_END_DEVICE*	pDrvCtrl,    char*		pAddress    )    {    UINT8		enetAdrs[6];    UINT8		count;    if (sysEnetAddrGet (pDrvCtrl->unit, enetAdrs) != ERROR )        {        for (count=0; count<6; count++)            pAddress[count] = enetAdrs[5-count];        }    }/********************************************************************************* nicEvbWritePort - write to the DMA port** RETURNS: N/A.*/LOCAL void nicEvbWritePort    (    UINT8		value    )    {#ifndef	NIC_FASTER    int			level = intLock ();#endif    do 	{	*(volatile char *) NIC_PORT = value;        }    while (!((*(volatile UINT8 *) NIC_DMA) & ACC_MASK));#ifndef	NIC_FASTER    intUnlock (level);#endif    }        /********************************************************************************* nicIoctl - the driver's I/O control routine** Perform device-specific commands.** RETURNS: 0, or EINVAL if the command 'cmd' is not supported.*/LOCAL int nicEvbIoctl    (    NICEVB_END_DEVICE* pDrvCtrl,    int cmd,    caddr_t data        )    {    int error = 0;    DRV_LOG (DRV_DEBUG_LOAD, "nicEvbIoctl Command %d\n", cmd, 2, 3, 4, 5, 6);        switch (cmd)	{        case EIOCSADDR:	    if (data == NULL)		return (EINVAL);

⌨️ 快捷键说明

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