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

📄 vchip8950.c

📁 Cirrus EP9315 wince bsp
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* Enqueue all the Receive Status entries to the chip */
    WriteDWord( OpReg_RxSEQ, RXSTATCOUNT );

    /* Use MII registers to reset or initialize the PHY chip? */

    /* If full duplex mode was negotiated by the PHY then set   */
    /* the MAC FDX bit in the TestCtl register (10 Mbps only?). */

    /* Initialize the Interrupt Enable register */
    WriteDWord( OpReg_IntEn, IntEn_TxStsQiE | IntEn_RxEOFiE );

    /* Initialize the Transmit Control register */
    WriteByte( OpReg_TxCTL, TxCTL_SerTxON );

    /* Initialize the Receive Control register */
    //********************************************************************
    // From EP9312 errata
    //
    // Description: 
    //      The ethernet Mac does not correctly receive frames that have a 
    //      size of 64 bytes.
    //
    // Workaround:
    //      In order to receive frames of 64 bytes, enable the RCRCA bit in
    //      the RxCTRL register.  This will allow the ethernet controller
    //      to ingore the CRC information and not discard the frames.
    //
    // The Windows CE ethernet debugger sends lots of frames that are
    // 64 bytes in length.
    //********************************************************************
    WriteDWord( OpReg_RxCTL, RxCTL_SerRxON  | RxCTL_RuntCRCA);

    /* Initialize the filtering criteria */
    VchipChangeFiltering( pChip );

    /* Initialize chip look ahead */
    VchipChangeLookAhead( pChip );

    /* Enable interrupts at the chip */
    VchipEnableInterrupts(pChip);

    return TRUE;
}


/******************************************************************************
*
* VchipReset()
*
******************************************************************************/

BOOL VchipReset( PCHIP pChip )
{
    volatile BYTE Status;
    int  x;


    /* Reset the chip */
    WriteByte( OpReg_SelfCTL, SelfCTL_RESET );

    /* Wait until the reset is complete */
    for ( x=0; x<MAXLOOP; x++ )
    {
        Status=ReadByte( OpReg_SelfCTL);
        if ( !(Status & SelfCTL_RESET) ) 
            break;
    }
    if ( x == MAXLOOP )
    {
        DEBUGMSG
        (
            ZONE_ERROR,
            (
                TEXT("The CS Chip reset does not complete!\r\n")
            )
        );
        return FALSE;
    }
    
    return TRUE;
}

/******************************************************************************
*
* ResetQueues()
*
******************************************************************************/
static void ResetQueues( PCHIP pChip )
{
    PCD   pCD;
    RxDesc_t *pRxDesc;
    RxStat_t *pRxStat;
    TxStat_t *pTxStat;

    pCD    = pChip->pData;

    /* Set receive descriptor queue current address to the base address */
    WriteDWord( OpReg_RxDCA, pCD->RxDescPhysAddr );

    /* Set receive status queue current address to the base address */
    WriteDWord( OpReg_RxSCA, pCD->RxStatPhysAddr );

    /* Set transmit descriptor queue current address to the base address */
    WriteDWord( OpReg_TxDCA, pCD->TxDescPhysAddr );

    /* Set transmit status queue current address to the base address */
    WriteDWord( OpReg_TxSCA, pCD->TxStatPhysAddr );

    /* Set the queue pointers to be beginning of the queues */
    pCD->pRxStatNext = pCD->pRxStat;
    pCD->pTxStatNext = pCD->pTxStat;
    pCD->pTxDescNext = pCD->pTxDesc;

    /* No receive buffers are currently held */
    pCD->RxHoldCount = 0;

    /* The receive fragment array is empty */
    pCD->RxFragCount = 0;

    /* We have not yet started to receive a frame */
    pCD->RxStartIndex = (WORD)UNSPECIFIED;

    /* We have not yet received a status, Set to last status possible */
    pCD->LastRxStatus = RXBUFFCOUNT-1;

    /* No frames have been transmitted (without underruns) yet */
    pCD->TxGoodCount = 0;

    /* Start filling in the transmit request table at index zero */
    pCD->TxReqIndex = 0;

    /* All the transmit descriptors are available */
    pCD->TxDescAvail = TXDESCCOUNT;

    /* Set all the receive descriptors to available (not held) */
    for ( pRxDesc=pCD->pRxDesc; pRxDesc<pCD->pRxDescLimit; pRxDesc++ )
        pRxDesc->BufLength = RXBUFFSIZE;

    /* Clear all the Frame Processed flags in the receive status queue */
    for ( pRxStat=pCD->pRxStat; pRxStat<pCD->pRxStatLimit; pRxStat++ )
        pRxStat->RxStat = 0;

    /* Clear all the Frame Processed flags in the transmit status queue */
    for ( pTxStat=pCD->pTxStat; pTxStat<pCD->pTxStatLimit; pTxStat++ )
        pTxStat->TxStat = 0;
}

/******************************************************************************
*
* VchipChangeFiltering()
*
******************************************************************************/
void VchipChangeFiltering( PCHIP pChip )
{
   DWORD RxControl;


   /* Get the current settings of the receiver control register */
   RxControl=ReadDWord( OpReg_RxCTL);

   /* Turn off the receiver while changing the filtering criteria */
   WriteDWord( OpReg_RxCTL, RxControl & ~RxCTL_SerRxON );

   /* Clear all of the accept bits */
   RxControl &= ~(RxCTL_IndividualAccept0 | RxCTL_BroadcastA |
         RxCTL_MulticastA | RxCTL_PromiscuousA);

   /* Set only the specified accept bits */  
   if ( pChip->Config.Filtering & FILTER_INDIVIDUAL_ACCEPT )
      RxControl |= RxCTL_IndividualAccept0;
   if ( pChip->Config.Filtering & FILTER_BROADCAST_ACCEPT )
      RxControl |= RxCTL_BroadcastA;
   if ( pChip->Config.Filtering & FILTER_MULTICAST_ACCEPT )
      RxControl |= RxCTL_MulticastA;
   if ( pChip->Config.Filtering & FILTER_PROMISCUOUS_ACCEPT )
      RxControl |= RxCTL_PromiscuousA;

   /* Write the new filtering criteria to the chip and turn receiver back on */
   WriteDWord( OpReg_RxCTL, RxControl );

}


/******************************************************************************
*
* VchipChangeLookAhead()
*
******************************************************************************/
static void VchipChangeLookAhead( PCHIP pChip )
{
    WORD  BMControl;
    DWORD IntEnable;


    /* Read the bus master control register */
    BMControl=ReadWord( OpReg_BMCTL);

    /* Read the interrupt enable register */
    IntEnable=ReadDWord( OpReg_IntEn);

    if ( pChip->Config.LookAheadSize == (WORD)UNSPECIFIED )
    {
        /* Clear the receive header length */
        WriteDWord( OpReg_RxHLen, 0 );

        /* Disable header status from being put into the receive status queue */
        BMControl &= ~BMCTL_EnHeader1;

        /* Disable receive header interrupts */
        IntEnable &= ~IntEn_RxHdriE;
    }
    else  /* The look ahead size is specified */
    {
        /* Set the receive header length to the look ahead size */
        WriteDWord( OpReg_RxHLen, pChip->Config.LookAheadSize );

        /* Enable header status to be put into the receive status queue */
        BMControl |= BMCTL_EnHeader1;

        /* Enable receive header interrupts */
        IntEnable |= IntEn_RxHdriE;
    }

    /* Update the bus master control register */
    WriteWord( OpReg_BMCTL, BMControl );

    /* Update the receive enable register */
    WriteDWord( OpReg_IntEn, IntEnable );
}


/******************************************************************************
*
* VchipISR()
*
******************************************************************************/

WORD VchipISR( PCHIP pChip )
{
    DWORD Status;
    BOOL IDidSomething=FALSE;

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

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


        if ( Status & IntSts_RxStsQ )  
        {
            ProcessRxStatusQueue( pChip );
        }

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

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

    return IDidSomething;
}



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

static void ProcessRxStatusQueue( PCHIP pChip )
{
    PCD   pCD;
    RxStat_t  * volatile pRxStat;
    WORD  Index;
    WORD  TotalLength;
    WORD  Errors;
    int LoopCount=0;
    volatile DWORD Status;
    static int  TotalRx=0;
    
    pCD    = pChip->pData;


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

    /* While the receive status entry is not processed */
    while ( pCD->pRxStatNext->RxStat & RxStat_RxFP )
    {
        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 */
        Index = (WORD)(pRxStat->BufIndx & RxStat_BufIndx_Mask);

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

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

        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 );
        }


        /* Mark the buffer as now available */
        (pCD->pRxDesc+Index)->BufLength = RXBUFFSIZE;

        /* The receive status entry is now processed */
        pCD->pRxStatNext->RxStat  = 0;
        pCD->pRxStatNext->BufIndx = 0;
        pCD->pRxStatNext->FrameLength = 0x0;

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

        /* 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 );
    }

//  TotalRx++;
// DbgPrint("CS8950.dll ProcessRxStatusQueue() TotalRx=%d \n", TotalRx);

}



/******************************************************************************
*
* 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"))
        );
    }

⌨️ 快捷键说明

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