2 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
21 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
27 * This file is part of the lwIP TCP/IP stack.
29 * Author: Adam Dunkels <adam@sics.se>
34 * This file is a skeleton for developing Ethernet network interface
35 * drivers for lwIP. Add code to the low_level functions and do a
36 * search-and-replace for the word "ethernetif" to replace it with
37 * something that better describes your network interface.
43 #include "lwip/pbuf.h"
45 #include <lwip/stats.h>
47 #include "netif/etharp.h"
49 /* Define those to better describe your network interface. */
54 struct eth_addr
*ethaddr
;
55 /* Add whatever per-interface state that is needed here. */
58 static const struct eth_addr ethbroadcast
= {{0xff,0xff,0xff,0xff,0xff,0xff}};
60 /* Forward declarations. */
61 static void ethernetif_input(struct netif
*netif
);
62 static err_t
ethernetif_output(struct netif
*netif
, struct pbuf
*p
,
63 struct ip_addr
*ipaddr
);
66 low_level_init(struct netif
*netif
)
68 struct ethernetif
*ethernetif
= netif
->state
;
70 /* set MAC hardware address length */
71 netif
->hwaddr_len
= 6;
73 /* set MAC hardware address */
78 /* maximum transfer unit */
81 /* broadcast capability */
82 netif
->flags
= NETIF_FLAG_BROADCAST
;
84 /* Do whatever else is needed to initialize interface. */
90 * Should do the actual transmission of the packet. The packet is
91 * contained in the pbuf that is passed to the function. This pbuf
97 low_level_output(struct netif
*netif
, struct pbuf
*p
)
99 struct ethernetif
*ethernetif
= netif
->state
;
105 pbuf_header(p
, -ETH_PAD_SIZE
); /* drop the padding word */
108 for(q
= p
; q
!= NULL
; q
= q
->next
) {
109 /* Send the data from the pbuf to the interface, one pbuf at a
110 time. The size of the data in each pbuf is kept in the ->len
112 send data
from(q
->payload
, q
->len
);
115 signal that packet should be
sent();
118 pbuf_header(p
, ETH_PAD_SIZE
); /* reclaim the padding word */
122 lwip_stats
.link
.xmit
++;
123 #endif /* LINK_STATS */
131 * Should allocate a pbuf and transfer the bytes of the incoming
132 * packet from the interface into the pbuf.
137 low_level_input(struct netif
*netif
)
139 struct ethernetif
*ethernetif
= netif
->state
;
143 /* Obtain the size of the packet and put it into the "len"
148 len
+= ETH_PAD_SIZE
; /* allow room for Ethernet padding */
151 /* We allocate a pbuf chain of pbufs from the pool. */
152 p
= pbuf_alloc(PBUF_RAW
, len
, PBUF_POOL
);
157 pbuf_header(p
, -ETH_PAD_SIZE
); /* drop the padding word */
160 /* We iterate over the pbuf chain until we have read the entire
161 * packet into the pbuf. */
162 for(q
= p
; q
!= NULL
; q
= q
->next
) {
163 /* Read enough bytes to fill this pbuf in the chain. The
164 * available data in the pbuf is given by the q->len
166 read data
into(q
->payload
, q
->len
);
168 acknowledge that packet has been
read();
171 pbuf_header(p
, ETH_PAD_SIZE
); /* reclaim the padding word */
175 lwip_stats
.link
.recv
++;
176 #endif /* LINK_STATS */
180 lwip_stats
.link
.memerr
++;
181 lwip_stats
.link
.drop
++;
182 #endif /* LINK_STATS */
189 * ethernetif_output():
191 * This function is called by the TCP/IP stack when an IP packet
192 * should be sent. It calls the function called low_level_output() to
193 * do the actual transmission of the packet.
198 ethernetif_output(struct netif
*netif
, struct pbuf
*p
,
199 struct ip_addr
*ipaddr
)
202 /* resolve hardware address, then send (or queue) packet */
203 return etharp_output(netif
, ipaddr
, p
);
208 * ethernetif_input():
210 * This function should be called when a packet is ready to be read
211 * from the interface. It uses the function low_level_input() that
212 * should handle the actual reception of bytes from the network
218 ethernetif_input(struct netif
*netif
)
220 struct ethernetif
*ethernetif
;
221 struct eth_hdr
*ethhdr
;
224 ethernetif
= netif
->state
;
226 /* move received packet into a new pbuf */
227 p
= low_level_input(netif
);
228 /* no packet could be read, silently ignore this */
229 if (p
== NULL
) return;
230 /* points to packet payload, which starts with an Ethernet header */
234 lwip_stats
.link
.recv
++;
235 #endif /* LINK_STATS */
239 switch (htons(ethhdr
->type
)) {
243 /* CSi disabled ARP table update on ingress IP packets.
244 This seems to work but needs thorough testing. */
245 /* update ARP table */
246 etharp_ip_input(netif
, p
);
248 /* skip Ethernet header */
249 pbuf_header(p
, -sizeof(struct eth_hdr
));
250 /* pass to network layer */
251 netif
->input(p
, netif
);
255 /* pass p to ARP module */
256 etharp_arp_input(netif
, ethernetif
->ethaddr
, p
);
269 sys_timeout(ARP_TMR_INTERVAL
, arp_timer
, NULL
);
275 * Should be called at the beginning of the program to set up the
276 * network interface. It calls the function low_level_init() to do the
277 * actual setup of the hardware.
282 ethernetif_init(struct netif
*netif
)
284 struct ethernetif
*ethernetif
;
286 ethernetif
= mem_malloc(sizeof(struct ethernetif
));
288 if (ethernetif
== NULL
)
290 LWIP_DEBUGF(NETIF_DEBUG
, ("ethernetif_init: out of memory\n"));
295 /* ifType ethernetCsmacd(6) @see RFC1213 */
296 netif
->link_type
= 6;
297 /* your link speed here */
298 netif
->link_speed
= ;
300 netif
->ifinoctets
= 0;
301 netif
->ifinucastpkts
= 0;
302 netif
->ifinnucastpkts
= 0;
303 netif
->ifindiscards
= 0;
304 netif
->ifoutoctets
= 0;
305 netif
->ifoutucastpkts
= 0;
306 netif
->ifoutnucastpkts
= 0;
307 netif
->ifoutdiscards
= 0;
310 netif
->state
= ethernetif
;
311 netif
->name
[0] = IFNAME0
;
312 netif
->name
[1] = IFNAME1
;
313 netif
->output
= ethernetif_output
;
314 netif
->linkoutput
= low_level_output
;
316 ethernetif
->ethaddr
= (struct eth_addr
*)&(netif
->hwaddr
[0]);
318 low_level_init(netif
);
322 sys_timeout(ARP_TMR_INTERVAL
, arp_timer
, NULL
);