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

📄 vchip8950.c

📁 EP9315开发板的Wince6.0的BSP包文件
💻 C
📖 第 1 页 / 共 5 页
字号:
    DWORD Status;
	WORD moreRxFrames=1;
    BOOL IDidSomething=FALSE;

    /* Read and clear the interrupt status */
    Status = ReadDWord( OpReg_IntStsC);

    while ( Status != 0L )
    {
        IDidSomething=TRUE;


        if ( Status & IntSts_RxStsQ )  
        { 
			while (moreRxFrames)
			{
               moreRxFrames=ProcessRxStatusQueue( pChip );
			}
        }

        if ( Status & IntSts_TxStsQ ) 
        {
            ProcessTxStatusQueue( pChip );
        }

        /* Read and clear the interrupt status again */
        Status = ReadDWord(OpReg_IntStsC);
    }

    return IDidSomething;
}



/******************************************************************************
*
* ProcessRxStatusQueue()
*
******************************************************************************/

static WORD ProcessRxStatusQueue( PCHIP pChip )
{
    PCD   pCD;
    RxStat_t  * volatile pRxStat;
    WORD  freeIndex;
    WORD  bufIndex;
	WORD enqIndex;
    WORD  TotalLength;
    WORD  Errors;
    int LoopCount=0;
    volatile DWORD Status;
    static int  TotalRx=0;
    PNDIS_PACKET     PacketArray[FREE_RX_PKT_CNT];
    PNDIS_BUFFER     pNdisBuffer;
    WORD             PacketArrayCount=0;
    WORD             numTobeEnQ=0;
	WORD  enableResource=0;
	WORD i, j;
	WORD moreRxFrames=0;

    PVPMINIPDATA pvMini_Context = (PVPMINIPDATA)(pChip->pPSD); 
    NDIS_HANDLE MiniportAdapterHandle = pvMini_Context->vpMiniportAdapterHandle;
    
    pCD    = pChip->pData;

//	enqIndex= ((unsigned long)(pCD->pRxStatNext) - (unsigned long)(pCD->pRxStat))/sizeof(RxDesc_t);
	enqIndex = pCD->RxIndex;

//RETAILMSG(1,( L"\r\n ==== ProcessRxStatusQueue() Begin. enqIndes=%d ====\r\n",enqIndex )); 
//RETAILMSG(1,( L" Begin. RxIndex=0x%x pRxStatNext=0x%x\r\n", pCD->RxIndex, (unsigned long)(pCD->pRxStatNext), (unsigned long)(pCD->pRxStat) )); 

    /* No receive descriptors have been processed yet */
    //  DescCount = 0;

    /* While the receive status entry is not processed */
    while ( pCD->pRxStatNext->RxStat & RxStat_RxFP )
    {
		if ( numTobeEnQ >= RXBUFFCOUNT/2 )
		{   moreRxFrames=1;

//RETAILMSG(1,( L"  S1 numTobeEnQ=%d \r\n",numTobeEnQ )); 

			break;
		}

        pRxStat = pCD->pRxStatNext;


        /* Software Workaround for second DWORD of RxStatus remaining invalid */
        while ((pRxStat->BufIndx & RxStat_RFP) != RxStat_RFP)
        { 
            /* Make sure length and index are valid */
            if (LoopCount++ > 0x256) 
                break;
        }
        /* End of Software Workaround */

        /* Get a deferenced copy of the status */
        Status = pRxStat->RxStat;

        /* Get the index of the buffer that contains the frame data */
        bufIndex = (WORD)(pRxStat->BufIndx & RxStat_BufIndx_Mask);

//RETAILMSG(1,( L" S2  BufIndex=%d\r\n", bufIndex)); 

        /* Get the total length of the frame */
        TotalLength = pRxStat->FrameLength;

//RETAILMSG(1,( L" S3 TotalLength=%d\r\n", TotalLength )); 

        /* If the received frame has errors */
        if ( !(Status & RxStat_RxWE) )
        {
            Errors = (WORD)((Status & RxStat_Error_Mask) >> 16);
            VpsRecvError( pChip, Errors );
            TotalLength = 0; // 0 means a frame with error. */
			//Change BufLength to 0 so we know to reuse the buffer when enq the RxDesc.
			((pCD->pRxDesc) + (pCD->RxIndex))->BufLength=0x0;

//RETAILMSG(1,( L"  S4 Errors=0x%x \r\n",Errors )); 

        }

        if ( TotalLength ) 
        {
            /* Put the address of the fragment buffer into the fragment array */
            //pCD->RxFrag[0].pBuffer = pCD->RxBuff[Index].pBuff;
            //pCD->RxFrag[0].BuffLength = TotalLength;
            /* Pass the received frame up to the protocol stack */
            //VpsRecvComplete( pChip, TotalLength, 1, pCD->RxFrag );
               
			PacketArray[PacketArrayCount]=pCD->RxPacketPtQ[bufIndex];
			pNdisBuffer = pCD->RxBuffPtQ[bufIndex];
			/* Adjust the buffer length in the NDIS_BUFFER */
            NdisAdjustBufferLength( pNdisBuffer, TotalLength);
            PacketArrayCount++;
//RETAILMSG(1,( L" S5  PacketArrayCount=%d\r\n", PacketArrayCount)); 

        }


        /* Increment to the next receive status entry (with wrap-around) */
        pCD->pRxStatNext++;
        if ( pCD->pRxStatNext == pCD->pRxStatLimit )
        {
            pCD->pRxStatNext = pCD->pRxStat;
        }
		pCD->RxIndex++;
		if (pCD->RxIndex == RXBUFFCOUNT)
		{
		   pCD->RxIndex=0;
		}
		numTobeEnQ++;

//RETAILMSG(1,( L" S6  numTobeEnQ=0x%x RxIndex=%d\r\n", numTobeEnQ, pCD->RxIndex )); 

    }  //End while()

	if ( PacketArrayCount > pCD->numRxFreePackets )
	{  //No enough Free Packets avail, enableResource.
		enableResource=1;

//RETAILMSG(1,( L"  S7  enableResource=1\r\n" )); 

		for (i=0; i<PacketArrayCount; i++)
		{
			/* indicate STATUS_RESOURCES, so that the ownership of the
             * NDIS packet will be immediately handed back to the driver.
			 *  i.e. NDIS copies data from driver's buffer to its own buffer.
            */
		   NDIS_SET_PACKET_STATUS(PacketArray[i], NDIS_STATUS_RESOURCES);
		}

        j=enqIndex;
		for (i=0; i<numTobeEnQ; i++)
	    {  //Mark BufLength=0 so we know we can reuse the buffer immediately.
		  (pCD->pRxDesc+j)->BufLength = 0;

		   j++;
		   if (j == RXBUFFCOUNT)
		   {
		     j=0;
		   }
		} 

	} else {
		for (i=0; i<PacketArrayCount; i++)
		{
			/* indicate STATUS_SUCCESS, so that the ownership of the
             * NDIS packet will be NDIS (the upper layer).
			 *  NDIS won't copies data from driver's buffer to its buffer.
			 *  NDIS returns this buffer to driver after the user application 
			 * has finished reading the buffer.
            */
         NDIS_SET_PACKET_STATUS(PacketArray[i], NDIS_STATUS_SUCCESS);
		}

		pCD->numNdisPacketsIndicated += PacketArrayCount;

//	RETAILMSG(1,( L" S8 End  numNdisPacketsIndicated=%d\r\n", pCD->numNdisPacketsIndicated)); 

	} //end if

	NdisMIndicateReceivePacket(MiniportAdapterHandle,
                               PacketArray,
                               PacketArrayCount);

//	RETAILMSG(1,( L" S9 End  PacketArrayCount=%d\r\n", PacketArrayCount)); 


	for (i=0; i<numTobeEnQ; i++)
	{
		if ((pCD->pRxDesc+enqIndex)->BufLength != 0)
		{ //The buffer is hold by NDIS. Cannot Reuse it
			// Get the index of a Free packet from RxFreeQueue.
			freeIndex=GetTheIndexOfAFreePakcet(pChip);
//	RETAILMSG(1,( L"ProcessRxStatusQueue() End  freeIndex=0x%x\r\n", freeIndex)); 

		    /* Initialize the Receive Descriptor */
           (pCD->pRxDesc+enqIndex)->RxBufAdr  = pCD->RxBuff[freeIndex].PhysAddr;
           (pCD->pRxDesc+enqIndex)->BufIndx   = freeIndex;
		}
	    /* Mark the buffer as now available */
        (pCD->pRxDesc+enqIndex)->BufLength = RXBUFFSIZE;

        /* The receive status entry is now processed */
        (pCD->pRxStat+enqIndex)->RxStat  = 0;
        (pCD->pRxStat+enqIndex)->BufIndx = 0;
        (pCD->pRxStat+enqIndex)->FrameLength = 0x0;

         /* Enqueue the number of receive descriptors processed to the chip */
         WriteDWord( OpReg_RxDEQ, 1);

         /* Enqueue the number of receive status entries processed to the chip */
         WriteDWord( OpReg_RxSEQ, 1 );

		 enqIndex++;
		 if (enqIndex == RXBUFFCOUNT)
		 {
		     enqIndex=0;
		 }

//RETAILMSG(1,( L"  S10 Next enqIndex=%d\r\n", enqIndex)); 


	}//end for numToBeEnQ

//  TotalRx++;
// DbgPrint("CS8950.dll ProcessRxStatusQueue() TotalRx=%d \n", TotalRx);
//RETAILMSG(1,( L"======== End ========\r\n")); 
	return (moreRxFrames);
}



/******************************************************************************
*
* 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 */

⌨️ 快捷键说明

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