[En-Nut-Discussion] Time needed to get packet from RTL on ATmega128

Dusan Ferbas dferbas at dfsoft.cz
Mon Jan 10 21:44:12 CET 2005


Hi Harald and Florin,

I think I need some info how to work with IOCHRDY signal (instead of those 
16 NOPs). If you think that this can save some time ?

Then even if I tried to modify NutArpCacheQuery() (see below, w/o comments) 
with fl_send I am still getting 2 ARPs for 1st UDP output packet which 
confuses me.

Finally problem with ARP storm and lost USART Rx interrupts. This means 
that for 2 ms there are so much RTL interrupts that there is no time to 
handle USART interrupt. I cannot understand this. I think that interrupts 
are maybe somewhere globally disabled. This is very easy to test I can send 
a link to ARP traffic generator.

If preceding is true it means that ATmega128 is not able to handle more 
than 20 RTL interrupts per ms so there is no time for USART int to occure. 
I can't believe this because dev/nicrtl.c:NicInterrupt() is quite short. If 
you think it can take 50us then the only solution will be to poll USART 
state from RTL int and temporarily disable RTL ints.

Anyone else with more experience ?

---
>Date: Mon, 10 Jan 2005 14:10:33 +0100
>From: Harald Kipp <harald.kipp at egnite.de>
>
>Dusan,
>
>Now I understand the problem. It definitely requires
>some time to think about. I can confirm, that ARP
>showers hadn't been considered, but have to.
>
>In general, the current state of the driver is a result
>of the work done by Bengt Florin. He greatly enhanced
>the reliability during heavy traffic situations, reducing
>packet loss as well as the need for occasional controller
>resets to almost zero.
>
>Not yet sure, what's the best solution to fix your problem.
>I'll come back to you.
>
>Harald


-------------
int NutArpCacheQuery(NUTDEVICE * dev, CONST u_long ip, u_char * mac)
{
     volatile ARPENTRY *entry;
     NETBUF *nb = 0;
     int rc = -1;
     u_char retries = 4;
     u_char      fl_send;

     if ((entry = NutArpCacheLookup(dev->dev_icb, ip)) != 0) {
         if (entry->ae_flags & ATF_COM) {
             memcpy(mac, ((ARPENTRY *) entry)->ae_ha, 6);
             return 0;
         }
         else
             fl_send = FALSE;            //already sent, but still pending
     }

     else {
         if (entry == 0 && (entry = NutArpCacheNew(dev->dev_icb, ip, 0, 0)) 
== 0)
             return -1;
         else
             fl_send = TRUE;
     }

     if (fl_send) {
         if ((nb = NutArpAllocNetBuf(ARPOP_REQUEST, ip, 0)) == 0)
             return -1;
     }

     while (retries--) {
         if (fl_send) {
             if (NutArpOutput(dev, nb))
                 break;
         }
         if (entry->ae_flags & ATF_COM) {
             memcpy(mac, ((ARPENTRY *) entry)->ae_ha, 6);
             rc = 0;
             break;
         }

         NutEventWait(&((ARPENTRY *) entry)->ae_tq, 500);
     }
     if (fl_send)
         NutNetBufFree(nb);
     return rc;
}



Dusan 




More information about the En-Nut-Discussion mailing list