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

📄 vchip8950.c

📁 Ep93XX TionProV2 BSP
💻 C
📖 第 1 页 / 共 5 页
字号:
/******************************************************************************
*
* VpsRecvComplete()
*
******************************************************************************/
static BOOL VpsRecvComplete( PCHIP pChip, WORD TotalLength, WORD FragCount,
   PFRAG pFrag)
{
    RECEIVE_CONTEXT ReceiveContext;

    VPM_SetupMiniContextFromPchip

    pvMini_Context->RcvOKs++;

    if ((TotalLength < VP_MIN_FRAMESIZE) ||
        (TotalLength > VP_MAX_FRAMESIZE))
    {
        pvMini_Context->RcvErrors++;
        return FALSE;
    } /* endif */

    ReceiveContext.pChip = pChip;
    ReceiveContext.FrameSize = (WORD)TotalLength;
    ReceiveContext.FragCount = (WORD)FragCount;
    ReceiveContext.pFrag = pFrag;

    NdisMEthIndicateReceive
    (
        MiniportAdapterHandle,
        (NDIS_HANDLE)&ReceiveContext,
        pFrag->pBuffer,
        VP_HEADERSIZE,
        pFrag->pBuffer+VP_HEADERSIZE,
        pFrag->BuffLength-VP_HEADERSIZE,
        TotalLength-VP_HEADERSIZE
    );

    NdisMEthIndicateReceiveComplete( MiniportAdapterHandle );


   return FALSE;  // Don't hold buffer
}


/******************************************************************************
*
* VpsRecvError(()
*
******************************************************************************/
static void VpsRecvError( PCHIP pChip, WORD Errors )
{
    VPM_SetupMiniContextFromPchip;

 
    // Keep track of OKs, Errors and confirm packet if necessary
    pvMini_Context->XmitErrors++;


    // Keep track of OKs, Errors and confirm packet if necessary
    if (Errors & RX_ERR_CRC_ERROR)
    {
        DEBUGMSG
        (
            ZONE_RECVERROR,
            (TEXT("VpsRecvError(): RX_ERR_CRC_ERROR\n"))
        );
        pvMini_Context->RcvCRCErrors++;
    }
    if (Errors & RX_ERR_EXTRA_DATA)
    {
        DEBUGMSG
        (
            ZONE_RECVERROR,
            (TEXT("VpsRecvError(): RX_ERR_EXTRA_DATA\n"))
        );
    }
    if (Errors & RX_ERR_RUNT)
    {
        DEBUGMSG
        (
            ZONE_RECVERROR,
            (TEXT("VpsRecvError(): RX_ERR_RUNT\n"))
        );
    }
    if (Errors & RX_ERR_FRAMING)
    {
        DEBUGMSG
        (
            ZONE_RECVERROR,
            (TEXT("VpsRecvError(): RX_ERR_FRAMING\n"))
        );
        pvMini_Context->RcvErrorAlignments++;
    }
    if (Errors & RX_ERR_OVERRUN)
    {
        DEBUGMSG
        (
            ZONE_RECVERROR,
            (TEXT("VpsRecvError(): RX_ERR_OVERRUN\n"))
        );
        pvMini_Context->RcvOverrun++;
    }
    if (Errors & RX_ERR_RX_ERR)
    {
        DEBUGMSG
        (
            ZONE_RECVERROR,
            (TEXT("VpsRecvError(): RX_ERR_RX_ERR\n"))
        );
    }

    if (Errors & RX_ERR_RX_MISS)
    {
        DEBUGMSG
        (
            ZONE_RECVERROR,
            (TEXT("VpsRecvError(): RX_ERR_RX_MISS\n"))
        );
    }

    if (Errors & RX_ERR_DRIBBLE)
    {
        DEBUGMSG
        (
            ZONE_RECVERROR,
            (TEXT("VpsRecvError(): RX_ERR_DRIBBLE\n"))
        );
    }
    if (Errors & RX_ERR_TOO_MANY_FRAGS)
    {
        DEBUGMSG
        (
            ZONE_RECVERROR,
            (TEXT("VpsRecvError(): RX_ERR_TOO_MANY_FRAGS\n"))
        );
    }
    if ( Errors & RX_ERR_NO_BUFFER ) 
    {
        DEBUGMSG
        (
            ZONE_RECVERROR,
            (TEXT("VpsRecvError(): RX_ERR_NO_BUFFER\n"))
        );
        pvMini_Context->RcvNoBuffers++;
    }
}



/******************************************************************************
*
* ProcessTxStatusQueue()
*
******************************************************************************/

void ProcessTxStatusQueue( PCHIP pChip )
{
    PCD   pCD;
    WORD  Status;
    MAXFL MaxFL;
    PTXREQ pTxReq;
 
    pCD    = pChip->pData;


    /* While the transmit status entry is not processed */
    while ( pCD->pTxStatNext->TxStat & TxStat_TxFP )
    {
        /* Get a derefrenced copy of the status */
        Status = pCD->pTxStatNext->TxStat;

        /* Find the associated transmit request */
        pTxReq = &pCD->TxReq[pCD->pTxStatNext->BufIndx];

        /* If the frame was not sent without errors */
        if ( !(Status & TxStat_TxWE) )
        {
            /* Report the errors */
            VpsSendError( pChip, pTxReq->SendID, (WORD)(Status&TxStat_Error_Mask));
        }

        if ( Status & TxStat_TxUnderrun )
        {
            /* If two underruns happen close together */
            if ( pCD->TxGoodCount < TXGOODMIN )
            {
                /* Read the Max Frame Length register */
                MaxFL.DWord = ReadDWord(OpReg_MaxFL);

                /* If the transmit start threshold is less than the maximum */
                if ( MaxFL.Word.TxStartThresh < TXSTARTMAX )
                {
                    /* Increase the transmit start threshold */
                    MaxFL.Word.TxStartThresh += TXSTARTSTEP;
                    WriteDWord( OpReg_MaxFL, MaxFL.DWord );
                }
            }

            /* Reset the number of frames transmitted without underruns */
            pCD->TxGoodCount = 0;

            RestartTransmit( pChip, pTxReq->StartIndex );
        }
        else  /* The frame did not have an underrun error */
        {
            /* Another frame has been transmitted without an underrun */
            pCD->TxGoodCount++;

            /* The transmit descriptors for this frame are now available */
            pCD->TxDescAvail += pTxReq->DescCount;


            /* Report that this send is now complete */
            VpsSendComplete( pChip, pTxReq->SendID );
        }

        /* The transmit status entry is now processed */
        pCD->pTxStatNext->TxStat = 0;

        /* Increment to the next transmit status entry (with wrap-around) */
        pCD->pTxStatNext++;
        if ( pCD->pTxStatNext == pCD->pTxStatLimit )
        {
            pCD->pTxStatNext = pCD->pTxStat;
        }
    }
}


/******************************************************************************
*
* VpsSendError(()
*
******************************************************************************/
static void VpsSendError( PCHIP pChip, DWORD SendID, WORD Errors )
{

    VPM_SetupMiniContextFromPchip
    pvMini_Context->XmitErrors++;

    if (Errors & TX_ERR_EXCESS_COLL)
    {
        DEBUGMSG
        (
            ZONE_SENDERROR,
            (TEXT("VpsSendError(): TX_ERR_EXCESS_COLL!\n"))
        );
        pvMini_Context->XmitMaxCollisions++;
    }
    if (Errors & TX_ERR_UNDERRUN)
    {
        DEBUGMSG
        (
            ZONE_SENDERROR,
            (TEXT("VpsSendError(): TX_ERR_UNDERRUN!\n"))
        );
        pvMini_Context->XmitUnderrun++;
       }
    if (Errors & TX_ERR_LOSS_CRS)
    {
        DEBUGMSG
        (
            ZONE_SENDERROR,
            (TEXT("VpsSendError(): TX_ERR_EXCESS_LOSS_CRS!\n"))
        );

        pvMini_Context->XmitLostCRS++;
    }
}

/******************************************************************************
*
* RestartTransmit()
*
******************************************************************************/
void RestartTransmit( PCHIP pChip, WORD StartIndex )
{
    PCD   pCD;
    WORD  NextIndex;
    WORD  BMControl;
    BYTE  BMStatus;
    int   x;

    pCD    = pChip->pData;

    /* Reset the transmit channel */
    BMControl=ReadWord( OpReg_BMCTL);
    WriteWord( OpReg_BMCTL, (WORD)(BMControl | BMCTL_TxChRes) );

    /* Wait until the channel reset is complete */
    for ( x=0; x<MAXLOOP; x++ )
    {
        BMControl=ReadWord( OpReg_BMCTL);
        if ( !(BMControl & BMCTL_TxChRes) ) 
            break;
    }

    /* Set descriptor current address to the starting transmit descriptor */
    WriteDWord( OpReg_TxDCA,
         pCD->TxDescPhysAddr + (StartIndex * sizeof(TxDesc_t)) );

    /* Re-enable (and initialize) the transmit descriptor processor */
    BMControl=ReadWord( OpReg_BMCTL);
    WriteWord( OpReg_BMCTL, (WORD)(BMControl | BMCTL_TxEn) );

    /* Wait until the transmit descriptor processor is active */
    for ( x=0; x<MAXLOOP; x++ )
    {
        BMStatus=ReadByte( OpReg_BMSts);
        if ( BMStatus & BMSts_TxAct ) 
            break;
    }

    /* Get the index of the next transmit descriptor */
    NextIndex = (WORD)(pCD->pTxDescNext - pCD->pTxDesc);
    if ( NextIndex <= StartIndex ) 
    {
        NextIndex += TXDESCCOUNT;
    }

    /* Re-enqueue the unprocessed transmit descriptors */
    WriteDWord( OpReg_TxDEQ, NextIndex-StartIndex );
}

/******************************************************************************
*
* VpsSendComplete()
*
******************************************************************************/
static void VpsSendComplete( PCHIP pChip, DWORD SendID )
{

    NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
    PNDIS_PACKET Packet;

    PNDIS_PACKET pTempTxPacket;
    PTXQUEUEELEMENT pTempTxQueueElem;
    PTXQUEUEELEMENT pTxQueueElem;

    VPM_SetupMiniContextFromPchip;

//    DEBUGMSG(ZONE_ERROR,(TEXT("VpsSendComplete packet %d\n"),(DWORD)SendID));

    pvMini_Context->XmitOKs++;

    if (pvMini_Context->TxQueueHead != NULL) 
    {
        pvMini_Context->XmitQueueDepth--;
        pTxQueueElem = (PVOID)&(pvMini_Context->TxQueueHead->MiniportReserved);
        if ( pTxQueueElem->XmitRC == NDIS_STATUS_NOT_INDICATING ) 
        {

            // No Indication needed, Send has not returned
            pTxQueueElem->XmitRC = Status;

        } 
        else 
        {

            Packet = NULL;
            // Run the Queue to the End or till packet SendID is found
            for (pTempTxPacket=pvMini_Context->TxQueueHead,
                 pTempTxQueueElem=(PVOID)&pTempTxPacket->MiniportReserved ;
                 pvMini_Context->TxQueueHead != NULL;
                 pTempTxPacket=pvMini_Context->TxQueueHead,
                 pTempTxQueueElem=(PVOID)&pTempTxPacket->MiniportReserved )
            {
                pvMini_Context->TxQueueHead = pTempTxQueueElem->NextPacket;
                if (pTempTxPacket == (PNDIS_PACKET)SendID)
                {
                    Packet = pTempTxPacket;
                    break;
                } 
                else 
                {
                    NdisMSendComplete
                    (
                        MiniportAdapterHandle,
                        pTempTxPacket,
                        NDIS_STATUS_FAILURE
                    );
                }
            } 

            // Confirm Send
            if (Packet != NULL) 
            {
                NdisMSendComplete(MiniportAdapterHandle,
                                  Packet,
                                  Status
                                  );
            }
        } 
    } 
    else 
    {
        pvMini_Context->XmitQueueDepth = 0;
    }

}


/******************************************************************************
*
* VchipSend()
*
* The return code indicates if the VCHIP held on the the transmit buffers.
* If the return code is TRUE, then the VCHIP held on to the transmit buffers
* and the VPS can not reuse the buffers until the VCHIP calls the
* ChipFreeSendBuff() routine.  If the return code is FALSE, then the VCHIP
* did not hold on to the transmit buffers and the VPS may immediately reuse
* them.
*
******************************************************************************/

WORD VchipSend( PCHIP pChip, DWORD SendID, WORD TotalLength)
{
    PCD    pCD;
    PTXREQ pTxReq;
    WORD   DescCount;
    TxDesc_t *pTxDesc;
//    BYTE  *pTxBuff;
//    int Frag;

    pCD    = pChip->pData;

    /* Verify that the total length is not too big */
    if ( TotalLength > 1514 )
    {
        VpsSendError( pChip, SendID, TX_ERR_TOO_BIG );
        VpsSendComplete( pChip, SendID);
        return FALSE;  /* Transmit buffers are not held */
    }

    pTxDesc=pCD->pTxDescNext;
    /* Only one transmit descriptor is used */
    DescCount=1;

    /* Fill in the transmit descriptor */
    pTxDesc->TxBufAdr  = pCD->TxBuff[pCD->TxReqIndex].PhysAddr;
    pTxDesc->BufLength = TotalLength;
    pTxDesc->BufIndx   = pCD->TxReqIndex;

    /* Start copying at the beginning of the next transmit buffer */
//    pTxBuff = pCD->TxBuff[pCD->TxReqIndex].pBuff;

    /* Copy the contents of the fragment buffers to the transmit buffer */
//    for ( Frag=0; Frag<FragCount; Frag++,pFrag++ )
//    {
//        NdisMoveMemory( pTxBuff, pFrag->pBuffer, pFrag->BuffLength );

⌨️ 快捷键说明

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