lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lwip-users] Patch for bug 23119


From: Ken Smith
Subject: Re: [lwip-users] Patch for bug 23119
Date: Thu, 12 Mar 2009 16:09:01 -0700

On Wed, Mar 11, 2009 at 6:34 AM, Kieran Mansley <address@hidden> wrote:
>
> The other interesting bit in the stats is that you're running out of MEM
> ARP_QUEUE fields.  This suggests that packets are being buffered by ARP
> while waiting for a reply.  If it didn't get a reply to its ARP queries
> (or if the ARP queries never made it out of the device) that would
> explain why no other traffic is sent.
>
> So it looks like lwIP is doing the right thing, but that something is
> preventing the device from sending or receiving packets.  Are you sure
> your driver is working correctly?

You have given me a lot of food for thought and I have been looking in
to your suggestions.  I have several new questions regarding lwIP
configuration.

- How can I artificially cause packets to be queued waiting for ARP replies?
- What is a good way to determine the optimal size of
MEMP_NUM_ARP_QUEUE?  (Eg. should it be based on PBUF_POOL_SIZE,
ARP_TABLE_SIZE, network latency, etc.?)
- What are the consequences of turning off ARP_QUEUEING?

Also, in looking at my ethernet driver the way it interfaces with
lwIP, I noticed some meaningful differences between my implementation
and the reference implementation in CVS HEAD.  In particular, my
implementation of ethernetif_input is an infinite loop that polls
low_level_input.  This function is spawned as its own task in
low_level_init.  The reference implementation just checks once for
input, processes that input, and returns so I believe the expectation
is that the ethernet driver will call ethernetif_input when it detects
a packet is ready.  Indeed, the comment reflects this.  But from what
context is ethernetif_input supposed to be called?  I'm starting to
think that my ethernetif_input implementation is backward or that I
need to implement it inside a critical section so that other contexts
are not attempting to make lwIP calls while packets are being read
from the interface.  Please advise on the following code fragments.

 74 static void low_level_init( struct netif *netif )
 75 {
...
113     xTaskCreate((void *)ethernetif_input, (signed portCHAR *)
"ETH_INT", netifINTERFACE_TASK_STACK_SIZE, NULL,
netifINTERFACE_TASK_PRIORITY, NULL);
114 }
...
289 static void ethernetif_input(struct netif *netif)
290 {
291     struct ethernetif   *ethernetif;
292     struct eth_hdr      *ethhdr;
293     struct pbuf         *p;
294
295     ( void ) netif; // make the compiler happy.
296
297     for( ;; )
298     {
299         do
300         {
301             ethernetif = xNetIf->state;
302
303             /* move received packet into a new pbuf */
304             p = low_level_input( xNetIf );
305
306             if( p == NULL )
307             {
308                 /* No packet could be read.  Wait a for an
interrupt to tell us
309                 there is more data available. */
310                 vEMACWaitForInput();
311             }
312
313         } while( p == NULL );
314
315         /* points to packet payload, which starts with an Ethernet header */
316         ethhdr = p->payload;
317
318         #if LINK_STATS
319             lwip_stats.link.recv++;
320         #endif /* LINK_STATS */
321
322         ethhdr = p->payload;
323
324         switch( htons( ethhdr->type ) )
325         {
326             /* IP packet? */
327             case ETHTYPE_IP:
328                 /* update ARP table */
329                 etharp_ip_input( xNetIf, p );
330
331                 /* skip Ethernet header */
332                 pbuf_header( p, (s16_t)-sizeof(struct eth_hdr) );
333
334                 /* pass to network layer */
335                 if (xNetIf->input( p, xNetIf ) != ERR_OK)
336                 {
337                     pbuf_free(p);
338                     p = NULL;
339                 }
340                 break;
341
342             case ETHTYPE_ARP:
343                 /* pass p to ARP module */
344                 etharp_arp_input( xNetIf, ethernetif->ethaddr, p );
345                 break;
346
347             default:
348                 pbuf_free( p );
349                 p = NULL;
350                 break;
351         }
352     }
353 }

   Regards,
   Ken




reply via email to

[Prev in Thread] Current Thread [Next in Thread]