[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