Best way to check Ethernet link

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

Best way to check Ethernet link

Jump to solution
10,039 Views
mspenard603
Contributor IV

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

Labels (1)
1 Solution
9,022 Views
carstengroen
Senior Contributor II

mspenard603@gmail.com

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....

View solution in original post

9 Replies
9,022 Views
dmckeever
Contributor II

PHY_GetLinkStatus(ENET, BOARD_ENET0_PHY_ADDRESS, &link);
by
if ( PHY_GetLinkStatus(ENET, BOARD_ENET0_PHY_ADDRESS, &link) != kStatus_Success )
   link = false;
0 Kudos
Reply
9,022 Views
mspenard603
Contributor IV

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

0 Kudos
Reply
9,023 Views
carstengroen
Senior Contributor II

mspenard603@gmail.com

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....

9,022 Views
mspenard603
Contributor IV

Thanks Carsten, that looks useful. Are there callback routines that you wrote too? 


cbETHNetIFStatus
0 Kudos
Reply
9,022 Views
carstengroen
Senior Contributor II

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;
 }
}
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
Reply
9,022 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Mike Spenard,

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.

pastedImage_1.png

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.
-------------------------------------------------------------------------------

0 Kudos
Reply
9,022 Views
mspenard603
Contributor IV

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.

0 Kudos
Reply
9,022 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Mike Spenard,

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.
-------------------------------------------------------------------------------

0 Kudos
Reply
9,022 Views
mspenard603
Contributor IV

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...??

0 Kudos
Reply