Hi everyone,
I use RT1064 with LAN 8720A phy, MCUXpresso 11.5.0 and SDK 2.11.0.
Below there is the ethernetif_phy_init() function:
void ethernetif_phy_init(struct ethernetif *ethernetif,
const ethernetif_config_t *ethernetifConfig,
phy_speed_t *speed,
phy_duplex_t *duplex)
{
status_t status;
bool link = false;
bool autonego = false;
uint32_t initWaitCount = 0;
uint32_t autoWaitCount = 0;
phy_config_t phyConfig = {
.phyAddr = ethernetifConfig->phyHandle->phyAddr,
.autoNeg = true,
};
ethernetifConfig->phyHandle->mdioHandle->resource.base = *ethernetif_enet_ptr(ethernetif);
LWIP_PLATFORM_DIAG(("Initializing PHY..."));
while ((initWaitCount < ENET_ATONEGOTIATION_TIMEOUT) && (!(link && autonego)))
{
status = PHY_Init(ethernetifConfig->phyHandle, &phyConfig);
if (kStatus_Success != status)
{
LWIP_ASSERT("\r\nCannot initialize PHY.\r\n", 0);
}
/* Wait for auto-negotiation success and link up */
autoWaitCount = ENET_ATONEGOTIATION_TIMEOUT;
do
{
PHY_GetAutoNegotiationStatus(ethernetifConfig->phyHandle, &autonego);
PHY_GetLinkStatus(ethernetifConfig->phyHandle, &link);
if (autonego && link)
{
break;
}
} while (--autoWaitCount);
if (!autonego)
{
PRINTF("PHY Auto-negotiation failed. Please check the cable connection and link partner setting.\r\n");
}
initWaitCount++;
}
if (autonego && link)
{
/* Get the actual PHY link speed. */
PHY_GetLinkSpeedDuplex(ethernetifConfig->phyHandle, speed, duplex);
}
#if 0 /* Disable assert. If initial auto-negation is timeout, \ \
the ENET is set to default (100Mbs and full-duplex). */
else
{
LWIP_ASSERT("\r\nGiving up PHY initialization. Please check the ENET cable connection and link partner setting and reset the board.\r\n", 0);
}
#endif
}
I think there is a potential problem.
After the PHY_Init() function the phy is checked for the autonego completion with PHY_GetAutoNegotiationStatus() and PHY_GetLinkStatus() functions. In my case the exit from the inner do-while loop occurs after 6000 to 8000 cycles, so I assigned:
#define ENET_ATONEGOTIATION_TIMEOUT (0x3FFFU)
in the lwiopts.h file. This way when the cable is plugged the main while loop is executed only once and the ethernetif_phy_init() function exits immediately.
But if the cable is not plugged, the main while loop is executed ENET_ATONEGOTIATION_TIMEOUT times, and every time the inner do-while loop is executed ENET_ATONEGOTIATION_TIMEOUT times: in this case the the ethernetif_phy_init() function exits in several hours.
This happens because ENET_ATONEGOTIATION_TIMEOUT is used for both the main while loop and the inner do-while loop and it should be high enough to wait for the autonego completion with the cable plugged, but low enough not to wait too long with the cable unplugged.
I suggest the use of different #define constants for every loop as in older SDK version (up to 2.82 there was ENET_ATONEGOTIATION_TIMEOUT and PHY_TIMEOUT_COUNT constants).
Many thanks
Biafra
Hi @biafra
Many thanks for your the valuable report/suggestion, I will deliver it to the respective team.
All the best,
Diego.