LwIP with PPP & Ethernet integration

Dependents:   NetworkingCoreLib

This is the mbed port of the LwIP stack: http://savannah.nongnu.org/projects/lwip/

It includes contributed content from NXP's port for LPCxxxx devices: http://www.lpcware.com/content/project/lightweight-ip-lwip-networking-stack

Licence

LwIP is licenced under the BSD licence:

Copyright (c) 2001-2004 Swedish Institute of Computer Science. 
All rights reserved. 
Redistribution and use in source and binary forms, with or without modification, 
are permitted provided that the following conditions are met: 
1. Redistributions of source code must retain the above copyright notice, 
this list of conditions and the following disclaimer. 
2. Redistributions in binary form must reproduce the above copyright notice, 
this list of conditions and the following disclaimer in the documentation 
and/or other materials provided with the distribution. 
3. The name of the author may not be used to endorse or promote products 
derived from this software without specific prior written permission. 
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
OF SUCH DAMAGE.
Committer:
donatien
Date:
Fri May 25 08:56:35 2012 +0000
Revision:
2:1a87f74b8e3b
Parent:
0:8e01dca41002
Removed compilation of EMAC driver when using PPP

Who changed what in which revision?

UserRevisionLine numberNew contents of line
donatien 0:8e01dca41002 1 /**
donatien 0:8e01dca41002 2 * @file
donatien 0:8e01dca41002 3 * Ethernet Interface Skeleton
donatien 0:8e01dca41002 4 *
donatien 0:8e01dca41002 5 */
donatien 0:8e01dca41002 6
donatien 0:8e01dca41002 7 /*
donatien 0:8e01dca41002 8 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
donatien 0:8e01dca41002 9 * All rights reserved.
donatien 0:8e01dca41002 10 *
donatien 0:8e01dca41002 11 * Redistribution and use in source and binary forms, with or without modification,
donatien 0:8e01dca41002 12 * are permitted provided that the following conditions are met:
donatien 0:8e01dca41002 13 *
donatien 0:8e01dca41002 14 * 1. Redistributions of source code must retain the above copyright notice,
donatien 0:8e01dca41002 15 * this list of conditions and the following disclaimer.
donatien 0:8e01dca41002 16 * 2. Redistributions in binary form must reproduce the above copyright notice,
donatien 0:8e01dca41002 17 * this list of conditions and the following disclaimer in the documentation
donatien 0:8e01dca41002 18 * and/or other materials provided with the distribution.
donatien 0:8e01dca41002 19 * 3. The name of the author may not be used to endorse or promote products
donatien 0:8e01dca41002 20 * derived from this software without specific prior written permission.
donatien 0:8e01dca41002 21 *
donatien 0:8e01dca41002 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
donatien 0:8e01dca41002 23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
donatien 0:8e01dca41002 24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
donatien 0:8e01dca41002 25 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
donatien 0:8e01dca41002 26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
donatien 0:8e01dca41002 27 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
donatien 0:8e01dca41002 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
donatien 0:8e01dca41002 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
donatien 0:8e01dca41002 30 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
donatien 0:8e01dca41002 31 * OF SUCH DAMAGE.
donatien 0:8e01dca41002 32 *
donatien 0:8e01dca41002 33 * This file is part of the lwIP TCP/IP stack.
donatien 0:8e01dca41002 34 *
donatien 0:8e01dca41002 35 * Author: Adam Dunkels <adam@sics.se>
donatien 0:8e01dca41002 36 *
donatien 0:8e01dca41002 37 */
donatien 0:8e01dca41002 38
donatien 0:8e01dca41002 39 /*
donatien 0:8e01dca41002 40 * This file is a skeleton for developing Ethernet network interface
donatien 0:8e01dca41002 41 * drivers for lwIP. Add code to the low_level functions and do a
donatien 0:8e01dca41002 42 * search-and-replace for the word "ethernetif" to replace it with
donatien 0:8e01dca41002 43 * something that better describes your network interface.
donatien 0:8e01dca41002 44 */
donatien 0:8e01dca41002 45
donatien 0:8e01dca41002 46 #include "lwip/opt.h"
donatien 0:8e01dca41002 47
donatien 0:8e01dca41002 48 #if 0 /* don't build, this is only a skeleton, see previous comment */
donatien 0:8e01dca41002 49
donatien 0:8e01dca41002 50 #include "lwip/def.h"
donatien 0:8e01dca41002 51 #include "lwip/mem.h"
donatien 0:8e01dca41002 52 #include "lwip/pbuf.h"
donatien 0:8e01dca41002 53 #include "lwip/sys.h"
donatien 0:8e01dca41002 54 #include <lwip/stats.h>
donatien 0:8e01dca41002 55 #include <lwip/snmp.h>
donatien 0:8e01dca41002 56 #include "netif/etharp.h"
donatien 0:8e01dca41002 57 #include "netif/ppp_oe.h"
donatien 0:8e01dca41002 58
donatien 0:8e01dca41002 59 /* Define those to better describe your network interface. */
donatien 0:8e01dca41002 60 #define IFNAME0 'e'
donatien 0:8e01dca41002 61 #define IFNAME1 'n'
donatien 0:8e01dca41002 62
donatien 0:8e01dca41002 63 /**
donatien 0:8e01dca41002 64 * Helper struct to hold private data used to operate your ethernet interface.
donatien 0:8e01dca41002 65 * Keeping the ethernet address of the MAC in this struct is not necessary
donatien 0:8e01dca41002 66 * as it is already kept in the struct netif.
donatien 0:8e01dca41002 67 * But this is only an example, anyway...
donatien 0:8e01dca41002 68 */
donatien 0:8e01dca41002 69 struct ethernetif {
donatien 0:8e01dca41002 70 struct eth_addr *ethaddr;
donatien 0:8e01dca41002 71 /* Add whatever per-interface state that is needed here. */
donatien 0:8e01dca41002 72 };
donatien 0:8e01dca41002 73
donatien 0:8e01dca41002 74 /* Forward declarations. */
donatien 0:8e01dca41002 75 static void ethernetif_input(struct netif *netif);
donatien 0:8e01dca41002 76
donatien 0:8e01dca41002 77 /**
donatien 0:8e01dca41002 78 * In this function, the hardware should be initialized.
donatien 0:8e01dca41002 79 * Called from ethernetif_init().
donatien 0:8e01dca41002 80 *
donatien 0:8e01dca41002 81 * @param netif the already initialized lwip network interface structure
donatien 0:8e01dca41002 82 * for this ethernetif
donatien 0:8e01dca41002 83 */
donatien 0:8e01dca41002 84 static void
donatien 0:8e01dca41002 85 low_level_init(struct netif *netif)
donatien 0:8e01dca41002 86 {
donatien 0:8e01dca41002 87 struct ethernetif *ethernetif = netif->state;
donatien 0:8e01dca41002 88
donatien 0:8e01dca41002 89 /* set MAC hardware address length */
donatien 0:8e01dca41002 90 netif->hwaddr_len = ETHARP_HWADDR_LEN;
donatien 0:8e01dca41002 91
donatien 0:8e01dca41002 92 /* set MAC hardware address */
donatien 0:8e01dca41002 93 netif->hwaddr[0] = ;
donatien 0:8e01dca41002 94 ...
donatien 0:8e01dca41002 95 netif->hwaddr[5] = ;
donatien 0:8e01dca41002 96
donatien 0:8e01dca41002 97 /* maximum transfer unit */
donatien 0:8e01dca41002 98 netif->mtu = 1500;
donatien 0:8e01dca41002 99
donatien 0:8e01dca41002 100 /* device capabilities */
donatien 0:8e01dca41002 101 /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
donatien 0:8e01dca41002 102 netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
donatien 0:8e01dca41002 103
donatien 0:8e01dca41002 104 /* Do whatever else is needed to initialize interface. */
donatien 0:8e01dca41002 105 }
donatien 0:8e01dca41002 106
donatien 0:8e01dca41002 107 /**
donatien 0:8e01dca41002 108 * This function should do the actual transmission of the packet. The packet is
donatien 0:8e01dca41002 109 * contained in the pbuf that is passed to the function. This pbuf
donatien 0:8e01dca41002 110 * might be chained.
donatien 0:8e01dca41002 111 *
donatien 0:8e01dca41002 112 * @param netif the lwip network interface structure for this ethernetif
donatien 0:8e01dca41002 113 * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
donatien 0:8e01dca41002 114 * @return ERR_OK if the packet could be sent
donatien 0:8e01dca41002 115 * an err_t value if the packet couldn't be sent
donatien 0:8e01dca41002 116 *
donatien 0:8e01dca41002 117 * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
donatien 0:8e01dca41002 118 * strange results. You might consider waiting for space in the DMA queue
donatien 0:8e01dca41002 119 * to become availale since the stack doesn't retry to send a packet
donatien 0:8e01dca41002 120 * dropped because of memory failure (except for the TCP timers).
donatien 0:8e01dca41002 121 */
donatien 0:8e01dca41002 122
donatien 0:8e01dca41002 123 static err_t
donatien 0:8e01dca41002 124 low_level_output(struct netif *netif, struct pbuf *p)
donatien 0:8e01dca41002 125 {
donatien 0:8e01dca41002 126 struct ethernetif *ethernetif = netif->state;
donatien 0:8e01dca41002 127 struct pbuf *q;
donatien 0:8e01dca41002 128
donatien 0:8e01dca41002 129 initiate transfer();
donatien 0:8e01dca41002 130
donatien 0:8e01dca41002 131 #if ETH_PAD_SIZE
donatien 0:8e01dca41002 132 pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
donatien 0:8e01dca41002 133 #endif
donatien 0:8e01dca41002 134
donatien 0:8e01dca41002 135 for(q = p; q != NULL; q = q->next) {
donatien 0:8e01dca41002 136 /* Send the data from the pbuf to the interface, one pbuf at a
donatien 0:8e01dca41002 137 time. The size of the data in each pbuf is kept in the ->len
donatien 0:8e01dca41002 138 variable. */
donatien 0:8e01dca41002 139 send data from(q->payload, q->len);
donatien 0:8e01dca41002 140 }
donatien 0:8e01dca41002 141
donatien 0:8e01dca41002 142 signal that packet should be sent();
donatien 0:8e01dca41002 143
donatien 0:8e01dca41002 144 #if ETH_PAD_SIZE
donatien 0:8e01dca41002 145 pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
donatien 0:8e01dca41002 146 #endif
donatien 0:8e01dca41002 147
donatien 0:8e01dca41002 148 LINK_STATS_INC(link.xmit);
donatien 0:8e01dca41002 149
donatien 0:8e01dca41002 150 return ERR_OK;
donatien 0:8e01dca41002 151 }
donatien 0:8e01dca41002 152
donatien 0:8e01dca41002 153 /**
donatien 0:8e01dca41002 154 * Should allocate a pbuf and transfer the bytes of the incoming
donatien 0:8e01dca41002 155 * packet from the interface into the pbuf.
donatien 0:8e01dca41002 156 *
donatien 0:8e01dca41002 157 * @param netif the lwip network interface structure for this ethernetif
donatien 0:8e01dca41002 158 * @return a pbuf filled with the received packet (including MAC header)
donatien 0:8e01dca41002 159 * NULL on memory error
donatien 0:8e01dca41002 160 */
donatien 0:8e01dca41002 161 static struct pbuf *
donatien 0:8e01dca41002 162 low_level_input(struct netif *netif)
donatien 0:8e01dca41002 163 {
donatien 0:8e01dca41002 164 struct ethernetif *ethernetif = netif->state;
donatien 0:8e01dca41002 165 struct pbuf *p, *q;
donatien 0:8e01dca41002 166 u16_t len;
donatien 0:8e01dca41002 167
donatien 0:8e01dca41002 168 /* Obtain the size of the packet and put it into the "len"
donatien 0:8e01dca41002 169 variable. */
donatien 0:8e01dca41002 170 len = ;
donatien 0:8e01dca41002 171
donatien 0:8e01dca41002 172 #if ETH_PAD_SIZE
donatien 0:8e01dca41002 173 len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
donatien 0:8e01dca41002 174 #endif
donatien 0:8e01dca41002 175
donatien 0:8e01dca41002 176 /* We allocate a pbuf chain of pbufs from the pool. */
donatien 0:8e01dca41002 177 p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
donatien 0:8e01dca41002 178
donatien 0:8e01dca41002 179 if (p != NULL) {
donatien 0:8e01dca41002 180
donatien 0:8e01dca41002 181 #if ETH_PAD_SIZE
donatien 0:8e01dca41002 182 pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
donatien 0:8e01dca41002 183 #endif
donatien 0:8e01dca41002 184
donatien 0:8e01dca41002 185 /* We iterate over the pbuf chain until we have read the entire
donatien 0:8e01dca41002 186 * packet into the pbuf. */
donatien 0:8e01dca41002 187 for(q = p; q != NULL; q = q->next) {
donatien 0:8e01dca41002 188 /* Read enough bytes to fill this pbuf in the chain. The
donatien 0:8e01dca41002 189 * available data in the pbuf is given by the q->len
donatien 0:8e01dca41002 190 * variable.
donatien 0:8e01dca41002 191 * This does not necessarily have to be a memcpy, you can also preallocate
donatien 0:8e01dca41002 192 * pbufs for a DMA-enabled MAC and after receiving truncate it to the
donatien 0:8e01dca41002 193 * actually received size. In this case, ensure the tot_len member of the
donatien 0:8e01dca41002 194 * pbuf is the sum of the chained pbuf len members.
donatien 0:8e01dca41002 195 */
donatien 0:8e01dca41002 196 read data into(q->payload, q->len);
donatien 0:8e01dca41002 197 }
donatien 0:8e01dca41002 198 acknowledge that packet has been read();
donatien 0:8e01dca41002 199
donatien 0:8e01dca41002 200 #if ETH_PAD_SIZE
donatien 0:8e01dca41002 201 pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
donatien 0:8e01dca41002 202 #endif
donatien 0:8e01dca41002 203
donatien 0:8e01dca41002 204 LINK_STATS_INC(link.recv);
donatien 0:8e01dca41002 205 } else {
donatien 0:8e01dca41002 206 drop packet();
donatien 0:8e01dca41002 207 LINK_STATS_INC(link.memerr);
donatien 0:8e01dca41002 208 LINK_STATS_INC(link.drop);
donatien 0:8e01dca41002 209 }
donatien 0:8e01dca41002 210
donatien 0:8e01dca41002 211 return p;
donatien 0:8e01dca41002 212 }
donatien 0:8e01dca41002 213
donatien 0:8e01dca41002 214 /**
donatien 0:8e01dca41002 215 * This function should be called when a packet is ready to be read
donatien 0:8e01dca41002 216 * from the interface. It uses the function low_level_input() that
donatien 0:8e01dca41002 217 * should handle the actual reception of bytes from the network
donatien 0:8e01dca41002 218 * interface. Then the type of the received packet is determined and
donatien 0:8e01dca41002 219 * the appropriate input function is called.
donatien 0:8e01dca41002 220 *
donatien 0:8e01dca41002 221 * @param netif the lwip network interface structure for this ethernetif
donatien 0:8e01dca41002 222 */
donatien 0:8e01dca41002 223 static void
donatien 0:8e01dca41002 224 ethernetif_input(struct netif *netif)
donatien 0:8e01dca41002 225 {
donatien 0:8e01dca41002 226 struct ethernetif *ethernetif;
donatien 0:8e01dca41002 227 struct eth_hdr *ethhdr;
donatien 0:8e01dca41002 228 struct pbuf *p;
donatien 0:8e01dca41002 229
donatien 0:8e01dca41002 230 ethernetif = netif->state;
donatien 0:8e01dca41002 231
donatien 0:8e01dca41002 232 /* move received packet into a new pbuf */
donatien 0:8e01dca41002 233 p = low_level_input(netif);
donatien 0:8e01dca41002 234 /* no packet could be read, silently ignore this */
donatien 0:8e01dca41002 235 if (p == NULL) return;
donatien 0:8e01dca41002 236 /* points to packet payload, which starts with an Ethernet header */
donatien 0:8e01dca41002 237 ethhdr = p->payload;
donatien 0:8e01dca41002 238
donatien 0:8e01dca41002 239 switch (htons(ethhdr->type)) {
donatien 0:8e01dca41002 240 /* IP or ARP packet? */
donatien 0:8e01dca41002 241 case ETHTYPE_IP:
donatien 0:8e01dca41002 242 case ETHTYPE_ARP:
donatien 0:8e01dca41002 243 #if PPPOE_SUPPORT
donatien 0:8e01dca41002 244 /* PPPoE packet? */
donatien 0:8e01dca41002 245 case ETHTYPE_PPPOEDISC:
donatien 0:8e01dca41002 246 case ETHTYPE_PPPOE:
donatien 0:8e01dca41002 247 #endif /* PPPOE_SUPPORT */
donatien 0:8e01dca41002 248 /* full packet send to tcpip_thread to process */
donatien 0:8e01dca41002 249 if (netif->input(p, netif)!=ERR_OK)
donatien 0:8e01dca41002 250 { LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
donatien 0:8e01dca41002 251 pbuf_free(p);
donatien 0:8e01dca41002 252 p = NULL;
donatien 0:8e01dca41002 253 }
donatien 0:8e01dca41002 254 break;
donatien 0:8e01dca41002 255
donatien 0:8e01dca41002 256 default:
donatien 0:8e01dca41002 257 pbuf_free(p);
donatien 0:8e01dca41002 258 p = NULL;
donatien 0:8e01dca41002 259 break;
donatien 0:8e01dca41002 260 }
donatien 0:8e01dca41002 261 }
donatien 0:8e01dca41002 262
donatien 0:8e01dca41002 263 /**
donatien 0:8e01dca41002 264 * Should be called at the beginning of the program to set up the
donatien 0:8e01dca41002 265 * network interface. It calls the function low_level_init() to do the
donatien 0:8e01dca41002 266 * actual setup of the hardware.
donatien 0:8e01dca41002 267 *
donatien 0:8e01dca41002 268 * This function should be passed as a parameter to netif_add().
donatien 0:8e01dca41002 269 *
donatien 0:8e01dca41002 270 * @param netif the lwip network interface structure for this ethernetif
donatien 0:8e01dca41002 271 * @return ERR_OK if the loopif is initialized
donatien 0:8e01dca41002 272 * ERR_MEM if private data couldn't be allocated
donatien 0:8e01dca41002 273 * any other err_t on error
donatien 0:8e01dca41002 274 */
donatien 0:8e01dca41002 275 err_t
donatien 0:8e01dca41002 276 ethernetif_init(struct netif *netif)
donatien 0:8e01dca41002 277 {
donatien 0:8e01dca41002 278 struct ethernetif *ethernetif;
donatien 0:8e01dca41002 279
donatien 0:8e01dca41002 280 LWIP_ASSERT("netif != NULL", (netif != NULL));
donatien 0:8e01dca41002 281
donatien 0:8e01dca41002 282 ethernetif = mem_malloc(sizeof(struct ethernetif));
donatien 0:8e01dca41002 283 if (ethernetif == NULL) {
donatien 0:8e01dca41002 284 LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n"));
donatien 0:8e01dca41002 285 return ERR_MEM;
donatien 0:8e01dca41002 286 }
donatien 0:8e01dca41002 287
donatien 0:8e01dca41002 288 #if LWIP_NETIF_HOSTNAME
donatien 0:8e01dca41002 289 /* Initialize interface hostname */
donatien 0:8e01dca41002 290 netif->hostname = "lwip";
donatien 0:8e01dca41002 291 #endif /* LWIP_NETIF_HOSTNAME */
donatien 0:8e01dca41002 292
donatien 0:8e01dca41002 293 /*
donatien 0:8e01dca41002 294 * Initialize the snmp variables and counters inside the struct netif.
donatien 0:8e01dca41002 295 * The last argument should be replaced with your link speed, in units
donatien 0:8e01dca41002 296 * of bits per second.
donatien 0:8e01dca41002 297 */
donatien 0:8e01dca41002 298 NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
donatien 0:8e01dca41002 299
donatien 0:8e01dca41002 300 netif->state = ethernetif;
donatien 0:8e01dca41002 301 netif->name[0] = IFNAME0;
donatien 0:8e01dca41002 302 netif->name[1] = IFNAME1;
donatien 0:8e01dca41002 303 /* We directly use etharp_output() here to save a function call.
donatien 0:8e01dca41002 304 * You can instead declare your own function an call etharp_output()
donatien 0:8e01dca41002 305 * from it if you have to do some checks before sending (e.g. if link
donatien 0:8e01dca41002 306 * is available...) */
donatien 0:8e01dca41002 307 netif->output = etharp_output;
donatien 0:8e01dca41002 308 netif->linkoutput = low_level_output;
donatien 0:8e01dca41002 309
donatien 0:8e01dca41002 310 ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
donatien 0:8e01dca41002 311
donatien 0:8e01dca41002 312 /* initialize the hardware */
donatien 0:8e01dca41002 313 low_level_init(netif);
donatien 0:8e01dca41002 314
donatien 0:8e01dca41002 315 return ERR_OK;
donatien 0:8e01dca41002 316 }
donatien 0:8e01dca41002 317
donatien 0:8e01dca41002 318 #endif /* 0 */