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

📄 ei82596end.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    SYS_INT_ENABLE (pDrvCtrl);    return (OK);    }/********************************************************************************* ei82596Send - arrange to transmit a packet** This routine takes a NET_BUFFER and a NET_ADDRESS and sends the data in the* NET_BUFFER to the NET_ADDRESS.** RETURNS:*/LOCAL STATUS ei82596Send    (    END_CTRL	*pDrvCtrl,    M_BLK_ID	pMblk    )    {    TFD *	pTfd;    int		len;    DRV_PRINT (DRV_DEBUG_TX, ("t "));#if 0    SYS_INT_DISABLE (pDrvCtrl);    if (pDrvCtrl->txBlocked)        {        SYS_INT_ENABLE (pDrvCtrl);        return (END_ERR_BLOCK);        }    SYS_INT_ENABLE (pDrvCtrl);#endif                    /* check device mode */    if (DRV_FLAGS_ISSET(EI_POLLING))        {#if 0#ifdef DRV_DEBUG        if (eiDebug & DRV_DEBUG_POLL_REDIR)            {            ei82596PollSend (pDrvCtrl, pNetBuf);            return (OK);            }#endif /*DRV_DEBUG*/        #endif        netMblkClChainFree (pMblk); /* free the given mBlk chain */	errno = EINVAL;        return (ERROR);        }    SYS_INT_DISABLE( pDrvCtrl );    if ((pTfd = (TFD *) ei82596QGet (&pDrvCtrl->freeQueue)) != NULL)        {        SYS_INT_ENABLE( pDrvCtrl );        len = netMblkToBufCopy (pMblk, (char *)pTfd->enetHdr, NULL);        netMblkClChainFree (pMblk);        /* set up the byte count field; use a min frame size of ETHERSMALL */        pTfd->count = max (ETHERSMALL, len);        pTfd->count &= ~0xc000;        /* arrange to to transmit the buffer */        SYS_INT_DISABLE( pDrvCtrl );        ei82596TxQPut (pDrvCtrl, pTfd);        SYS_INT_ENABLE( pDrvCtrl );        }    else /* case if the pfd is equal to NULL */        {        pDrvCtrl->txBlocked = TRUE;        SYS_INT_ENABLE( pDrvCtrl );        return (END_ERR_BLOCK);        }    return (OK);    }/********************************************************************************* ei82596Int - entry point for handling interrupts from the 82596** The interrupting events are acknowledged to the device, so that the device* will deassert its interrupt signal.  The amount of work done here is kept* to a minimum; the bulk of the work is defered to the netTask.  Several flags* are used here to synchronize with task level code and eliminate races.*/LOCAL void ei82596Int    (    END_CTRL *pDrvCtrl    )    {    SCB		*pScb=pDrvCtrl->pScb;    int		unit=pDrvCtrl->unit;    UINT16	event;    event = pScb->scbStatus & (SCB_S_CX | SCB_S_FR | SCB_S_CNA | SCB_S_RNR);    DRV_PRINT (DRV_DEBUG_INT, ("eiInt: event=0x%x\n", event));    ei82596Command (pDrvCtrl, event);        /* ack the events */    sys596IntAck (unit);                     /* ack 596 interrupt */    /* Handle transmitter interrupt */    if (event & SCB_S_CNA)                   /* reclaim tx tfds */        {        pDrvCtrl->wdTxTimeout = 0;           /* reset timeout count */        ei82596QCat (&pDrvCtrl->cleanQueue, &pDrvCtrl->cblQueue);        ei82596QInit (&pDrvCtrl->cblQueue);                if (! pDrvCtrl->txCleaning)          /* not cleaning? */            {            pDrvCtrl->txCleaning = TRUE;            /* defer cleanup */            netJobAdd ((FUNCPTR) ei82596TxCleanQ, (int) pDrvCtrl, 0, 0, 0, 0);            }        if (pDrvCtrl->txBlocked)            {            /* potential race condition ??? */            pDrvCtrl->txBlocked = FALSE;            netJobAdd ((FUNCPTR) muxTxRestart, (int) &pDrvCtrl->endObj, 0, 0,                       0, 0);            }        if (pDrvCtrl->txQueue.head != NULL)  /* anything to flush? */            ei82596TxQFlush (pDrvCtrl);      /* flush the tx q */        else            pDrvCtrl->txIdle = TRUE;      /* transmitter idle */        }    /* Handle receiver interrupt */    if (event & SCB_S_FR)	{	pDrvCtrl->wdRxTimeout = 0;           /* reset timeout count */	if (! pDrvCtrl->rxHandling)            {            pDrvCtrl->rxHandling = TRUE;            (void) netJobAdd ((FUNCPTR) ei82596RxIntHandle,                              (int) pDrvCtrl,0, 0, 0, 0);/* netTask processes */	    }        }    }/********************************************************************************* ei82596TxCleanQ - checks errors in completed TFDs and moves TFDs to free queue** This routine is executed by netTask.  It "cleans" the TFDs on the clean-up* queue by checking each one for errors and then returning the TFD to the* "free TFD" queue.  The startup routine is sometimes called here to eliminate* the lock-out case where the driver input queue is full but there are no* TFDs available.*/LOCAL void ei82596TxCleanQ    (    END_CTRL *pDrvCtrl    )    {    TFD	*	pTfd;    do        {        pDrvCtrl->txCleaning = TRUE;        /* process transmitted frames */        while (1)            {            /* INT and SEM locks while manipulating this queue */            END_TX_SEM_TAKE (&pDrvCtrl->endObj, WAIT_FOREVER);            SYS_INT_DISABLE( pDrvCtrl );            pTfd = (TFD*) ei82596QGet ((EI_LIST *)&pDrvCtrl->cleanQueue);            SYS_INT_ENABLE( pDrvCtrl );            END_TX_SEM_GIVE (&pDrvCtrl->endObj);                        if (pTfd == NULL)                break;            if (!(pTfd->status & CFD_S_OK))          /* packet not sent */                {                END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_ERRS,  +1);                END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, -1);                }            /* return to tfdQ */            END_TX_SEM_TAKE (&pDrvCtrl->endObj, WAIT_FOREVER);            ei82596QPut (pDrvCtrl,(EI_LIST *)&pDrvCtrl->freeQueue,                         (EI_NODE*)pTfd);#ifdef DRV_DEBUG            nLoan--;#endif            END_TX_SEM_GIVE (&pDrvCtrl->endObj);                        }        pDrvCtrl->txCleaning = FALSE;        }    while (pDrvCtrl->cleanQueue.head != NULL);       /* check again */    }/********************************************************************************* ei82596RxIntHandle - 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.*/LOCAL void ei82596RxIntHandle    (    END_CTRL *pDrvCtrl    )    {    RFD *pRfd;    do        {        pDrvCtrl->rxHandling = TRUE;         /* interlock with ei82596Int()*/        while ((pRfd = ei82596RxQGet (pDrvCtrl)) != NULL)            ei82596Recv (pDrvCtrl, pRfd);        pDrvCtrl->rxHandling = FALSE;        /* interlock with ei82596Int()*/        }    while (ei82596RxQFull (pDrvCtrl));          /* make sure rx q still empty */    }/********************************************************************************* ei82596Recv - pass a received frame to the upper layer*** RETURNS: */LOCAL void ei82596Recv    (    END_CTRL *	pDrvCtrl,    RFD *	pRfd    )    {    RFD * 	pRfdLoaned 	= NULL;    M_BLK_ID	pMblk		= NULL;    CL_BLK_ID	pClBlk		= NULL;    /* process the frame, if there are no errors */    if ((pRfd->status & (RFD_S_OK | RFD_S_COMPLETE)) !=     					(RFD_S_OK | RFD_S_COMPLETE))	goto eiRecvError;    if ((pMblk = netMblkGet (pDrvCtrl->endObj.pNetPool,                             M_DONTWAIT, MT_DATA)) == NULL)        goto eiRecvError;    if ((pClBlk = netClBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT)) == NULL)        goto eiRecvError;        if ((pRfdLoaned = (RFD *) netClusterGet (pDrvCtrl->endObj.pNetPool,                                             pDrvCtrl->pClPoolId)) == NULL)        goto eiRecvError;    /* offset pRfdLoaned if needed */    pRfdLoaned = (RFD *) (((char *) pRfdLoaned) + pDrvCtrl->offset);    DRV_PRINT (DRV_DEBUG_RX, ("r "));    netClBlkJoin (pClBlk, ((char *)pRfd) - pDrvCtrl->offset,		  sizeof (RFD) + pDrvCtrl->offset, NULL, 0, 0, 0);    netMblkClJoin (pMblk, pClBlk);    END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1);    pMblk->mBlkHdr.mFlags 	|= M_PKTHDR;    pMblk->mBlkHdr.mData  	= (char *)&pRfd->enetHdr [0];    pMblk->mBlkHdr.mLen		= pRfd->count & ~0xc000;    pMblk->mBlkPktHdr.len 	= pMblk->mBlkHdr.mLen;    /* return the buffer to the receive queue */    ei82596RxQPut (pDrvCtrl, (RFD *)pRfdLoaned);        END_RCV_RTN_CALL (&pDrvCtrl->endObj, pMblk);    return; eiRecvError:    END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);    /* return the buffer to the receive queue */    ei82596RxQPut (pDrvCtrl, (RFD *)pRfd);    if (pClBlk)        netClBlkFree (pDrvCtrl->endObj.pNetPool, pClBlk);     if (pMblk)        netMblkFree (pDrvCtrl->endObj.pNetPool, pMblk);     return;    }/********************************************************************************* ei82596PollStart - start polling mode** RETURNS:*/LOCAL STATUS ei82596PollStart    (    END_CTRL 	*pDrvCtrl    )    {    int		intLevel;    DRV_LOG (DRV_DEBUG_POLL, "PollStart", 0, 1, 2, 3, 4, 5 );    intLevel = intLock();                         /* lock interrupts */    SYS_INT_DISABLE( pDrvCtrl );    DRV_FLAGS_SET (EI_POLLING);    intUnlock (intLevel);                         /* unlock interupts */    return (OK);    }/********************************************************************************* ei82596PollStop - stop polling mode** RETURNS:*/LOCAL STATUS ei82596PollStop    (    END_CTRL 	*pDrvCtrl    )    {    int		intLevel;    DRV_LOG (DRV_DEBUG_POLL, "PollStop", 0, 1, 2, 3, 4, 5);        intLevel = intLock();    SYS_INT_ENABLE( pDrvCtrl );    DRV_FLAGS_CLR (EI_POLLING);    intUnlock (intLevel);    return (OK);    }/********************************************************************************* ei82596PollSend - transmit a packet in polled mode** RETURNS:*/LOCAL STATUS ei82596PollSend    (    END_CTRL 	*pDrvCtrl,    M_BLK_ID	pMblk		/* pointer to the mBlk/cluster pair */    )    {    TFD 	*pTfd;    char 	*pTemp;    int		len;    DRV_LOG (DRV_DEBUG_POLL_TX, "T", 0, 1, 2, 3, 4, 5);    /* check if the command unit is active */    if (pDrvCtrl->pScb->scbStatus & SCB_S_CUACTIVE)        {        DRV_LOG (DRV_DEBUG_POLL_TX, "e ", 0, 1, 2, 3, 4, 5);        return (EAGAIN);        }    /* Is this ours? */    pTfd = pDrvCtrl->pPollTfd;    len = netMblkToBufCopy (pMblk, (char *)pTfd->enetHdr, NULL);        DRV_LOG (DRV_DEBUG_POLL_TX, "h ", 0, 1, 2, 3, 4, 5);            pTfd->count = max (len, ETHERSMALL) & ~0xc000;    /* transmit the buffer */    pTfd->status   = 0;    pTfd->command  = CFD_C_XMIT | CFD_C_EL;    pTfd->count   |= TFD_CNT_EOF;    pTfd->reserved = 0;    LINK_WR (&pTfd->lBufDesc, NULL);        pTemp = CACHE_DRV_VIRT_TO_PHYS (&pDrvCtrl->cacheFuncs, pTfd);    LINK_WR (&pDrvCtrl->pScb->pCB, pTemp);    ei82596Command (pDrvCtrl, SCB_C_CUSTART);        /* wait for the command to complete */    while (pDrvCtrl->pScb->scbStatus & SCB_S_CUACTIVE)        ;                       /* HELP: timeout */    /* update statistics */        if (pTfd->status & CFD_S_OK)        END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, +1);    if (pTfd->status & CFD_S_RETRY)        END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_ERRS, +1);        return (OK);    }

⌨️ 快捷键说明

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