# 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 }