The Pedigree Project 0.1
ethernetif.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
26/*
27 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
28 * All rights reserved.
29 *
30 * Redistribution and use in source and binary forms, with or without modification,
31 * are permitted provided that the following conditions are met:
32 *
33 * 1. Redistributions of source code must retain the above copyright notice,
34 * this list of conditions and the following disclaimer.
35 * 2. Redistributions in binary form must reproduce the above copyright notice,
36 * this list of conditions and the following disclaimer in the documentation
37 * and/or other materials provided with the distribution.
38 * 3. The name of the author may not be used to endorse or promote products
39 * derived from this software without specific prior written permission.
40 *
41 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
42 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
43 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
44 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
45 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
46 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
47 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
48 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
49 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
50 * OF SUCH DAMAGE.
51 *
52 * This file is part of the lwIP TCP/IP stack.
53 *
54 * Author: Adam Dunkels <adam@sics.se>
55 *
56 */
57
58/*
59 * This file is a skeleton for developing Ethernet network interface
60 * drivers for lwIP. Add code to the low_level functions and do a
61 * search-and-replace for the word "ethernetif" to replace it with
62 * something that better describes your network interface.
63 */
64
65#include "lwip/opt.h"
66
67#if 0 /* don't build, this is only a skeleton, see previous comment */
68
69#include "lwip/def.h"
70#include "lwip/mem.h"
71#include "lwip/pbuf.h"
72#include "lwip/stats.h"
73#include "lwip/snmp.h"
74#include "lwip/ethip6.h"
75#include "lwip/etharp.h"
76#include "netif/ppp/pppoe.h"
77
78/* Define those to better describe your network interface. */
79#define IFNAME0 'e'
80#define IFNAME1 'n'
81
88struct ethernetif {
89 struct eth_addr *ethaddr;
90 /* Add whatever per-interface state that is needed here. */
91};
92
93/* Forward declarations. */
94static void ethernetif_input(struct netif *netif);
95
103static void
104low_level_init(struct netif *netif)
105{
106 struct ethernetif *ethernetif = netif->state;
107
108 /* set MAC hardware address length */
109 netif->hwaddr_len = ETHARP_HWADDR_LEN;
110
111 /* set MAC hardware address */
112 netif->hwaddr[0] = ;
113 ...
114 netif->hwaddr[5] = ;
115
116 /* maximum transfer unit */
117 netif->mtu = 1500;
118
119 /* device capabilities */
120 /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
122
123#if LWIP_IPV6 && LWIP_IPV6_MLD
124 /*
125 * For hardware/netifs that implement MAC filtering.
126 * All-nodes link-local is handled by default, so we must let the hardware know
127 * to allow multicast packets in.
128 * Should set mld_mac_filter previously. */
129 if (netif->mld_mac_filter != NULL) {
130 ip6_addr_t ip6_allnodes_ll;
131 ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll);
132 netif->mld_mac_filter(netif, &ip6_allnodes_ll, NETIF_ADD_MAC_FILTER);
133 }
134#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
135
136 /* Do whatever else is needed to initialize interface. */
137}
138
155static err_t
156low_level_output(struct netif *netif, struct pbuf *p)
157{
158 struct ethernetif *ethernetif = netif->state;
159 struct pbuf *q;
160
161 initiate transfer();
162
163#if ETH_PAD_SIZE
164 pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
165#endif
166
167 for (q = p; q != NULL; q = q->next) {
168 /* Send the data from the pbuf to the interface, one pbuf at a
169 time. The size of the data in each pbuf is kept in the ->len
170 variable. */
171 send data from(q->payload, q->len);
172 }
173
174 signal that packet should be sent();
175
176 MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len);
177 if (((u8_t*)p->payload)[0] & 1) {
178 /* broadcast or multicast packet*/
179 MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts);
180 } else {
181 /* unicast packet */
182 MIB2_STATS_NETIF_INC(netif, ifoutucastpkts);
183 }
184 /* increase ifoutdiscards or ifouterrors on error */
185
186#if ETH_PAD_SIZE
187 pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
188#endif
189
190 LINK_STATS_INC(link.xmit);
191
192 return ERR_OK;
193}
194
203static struct pbuf *
204low_level_input(struct netif *netif)
205{
206 struct ethernetif *ethernetif = netif->state;
207 struct pbuf *p, *q;
208 u16_t len;
209
210 /* Obtain the size of the packet and put it into the "len"
211 variable. */
212 len = ;
213
214#if ETH_PAD_SIZE
215 len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
216#endif
217
218 /* We allocate a pbuf chain of pbufs from the pool. */
220
221 if (p != NULL) {
222
223#if ETH_PAD_SIZE
224 pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
225#endif
226
227 /* We iterate over the pbuf chain until we have read the entire
228 * packet into the pbuf. */
229 for (q = p; q != NULL; q = q->next) {
230 /* Read enough bytes to fill this pbuf in the chain. The
231 * available data in the pbuf is given by the q->len
232 * variable.
233 * This does not necessarily have to be a memcpy, you can also preallocate
234 * pbufs for a DMA-enabled MAC and after receiving truncate it to the
235 * actually received size. In this case, ensure the tot_len member of the
236 * pbuf is the sum of the chained pbuf len members.
237 */
238 read data into(q->payload, q->len);
239 }
240 acknowledge that packet has been read();
241
242 MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len);
243 if (((u8_t*)p->payload)[0] & 1) {
244 /* broadcast or multicast packet*/
245 MIB2_STATS_NETIF_INC(netif, ifinnucastpkts);
246 } else {
247 /* unicast packet*/
248 MIB2_STATS_NETIF_INC(netif, ifinucastpkts);
249 }
250#if ETH_PAD_SIZE
251 pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
252#endif
253
254 LINK_STATS_INC(link.recv);
255 } else {
256 drop packet();
257 LINK_STATS_INC(link.memerr);
258 LINK_STATS_INC(link.drop);
259 MIB2_STATS_NETIF_INC(netif, ifindiscards);
260 }
261
262 return p;
263}
264
274static void
275ethernetif_input(struct netif *netif)
276{
277 struct ethernetif *ethernetif;
278 struct eth_hdr *ethhdr;
279 struct pbuf *p;
280
281 ethernetif = netif->state;
282
283 /* move received packet into a new pbuf */
284 p = low_level_input(netif);
285 /* if no packet could be read, silently ignore this */
286 if (p != NULL) {
287 /* pass all packets to ethernet_input, which decides what packets it supports */
288 if (netif->input(p, netif) != ERR_OK) {
289 LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
290 pbuf_free(p);
291 p = NULL;
292 }
293 }
294}
295
308err_t
309ethernetif_init(struct netif *netif)
310{
311 struct ethernetif *ethernetif;
312
313 LWIP_ASSERT("netif != NULL", (netif != NULL));
314
315 ethernetif = mem_malloc(sizeof(struct ethernetif));
316 if (ethernetif == NULL) {
317 LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n"));
318 return ERR_MEM;
319 }
320
321#if LWIP_NETIF_HOSTNAME
322 /* Initialize interface hostname */
323 netif->hostname = "lwip";
324#endif /* LWIP_NETIF_HOSTNAME */
325
326 /*
327 * Initialize the snmp variables and counters inside the struct netif.
328 * The last argument should be replaced with your link speed, in units
329 * of bits per second.
330 */
331 MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
332
333 netif->state = ethernetif;
334 netif->name[0] = IFNAME0;
335 netif->name[1] = IFNAME1;
336 /* We directly use etharp_output() here to save a function call.
337 * You can instead declare your own function an call etharp_output()
338 * from it if you have to do some checks before sending (e.g. if link
339 * is available...) */
340 netif->output = etharp_output;
341#if LWIP_IPV6
342 netif->output_ip6 = ethip6_output;
343#endif /* LWIP_IPV6 */
344 netif->linkoutput = low_level_output;
345
346 ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
347
348 /* initialize the hardware */
349 low_level_init(netif);
350
351 return ERR_OK;
352}
353
354#endif /* 0 */
#define LWIP_DEBUGF(debug, message)
Definition debug.h:183
s8_t err_t
Definition err.h:76
@ ERR_OK
Definition err.h:82
@ ERR_MEM
Definition err.h:84
#define ETH_PAD_SIZE
Definition opt.h:624
#define NETIF_DEBUG
Definition opt.h:2657
#define NETIF_FLAG_LINK_UP
Definition netif.h:106
#define NETIF_FLAG_ETHARP
Definition netif.h:110
#define NETIF_FLAG_BROADCAST
Definition netif.h:100
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
Definition pbuf.c:267
u8_t pbuf_free(struct pbuf *p)
Definition pbuf.c:734
@ PBUF_POOL
Definition pbuf.h:142
@ PBUF_RAW
Definition pbuf.h:113
void * mem_malloc(mem_size_t size)
Definition mem.c:622
@ NETIF_ADD_MAC_FILTER
Definition netif.h:166
u8_t pbuf_header(struct pbuf *p, s16_t header_size_increment)
Definition pbuf.c:684
Definition netif.h:244
u8_t flags
Definition netif.h:324
char name[2]
Definition netif.h:326
void * state
Definition netif.h:298
netif_input_fn input
Definition netif.h:263
u8_t hwaddr[NETIF_MAX_HWADDR_LEN]
Definition netif.h:322
u16_t mtu
Definition netif.h:318
netif_linkoutput_fn linkoutput
Definition netif.h:274
u8_t hwaddr_len
Definition netif.h:320
Definition pbuf.h:161
u16_t tot_len
Definition pbuf.h:175
struct pbuf * next
Definition pbuf.h:163
u16_t len
Definition pbuf.h:178
void * payload
Definition pbuf.h:166