SDK init ethernet phy trouble

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SDK init ethernet phy trouble

1,254 Views
biafra
Senior Contributor I

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

 

1 Reply

1,179 Views
diego_charles
NXP TechSupport
NXP TechSupport

Hi @biafra 

Many thanks for your the valuable report/suggestion, I will deliver it to the respective team.

All the best, 

Diego.