Hello, over the last few days I’ve spent a lot of time trying to figure out why I couldn’t talk to a Zynq 7000 board when executing a very specific boot-up sequence. The (repeatable) problem ocurred when I had a direct Ethernet connection between a desktop and the Zynq 7000. Both devices started powered off. I then started the Zynq board, waited a few seconds, and then started the desktop. If I did this, I just couldn’t talk to the Zynq board, couldn’t ping it, etc.
After looking troubleshooting for days, I (think) finally found the problem. In the function xNetworkInterfaceInitialise()
there is a line of code that initializes the PHY, ulLinkSpeed = Phy_Setup( pxEMAC_PS );
. Going deeper into this call, the PC ends up in the file x_emacpsif_physpeed.c
, specifically in the loop below:
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 );
}
This loop does not return until the PHY detects a link and autonegotiates. The desktop is still powered off. The problem happens the moment I power on the desktop. Within seconds of it turning it on, the PHY negotiated a speed of 10 Mbps, well before the Windows OS even launched. At this point the Zynq thinks it is talking via 10 Mbps speeds, not the 1000 Mbps that both devices are capable of. After Windows starts up, for some reason the NIC does not go down to 10 Mbps, might be some configuration, not sure.
My knowledge of PHY is very minimal. What is supposed to happen here? I find it very strange that the Zynq’s PHY autonegotiates to 10 Mbps within seconds of the desktop powering on.
Also, looking through the FreeRTOS-Plus-TCP code, I don’t see anywhere where the MAC asks the PHY to re-autonegotiate. Seems like once a speed is picked through xNetworkInterfaceInitialise()
, there’s no going back. Even if the PHY link goes down and then high again, it does not autonegotiate. Should it?
Any input or help is much appreciated.