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

📄 m5200fecend.c

📁 MPC5200 BSP 支持ATA,USB, I2C,扩展网口
💻 C
📖 第 1 页 / 共 5 页
字号:
            bufLen = pCurr->mBlkHdr.mLen;            pCurr = ((M_BLK *) pCurr->mBlkHdr.mNext);        if (bufLen == 0)            continue;        /* just in case we have to pad it */            totLen += bufLen;    		    		/* flush the cache, if necessary */            MOT_FEC_CACHE_FLUSH (pBuf, bufLen);                /* get and set up the current TBD */            pTbd = pTbdList->pTbd;            MOT_FEC_BD_LONG_WR (pTbd, MOT_FEC_BD_ADDR_OFF, (UINT32) pBuf);            MOT_FEC_BD_WORD_RD (pTbd, MOT_FEC_BD_STAT_OFF, tbdStatus);                 /*         * complete TBD construction based on whether or not this is the last         * fragment         */        if (--fragNum > 0)            {            MOT_FEC_LOG (MOT_FEC_DBG_TX, ("motFecSend more mblks \n"),                          1, 2, 3, 4, 5, 6);                MOT_FEC_BD_WORD_WR (pTbd, MOT_FEC_BD_LEN_OFF, bufLen);                MOT_FEC_BD_WORD_WR (pTbd, MOT_FEC_BD_STAT_OFF,                    (tbdStatus | MOT_FEC_TBD_RDY));            }        else            {            MOT_FEC_LOG (MOT_FEC_DBG_TX, ("before bufLen: 0x%x ETHERSMALL: 0x%x\n"),                          bufLen, ETHERSMALL, 0, 0, 0, 0);                if (totLen < ETHERSMALL)            bufLen = max (bufLen, (ETHERSMALL - totLen + bufLen));                MOT_FEC_LOG (MOT_FEC_DBG_TX, ("motFecSend last len=0x%x\n"),                          bufLen, 2, 3, 4, 5, 6);                MOT_FEC_BD_WORD_WR (pTbd, MOT_FEC_BD_LEN_OFF, bufLen);                MOT_FEC_BD_WORD_WR (pTbd, MOT_FEC_BD_STAT_OFF,                    (MOT_FEC_TBD_LAST | MOT_FEC_TBD_CRC                    | MOT_FEC_TBD_RDY | tbdStatus));                        }            /* move on to the next element */            pTbdList = pTbdList->pNext;        }    /* kick the transmitter */        SDMA_TASK_ENABLE(SDMA_TCR, txTaskId);    return (OK);    }/******************************************************************************** motFecPktCopyTransmit - copy and transmit a packet** This routine transmits the packet described by the given parameters* over the network, after copying the mBlk to the driver's buffer.* It also updates statistics.** RETURNS: OK, or ERROR if no resources were available.*/LOCAL STATUS motFecPktCopyTransmit    (    DRV_CTRL *  pDrvCtrl,       /* pointer to DRV_CTRL structure */    M_BLK *     pMblk,          /* pointer to the mBlk */    UINT8     fragNum,    /* number of fragments */    UINT16     pktType        /* packet type */    )    {    UINT16        len = 0;    /* length of data to be sent */    char *        pBuf = NULL;    /* pointer to data to be sent */    MOT_FEC_TBD_ID    pTbd = NULL;    /* pointer to the current ready TBD */    MOT_FEC_TBD_LIST_ID    pTbdList = NULL;/* pointer to the TBD list*/    UINT16        tbdStatus;    /* holder for the TBD status */    MOT_FEC_LOG (MOT_FEC_DBG_TX, ("motFecSend...\n"), 1, 2, 3, 4, 5, 6);    /* get a cluster buffer from the pool */    pBuf = NET_BUF_ALLOC();    if (pBuf == NULL)        {        /* set to stall condition */            pDrvCtrl->txStall = TRUE;            return (ERROR);        }    /* get the current free TBD list */    pTbdList = motFecTbdListSet (pDrvCtrl, fragNum);    if (pTbdList == (MOT_FEC_TBD_LIST_ID) NULL)        {        /* set to stall condition */            NET_BUF_FREE ((UCHAR *) pBuf);            pDrvCtrl->txStall = TRUE;            return (ERROR);        }    /* store the packet type */    pTbdList->pktType = pktType;    /* store the buffer pointer and its type */    pTbdList->bufType = BUF_TYPE_CL;    pTbdList->pBuf = (UINT8 *)pBuf;    /* copy data and free the Mblk */    len = netMblkToBufCopy (pMblk, (char *) pBuf, NULL);    netMblkClChainFree (pMblk);    len = max (ETHERSMALL, len);        /* flush the cache, if necessary */    MOT_FEC_CACHE_FLUSH (pBuf, len);         /* get and set up the current TBD */    pTbd = pTbdList->pTbd;    MOT_FEC_BD_LONG_WR (pTbd, MOT_FEC_BD_ADDR_OFF, (UINT32) pBuf);    MOT_FEC_BD_WORD_WR (pTbd, MOT_FEC_BD_LEN_OFF, len);    MOT_FEC_BD_WORD_RD (pTbd, MOT_FEC_BD_STAT_OFF, tbdStatus);    MOT_FEC_BD_WORD_WR (pTbd, MOT_FEC_BD_STAT_OFF,            (MOT_FEC_TBD_LAST | MOT_FEC_TBD_CRC            | MOT_FEC_TBD_RDY | tbdStatus));    /* kick the transmitter */		SDMA_TASK_ENABLE(SDMA_TCR, txTaskId);        return (OK);    }/******************************************************************************** motFecMblkWalk - walk the mBlk** This routine walks the mBlk whose address is in <pMblk>, computes* the number of fragments it is made of, and returns it in the parameter* <pFragNum>. In addition, it finds out whether the specified packet* is unicast or multicast, and sets <pPktType> accordingly.** RETURNS: OK, or ERROR in case of invalid mBlk.*/LOCAL STATUS motFecMblkWalk    (    M_BLK *     pMblk,          /* pointer to the mBlk */    UINT8 *    pFragNum,    /* number of fragments */    UINT16 *    pPktType    /* packet type */    )    {    M_BLK *        pCurr = pMblk;        /* the current mBlk */    if (pMblk == NULL)        {        MOT_FEC_LOG (MOT_FEC_DBG_TX, ("motFecSend: invalid pMblk\n"),                                      0, 0, 0, 0, 0, 0);        return (ERROR);        }    /* walk this mBlk */    while (pCurr != NULL)        {        /* keep track of the number of fragments in this mBlk */            if (pCurr->mBlkHdr.mLen != 0)            (*pFragNum)++;            pCurr = ((M_BLK *) pCurr->mBlkHdr.mNext);        }    /* set the packet type to multicast or unicast */    if (pMblk->mBlkHdr.mData[0] & (UINT8) 0x01)        {        (*pPktType) = PKT_TYPE_MULTI;        }    else        {        (*pPktType) = PKT_TYPE_UNI;        }    return (OK);    }/******************************************************************************** motFecTbdListSet - set up a list of available transmit descriptors** This routine sets up a list of available buffer descriptors for use by* the send routine.** RETURNS: a pointer to a transmit descriptors list, or NULL.*/LOCAL MOT_FEC_TBD_LIST_ID motFecTbdListSet    (    DRV_CTRL *  pDrvCtrl,       /* pointer to DRV_CTRL structure */    UINT8    tbdNum         /* number of tbd */    )    {    MOT_FEC_TBD_ID    pTbd = NULL;        /* pointer to the current TBD */    UINT16        tbdIndex = pDrvCtrl->tbdIndex;    /* TBD index */    UINT16        nextIndex = 0;        /* index to the next TBD */    UINT16        currIndex = 0;        /* index to the current TBD */    UINT16        i = 0;            /* an index */    MOT_FEC_TBD_LIST_ID    pTbdList = NULL;    /* set the number of TBDs in this list */    pDrvCtrl->pTbdList [tbdIndex]->fragNum = tbdNum;    /* initialize the list */    for (i = 0; i < tbdNum; i++)        {            /* get the current free TBD */            if ((pTbd = motFecTbdGet (pDrvCtrl)) == NULL)            {            return (NULL);            }        currIndex = pDrvCtrl->tbdIndex;        nextIndex = (currIndex + 1) % (pDrvCtrl->tbdNum);            pTbdList = pDrvCtrl->pTbdList [currIndex];            pTbdList->pTbd = pTbd;        pTbdList->pBuf = NULL;            pTbdList->pNext = pDrvCtrl->pTbdList [nextIndex];                /* update some indeces for a correct handling of the TBD ring */            pDrvCtrl->tbdIndex = (pDrvCtrl->tbdIndex + 1) % pDrvCtrl->tbdNum;        }    /* terminate the list properly */    pTbdList->pNext = NULL;    /* keep track of the clean TBDs */    pDrvCtrl->cleanTbdNum -= tbdNum;    return (pDrvCtrl->pTbdList [tbdIndex]);    }/******************************************************************************** motFecTbdGet - get the first available transmit descriptor** This routine gets the first available buffer descriptor in the transmit* ring. It checks the descriptor is owned by the host and it has been* cleaned by the motFecTbdClean() routine.** RETURNS: an available transmit descriptor, otherwise NULL.*/LOCAL MOT_FEC_TBD_ID motFecTbdGet    (    DRV_CTRL *  pDrvCtrl       /* pointer to DRV_CTRL structure */    )    {    MOT_FEC_TBD_ID    nextTbd = NULL;    /* holder for the next TBD */    UINT16    tbdStatus;    /* holder for the TBD status */    MOT_FEC_NEXT_TBD (pDrvCtrl, nextTbd);		/* Make cache consistent with memory */    MOT_FEC_BD_CACHE_INVAL (nextTbd, MOT_FEC_TBD_SZ);    MOT_FEC_BD_WORD_RD ((char *) nextTbd, MOT_FEC_BD_STAT_OFF, tbdStatus);    if ((tbdStatus & MOT_FEC_TBD_RDY) == MOT_FEC_TBD_RDY)        {        MOT_FEC_LOG (MOT_FEC_DBG_TX, ("motFecSend... not our Tbd \n"),                          1, 2, 3, 4, 5, 6);        return (NULL);        }    return ((MOT_FEC_TBD_ID) nextTbd);    }/******************************************************************************** motFecTbdClean - clean the transmit buffer descriptors ring** This routine is run in netTask's context. It cleans the transmit* buffer descriptors ring. It also calls motFecTbdCheck() to check* for any transmit errors, and possibly up-dates statistics.** SEE ALSO: motFecTbdCheck()** RETURNS: N/A.*/LOCAL void motFecTbdClean    (    DRV_CTRL *  pDrvCtrl       /* pointer to DRV_CTRL structure */    )    {    MOT_FEC_TBD_ID    pUsedTbd;        /* first used TBD */    UINT32         		retVal = 0;        /* return value */		  MOT_FEC_LOG (MOT_FEC_DBG_TX, ("motFecTbdClean\n"), 1, 2, 3, 4, 5, 6);    END_TX_SEM_TAKE (&pDrvCtrl->endObj, WAIT_FOREVER);    /* process all the consumed TBDs */    while (pDrvCtrl->cleanTbdNum < pDrvCtrl->tbdNum)        {        MOT_FEC_TBD_LIST_ID    pTbdList;        MOT_FEC_TBD_LIST_ID    pTempList;            pTbdList = pDrvCtrl->pTbdList [pDrvCtrl->usedTbdIndex];        pTempList = pTbdList;            /* first, we detect abnormal events */            while (pTempList != NULL)            {            pUsedTbd = pTempList->pTbd;                /* check on this TBD */                retVal = motFecTbdCheck (pDrvCtrl, pUsedTbd);                if (retVal == MOT_FEC_TBD_BUSY)                {                END_TX_SEM_GIVE (&pDrvCtrl->endObj);                return;                }                if (retVal == MOT_FEC_TBD_ERROR)                {                break;                }                /* move on to the next element in the list */                pTempList = pTempList->pNext;            }            /* free the Mblk or the cluster, whichever is appropriate */        if ((pTbdList->bufType == ((UINT16) BUF_TYPE_MBLK))            && (pTbdList->pBuf != NULL))            {            netMblkClChainFree ((M_BLK *) pTbdList->pBuf);                pTbdList->pBuf = NULL;            }        else            {            if ((pTbdList->bufType == ((UINT16) BUF_TYPE_CL))                && (pTbdList->pBuf != NULL))                {                /* it's a cluster */                        NET_BUF_FREE (pTbdList->pBuf);                        pTbdList->pBuf = NULL;                }            }        pTempList = pTbdList;            /* finally, we clean this TBD list */            while (pTempList != NULL)            {            pUsedTbd = pTempList->pTbd;                        /* clean this buffer descriptor, mirror motFecTbdInit() */                if (pDrvCtrl->usedTbdIndex == (pDrvCtrl->tbdNum - 1))                {                MOT_FEC_BD_WORD_WR (pUsedTbd, MOT_FEC_BD_STAT_OFF,                            MOT_FEC_TBD_WRAP);                }            else                {                MOT_FEC_BD_WORD_WR (pUsedTbd, MOT_FEC_BD_STAT_OFF, 0);                }                /* update some indeces for a correct handling of the TBD ring */                pDrvCtrl->cleanTbdNum++;            pDrvCtrl->usedTbdIndex = (pDrvCt

⌨️ 快捷键说明

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