ethernetif.c File Reference


Detailed Description

Ethernet Interface Skeleton.

Definition in file ethernetif.c.

#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include <lwip/stats.h>
#include <lwip/snmp.h>
#include "netif/etharp.h"
#include "netif/ppp_oe.h"
#include "conf_eth.h"
#include "macb.h"

Go to the source code of this file.

Data Structures

struct  ethernetif
 Helper struct to hold private data used to operate your ethernet interface. More...

Defines

#define IFNAME0   'e'
#define IFNAME1   'n'
#define netifGUARD_BLOCK_NBTICKS   ( 250 )

Functions

err_t ethernetif_init (struct netif *netif)
 Should be called at the beginning of the program to set up the network interface.
static void ethernetif_input (void *pvParameters)
 This function should be called when a packet is ready to be read from the interface.
static void low_level_init (struct netif *netif)
 In this function, the hardware should be initialized.
static struct pbuf * low_level_input (struct netif *netif)
 Should allocate a pbuf and transfer the bytes of the incoming packet from the interface into the pbuf.
static err_t low_level_output (struct netif *netif, struct pbuf *p)
 This function should do the actual transmission of the packet.


Define Documentation

#define IFNAME0   'e'

Definition at line 62 of file ethernetif.c.

Referenced by ethernetif_init().

#define IFNAME1   'n'

Definition at line 63 of file ethernetif.c.

Referenced by ethernetif_init().

#define netifGUARD_BLOCK_NBTICKS   ( 250 )

Definition at line 65 of file ethernetif.c.

Referenced by low_level_input(), and low_level_output().


Function Documentation

err_t ethernetif_init ( struct netif *  netif  ) 

Should be called at the beginning of the program to set up the network interface.

It calls the function low_level_init() to do the actual setup of the hardware.

This function should be passed as a parameter to netif_add().

Parameters:
netif the lwip network interface structure for this ethernetif
Returns:
ERR_OK if the loopif is initialized ERR_MEM if private data couldn't be allocated any other err_t on error

Definition at line 334 of file ethernetif.c.

References IFNAME0, IFNAME1, low_level_init(), and low_level_output().

Referenced by prvEthernetConfigureInterface().

00335 {
00336   /* struct ethernetif *ethernetif; */
00337 
00338   LWIP_ASSERT("netif != NULL", (netif != NULL));
00339     
00340   /*ethernetif = (struct ethernetif *)mem_malloc(sizeof(struct ethernetif));
00341   if (ethernetif == NULL)
00342   {
00343     LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n"));
00344     return ERR_MEM;
00345   }*/
00346 
00347 #if LWIP_NETIF_HOSTNAME
00348   /* Initialize interface hostname */
00349   netif->hostname = "lwip";
00350 #endif /* LWIP_NETIF_HOSTNAME */
00351 
00352   /*
00353    * Initialize the snmp variables and counters inside the struct netif.
00354    * The last argument should be replaced with your link speed, in units
00355    * of bits per second.
00356    */
00357 #if LWIP_SNMP
00358   NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 100000000);
00359 #endif /* LWIP_SNMP */
00360 
00361   netif->state = NULL; /* ethernetif;
00362   ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]); */
00363   netif->name[0] = IFNAME0;
00364   netif->name[1] = IFNAME1;
00365   /* We directly use etharp_output() here to save a function call.
00366    * You can instead declare your own function an call etharp_output()
00367    * from it if you have to do some checks before sending (e.g. if link
00368    * is available...) */
00369   netif->output = etharp_output;
00370   netif->linkoutput = low_level_output;
00371 
00372   /* initialize the hardware */
00373   low_level_init(netif);
00374 
00375 /* DONE BY THE LWIP TASK.
00376   // Initializes the ARP table and queue.
00377   etharp_init();
00378 
00379   // You must call etharp_tmr at a ARP_TMR_INTERVAL (5 seconds) regular interval
00380   // after this initialization.
00381   sys_timeout(ARP_TMR_INTERVAL, (sys_timeout_handler)arp_timer, NULL);
00382 */
00383   return ERR_OK;
00384 }

static void ethernetif_input ( void *  pvParameters  )  [static]

This function should be called when a packet is ready to be read from the interface.

It uses the function low_level_input() that should handle the actual reception of bytes from the network interface. Then the type of the received packet is determined and the appropriate input function is called.

Parameters:
netif the lwip network interface structure for this ethernetif

Definition at line 280 of file ethernetif.c.

References low_level_input().

Referenced by low_level_init().

00281 {
00282   struct netif      *netif = (struct netif *)pvParameters;
00283   struct pbuf       *p;
00284 
00285 
00286   for( ;; )
00287   {
00288     do
00289     {
00290       /* move received packet into a new pbuf */
00291       p = low_level_input( netif );
00292       if( p == NULL )
00293       {
00294         /* No packet could be read.  Wait a for an interrupt to tell us
00295         there is more data available. */
00296         vMACBWaitForInput(100);
00297       }
00298     }while( p == NULL );
00299 
00300     if( ERR_OK != ethernet_input( p, netif ) )
00301     {
00302       pbuf_free(p);
00303       p = NULL;
00304     }
00305   }
00306 }

static void low_level_init ( struct netif *  netif  )  [static]

In this function, the hardware should be initialized.

Called from ethernetif_init().

Parameters:
netif the already initialized lwip network interface structure for this ethernetif

Definition at line 89 of file ethernetif.c.

References ETHERNET_CONF_ETHADDR0, ETHERNET_CONF_ETHADDR1, ETHERNET_CONF_ETHADDR2, ETHERNET_CONF_ETHADDR3, ETHERNET_CONF_ETHADDR4, ETHERNET_CONF_ETHADDR5, ethernetif_input(), netifINTERFACE_TASK_PRIORITY, netifINTERFACE_TASK_STACK_SIZE, and sys_thread_new().

Referenced by ethernetif_init().

00090 {
00091   unsigned portBASE_TYPE uxPriority;
00092 
00093 
00094   /* set MAC hardware address length */
00095   netif->hwaddr_len = ETHARP_HWADDR_LEN;
00096 
00097   /* set MAC hardware address */
00098   netif->hwaddr[0] = ETHERNET_CONF_ETHADDR0;
00099   netif->hwaddr[1] = ETHERNET_CONF_ETHADDR1;
00100   netif->hwaddr[2] = ETHERNET_CONF_ETHADDR2;
00101   netif->hwaddr[3] = ETHERNET_CONF_ETHADDR3;
00102   netif->hwaddr[4] = ETHERNET_CONF_ETHADDR4;
00103   netif->hwaddr[5] = ETHERNET_CONF_ETHADDR5;
00104 
00105   /* maximum transfer unit */
00106   netif->mtu = 1500;
00107   
00108   /* device capabilities */
00109   /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
00110   netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
00111  
00112   /* Do whatever else is needed to initialize interface. */  
00113   /* Initialise the MACB. */
00114   // NOTE: This routine contains code that polls status bits. If the Ethernet
00115   // cable is not plugged in then this can take a considerable time.  To prevent
00116   // this from starving lower priority tasks of processing time we lower our
00117   // priority prior to the call, then raise it back again once the initialization
00118   // is complete.
00119   // Read the priority of the current task.
00120   uxPriority = uxTaskPriorityGet( NULL );
00121   // Set the priority of the current task to the lowest possible.
00122   vTaskPrioritySet( NULL, tskIDLE_PRIORITY );
00123   // Init the MACB interface.
00124   while( xMACBInit(&AVR32_MACB) == FALSE )
00125   {
00126     __asm__ __volatile__ ( "nop" );
00127   }
00128   // Restore the priority of the current task.
00129   vTaskPrioritySet( NULL, uxPriority );
00130 
00131   /* Create the task that handles the MACB input packets. */
00132   sys_thread_new( "ETHINT", ethernetif_input, netif, netifINTERFACE_TASK_STACK_SIZE,
00133                   netifINTERFACE_TASK_PRIORITY );
00134 }

static struct pbuf* low_level_input ( struct netif *  netif  )  [static, read]

Should allocate a pbuf and transfer the bytes of the incoming packet from the interface into the pbuf.

Parameters:
netif the lwip network interface structure for this ethernetif
Returns:
a pbuf filled with the received packet (including MAC header) NULL on memory error

Definition at line 205 of file ethernetif.c.

References netifGUARD_BLOCK_NBTICKS.

Referenced by ethernetif_input().

00206 {
00207   struct pbuf             *p = NULL;
00208   struct pbuf             *q;
00209   u16_t                   len;
00210   static xSemaphoreHandle xRxSemaphore = NULL;
00211 
00212 
00213   /* Parameter not used. */
00214   ( void ) netif;
00215 
00216   if( xRxSemaphore == NULL )
00217   {
00218     vSemaphoreCreateBinary( xRxSemaphore );
00219   }
00220 
00221   /* Access to the MACB is guarded using a semaphore. */
00222   if( xSemaphoreTake( xRxSemaphore, netifGUARD_BLOCK_NBTICKS ) )
00223   {
00224     /* Obtain the size of the packet. */
00225     len = ulMACBInputLength();
00226 
00227     if( len )
00228     {
00229 #if ETH_PAD_SIZE
00230       len += ETH_PAD_SIZE;    /* allow room for Ethernet padding */
00231 #endif
00232 
00233       /* We allocate a pbuf chain of pbufs from the pool. */
00234       p = pbuf_alloc( PBUF_RAW, len, PBUF_POOL );
00235 
00236       if( p != NULL )
00237       {
00238 #if ETH_PAD_SIZE
00239         pbuf_header( p, -ETH_PAD_SIZE );    /* drop the padding word */
00240 #endif
00241 
00242         /* Let the driver know we are going to read a new packet. */
00243         vMACBRead( NULL, 0, len );
00244 
00245         /* We iterate over the pbuf chain until we have read the entire
00246         packet into the pbuf. */
00247         for( q = p; q != NULL; q = q->next )
00248         {
00249           /* Read enough bytes to fill this pbuf in the chain. The
00250           available data in the pbuf is given by the q->len variable. */
00251           vMACBRead( q->payload, q->len, len );
00252         }
00253 
00254 #if ETH_PAD_SIZE
00255         pbuf_header( p, ETH_PAD_SIZE );     /* reclaim the padding word */
00256 #endif
00257         LINK_STATS_INC(link.recv);
00258       }
00259       else
00260       {
00261         LINK_STATS_INC(link.memerr);
00262         LINK_STATS_INC(link.drop);
00263       }
00264     }
00265     xSemaphoreGive( xRxSemaphore );
00266   }
00267 
00268   return p;
00269 }

static err_t low_level_output ( struct netif *  netif,
struct pbuf *  p 
) [static]

This function should do the actual transmission of the packet.

The packet is contained in the pbuf that is passed to the function. This pbuf might be chained.

Parameters:
netif the lwip network interface structure for this ethernetif
p the MAC packet to send (e.g. IP packet including MAC addresses and type)
Returns:
ERR_OK if the packet could be sent an err_t value if the packet couldn't be sent
Note:
Returning ERR_MEM here if a DMA queue of your MAC is full can lead to strange results. You might consider waiting for space in the DMA queue to become available since the stack doesn't retry to send a packet dropped because of memory failure (except for the TCP timers).

Definition at line 153 of file ethernetif.c.

References netifGUARD_BLOCK_NBTICKS.

Referenced by ethernetif_init().

00154 {
00155   struct pbuf             *q;
00156   static xSemaphoreHandle xTxSemaphore = NULL;
00157   err_t                   xReturn = ERR_OK;
00158 
00159 
00160   ( void )netif; // Unused param, avoid a compiler warning.
00161 
00162   if( xTxSemaphore == NULL )
00163   {
00164     vSemaphoreCreateBinary( xTxSemaphore );
00165   }
00166 
00167 #if ETH_PAD_SIZE
00168   pbuf_header( p, -ETH_PAD_SIZE );    /* drop the padding word */
00169 #endif
00170 
00171   /* Access to the MACB is guarded using a semaphore. */
00172   if( xSemaphoreTake( xTxSemaphore, netifGUARD_BLOCK_NBTICKS ) )
00173   {
00174     for( q = p; q != NULL; q = q->next )
00175     {
00176       /* Send the data from the pbuf to the interface, one pbuf at a
00177       time. The size of the data in each pbuf is kept in the ->len
00178       variable.  if q->next == NULL then this is the last pbuf in the
00179       chain. */
00180       if( !lMACBSend(&AVR32_MACB, q->payload, q->len, ( q->next == NULL ) ) )
00181       {
00182         xReturn = ~ERR_OK;
00183       }
00184     }
00185     xSemaphoreGive( xTxSemaphore );
00186   }
00187 
00188 #if ETH_PAD_SIZE
00189   pbuf_header( p, ETH_PAD_SIZE );     /* reclaim the padding word */
00190 #endif
00191 
00192   LINK_STATS_INC(link.xmit);  // Traces
00193 
00194   return ERR_OK;
00195 }


Generated on Mon Nov 2 11:38:47 2009 for AVR32 - PolarSSL - SSL Example by  doxygen 1.5.5