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

📄 ibmemacend.c

📁 WINDRIVER SBC405 BSP
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (pNewCluster == NULL)        {        DRV_LOG (DRV_DEBUG_ERROR, "Recv netClusterGet failed\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;        }    /* Get a cluster block for the full cluster. */    if ((pClBlk = netClBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT)) == NULL)        {        netClFree (pDrvCtrl->end.pNetPool, pNewCluster);        DRV_LOG (DRV_DEBUG_ERROR, "Out of Cluster Blocks!\n", 1, 2, 3, 4, 5, 6);        END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);        pNewCluster = NULL;        /* Toss the packet, but reuse the cluster */        goto cleanRXD;        }    /*     * Get an mBlk for the full cluster     */    if ((pMblk = mBlkGet(pDrvCtrl->end.pNetPool, M_DONTWAIT, MT_DATA)) == NULL)        {        netClBlkFree (pDrvCtrl->end.pNetPool, pClBlk);        netClFree (pDrvCtrl->end.pNetPool, pNewCluster);        DRV_LOG (DRV_DEBUG_ERROR, "Out of M Blocks!\n", 1, 2, 3, 4, 5, 6);        END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);        pNewCluster = NULL;        /* Toss the packet, but reuse the cluster */        goto cleanRXD;        }    END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1);    len = pRxDesc->dataLen;             /* get packet length */    pCluster = pRxDesc->bufferAdrs;     /* Pointer to the packet */    DRV_LOG (DRV_DEBUG_RX, "Packet @ 0x%X for %d bytes!\n", pCluster,             len, 3, 4, 5, 6);    /*     * Join the full cluster from the RX descriptor ring to the cluster block     * obtained above and then join the cluster block to the mBlk obtained     * above. Complete the information in the mBlk.     */    netClBlkJoin (pClBlk, pCluster, len, NULL, 0, 0, 0);    netMblkClJoin (pMblk, pClBlk);    pMblk->mBlkHdr.mLen   = len;    pMblk->mBlkHdr.mFlags |= M_PKTHDR;    pMblk->mBlkPktHdr.len = len;    /*     * Invalidate the cluster so upper layers will see the packet data     * in memory and not stale data in cache.     */    EMAC_CACHE_INVALIDATE (pMblk->mBlkHdr.mData, len);    DRV_LOG (DRV_DEBUG_RX, "Handing packet off to MUX\n", 1, 2, 3, 4, 5, 6);    /* Call the upper layer's receive routine. */    END_RCV_RTN_CALL(&pDrvCtrl->end, pMblk);cleanRXD:    /*     * Prepare the RX descriptor to receive another packet now that the     * packet just received has been handed off to the MUX layer. To do this     * the address of the new cluster obtained above must be written to the     * descriptor.  If an error occurred above obtaining a new cluster or     * mBlk, pNewCluster will be NULL. In this case bufferAdrs will not be     * updated (the existing buffer will be used again).     */    if (pNewCluster != NULL)        pRxDesc->bufferAdrs = pNewCluster;    /*     * Re-initialize the rest of the RX descriptor to prepare it to     * receive again.   pRxDesc->bufferAdrs should already be filled     * in at this point!     */    pRxDesc->dataLen = 0;    if (index == (pDrvCtrl->numRxD - 1))        pRxDesc->statusControl = EMAC_RX_DESC_INIT | MAL_RX_CTRL_WRAP;    else        pRxDesc->statusControl = EMAC_RX_DESC_INIT;    DRV_LOG (DRV_DEBUG_RECV, "<-ibmEmacRecv \n", 1, 2, 3, 4, 5, 6);    return (OK);    }/********************************************************************************* ibmEmacSend - the driver send routine** This routine is called by muxSend.  The packet to be sent is contained in the* mBlk.  Hardware addessing information must already be present in the* packet data.  ibmEmacSendCopy or ibmEmacSendNoCopy is called to actually* send out the packet (depending on the state of the inputFlags).** RETURNS: OK or ERROR.*/LOCAL STATUS ibmEmacSend    (    EMAC_DRV_CTRL *   pDrvCtrl,    M_BLK_ID            pMblk      /* data to send */    )    {    STATUS      rc;    DRV_LOG (DRV_DEBUG_SEND, "->ibmEmacSend \n", 1, 2, 3, 4, 5, 6);    /*     * Obtain exclusive access to transmitter.  This is necessary because     * we might have more than one stack transmitting at once.     */    if (!(pDrvCtrl->localFlags & EMAC_POLLING_MODE))        END_TX_SEM_TAKE (&pDrvCtrl->end, WAIT_FOREVER);    /*     * Depending on the input flag passed in to ibmEmacEndLoad, call the     * appropriate send routine.  Copy or zero copy.     */    if (pDrvCtrl->inputFlags & EMAC_INPUT_TX_COPY)        rc = ibmEmacSendCopy(pDrvCtrl, pMblk);    else        rc = ibmEmacSendNoCopy(pDrvCtrl, pMblk);    /*     * If both TX channels are being used, use the other channel for the     * next packet.     */    pDrvCtrl->txChannel = (pDrvCtrl->txChannel + 1) % pDrvCtrl->numTxChannels;    /* Give up the semaphore */    if (!(pDrvCtrl->localFlags & EMAC_POLLING_MODE))        END_TX_SEM_GIVE (&pDrvCtrl->end);    /* Bump the appropriate statistic counter */    if (rc == OK)        END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1);    else        END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_ERRS, +1);    DRV_LOG (DRV_DEBUG_SEND, "<-ibmEmacSend \n", 1, 2, 3, 4, 5, 6);    return (rc);    }/********************************************************************************* ibmEmacSendCopy - the driver send routine (with copy)** This routine takes a M_BLK_ID sends off the data in the M_BLK_ID.* The buffer must already have the addressing information properly installed* in it.  This is done by a higher layer.  This routine acquires a new* cluster and copies the packet data from the M_BLK_ID into the cluster.** RETURNS: OK or ERROR.*/LOCAL STATUS ibmEmacSendCopy    (    EMAC_DRV_CTRL *   pDrvCtrl,    M_BLK_ID            pMblk      /* data to send */    )    {    MAL_BD *            pTxDesc;    TX_INFO *           pTxChn;    char *              pBuf;    int                 level;    int                 len = 0;    DRV_LOG (DRV_DEBUG_SEND, "->ibmEmacSendCopy \n", 1, 2, 3, 4, 5, 6);    pTxChn = pDrvCtrl->txInfo + pDrvCtrl->txChannel;    pTxDesc = pTxChn->pTxDesc + pTxChn->indexTxD;    DRV_LOG (DRV_DEBUG_TX, "Send : index %d TX desc = 0x%X channel = %d\n",             pTxChn->indexTxD, (int)pTxDesc, pDrvCtrl->txChannel, 4, 5, 6);    /* Make sure that an available TX descriptor exists. */    if (pTxDesc->statusControl & MAL_TX_CTRL_READY)        {        DRV_LOG (DRV_DEBUG_ERROR, "Out of TX descriptors.\n",                                   1, 2, 3, 4, 5, 6);        level = intLock ();        pDrvCtrl->localFlags |= EMAC_TX_BLOCKED;        intUnlock (level);       	/* kick the wd to ensure we unblock the MUX again, 5sec delay */        wdStart(pDrvCtrl->wdRestart,5*sysClkRateGet(),(FUNCPTR)ibmEmacWdRestart,(int)pDrvCtrl);        return (END_ERR_BLOCK);        }    /*     * pMblk could contain multiple clusters.  Get a new cluster that will     * be used to combine the data in the clusters in pMblk.     */    pBuf = netClusterGet(pDrvCtrl->end.pNetPool, pDrvCtrl->pClPoolId);    if (pBuf == NULL)        {        DRV_LOG (DRV_DEBUG_ERROR, "Send netClusterGet failed\n",                        1 , 2, 3, 4, 5, 6);        level = intLock ();        pDrvCtrl->localFlags |= EMAC_TX_BLOCKED;        intUnlock (level);       	/* kick the wd to ensure we unblock the MUX again, 5sec delay */        wdStart(pDrvCtrl->wdRestart,5*sysClkRateGet(),(FUNCPTR)ibmEmacWdRestart,(int)pDrvCtrl);        return (END_ERR_BLOCK);        }    DRV_LOG (DRV_DEBUG_TX, "New cluster pBuf = 0x%x\n",             (int)pBuf, 2, 3, 4, 5, 6);	/* ready to send, so clear the watchdog */	wdCancel(pDrvCtrl->wdRestart);    /*     * Combine (copy) all of the data in pMblk into the newly acquired cluster.     * Padding to the minimum length is not necessary because the EMAC will     * take care of it before appending the FCS.     */    len = netMblkToBufCopy (pMblk, pBuf, NULL);    netMblkClChainFree(pMblk);    /* Save the cluster address so that Send Cleanup can free it later. */    pTxChn->txFree[pTxChn->indexTxD].typeFree = EMAC_TX_FREE_CLUSTER;    pTxChn->txFree[pTxChn->indexTxD].pFree = pBuf;    /* Flush the buffer/cluster out to memory */    EMAC_CACHE_FLUSH (pBuf, len);    /* Prepare the buffer descriptor for transmit */    pTxDesc->bufferAdrs = pBuf;    pTxDesc->dataLen = len;    pTxDesc->statusControl |= (MAL_TX_CTRL_READY |                               MAL_TX_CTRL_LAST  |                               MAL_TX_CTRL_INTR);    /* Make sure descriptor update gets out to memory before TX begins */    EIEIO_SYNC;    /* Transmit the packet. Tell EMAC to Get the New Packet */    EMAC_REG_WRITE(pDrvCtrl, EMAC_TMR0, pTxChn->getNewPacketTX);    DRV_LOG (DRV_DEBUG_TX, "Packet was transmitted\n", 1, 2, 3, 4, 5, 6);    /* Bump the TX descriptor ring placeholder to the next position. */    pTxChn->indexTxD = (pTxChn->indexTxD + 1) % pTxChn->numTxD;    return (OK);    }/********************************************************************************* ibmEmacSendNoCopy - the driver send routine (zero copy)** This routine takes a M_BLK_ID sends off the data in the M_BLK_ID.* The buffer must already have the addressing information properly installed* in it.  This is done by a higher layer.  This transmits the data directly* from the M_BLK_ID (zero copy).** RETURNS: OK or ERROR.*/LOCAL STATUS ibmEmacSendNoCopy    (    EMAC_DRV_CTRL *   pDrvCtrl,    M_BLK_ID            pMblk      /* data to send */    )    {    M_BLK_ID            pTempMblk;    int                 numBuffers = 0;    MAL_BD *            pTxDesc;    MAL_BD *            pTxDescFirst = NULL;    TX_INFO *           pTxChn;    int                 level;    int                 i;    int                 tempIndex;    int                 firstIndex = 0;    DRV_LOG (DRV_DEBUG_SEND, "->ibmEmacSendNoCopy \n", 1, 2, 3, 4, 5, 6);    DRV_LOG (DRV_DEBUG_TX, "Total packet length = %d\n",                     pMblk->mBlkPktHdr.len,2,3,4,5,6);    pTxChn = pDrvCtrl->txInfo + pDrvCtrl->txChannel;    /* Count of the number of clusters associated with this Mblk */    pTempMblk = pMblk;    while (pTempMblk != NULL)        {        numBuffers++;        pTempMblk = pTempMblk->mBlkHdr.mNext;        }    /*     * Check to be sure the number of buffers required for this packet     * doesn't exceed the total number of descriptors for this TX channel.     * If it does, let send with copy handle this packet.     */    if (numBuffers > pTxChn->numTxD)        {        DRV_LOG (DRV_DEBUG_ERROR, "%d buffs req exceeds num of descriptors\n",                                  numBuffers,2,3,4,5,6);        return(ibmEmacSendCopy(pDrvCtrl, pMblk));        }    /* Make sure that enough available TX descriptors exist. */    for (i=0; i < numBuffers; i++)        {        tempIndex = (pTxChn->indexTxD + i) % pTxChn->numTxD;        pTxDesc = pTxChn->pTxDesc + tempIndex;        if (pTxDesc->statusControl & MAL_TX_CTRL_READY)            {            DRV_LOG (DRV_DEBUG_ERROR, "Out of TX descriptors.\n",                                       1, 2, 3, 4, 5, 6);            level = intLock ();            pDrvCtrl->localFlags |= EMAC_TX_BLOCKED;            intUnlock (level);            return (END_ERR_BLOCK);            }        }    /* Initialize the buffer descriptors */    pTempMblk = pMblk;    while (pTempMblk != NULL)        {        pTxDesc = pTxChn->pTxDesc + pTxChn->indexTxD;        /* Is this the last descriptor in the packet? */        if (pTempMblk->mBlkHdr.mNext == NULL)            {            /* Save the Mblk address so that Send Cleanup can free it later. */            pTxChn->txFree[pTxChn->indexTxD].typeFree = EMAC_TX_FREE_MBLK_LAST;            pTxChn->txFree[pTxChn->indexTxD].pFree = (UCHAR *)pMblk;            pTxDesc->statusControl |= (MAL_TX_CTRL_LAST | MAL_TX_CTRL_INTR);            }        else if (pTxDescFirst != NULL)            {            pTxChn->txFree[pTxChn->indexTxD].typeFree = EMAC_TX_FREE_MBLK;            }        /* Flush the buffer/cluster out to memory */        EMAC_CACHE_FLUSH (pTempMblk->mBlkHdr.mData, pTempMblk->mBlkHdr.mLen);        /* Prepare the buffer descriptor for transmit */        pTxDesc->bufferAdrs = pTempMblk->mBlkHdr.mData;        pTxDesc->dataLen = pTempMblk->mBlkHdr.mLen;        DRV_LOG (DRV_DEBUG_TX, "  buf addr = 0x%x len = %d

⌨️ 快捷键说明

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