[En-Nut-Discussion] detecting an unplugged network cable

elbric0 elbric0 at f-m.fm
Fri Nov 12 15:46:50 CET 2010


Hi Ulrich,

> But I am not sure if the whole registration is done correctly the way 
> you did it.
> NutRegisterDevice() should not fail, cable connected or not. It 
> initializes the hardware and does basic setup.

I am using Ethernut 4.8.7 on an Olimex SAM7-EX256 board. I observe the same behavior with the httpd example and with my own project. In both cases, NutRegisterDevice() fails after a little more than three minutes.

I think the following is happening.

- NutRegisterDevice() calls EmacInit().
- EmacInit() calls twice EmacReset(EMAC_LINK_LOOPS)	
	(EMAC_LINK_LOOPS value is 1000000)
- EmacReset tries to handle PHY auto negotiation but, after a very long timeout, it fails because the cable is disconnected.

    /* Handle auto negotiation if configured. */
    phyval = phy_inw(NIC_PHY_BMCR);
    if (phyval & NIC_PHY_BMCR_ANEGENA) {
        /* Wait for auto negotiation completed. */
        phy_inw(NIC_PHY_BMSR);  /* Discard previously latched status. */
        while (--tmo) {
            if (phy_inw(NIC_PHY_BMSR) & NIC_PHY_BMSR_ANCOMPL) {
                break;
            }
        }
        /* Return error on link timeout. */
        if (tmo == 0) {
            outr(EMAC_NCR, inr(EMAC_NCR) & ~EMAC_MPE);
            return -1;
        }

Your plan to handle disconnection with EmacCtl and events seems good. I guess it involves moving the auto negotiation to a separate thread? Or maybe it's already done in a newer code version?

Best regards

Jasmin


Le 2010-11-11 à 15:31, Ulrich Prinz a écrit :

> Hi!
> 
> I actually rework the at91_emac.c and found some problems regarding the 
> PHY handling. Unfortunately the PHY is the first one that recognizes a 
> cable disconnect. But the EMAC can detect this too, I guess. But it then 
> needs to do something. First thing to do should be to ask the PHY what 
> has happened on the front side. Instead the stack thinks, that the EMAC 
> has faulted and resets it again and again.
> 
> I rewrote the PHY part for the AT91 only. Now I need to glue it more 
> tight to the EMAC part. After that I can find out how to more elegantly 
> detect error conditions.
> A disconnected cable should be the easy thing to find out.
> 
> But I am not sure if the whole registration is done correctly the way 
> you did it.
> NutRegisterDevice() should not fail, cable connected or not. It 
> initializes the hardware and does basic setup.
> Then normally DHCP is started and that one will fail if the cable is not 
> in and fall back to fixed address. Then further packages sent or or 
> requested will fail too.
> So there is a function missing that gives more detailed information 
> about the network status.
> 
> So I started to add a EmacCtl that can be called for detecting EMAC and 
> PHY states and control some functions.
> But I am not finished yet. But with this you can detect the network 
> stack state more friendly. It should not be needed to re-register the 
> complete device but only restart the logical stack and request a new IP 
> via DHCP if enabled.
> 
> Oh, AFAIK the DHCP is a thread that runs autonomously. It must be one as 
> a lease may expire and it must request a new lease. So there must be a 
> mechanism that keeps track of the connection. Unfortunately it cannot 
> detect the unplugged situation as this is not provided by the EMAC/PHY 
> driver.
> Ok, looks like there is some work still open.
> 
> Best regards,
> Ulrich
> 
> Am 08.11.2010 15:15, schrieb elbric0:
>> Hi!
>> 
>> Thanks for your answers. It's a good idea to run network stuff in a thread. However I still have a problem with NutRegisterDevice. When the network cable is unplugged, it takes a little more than three minutes before it returns an error. And it doesn't seems to yield the cpu as long as it is running.
>> 
>> I have this code in my network thread:
>> 
>> NutThreadSetPriority(128);
>> while (NutRegisterDevice(&DEV_ETHER, 0, 0))
>> {
>>         puts("\tFailed. Retrying in 10 sec.");
>>         NutSleep(10000);    /* Sleep for 10 sec */
>> }
>> 
>> I didn't change the priority of the main task. So I assume it is 64. The main task should print the time every minute.
>> 
>> When the network cable is unplugged, the "Failed" message and the time are both printed every 3 minutes. So I am quite sure that NutRegisterDevice blocks for all that time.
>> 
>> Is it the normal behavior?
>> 
>> Best regards
>> 
>> Jasmin
>> 
>> 
>> Le 2010-11-08 à 06:16, Ulrich Prinz a écrit :
>> 
>>> Hi!
>>> 
>>> The driver itself detects that fact and does not start ethernet. To not
>>> get blocked by DHCP you should run DHCP as a thread. The httpd example
>>> is not a good reference or that, I think.
>>> I am actually reworkign that part... The new PHY driver can give you
>>> the information if the cable is connected. But it can take a while for
>>> AutoNegotiation to link up and you have to wait that time until the
>>> system times out....
>>> 
>>> Nope, the best way is to start network an DHCP in a thread. Anything
>>> else doesn't work.
>>> 
>>> Best Regards
>>> Ulrich
>>> 
>>> 
>>> -----Original Message-----
>>> From: elbric0<elbric0 at f-m.fm>
>>> To: en-nut-discussion at egnite.de
>>> Sent: Mon, Nov 8, 2010 1:47 am
>>> Subject: [En-Nut-Discussion] detecting an unplugged network cable
>>> 
>>> 
>>> Hi,I would like to detect if a network cable is unplugged at boot time
>>> and skip everything related to network when it is the case.
>>> NutRegisterDevice(&DEV_ETHER, 0, 0) returns an error after a long while
>>> when the cable is unplugged. It is possible to use that, but it is a
>>> little annoying as is makes boot time quite long. Is there another way
>>> to make the check or a way to make NutRegisterDevice return faster?Best
>>> RegardsJasmin_______________________________________________http://lists.
>>> egnite.de/mailman/listinfo/en-nut-discussion
>>> 
>>> _______________________________________________
>>> http://lists.egnite.de/mailman/listinfo/en-nut-discussion
>> 
>> _______________________________________________
>> http://lists.egnite.de/mailman/listinfo/en-nut-discussion
> _______________________________________________
> http://lists.egnite.de/mailman/listinfo/en-nut-discussion




More information about the En-Nut-Discussion mailing list