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

📄 gei82543rcvsnd.c

📁 intel 82543 千兆网卡 vxworks驱动源码
💻 C
字号:


#include "gei82543Lib.h"

LOCAL void      gei82543RxDesUpdate         (END_DEVICE *);
extern void * sysVirtToPhys(void *virtAddr);
#define GEI_CAPACITY_LIMIT 5
/*************************************************************************
*
* gei82543RxDesUpdate - clean up the receive descriptor
*
* This routine cleans up receive descriptors, reusing the current cluster.
* Then it updates the tail pointer to make it available to the
* hardware.
*
* RETURNS: N/A
*/

LOCAL void gei82543RxDesUpdate
    (
    END_DEVICE *    pDrvCtrl    /* device to update  */
    )
{
    int         tempTail;        /* temporary tail index */
    char *      pRxDesc;     /* RX descriptor */
    int         tail;
    DRV_LOG (DRV_DEBUG_RX, "gei82543RxDesUpdate...\n", 1, 2, 3, 4, 5, 6);

    /* get the RX tail descriptor */
    tempTail = pDrvCtrl->rxDescTail;
    pRxDesc = GEI_GET_RX_DESC_ADDR(tempTail);

    /* clean up status field */
    GEI_WRITE_DESC_BYTE(pRxDesc,RXDESC_STATUS_OFFSET, 0);

    /* update the tail pointer */
    tail = tempTail + 1;
    if (tail == pDrvCtrl->rxDescNum)
    {
        tail = 0;
    }
    pDrvCtrl->rxDescTail = tail;


    /* kick this descriptor for receiving packet */
    GEI_WRITE_REG(INTEL_82543GC_RDT, (UINT32)tempTail);

    CACHE_PIPE_FLUSH();/*lint !e522*/

    DRV_LOG (DRV_DEBUG_RX, "gei82543RxDesUpdate...Done\n",
                            1, 2, 3, 4, 5, 6);
    return;
}

STATUS gei82543Recv
    (
    END_DEVICE *    pDrvCtrl,    /* device structure */
    char *          pRxDesc,     /* pointer to RX descriptor */
    UINT8           rxdStat      /* RX descriptor status */
    )
 {
    UINT16                len;              /* len of packet received */
    UINT8                 rxdErr;           /* RX descriptor Error field */
    UINT8                 csumErr;          /* RX descriptor Error field */
    int             tempTail;
    UINT32            tmpAddr;
    UINT32          globalPort=0;
    char *          pBuf;
    char *          pNewData ;
    void *          pkt;
    int             tail;

    DRV_LOG (DRV_DEBUG_RX, "gei82543Recv start...\n",  1, 2, 3, 4, 5, 6);

    /* check packet status */
    if (!(rxdStat & RXD_STAT_EOP))
    {
        DRV_CHG_CNT(pDrvCtrl->noPacketEOP,1);
        DRV_LOG (DRV_DEBUG_RX, "Packet EOP not set\n", 1, 2, 3, 4, 5, 6);

        LOGMSG("Packet EOP not set \n",1,2,3,4,5,6);

        goto receiveError;
    }

    csumErr = GEI_READ_DESC_BYTE(pRxDesc, RXDESC_ERROR_OFFSET);
    rxdErr = csumErr & ~(RXD_ERROR_IPE | RXD_ERROR_TCPE | RXD_ERROR_RSV);

    if (rxdErr != 0)
    {
        DRV_CHG_CNT(pDrvCtrl->errPacketNum,1);
        DRV_LOG (DRV_DEBUG_RX, "Packet Error 0x%x\n", rxdErr, 2, 3, 4, 5, 6);
        LOGMSG("Packet error 0x%x \n",rxdErr, 2, 3, 4, 5, 6);
        goto receiveError;
     }

    /* get packet length */
    GEI_READ_DESC_WORD(pRxDesc, RXDESC_LENGTH_OFFSET, len);

    if(len < MIN_ETHER_PACKET_SIZE)
    {
        DRV_LOG (DRV_DEBUG_RX, ("invalid packet length=0x%x!\n"), len,
                                 0, 0, 0, 0, 0);
        goto receiveError;
    }
    DRV_CHG_CNT(pDrvCtrl->rxPacketNum,1);

    pNewData = (char *)endPktAlloc();
    if ((char*)NULL == pNewData)
    {
        DRV_LOG (DRV_DEBUG_RX, ("Cannot malloc EndBuf for RX!\n"), 0,
                                 0, 0, 0, 0, 0);
        DRV_CHG_CNT(pDrvCtrl->noEndBuf,1);
        goto receiveError;
    }
    else
    {
        DRV_CHG_CNT(pDrvCtrl->rxPktAlloc1Num,1);   
    }

    if ( NULL== pDrvCtrl->drvObj.net)
    {
        globalPort = Ros_GlobalPort(pDrvCtrl->drvObj.slot, 1, 0);
        if(NULL==(pDrvCtrl->drvObj.net = (void *)if_search(globalPort)))
        {
            DRV_CHG_CNT(pDrvCtrl->searchNetErr,1);
            endPktFree(pNewData);
            return ERROR;
        }

    }
    /*get the end buffer address from pEndBufForRx[],not from the 
    GEI_READ_DESC_LONG(pRxDesc, RXDESC_BUFADRLOW_OFFSET, rxBufAddr);
      the rxBufAddr may be wrong after several shut/no shut operations
    GEI_READ_DESC_LONG(pRxDesc, RXDESC_BUFADRLOW_OFFSET, rxBufAddr);
    pBufAddr = (char *)rxBufAddr;*/

    pBuf = pDrvCtrl->pEndBufForRx[pDrvCtrl->rxDescTail];
    /*view the content of the packets*/
    drv_DebugRcvSndPkt(globalPort, (char *)pBuf, len, RX_DIRECTION);

    END_BUF_GET_PKT(pBuf,pkt);/*lint !e63*/
    etherPktProcess(pkt, pBuf, pDrvCtrl->drvObj.net, len);

    /*
     * Pre-invalidate new cluster before handing to hardware to avoid
     * later cache-line write-back of dirty lines, which could overwrite
     * received data. [This is especially important when using RX checksum
     * offload.] Unfortunately, this requires that we invalidate
     * the whole cluster rather than just the received portion.
     */
     tmpAddr= (UINT32)sysVirtToPhys(pNewData);
    GEI_WRITE_DESC_LONG(pRxDesc, RXDESC_BUFADRLOW_OFFSET,tmpAddr);

    /*put the new buffer address in pEndBufForRx[]*/
    pDrvCtrl->pEndBufForRx[pDrvCtrl->rxDescTail] = (char *)tmpAddr;

    tempTail = pDrvCtrl->rxDescTail;
    tail = tempTail + 1;
    if (tail == pDrvCtrl->rxDescNum)
    {
        tail = 0;
    }
    pDrvCtrl->rxDescTail = tail;

    /* kick this descriptor for receiving packet */
    GEI_WRITE_REG(INTEL_82543GC_RDT, (UINT32)tempTail);

    CACHE_PIPE_FLUSH ();  /*lint !e522*/

    /* clean up status field */
    GEI_WRITE_DESC_BYTE(pRxDesc,RXDESC_STATUS_OFFSET, 0);

    DRV_LOG (DRV_DEBUG_RX, "Receive done!\n", 1, 2, 3, 4, 5, 6);

    return OK;

receiveError:
    gei82543RxDesUpdate (pDrvCtrl);   /*lint !e961*/

    if (pDrvCtrl->adaptor.boardType == PRO1000_546_BOARD)
    {
        pDrvCtrl->rxPacketDrvErr++;
    }

    DRV_LOG (DRV_DEBUG_RX, "Receive ERROR!\n", 1, 2, 3, 4, 5, 6);

    return ERROR;
 }




/*************************************************************************
*
* gei82543EndSend - driver send routine
*
* RETURNS: OK or ERROR.*/

STATUS drv_gei82543EndSend(UINT32  gPort, char *pBuf, int pktSize,char *pData)
{
    int slotNum;
    STATUS rc = OK;

    UINT32 tmpAddr; 
    INTEL82543_TX_DES *    pDesc = (INTEL82543_TX_DES *)NULL;
    END_DEVICE *pDrvCtrl = (END_DEVICE *)NULL;
    int             tmpTail;

    DRV_LOG (DRV_DEBUG_TX, "gei82543EndSend...\n", 1, 2, 3, 4, 5, 6);
    slotNum = Ros_LocalPanel(gPort);
    pDrvCtrl = geiEndDevice[slotNum];

    if ((slotNum < 1) || (slotNum > MAX_IF_CARD_NUM) ||
      ((char *)NULL == pBuf) || ((char *)NULL == pData) ||
      ((END_DEVICE *)NULL == pDrvCtrl))
    {
        return ERROR;
    }

    IF_DRV_TX_SEM_TAKE (&pDrvCtrl->drvObj, WAIT_FOREVER);

    /* check device start flag */
    if (pDrvCtrl->devStartFlag != TRUE)
    {
        DRV_LOG (DRV_DEBUG_TX, 
            "drv_gei82543EndSend:Driver has not been started!\n", 
            1, 2,3, 4, 5, 6);
        IF_DRV_TX_SEM_GIVE(&pDrvCtrl->drvObj);
        return ERROR;
    }

    DRV_CHG_CNT(pDrvCtrl->txIntCount,1);

    /*get the current transmit descriptor*/
    pDesc = (INTEL82543_TX_DES *)GEI_GET_TX_DESC_ADDR(pDrvCtrl->txDescTail);

    if (TXD_STAT_DD == (pDesc->TxStatus & TXD_STAT_DD))
    {
        /*empty current DESC which packet have been sent out by MAC controller.*/
        if ((char *)NULL != pDrvCtrl->pEndBufForMng[pDrvCtrl->txDescTail])
        {
            DRV_LOG (DRV_DEBUG_TX, "gei82543EndSend...Free TxBD!\n", 1, 2, 3, 4, 5, 6);
            /*must free pData*/
            endPktFree(pDrvCtrl->pEndBufForMng[pDrvCtrl->txDescTail]);
            pDrvCtrl->pEndBufForMng[pDrvCtrl->txDescTail]=NULL;
        }

        /*view the content of the packets*/
        drv_DebugRcvSndPkt(gPort, (char *)pBuf, pktSize, TX_DIRECTION);
        pDrvCtrl->pEndBufForMng[pDrvCtrl->txDescTail] = pData;

        /*set the properity of the sending buffer*/
        pDesc->TxpktLen = Drv_Swap16((UINT16)pktSize);
        tmpAddr	=(UINT32)sysVirtToPhys((void*)pBuf);
        pDesc->pTxBufferLow = (char*)Drv_Swap32(tmpAddr);
        pDesc->TxCmd = TXD_CMD_RS | TXD_CMD_EOP | TXD_CMD_IFCS |TXD_CMD_IDE;
        pDesc->TxStatus  = 0;

        GEI_GET_TX_DESC_TAIL_UPDATE(tmpTail, 1);

        pDrvCtrl->txDescFreeNum --;
        if(0==pDrvCtrl->txDescFreeNum)
        {
            pDrvCtrl->txDescFreeNum=GEI_DEFAULT_TXDES_NUM-1;
        }

        CACHE_PIPE_FLUSH();  /*lint !e522*/

        GEI_WRITE_REG(INTEL_82543GC_TDT, (UINT32)tmpTail);

        pDrvCtrl->txDescTail = tmpTail;

        DRV_LOG (DRV_DEBUG_TX, "gei82543EndSend...done\n",
                                 1, 2, 3, 4, 5, 6);
    }
    else
    {
        DRV_LOG (DRV_DEBUG_TX, "gei82543EndSend...No TxBD OK!\n", 1, 2, 3, 4, 5, 6);
        DRV_CHG_CNT(pDrvCtrl->txBDNotOK,1);

        rc = ERROR;
    }
    DRV_CHG_CNT(pDrvCtrl->txPacketNum,1);
    IF_DRV_TX_SEM_GIVE(&pDrvCtrl->drvObj);
    return (rc);

}

int drv_MgeoCapacity(UINT32  gPort)
{
    signed int              distance;
    int                     tmpTail;
    INTEL82543_TX_DES *   pDesc; /* pointer to descriptor */
    END_DEVICE *pDrvCtrl;
    int slotNum;
    slotNum = Ros_LocalPanel(gPort);
    pDrvCtrl = geiEndDevice[slotNum];
	
    if ((slotNum < 1) || (slotNum > MAX_IF_CARD_NUM) ||
      ((END_DEVICE *)NULL == pDrvCtrl))
    {
        return ERROR;
    }

    DRV_LOG (DRV_DEBUG_TX, ("drv_MgeoCapacity...\n"), 1, 2, 3, 4, 5, 6);
    IF_DRV_TX_SEM_TAKE (&pDrvCtrl->drvObj, WAIT_FOREVER);

    /*make sure the driver is running*/
    if (pDrvCtrl->devStartFlag == FALSE)
    {
        DRV_LOG (DRV_DEBUG_TX, ("MGEO driver is not running...\n"), 1, 2, 3, 4, 5, 6);
        IF_DRV_TX_SEM_GIVE(&(pDrvCtrl->drvObj));
        return (0);
    }

    distance = 0;
    tmpTail = pDrvCtrl->txDescTail + 1;

    while(distance < GEI_CAPACITY_LIMIT + 1)/*just find 5 available txbds*/
    {
        if (tmpTail >= pDrvCtrl->txDescNum)
        {
            tmpTail = 0;
        }

	 /*get the  descriptor to be checked*/
        pDesc = (INTEL82543_TX_DES *) GEI_GET_TX_DESC_ADDR(tmpTail);

	 /*check the bd's DD bit to detemine the txbd whether it is available*/
        if (TXD_STAT_DD !=(pDesc->TxStatus & TXD_STAT_DD))
        {
            DRV_LOG (DRV_DEBUG_TX, ("TXBD is not OK...\n"), 1, 2, 3, 4, 5, 6); 
            IF_DRV_TX_SEM_GIVE(&pDrvCtrl->drvObj);
            return distance - 1;
        }
        distance++;
        tmpTail++;
    }

    DRV_LOG (DRV_DEBUG_TX, "drv_MgeoCapacity...done\n",1, 2, 3, 4, 5, 6);
    IF_DRV_TX_SEM_GIVE(&(pDrvCtrl->drvObj));

    return distance - 1;   
}

⌨️ 快捷键说明

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