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

📄 ibmemacend.c

📁 WINDRIVER SBC405 BSP
💻 C
📖 第 1 页 / 共 5 页
字号:
        else            isrClear = EMAC_ISR_TX_INTS | EMAC_ISR_DB0;        EMAC_REG_WRITE(pDrvCtrl, EMAC_ISR, isrClear);        }    /*     * Check to see if there was a RX error.  Clear the status bits for the     * RX error.  Keep count of these errors in the main device structure.     *     * Note that non-zero values of EMAC_ISR_RX_INTS are used primarily     * for debugging.  When EMAC_ISR_RX_INTS is zero, some compilers     * may warn about an always-false conditional expression.     */    if (isrReg & EMAC_ISR_RX_INTS)        {        pDrvCtrl->intErrorRX++;        EMAC_REG_WRITE(pDrvCtrl, EMAC_ISR, EMAC_ISR_RX_INTS);        }    return;    }/********************************************************************************* ibmEmacTxeobInt - handle controller TX end-of-buffer interrupt** This routine is called at interrupt level in response to an interrupt from* the MAL.*/LOCAL void ibmEmacTxeobInt    (    EMAC_DRV_CTRL *   pDrvCtrl    )    {    DRV_LOG (DRV_DEBUG_TX, "EMAC TX EOB int\n", 1, 2, 3, 4, 5, 6);    /* Start the cleanup job */    if ((pDrvCtrl->localFlags & EMAC_TX_CLEAN_RUNNING) == 0)        {        if (netTaskId && netTaskId != ERROR)            {            pDrvCtrl->localFlags |= EMAC_TX_CLEAN_RUNNING;            netJobAdd((FUNCPTR)ibmEmacSendCleanup, (int)pDrvCtrl, 0, 0, 0, 0);            }        else            ibmEmacSendCleanup(pDrvCtrl);        }    if (pDrvCtrl->localFlags & EMAC_TX_BLOCKED)        {        DRV_LOG (DRV_DEBUG_ERROR, "TX blocked.  Call muxRestart\n",                                  1 , 2, 3, 4, 5, 6);        pDrvCtrl->localFlags &= ~EMAC_TX_BLOCKED;        if (netTaskId && netTaskId != ERROR)            netJobAdd((FUNCPTR)muxTxRestart, (int)&pDrvCtrl->end, 0, 0, 0, 0);        else            muxTxRestart(&pDrvCtrl->end);        }    return;    }/********************************************************************************* ibmEmacWdRestart - handle restart in case MUX blocks or driver fails** This routine is called at interrupt level (WatchDog) in case the MUX is blocked* or the hardware fails.*/LOCAL void ibmEmacWdRestart    (    EMAC_DRV_CTRL *   pDrvCtrl    ){    DRV_LOG(DRV_DEBUG_ERROR, "INFO: RestartWatchdog kicks driver\n", 1, 2, 3, 4, 5, 6);    /* Now that status from the packet just transmitted has been copied back     * to the main TX ring, it is safe to allow another TX operation. */	/* semGive (pDrvCtrl->txSem2nd); */    /* Start the cleanup job */    if ((pDrvCtrl->localFlags & EMAC_TX_CLEAN_RUNNING) == 0)	{        pDrvCtrl->localFlags |= EMAC_TX_CLEAN_RUNNING;        if ( netJobAdd((FUNCPTR)ibmEmacSendCleanup, (int)pDrvCtrl, 0, 0, 0, 0) == ERROR )			DRV_LOG (DRV_DEBUG_ERROR, "FATAL: netJobAdd ibmEmacSendCleanup failed\n",1,2,3,4,5,6); 	}	/* check if TX is/was blocked, unblock it*/    if (pDrvCtrl->localFlags & EMAC_TX_BLOCKED)	{		DRV_LOG (DRV_DEBUG_ERROR, "INFO: Watchdog expired: MUX blocked, unblocking, calling muxRestart\n",1,2,3,4,5,6);        pDrvCtrl->localFlags &= ~EMAC_TX_BLOCKED;        if ( netJobAdd((FUNCPTR)muxTxRestart, (int)&pDrvCtrl->end, 0, 0, 0, 0) == ERROR )			DRV_LOG (DRV_DEBUG_ERROR, "FATAL: netJobAdd muxTxRestart failed\n",1,2,3,4,5,6);	}    return;}/********************************************************************************* ibmEmacRxeobInt - handle controller RX end-of-buffer interrupt** This routine is called at interrupt level in response to an interrupt from* the MAL.*/LOCAL void ibmEmacRxeobInt    (    EMAC_DRV_CTRL *   pDrvCtrl    )    {    DRV_LOG (DRV_DEBUG_INT, "EMAC RX EOB int: 0x%x 0x%x\n", pDrvCtrl->indexRxD,        (pDrvCtrl->pRxDesc + pDrvCtrl->indexRxD)->statusControl, 3, 4, 5, 6);    /*     * If tnetTask is running and not already handling received packets     * for this interface, arrange to process the received packets at     * task level.     */    if (!(pDrvCtrl->localFlags & EMAC_HANDLE_RX_RUNNING))        {        if (netTaskId && netTaskId != ERROR)            {            pDrvCtrl->localFlags |= EMAC_HANDLE_RX_RUNNING;            netJobAdd((FUNCPTR)ibmEmacHandleRecvInt, (int)pDrvCtrl,FALSE,0,0,0);            }        else            ibmEmacHandleRecvInt(pDrvCtrl, FALSE);        }    return;    }/********************************************************************************* ibmEmacTxdeInt - handle TX descriptor error interrupt** This routine is called at interrupt level in response to an interrupt from* the MAL.*/LOCAL void ibmEmacTxdeInt    (    EMAC_DRV_CTRL *   pDrvCtrl    )    {    DRV_LOG (DRV_DEBUG_ERROR, "EMAC TX DE int\n", 1, 2, 3, 4, 5, 6);    /*     * The send routines check to be sure that enough TX descriptors are     * available to send a packet, and initialize all descriptors required     * to transmit the packet before kicking the transmitter.     * This interrupt should never occur.  If it does, restart.     */    ibmEmacRestart(pDrvCtrl);    return;    }/********************************************************************************* ibmEmacRxdeInt - handle RX descriptor error interrupt** This routine is called at interrupt level in response to an interrupt from* the MAL.*/LOCAL void ibmEmacRxdeInt    (    EMAC_DRV_CTRL *   pDrvCtrl    )    {    DRV_LOG (DRV_DEBUG_ERROR, "EMAC RX DE int\n", 1, 2, 3, 4, 5, 6);    /*     * Start ibmEmacHandleRecvInt running (at task level if tnetTask     * is available), and tell it to restart the RX channel when it is     * finished because MAL automatically disables the channel when     * this interrupt occurred.     */    if (netTaskId && netTaskId != ERROR)        {        pDrvCtrl->localFlags |= EMAC_HANDLE_RX_RUNNING;        netJobAdd((FUNCPTR)ibmEmacHandleRecvInt, (int)pDrvCtrl, TRUE,0,0,0);        }    else        ibmEmacHandleRecvInt(pDrvCtrl, TRUE);    return;    }/********************************************************************************* ibmEmacMalSerrInt - handle MAL SERR (system error) interrupt** This routine is called at interrupt level in response to an interrupt from* the controller.*/LOCAL void ibmEmacMalSerrInt    (    EMAC_DRV_CTRL *   pDrvCtrl    )    {    DRV_LOG (DRV_DEBUG_ERROR, "EMAC-MAL SERR int\n", 1, 2, 3, 4, 5, 6);    /* MAL should have already reset the channel */    /* SERR is fatal, just restart the EMAC */    pDrvCtrl->lastError.errCode = END_ERR_RESET;    pDrvCtrl->lastError.pMesg = "MAL System Error.";    if (netTaskId && netTaskId != ERROR)        netJobAdd ((FUNCPTR)muxError, (int)&pDrvCtrl->end,                   (int)&pDrvCtrl->lastError,                   0, 0, 0);    else        muxError (&pDrvCtrl->end, &pDrvCtrl->lastError);    END_FLAGS_CLR (&pDrvCtrl->end, (IFF_UP | IFF_RUNNING));    ibmEmacRestart(pDrvCtrl);    return;    }/********************************************************************************* ibmEmacHandleRecvInt - task level interrupt service for received packets** This routine is called at task level indirectly by the interrupt* service routine to process received messages.** The double loop is to protect against a race condition where the interrupt* code sees EMAC_HANDLE_RX_RUNNING as TRUE, but it is then turned off by the* task code.*/LOCAL void ibmEmacHandleRecvInt    (    EMAC_DRV_CTRL *   pDrvCtrl,    int               resetChan    )    {    MAL_BD * pRxDesc;    /*     * Keep getting RX descriptors and calling the receive function until     * there are no more ready to handle.     */    pRxDesc = (MAL_BD *)NULL;    do        {        pDrvCtrl->localFlags |= EMAC_HANDLE_RX_RUNNING;        while ((pRxDesc = ibmEmacRecvDescGet(pDrvCtrl)) != (MAL_BD *)NULL)            {            ibmEmacRecv(pDrvCtrl, pRxDesc);            };        pDrvCtrl->localFlags &= ~EMAC_HANDLE_RX_RUNNING;        }    while (ibmEmacRecvDescGet(pDrvCtrl) != NULL);    /*     * This function may have been run as a result of an RX descriptor error     * interrupt (RXDE).  If so, the RX channel was disabled by MAL and must     * be re-activated for RX operation to continue. When a channel is     * reactivated, it begins to process descriptors from the beginning of the     * descriptor table, so the current RX descriptor index must be reset.     */    if (resetChan == TRUE)        {        pDrvCtrl->indexRxD = 0;        malChannelActivate(pDrvCtrl->pMalData, MAL_RX_TYPE,                           pDrvCtrl->rxChn0MalChannel);        }    }/********************************************************************************* ibmEmacRecvDescGet - get the next receive descriptor** Returns a ptr to next RX descriptor to process, or NULL if none are ready.*/LOCAL MAL_BD * ibmEmacRecvDescGet    (    EMAC_DRV_CTRL *   pDrvCtrl    )    {    volatile MAL_BD *            pRxDesc;    /* Point to the next RX descriptor */    pRxDesc = pDrvCtrl->pRxDesc + pDrvCtrl->indexRxD;    /*     * If the descriptor says the buffer is no longer empty, return the     * pointer to the descriptor, else return NULL (buffer is still empty).     */    if ((pRxDesc->statusControl & MAL_RX_CTRL_EMPTY) == 0)        {        DRV_LOG (DRV_DEBUG_RX, "RX desc got data\n", 1, 2, 3, 4, 5, 6);        return((MAL_BD *)pRxDesc);        }    else        {        DRV_LOG (DRV_DEBUG_RX, "RX desc no data yet\n", 1, 2, 3, 4, 5, 6);        return ((MAL_BD *)NULL);        }    }/********************************************************************************* ibmEmacRecv - process the next incoming packet** RETURNS: OK/ERROR*/LOCAL STATUS ibmEmacRecv    (    EMAC_DRV_CTRL *   pDrvCtrl,    MAL_BD *          pRxDesc    )    {    int                 len;    char *              pCluster;    char *              pNewCluster = NULL;    CL_BLK_ID           pClBlk;    M_BLK_ID            pMblk;    USHORT              statusRx;    int                 index;    DRV_LOG (DRV_DEBUG_RECV, "->ibmEmacRecv \n", 1, 2, 3, 4, 5, 6);    index = pDrvCtrl->indexRxD;    /* Bump the RX descriptor ring placeholder to the next position. */    pDrvCtrl->indexRxD = (index + 1) % pDrvCtrl->numRxD;    /* Check packet for errors */    statusRx = pRxDesc->statusControl;    DRV_LOG (DRV_DEBUG_RX, "EmacRecv : RxDesc = %X index = %d\n", statusRx,                            index, 3, 4, 5, 6);    /* If any of the error bits are set in the RX descriptor bump error count */    if (statusRx & EMAC_RX_ERRORS)        {        DRV_LOG (DRV_DEBUG_ERROR, "Status in RX Desc = 0x%x\n",                                   statusRx, 2, 3, 4, 5, 6);        END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);        /* Toss the packet, but reuse the cluster */        goto cleanRXD;        }    /* If the packet spans more than one buffer, this is also an error. */    if ((statusRx & MAL_RX_ONE_BUFFER) != MAL_RX_ONE_BUFFER)        {        DRV_LOG (DRV_DEBUG_ERROR, "RX packet spans >1 buffer\n",                                   1, 2, 3, 4, 5, 6);        END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);        /* Toss the packet, but reuse the cluster */        goto cleanRXD;        }    /* If we cannot get a new cluster to replace the full one, then bail out. */    pNewCluster = netClusterGet (pDrvCtrl->end.pNetPool,                                 pDrvCtrl->pClPoolId);

⌨️ 快捷键说明

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