10 years, 2 months ago.

Ethernet - Link Status and Recovery

I was looking around to find out the best practice to manage a wired Ethernet link. Cases of interest include - boot w/o the cable plugged in, plugging in the cable after boot, unplugging the cable while running, and then replugging the cable. Basically, try to make it robust to handle what might happen.

After browsing about for pieces, I found a few scraps and landed on this combination - but invite review (am I missing any scenarios that would make it better? Is there an API that I didn't spot and should have? While I'm first interested in the LPC1768, is there an easy equivalent for others? Anything better than the mbed_reset() recovery for eth.init()?).

#include "mbed.h"
#include "EthernetInterface.h"
#include "lpc_phy.h"

extern "C" void mbed_reset();

Serial pc(USBTX, USBRX);
EthernetInterface eth;

#define DP8_SPEED10MBPS    (1 << 1)   /**< 1=10MBps speed */
#define DP8_VALID_LINK     (1 << 0)   /**< 1=Link active */

uint32_t mii_read_data(void)
{
    return lpc_mii_read_data();
}

bool get_link_status(void)
{
    return (lpc_mii_read_data() & DP8_VALID_LINK) ? true : false;
}

int get_connection_speed()
{
    return (lpc_mii_read_data() & DP8_SPEED10MBPS) ? 10 : 100;
}

int main()
{
    pc.baud(460800);
    printf("\r\n\r\nEthernet Connection Test - Build " __DATE__ " - " __TIME__ "\r\n");

    pc.printf("Initializing interface...\r\n");
    if (0 == eth.init()) {  // Calling twice causes Error - alternate blue blink
        do {
            pc.printf("Connecting to network...\r\n");
            if (0 == eth.connect()) {   //
                int speed = get_connection_speed();
                pc.printf("Connected at %d Mb/s\r\n", speed);
                while (get_link_status()) {
                    pc.printf("Connection is good.\r\n");
                    wait(10);
                }
                pc.printf("lost connection.\r\n");
                eth.disconnect();
            } else {
                pc.printf("  ... failed to connect.\r\n");
            }
            wait(5);
            pc.printf("about to retry.\r\n");
            wait(5);
        } while (1);
    } else {
        pc.printf("  ... failed to initialize, reboot required.\r\n");
        wait(5);
        mbed_reset();   // Is there any better option than to reboot?
    }
}

1 Answer

David Smart
poster
9 years, 10 months ago.

After 4 months w/o reply, I guess the technique above is as good as any. Closing this question.

Hi David,

Regarding your question about better way to reset Ethernet:

During my work with a LPC1768 based customized board, I don't see the need of reset. My application worked well in the following scenarios:

1) Application starts with no ethernet cable plugged in, it takes a well to initialize ethernet (because of default timeout being 15 seconds), then when cable is plugged in, get_link_status() will be able to detect the status change, and IP, gateway, mask will be assigned (in DHCP mode), then all ethernet base operations will start to run properly.

2) Application starts with cable plugged in, sucessfully initialize ethernet , run some ethernet based operations, then when cable is unplugged, get_link_status() will also be able to detect and status change. After a while, when cable is plugged back in, again get_link_status() will be able to detect the change in status, and all ethernet based operations will be able to run properly again.

What would be other scenarios that needs to reset ethernet? I am developing a commercial product, so I am trying to cover all possible user cases.

posted by Zhiyong Li 02 Mar 2015

Assigned to David Smart 9 years, 10 months ago.

This means that the question has been accepted and is being worked on.