drivers: ethernet: eth_mcux: fix phy_event state diagram sequence

When the phy_event state diagram ends up in the
eth_mcux_phy_state_read_status case, the eth carrier
is enabled. However, this step only happens when an
interface is available in the context.

Regardless of the state of the iface, the state machine
will switch to eth_mcux_phy_state_read_duplex in the next
iteration. Thus, the states diagram never returns to the
previous state. As a result, the eth carrier will never
be enabled in the future.

This problem is fixed by setting the wait state if the
iface is not available.

Signed-off-by: Ibe Van de Veire <ibe.vandeveire@gmail.com>
This commit is contained in:
Ibe Van de Veire 2023-04-07 15:12:14 +02:00 committed by Carles Cufí
parent aee70b0ff6
commit 0927250fd2

View file

@ -546,7 +546,7 @@ static void eth_mcux_phy_event(struct eth_context *context)
status = ENET_ReadSMIData(context->base);
link_up = status & PHY_BSTATUS_LINKSTATUS_MASK;
#endif
if (link_up && !context->link_up) {
if (link_up && !context->link_up && context->iface != NULL) {
/* Start reading the PHY control register. */
#if !defined(CONFIG_ETH_MCUX_NO_PHY_SMI)
ENET_StartSMIRead(context->base, context->phy_addr,
@ -555,16 +555,12 @@ static void eth_mcux_phy_event(struct eth_context *context)
#endif
context->link_up = link_up;
context->phy_state = eth_mcux_phy_state_read_duplex;
/* Network interface might be NULL at this point */
if (context->iface) {
net_eth_carrier_on(context->iface);
k_msleep(USEC_PER_MSEC);
}
net_eth_carrier_on(context->iface);
k_msleep(USEC_PER_MSEC);
#if defined(CONFIG_ETH_MCUX_NO_PHY_SMI)
k_work_submit(&context->phy_work);
#endif
} else if (!link_up && context->link_up) {
} else if (!link_up && context->link_up && context->iface != NULL) {
LOG_INF("%s link down", eth_name(context->base));
context->link_up = link_up;
k_work_reschedule(&context->delayed_phy_work,