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

📄 vchip8950.c

📁 EP9315开发板的Wince6.0的BSP包文件
💻 C
📖 第 1 页 / 共 5 页
字号:
        );
        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;
}


static BOOL Check_PHY_ID_Type( PCHIP pChip, WORD PHYAddress)
{
    PCD  pCD;
    BOOL Result;
    union
    {
      WORD  Word[2];
      DWORD DWord;
    } PHYID;

    pCD = (PCD)pChip->pData;

     /* Read PHY ID register 1 */
     Result = ReadPHY( pChip, PHYAddress, PHYReg_PHYIDR1, &PHYID.Word[1] );
     if ( Result != TRUE )
     {
        return FALSE;
	 }

     /* Read PHY ID register 2 */
     Result = ReadPHY( pChip, PHYAddress, PHYReg_PHYIDR2, &PHYID.Word[0] );
     if ( Result != TRUE )
	 {
        return FALSE;
	 }

      /* Check if it is a PHY that we know about */
     if ( ((PHYID.DWord & PHYID_OUI_Mask)   == PHYID_OUI_National) &&
         ((PHYID.DWord & PHYID_Model_Mask) == PHYID_Model_DP83840) )
	 {
         pCD->PHYType = PHY_TYPE_NATIONAL;
         DEBUGMSG(ZONE_INIT,(TEXT("Detected National PHY at address: %x\r\n"), PHYAddress) );
	 }
     else if ( ((PHYID.DWord & PHYID_OUI_Mask)   == PHYID_OUI_Crystal) &&
              ((PHYID.DWord & PHYID_Model_Mask) == PHYID_Model_CS8952) )
	 {
         pCD->PHYType = PHY_TYPE_CRYSTAL;
         DEBUGMSG(ZONE_INIT,(TEXT("Detected Crystal PHY at address: %x\r\n"), PHYAddress) );
	 }
     else if ( ((PHYID.DWord & PHYID_OUI_Mask)   == PHYID_OUI_ICS) &&
             ((PHYID.DWord & PHYID_Model_Mask) == PHYID_Model_ICS1890) )
	 {
         pCD->PHYType = PHY_TYPE_ICS;
         DEBUGMSG(ZONE_INIT,(TEXT("Detected ICS1890 PHY at address: %x\r\n"), PHYAddress) );
	 }
     else if ( ((PHYID.DWord & PHYID_OUI_Mask)   == PHYID_OUI_BROADCOM) &&
             ((PHYID.DWord & PHYID_Model_Mask) == PHYID_Model_BCM5201) )
	 {                                                                  
         pCD->PHYType = PHY_TYPE_BROADCOM;                              
         DEBUGMSG(ZONE_INIT,(TEXT("Detected Broadcom PHY at address: %x\r\n"), PHYAddress) );
	 }                                                                  
     else if ( ((PHYID.DWord & PHYID_OUI_Mask)   == PHYID_OUI_MICREL) &&
          ((PHYID.DWord & PHYID_Model_Mask) == PHYID_Model_KS8721BL) )
	 {                                                                  
         pCD->PHYType = PHY_TYPE_MICREL_8721BL;                              
         DEBUGMSG(ZONE_INIT,(TEXT("Detected Micrel KS8721BL PHY at address: %x\r\n"), PHYAddress ));
	 }
     else if (PHYID.DWord == 0x00406212)
	 {
         pCD->PHYType = PHY_TYPE_BROADCOM;
         DEBUGMSG(ZONE_INIT,(TEXT("Detected Broadcom PHY at address: %x\r\n"), PHYAddress) );
	 }
     else if (PHYID.DWord == 0x78100003)
	 {
         pCD->PHYType = PHY_TYPE_LEVEL1; /* clc */
         DEBUGMSG(ZONE_INIT,(TEXT("Detected Level1 PHY at address: %x\r\n"), PHYAddress) );
	 } else
	 {
         pCD->PHYType = PHY_TYPE_UNKNOWN; 
         DEBUGMSG(ZONE_INIT,(TEXT("Detected Unknown PHY at address: %x\r\n"), PHYAddress) );
	 }
 

     /* Save the address of the PHY */
     pCD->PHYAddress = PHYAddress;

     /* Get the PHY revision level */
     pCD->PHYRevision = (BYTE)(PHYID.DWord & PHYID_Revision_Mask);

     return TRUE;
}

static BOOL FindPHYType( PCHIP pChip )
{
    PCD  pCD;
    WORD PHYAddress;
    BOOL IsPHYFound;

    pCD = (PCD)pChip->pData;

    /* Search for a known type of PHY */
    for ( PHYAddress=1; PHYAddress<=31; PHYAddress++ )
    {
      IsPHYFound=Check_PHY_ID_Type(pChip, PHYAddress);
      if (IsPHYFound == TRUE )
	  {
		  break;
	  }     
    } //end for PhyId 1-31


    /* If did not find a PHY */
    if ( IsPHYFound == FALSE )
    {
	   //PHY address 0 is for broadcasting. All PHYs will respond to address 0.
	   //However, some users may connect PHY to address 0.  So search it.
	   IsPHYFound=Check_PHY_ID_Type(pChip, 0);	   
    }

	if ( IsPHYFound == FALSE )
	{
 //       DEBUGMSG(ZONE_ERROR,(TEXT("Error: EthernetMAC: A PHY is not found!\r\n") ));
        RETAILMSG(1,( TEXT("Error: EthernetMAC: PHY is not found!\n"))); 
	}

    return IsPHYFound;
}

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


    FindPHYType(pChip);
    PhyId = ((PCD)pChip->pData)->PHYAddress;
    //
    // 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, BMCR_Full_Duplex|BMCR_100_MBPS); 

		//set MAC for Full Duplex too.
		b8 = ReadByte(OpReg_TestCTL); 
        b8 |=  TestCTL_MACFDX;
        WriteByte(OpReg_TestCTL, b8);

        DEBUGMSG
        (
            ZONE_ERROR,
            (
                TEXT("EthernetMAC: Error! PHY cannot complete Auto Negotiation. Set to 100MBps Full Duplex.\n")
            )
        );

        return FALSE;
    }


	//CS8952 needs 1 second delay.  Otherwise it won't send the 1st frame.
	if ( ((PCD)pChip->pData)->PHYType == PHY_TYPE_CRYSTAL)
	{
       Sleep(1000);
	}

    strDuplex = L"Half";   

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

    if((val & ANLPAR_10BaseT_FDX_Able) || (val & ANLPAR_100BaseTX_FDX_Able)) 
    {
        b8 = ReadByte(OpReg_TestCTL); 
        b8 |=  TestCTL_MACFDX;
        WriteByte(OpReg_TestCTL, b8);

        strDuplex = L"Full";   
    }

    
    strSpeed = L"10";   
    //
    // Lets print out the current mode that we are operating in.
    //
    if((val & ANLPAR_100BaseTX_FDX_Able) || (val & ANLPAR_100BaseTX_HDX_Able))
    {
        strSpeed = L"100";   
    }


     // 
    // Show the current link mode.
    //
    DEBUGMSG
    (
        ZONE_INIT,
        (
            TEXT("EthernetMAC: PhyID=%d PhyType=%d Speed=%s Mbs, Duplex=%s.\n"), 
			PhyId,
			((PCD)pChip->pData)->PHYType,
            strSpeed, 
            strDuplex
        )
    );


/*
RETAILMSG(1,
        ( TEXT("EthernetMAC: PhyID=%d PhyType=%d Speed=%s Mbs, Duplex=%s.\n"), 
		   PhyId,
			((PCD)pChip->pData)->PHYType,
            strSpeed, 
            strDuplex
        )
    );
*/

   return TRUE;
}



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

    pCD = (PCD)pChip->pData;

    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 )
        {

⌨️ 快捷键说明

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