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

📄 vchip8950.c

📁 Cirrus EP9315 wince bsp
💻 C
📖 第 1 页 / 共 5 页
字号:
    int  x;

    /* Ensure that the PHY is not busy */
    for ( x=0; x<MAXLOOP; x++ )
    {
        Status=ReadByte( OpReg_MIISts);
        if ( !(Status & MIISts_Busy) ) break;
    }
    if ( x == MAXLOOP ) 
    {       
        DEBUGMSG
        (
            ZONE_ERROR,
            (
                TEXT("First PHY write failed, Address = 0x%x, Register = 0x%x, Value = 0x%x.\r\n"),
                (ULONG)Address,
                (ULONG)Register,
                (ULONG)Value
            )
        );
        return FALSE;
    }

    /* Put the PHY data into the PHY Data register */
    WriteWord( OpReg_MIIData, Value );

    /* Issue the command to write to the register within the PHY */
    WriteWord( OpReg_MIICmd,(WORD)(MIICmd_Opcode_Write |(Address<<5)| Register));

    /* Wait until the command is completed */
    for ( x=0; x<MAXLOOP; x++ )
    {
        Status=ReadByte( OpReg_MIISts );
        if ( !(Status & MIISts_Busy) ) 
            break;
    }
    if ( x == MAXLOOP ) 
    {       
        DEBUGMSG
        (
            ZONE_ERROR,
            (
                TEXT("Second PHY write failed, Address = 0x%x, Register = 0x%x, Value = 0x%x.\r\n"),
                (ULONG)Address,
                (ULONG)Register,
                (ULONG)Value
            )
        );
        return FALSE;
    }

    return TRUE;
}

/******************************************************************************
*
* PHYAutoNegotiation(PCHIP pChip);
* Purpose: PHY Auto Negotiation to detect the link speed (10/100Mbps) and 
*          duplex (half/full).
* return:  TRUE: successful. FALSE: fail
*
******************************************************************************/
#define     MAX_AUTOCONFIGTIME          (4 * 100)
static int PHYAutoNegotiation(PCHIP pChip)
{
    unsigned short   val;
    int              x;
    unsigned short   PhyId;
    unsigned char    b8;
    WORD             Result;
    WCHAR            *strDuplex, *strSpeed;

    PhyId = 0x1;

    //
    // Write to Auto-Negotiation Advertisement Register (0x04)
    // Set IEEE_802.3, and advertise 100/10M full/half duplex available
    //
    val = ANAR_SeltField_IEEE8023 | ANAR_10BaseT_HDX_Able | ANAR_10BaseT_FDX_Able | 
          ANAR_100BaseTX_HDX_Able | ANAR_100BaseTX_FDX_Able;
    Result = WritePHY( pChip, PhyId, PHYReg_ANAR, val);
    ASSERT(Result);


    /*write to Basic Mode Control Register (0x00), enable and restart auto negotiation*/
    val = BMCR_Restart_Auto_Neg| BMCR_Auto_Neg_Enable;
    Result = WritePHY( pChip, PhyId, PHYReg_BMCR, val);

    //
    //
    // 02/14/02 @melody Auto_Neg should be compeleted in 5 min.
    //
    // I am not going to hang the system for 5 minutes while whating to boot
    // If it doesn't autoconfigure in 4 seconds then assume it is 10Mbit Half.
    //
    for(x = 0; x<MAX_AUTOCONFIGTIME; x++)  
    { 
        /* Check if Auto-Negotiation complete? */
        Sleep(10);
        Result = ReadPHY( pChip, PhyId, PHYReg_BMSR, &val );
        if((val & BMSR_Auto_Neg_Complete) )
        {
            break;
        }
    }

    if(x == MAX_AUTOCONFIGTIME)
    {
        //
        // If this fails set to Half_Duplex 10 Mbit.
        //
        Result = WritePHY( pChip, 0x0, PHYReg_BMCR, 0x0000); 
        DEBUGMSG
        (
            ZONE_ERROR,
            (
                TEXT("CS8950: Error! PHY cannot complete Auto Negotiation.\n")
            )
        );

        return FALSE;
    }

    /* if the Link is Full Duplex, then set MAC for Full Duplex too. */  
    Result = ReadPHY( pChip, PhyId, PHYReg_ANLPAR, &val );

    Result = ReadPHY( pChip, PhyId, PHYReg_SSR, &val );
    if(val & SSR_Full_Duplex ) 
    {
        b8 = ReadByte(OpReg_TestCTL); 
        b8 |=  TestCTL_MACFDX;
        WriteByte(OpReg_TestCTL, b8);
    }

    //
    // Lets print out the current mode that we are operating in.
    //
    if(val & SSR_Full_Duplex)
    {
        strDuplex = L"Full";   
    }
    else
    {
        strDuplex = L"Half";   
    }

    if(val & SSR_10_Mbps)
    {
        strSpeed = L"10";   
    }
    else
    {
        strSpeed = L"100";   
    }

    // 
    // Show the current link mode.
    //
    DEBUGMSG
    (
        ZONE_INIT,
        (
            TEXT("CS8950: Speed = %s Mbs, Duplex = %s.\n"), 
            strSpeed, 
            strDuplex
        )
    );



   return TRUE;
}



/******************************************************************************
*
* StartupPHY()
*
******************************************************************************/
static BOOL StartupPHY( PCHIP pChip )
{
    PCD     pCD;
    WORD    Result;
    WORD    val=0;
    BYTE    b8;

    pCD = (PCD)pChip->pData;
    /* Disable 2nd PHY */
    //Result = WritePHY( pChip, 0x1f, PHYReg_BMCR, BMCR_Power_Down);
    //ASSERT(Result);


    /* QQQQQQQ Disable SQE in Reg 0x13 */
    Result = WritePHY( pChip, 0x0, 0x13, 0x0000);
    ASSERT(Result);


    /* Set PHY Internal LoopBack */
    /*     Result = WritePHY( pChip, 0x0, PHYReg_BMCR, BMCR_Full_Duplex|BMCR_Loopback);*/
    /*Result = WritePHY( pChip, 0x0, PHYReg_BMCR, BMCR_Auto_Neg_Enable|BMCR_Restart_Auto_Neg);*/
    //     Result = WritePHY( pChip, 0x0, PHYReg_BMCR, BMCR_Full_Duplex); }
    //Result = WritePHY( pChip, 0x0, PHYReg_BMCR, 0x0000); //Half_Duplex
    // @melody 09/10/01   Result = WritePHY( pChip, 0x0, PHYReg_BMCR, 0x0000); //Half_Duplex
    //ASSERT(Result);
    /* @melody 09/10/01  */

    pChip->Config.DetectedMediaType  = MEDIA_BASE_T;
    pChip->Config.DetectedMediaSpeed = MEDIA_10_MBPS;
    pChip->Config.CurrentDuplexMode  = DUPLEX_HALF;

    if ( pChip->Config.RequestedMediaSpeed == MEDIA_AUTO_DETECT ||
          pChip->Config.RequestedDuplexMode == DUPLEX_AUTO_NEGOTIATE ) 
    {
        Result =PHYAutoNegotiation(pChip);
    } 
    else 
    {
        if ( pChip->Config.RequestedMediaSpeed == MEDIA_100_MBPS ) 
        {
             val = BMCR_100_MBPS;
             pChip->Config.DetectedMediaSpeed = MEDIA_100_MBPS;
        }

        if ( pChip->Config.RequestedDuplexMode == DUPLEX_FULL ) 
        {
             val = val | DUPLEX_FULL;
             pChip->Config.CurrentDuplexMode  = DUPLEX_FULL;

             /* if the Link is Full Duplex, then set MAC for Full Duplex too. */  
             b8 = ReadByte(OpReg_TestCTL); 
             b8 |=  TestCTL_MACFDX;
             WriteByte(OpReg_TestCTL, b8);
        }

        Result = WritePHY( pChip, 0x0, PHYReg_BMCR, val);
    }

    return TRUE;
}


/******************************************************************************
*
* StartupQueues()
*
******************************************************************************/
static BOOL StartupQueues( PCHIP pChip )
{
    PCD   pCD;
    WORD  Index;
    BOOL  Result;

    pCD    = pChip->pData;

    /* Allocate shared memory for the Receive Descriptor Queue */
    Result = VosAllocSharedMemory( pChip, sizeof(RxDesc_t)*RXDESCCOUNT,
         &(PVOID)pCD->pRxDesc, &pCD->RxDescPhysAddr );
    if ( Result != TRUE ) 
    {
        return FALSE;
    }

    /* Initialize Receive Descriptor Queue limit pointer */
    pCD->pRxDescLimit = pCD->pRxDesc + RXDESCCOUNT;

    /* Initialize the Receive Descriptor Queue registers */
    WriteDWord( OpReg_RxDBA, pCD->RxDescPhysAddr );
    WriteWord(  OpReg_RxDBL, sizeof(RxDesc_t)*RXDESCCOUNT );
    WriteDWord( OpReg_RxDTH, 0x00040002 );

    /* Allocate shared memory for the Receive Status Queue */
    Result = VosAllocSharedMemory( pChip, sizeof(RxStat_t)*RXSTATCOUNT,
         &(PVOID)pCD->pRxStat, &pCD->RxStatPhysAddr );
    if ( Result != TRUE)
    {
        return FALSE;
    }

    /* Initialize Receive Status Queue limit pointer */
    pCD->pRxStatLimit = pCD->pRxStat + RXSTATCOUNT;

    /* Initialize the Receive Status Queue registers */
    WriteDWord( OpReg_RxSBA, pCD->RxStatPhysAddr );
    WriteWord( OpReg_RxSBL, sizeof(RxStat_t)*RXSTATCOUNT);
    WriteDWord(OpReg_RxSTH, 0x00040002 );

    /* Allocate shared memory for the Transmit Descriptor Queue */
    Result = VosAllocSharedMemory( pChip, sizeof(TxDesc_t)*TXDESCCOUNT,
         &(PVOID)pCD->pTxDesc, &pCD->TxDescPhysAddr );
    if ( Result != TRUE )
    {
        return FALSE;
    }

    /* Initialize Transmit Descriptor Queue limit pointer */
    pCD->pTxDescLimit = pCD->pTxDesc + TXDESCCOUNT;

    /* Initialize the Transmit Descriptor Queue registers */
    WriteDWord( OpReg_TxDBA, pCD->TxDescPhysAddr );
    WriteWord( OpReg_TxDBL, sizeof(TxDesc_t)*TXDESCCOUNT );
    WriteDWord( OpReg_TxDTH, 0x00040002 );

    /* Allocate shared memory for the Transmit Status Queue */
    Result = VosAllocSharedMemory( pChip, sizeof(TxStat_t)*TXSTATCOUNT,
         &(PVOID)pCD->pTxStat, &pCD->TxStatPhysAddr );
    if ( Result != TRUE )
    {
        return FALSE;
    }

    /* Initialize Transmit Status Queue limit pointer */
    pCD->pTxStatLimit = pCD->pTxStat + TXSTATCOUNT;

    /* Initialize the Transmit Status Queue registers */
    WriteDWord( OpReg_TxSBA, pCD->TxStatPhysAddr );
    WriteWord(  OpReg_TxSBL, sizeof(TxStat_t)*TXSTATCOUNT );
    WriteDWord( OpReg_TxSTH, 0x00040002 );

    /* Allocate receive buffers and initialize the Receive Descriptor Queue */
    for ( Index=0; Index<RXDESCCOUNT; Index++ )
    {
        /* Allocate shared memory for a receive buffer */
        Result = VosAllocSharedMemory( pChip, RXBUFFSIZE,
            &(PVOID)pCD->RxBuff[Index].pBuff, &pCD->RxBuff[Index].PhysAddr );
        if ( Result != TRUE )
        {
            return FALSE;
        }

        /* Initialize the Receive Descriptor */
        (pCD->pRxDesc+Index)->RxBufAdr  = pCD->RxBuff[Index].PhysAddr;
        (pCD->pRxDesc+Index)->BufLength = RXBUFFSIZE;
        (pCD->pRxDesc+Index)->BufIndx   = Index;
    }

      /* Allocate the transmit buffers */
    for ( Index=0; Index<TXBUFFCOUNT; Index++ )
    {
        /* Allocate shared memory for a transmit buffer */
        Result = VosAllocSharedMemory( pChip, TXBUFFSIZE,
                &(PVOID)pCD->TxBuff[Index].pBuff, &pCD->TxBuff[Index].PhysAddr );
        if ( Result != TRUE )
        {
            return FALSE;
        }
    }

    /* Initialize receive and transmit buffer thresholds */
    WriteDWord( OpReg_RxBTH, 0x00800040 );
    WriteDWord( OpReg_TxBTH, 0x00200010 );

    return TRUE;
}




/******************************************************************************
*
* VchipInit()
*
******************************************************************************/

static BOOL VchipInit( PCHIP pChip )
{
    PCD             pCD;
    BYTE            Status;
    BOOL            b;
    LARGE_INTEGER   liCurrent, liStart;


    pCD    = pChip->pData;


    /* Reset the chip */
    //Result = VchipReset( pChip );
    //if ( Result != TRUE )
    //{
    //    return FALSE;
    //}

    /* Reset the queues */
    ResetQueues( pChip );

    /* Enable the transmit descriptor processor */
    WriteWord( OpReg_BMCTL, BMCTL_TxEn );

    /* Wait until the transmit descriptor processor is active */
    b = QueryPerformanceCounter(&liStart);
    for(;;)
    {
        b = QueryPerformanceCounter(&liCurrent);
        ASSERT(b);
        if((liCurrent.QuadPart - liStart.QuadPart) > MAC_INITIALIZATION_TIMEOUT)
        {
            DEBUGMSG
            (
                ZONE_ERROR,
                (
                    TEXT("CS8950: The transmit descriptor processor is not active 0x%08x!\n"),
                    Status
                )
            );

            DumpRegisters();
            return FALSE;
        }
        Status=ReadByte( OpReg_BMSts);
        if ( Status & BMSts_TxAct ) 
            break;
    }


    /* Enable the receive descriptor processor */
    WriteWord( OpReg_BMCTL, BMCTL_RxEn );

    /* Wait until the receive descriptor processor is active */
    b = QueryPerformanceCounter(&liStart);
    ASSERT(b);
    for(;;)
    {
        b = QueryPerformanceCounter(&liCurrent);
        ASSERT(b);
        if((liCurrent.QuadPart - liStart.QuadPart) > MAC_INITIALIZATION_TIMEOUT)
        {
            DEBUGMSG
            (
                ZONE_ERROR,
                (
                    TEXT("CS8950: The receive descriptor processor is not active! OpReg_BMSts=%x \n"),
                    Status
                )
            );

            DumpRegisters();
            return FALSE;
        }
        Status=ReadByte( OpReg_BMSts);
        if ( Status & BMSts_RxAct ) 
            break;
    }



    /* Enqueue all the Receive Descriptors to the chip */
    WriteDWord(OpReg_RxDEQ, RXDESCCOUNT );

⌨️ 快捷键说明

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