in portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c [290:437]
unsigned get_IEEE_phy_speed( XEmacPs * xemacpsp )
{
u16 temp;
u16 control;
u16 status;
u16 partner_capabilities;
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
u32 phy_addr = XPAR_PCSPMA_SGMII_PHYADDR;
#else
u32 phy_addr = detect_phy( xemacpsp );
#endif
FreeRTOS_printf( ( "Start PHY autonegotiation \n" ) );
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
#else
XEmacPs_PhyWrite( xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 2 );
XEmacPs_PhyRead( xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, &control );
control |= IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK;
XEmacPs_PhyWrite( xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, control );
XEmacPs_PhyWrite( xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0 );
XEmacPs_PhyRead( xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, &control );
control |= IEEE_ASYMMETRIC_PAUSE_MASK;
control |= IEEE_PAUSE_MASK;
control |= ADVERTISE_100;
control |= ADVERTISE_10;
XEmacPs_PhyWrite( xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, control );
XEmacPs_PhyRead( xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
&control );
control |= ADVERTISE_1000;
XEmacPs_PhyWrite( xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
control );
XEmacPs_PhyWrite( xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0 );
XEmacPs_PhyRead( xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_CONTROL_REG,
&control );
control |= ( 7 << 12 ); /* max number of gigabit attempts */
control |= ( 1 << 11 ); /* enable downshift */
XEmacPs_PhyWrite( xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_CONTROL_REG,
control );
#endif /* if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1 */
XEmacPs_PhyRead( xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control );
control |= IEEE_CTRL_AUTONEGOTIATE_ENABLE;
control |= IEEE_STAT_AUTONEGOTIATE_RESTART;
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
control &= IEEE_CTRL_ISOLATE_DISABLE;
#endif
XEmacPs_PhyWrite( xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control );
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
#else
XEmacPs_PhyRead( xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control );
control |= IEEE_CTRL_RESET_MASK;
XEmacPs_PhyWrite( xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control );
while( 1 )
{
XEmacPs_PhyRead( xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control );
if( control & IEEE_CTRL_RESET_MASK )
{
continue;
}
else
{
break;
}
}
#endif /* if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1 */
FreeRTOS_printf( ( "Waiting for PHY to complete autonegotiation.\n" ) );
XEmacPs_PhyRead( xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status );
while( !( status & IEEE_STAT_AUTONEGOTIATE_COMPLETE ) )
{
vTaskDelay( MINIMUM_SLEEP_TIME );
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
#else
XEmacPs_PhyRead( xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_STATUS_REG_2,
&temp );
if( temp & IEEE_AUTONEG_ERROR_MASK )
{
FreeRTOS_printf( ( "Auto negotiation error \n" ) );
}
#endif
XEmacPs_PhyRead( xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET,
&status );
}
FreeRTOS_printf( ( "autonegotiation complete \n" ) );
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
#else
XEmacPs_PhyRead( xemacpsp, phy_addr, IEEE_SPECIFIC_STATUS_REG, &partner_capabilities );
#endif
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
FreeRTOS_printf( ( "Waiting for Link to be up; Polling for SGMII core Reg \n" ) );
XEmacPs_PhyRead( xemacpsp, phy_addr, 5, &temp );
while( !( temp & 0x8000 ) )
{
XEmacPs_PhyRead( xemacpsp, phy_addr, 5, &temp );
}
if( ( temp & 0x0C00 ) == 0x0800 )
{
XEmacPs_PhyRead( xemacpsp, phy_addr, 0, &temp );
return 1000;
}
else if( ( temp & 0x0C00 ) == 0x0400 )
{
XEmacPs_PhyRead( xemacpsp, phy_addr, 0, &temp );
return 100;
}
else if( ( temp & 0x0C00 ) == 0x0000 )
{
XEmacPs_PhyRead( xemacpsp, phy_addr, 0, &temp );
return 10;
}
else
{
FreeRTOS_printf( ( "get_IEEE_phy_speed(): Invalid speed bit value, Deafulting to Speed = 10 Mbps\n" ) );
XEmacPs_PhyRead( xemacpsp, phy_addr, 0, &temp );
XEmacPs_PhyWrite( xemacpsp, phy_addr, 0, 0x0100 );
return 10;
}
#else /* if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1 */
if( ( ( partner_capabilities >> 14 ) & 3 ) == 2 ) /* 1000Mbps */
{
return 1000;
}
else if( ( ( partner_capabilities >> 14 ) & 3 ) == 1 ) /* 100Mbps */
{
return 100;
}
else /* 10Mbps */
{
return 10;
}
#endif /* if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1 */
}