Hi All,
What is the best way to find out if Ethernet link is up/down? Using iMXRT1062 SDK 2.5.2 with LWIP.
I assume there's a way to get status from the KSZ8081 PHY.
And where does one typically augment LWIP to handle cable insertion/removals?
Thank you
Solved! Go to Solution.
I do this in a RT1064/LwIP Ethernet project:
In init phase:
// initialize lwIP stack and network interfaces
tcpip_init(NULL, NULL);
sys_lock_tcpip_core();
netif_add(&fsl_netif0, &ip_addr, &ip_addr, &ip_addr, &fsl_enet_config0, ethernetif0_init, ethernet_input);
//netif_add(&fsl_netif0, &fsl_netif0_ipaddr, &fsl_netif0_netmask, &fsl_netif0_gw, &fsl_enet_config0, ethernetif0_init, ethernet_input);
netif_set_default(&fsl_netif0);
netif_set_status_callback(&fsl_netif0, cbETHNetIFStatus);
netif_set_link_callback(&fsl_netif0, cbETHLinkStatus);
//netif_set_up(&fsl_netif0);
//dhcp_start(&fsl_netif0);
sys_unlock_tcpip_core();
In the "main loop" (thread that handles network stuff):
bool link;
static bool oldLink=FALSE;
PHY_GetLinkStatus(ENET, BOARD_ENET0_PHY_ADDRESS, &link);
if (link != oldLink) {
if (link) {
ledMMI(LED_BLUE, LED_ON);
sys_lock_tcpip_core();
netif_set_up(&fsl_netif0);
dhcp_start(&fsl_netif0);
sys_unlock_tcpip_core();
phy_speed_t speed;
phy_duplex_t duplex;
PHY_GetLinkSpeedDuplex(ENET, BOARD_ENET0_PHY_ADDRESS, &speed, &duplex);
messageDebug(DBG_NOTE, __MODULE__, __LINE__, "Link is coming up, speed=%i MBit, duplex=%s", speed==kPHY_Speed100M?100:10, duplex==kPHY_FullDuplex?"Full":"Half");
} else {
ledMMI(LED_BLUE, LED_OFF);
messageDebug(DBG_WAR, __MODULE__, __LINE__, "Link is going down..");
sys_lock_tcpip_core();
dhcp_release_and_stop(&fsl_netif0);
netif_set_down(&fsl_netif0);
sys_unlock_tcpip_core();
}
oldLink=link;
}
Hope it will help you in some way....
PHY_GetLinkStatus(ENET, BOARD_ENET0_PHY_ADDRESS, &link);
by
if ( PHY_GetLinkStatus(ENET, BOARD_ENET0_PHY_ADDRESS, &link) != kStatus_Success )
link = false;
One other thing that's required, in case someone else turns up this question... To keep link bouncing from causing a halting assert() the following is needed:
Setting the following in fsl_phy.c
#define PHY_TIMEOUT_COUNT 0x0000FFFU // mls; default=0x3FFFFFFU
And in lwopts.h
#define LWIP_NOASSERT
I do this in a RT1064/LwIP Ethernet project:
In init phase:
// initialize lwIP stack and network interfaces
tcpip_init(NULL, NULL);
sys_lock_tcpip_core();
netif_add(&fsl_netif0, &ip_addr, &ip_addr, &ip_addr, &fsl_enet_config0, ethernetif0_init, ethernet_input);
//netif_add(&fsl_netif0, &fsl_netif0_ipaddr, &fsl_netif0_netmask, &fsl_netif0_gw, &fsl_enet_config0, ethernetif0_init, ethernet_input);
netif_set_default(&fsl_netif0);
netif_set_status_callback(&fsl_netif0, cbETHNetIFStatus);
netif_set_link_callback(&fsl_netif0, cbETHLinkStatus);
//netif_set_up(&fsl_netif0);
//dhcp_start(&fsl_netif0);
sys_unlock_tcpip_core();
In the "main loop" (thread that handles network stuff):
bool link;
static bool oldLink=FALSE;
PHY_GetLinkStatus(ENET, BOARD_ENET0_PHY_ADDRESS, &link);
if (link != oldLink) {
if (link) {
ledMMI(LED_BLUE, LED_ON);
sys_lock_tcpip_core();
netif_set_up(&fsl_netif0);
dhcp_start(&fsl_netif0);
sys_unlock_tcpip_core();
phy_speed_t speed;
phy_duplex_t duplex;
PHY_GetLinkSpeedDuplex(ENET, BOARD_ENET0_PHY_ADDRESS, &speed, &duplex);
messageDebug(DBG_NOTE, __MODULE__, __LINE__, "Link is coming up, speed=%i MBit, duplex=%s", speed==kPHY_Speed100M?100:10, duplex==kPHY_FullDuplex?"Full":"Half");
} else {
ledMMI(LED_BLUE, LED_OFF);
messageDebug(DBG_WAR, __MODULE__, __LINE__, "Link is going down..");
sys_lock_tcpip_core();
dhcp_release_and_stop(&fsl_netif0);
netif_set_down(&fsl_netif0);
sys_unlock_tcpip_core();
}
oldLink=link;
}
Hope it will help you in some way....
Thanks Carsten, that looks useful. Are there callback routines that you wrote too?
cbETHNetIFStatus
Sorry, forgot these two, they are here:
//---------------------------------------------------------------------------------------
// netif link callback
// Gets called whenever the link goes up or down
//---------------------------------------------------------------------------------------
static void cbETHLinkStatus(struct netif *state_netif) {
if (netif_is_link_up(state_netif)) {
messageDebug(DBG_INFO, __MODULE__, __LINE__,"cbETHLinkStatus==UP");
} else {
messageDebug(DBG_INFO, __MODULE__, __LINE__,"cbETHLinkStatus==DOWN");
}
}
//---------------------------------------------------------------------------------------
// netif callback
// called when netif (ETH) goes up or down
//---------------------------------------------------------------------------------------
static void cbETHNetIFStatus(struct netif *state_netif) {
char ip[16];
char ipgw[16];
if (netif_is_up(state_netif)) {
strcpy(ip, ip4addr_ntoa(netif_ip4_addr(state_netif)));
strcpy(ipgw, ip4addr_ntoa(netif_ip4_gw(state_netif)));
messageDebug(DBG_INFO, __MODULE__, __LINE__,"cbETHNetIFStatus==UP, local interface IP is %s, GW IP is %s", ip, ipgw);
if (state_netif->ip_addr.addr) gConnected=TRUE;
} else {
messageDebug(DBG_INFO, __MODULE__, __LINE__,"cbETHNetIFStatus==DOWN");
gConnected=FALSE;
}
}
Thank you for your interest in NXP Semiconductor products and
for the opportunity to serve you.
Checking the status of LED1/SPEED pin is an efficient way to figure out the Ethernet link is up/down.
Fig 1
Have a great day,
TIC
-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------
For example... enet_init() tries to init the PHY using PHY_init(). And PHY_Init() checks for link. But upon a return failure enet_init() does an assert and the whole app halts.
status = PHY_Init(ethernetif->base, ethernetifConfig->phyAddress, sysClock);
if (kStatus_Success != status)
{
LWIP_ASSERT("\r\nCannot initialize PHY.\r\n", 0);
}
This behavior is no good if there's ever a missing ethernet cable at boot.
So this is why I ask where and how one typically addresses this.
Thanks for your reply.
It seems that you'd like to know how the Lwip handles the Ethernet link become down, such as missing ethernet cable.
If yes, the Lwip can detect this error, however, it's up on the protocol used, such as ICMP, TCP protocol is able to detect the status of ethernet link.
About the codes, please learn them via reviewing the Lwip's guide.
https://lwip.fandom.com/wiki/LwIP_Application_Developers_Manual
Have a great day,
TIC
-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------
Ok. But where and how does one typically do this? Seems like a common thing to not lock up on cable disconnect. Surely there's example code someplace...??