root/webserver/example/freeRTOS/Demo/Common/ethernet/lwIP/netif/ethernetif.c

Revision 14, 8.5 kB (checked in by phil, 15 years ago)

added unmodified FreeRTOS package V5.4.1 with only web srv demo source for LPC2368 for CrossWorks?

Line 
1 /*
2  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
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.
15  *
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
25  * OF SUCH DAMAGE.
26  *
27  * This file is part of the lwIP TCP/IP stack.
28  *
29  * Author: Adam Dunkels <adam@sics.se>
30  *
31  */
32
33 /*
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.
38  */
39
40 #include "lwip/opt.h"
41 #include "lwip/def.h"
42 #include "lwip/mem.h"
43 #include "lwip/pbuf.h"
44 #include "lwip/sys.h"
45 #include <lwip/stats.h>
46
47 #include "netif/etharp.h"
48
49 /* Define those to better describe your network interface. */
50 #define IFNAME0 'e'
51 #define IFNAME1 'n'
52
53 struct ethernetif {
54   struct eth_addr *ethaddr;
55   /* Add whatever per-interface state that is needed here. */
56 };
57
58 static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
59
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);
64
65 static void
66 low_level_init(struct netif *netif)
67 {
68   struct ethernetif *ethernetif = netif->state;
69  
70   /* set MAC hardware address length */
71   netif->hwaddr_len = 6;
72
73   /* set MAC hardware address */
74   netif->hwaddr[0] = ;
75   ...
76   netif->hwaddr[5] = ;
77
78   /* maximum transfer unit */
79   netif->mtu = 1500;
80  
81   /* broadcast capability */
82   netif->flags = NETIF_FLAG_BROADCAST;
83  
84   /* Do whatever else is needed to initialize interface. */ 
85 }
86
87 /*
88  * low_level_output():
89  *
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
92  * might be chained.
93  *
94  */
95
96 static err_t
97 low_level_output(struct netif *netif, struct pbuf *p)
98 {
99   struct ethernetif *ethernetif = netif->state;
100   struct pbuf *q;
101
102   initiate transfer();
103  
104 #if ETH_PAD_SIZE
105   pbuf_header(p, -ETH_PAD_SIZE);                        /* drop the padding word */
106 #endif
107
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
111        variable. */
112     send data from(q->payload, q->len);
113   }
114
115   signal that packet should be sent();
116
117 #if ETH_PAD_SIZE
118   pbuf_header(p, ETH_PAD_SIZE);                 /* reclaim the padding word */
119 #endif
120  
121 #if LINK_STATS
122   lwip_stats.link.xmit++;
123 #endif /* LINK_STATS */     
124
125   return ERR_OK;
126 }
127
128 /*
129  * low_level_input():
130  *
131  * Should allocate a pbuf and transfer the bytes of the incoming
132  * packet from the interface into the pbuf.
133  *
134  */
135
136 static struct pbuf *
137 low_level_input(struct netif *netif)
138 {
139   struct ethernetif *ethernetif = netif->state;
140   struct pbuf *p, *q;
141   u16_t len;
142
143   /* Obtain the size of the packet and put it into the "len"
144      variable. */
145   len = ;
146
147 #if ETH_PAD_SIZE
148   len += ETH_PAD_SIZE;                                          /* allow room for Ethernet padding */
149 #endif
150
151   /* We allocate a pbuf chain of pbufs from the pool. */
152   p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
153  
154   if (p != NULL) {
155
156 #if ETH_PAD_SIZE
157     pbuf_header(p, -ETH_PAD_SIZE);                      /* drop the padding word */
158 #endif
159
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
165        * variable. */
166       read data into(q->payload, q->len);
167     }
168     acknowledge that packet has been read();
169
170 #if ETH_PAD_SIZE
171     pbuf_header(p, ETH_PAD_SIZE);                       /* reclaim the padding word */
172 #endif
173
174 #if LINK_STATS
175     lwip_stats.link.recv++;
176 #endif /* LINK_STATS */     
177   } else {
178     drop packet();
179 #if LINK_STATS
180     lwip_stats.link.memerr++;
181     lwip_stats.link.drop++;
182 #endif /* LINK_STATS */     
183   }
184
185   return p; 
186 }
187
188 /*
189  * ethernetif_output():
190  *
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.
194  *
195  */
196
197 static err_t
198 ethernetif_output(struct netif *netif, struct pbuf *p,
199       struct ip_addr *ipaddr)
200 {
201  
202  /* resolve hardware address, then send (or queue) packet */
203   return etharp_output(netif, ipaddr, p);
204  
205 }
206
207 /*
208  * ethernetif_input():
209  *
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
213  * interface.
214  *
215  */
216
217 static void
218 ethernetif_input(struct netif *netif)
219 {
220   struct ethernetif *ethernetif;
221   struct eth_hdr *ethhdr;
222   struct pbuf *p;
223
224   ethernetif = netif->state;
225  
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 */
231   ethhdr = p->payload;
232
233 #if LINK_STATS
234   lwip_stats.link.recv++;
235 #endif /* LINK_STATS */
236
237   ethhdr = p->payload;
238    
239   switch (htons(ethhdr->type)) {
240   /* IP packet? */
241   case ETHTYPE_IP:
242 #if 0
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);
247 #endif
248     /* skip Ethernet header */
249     pbuf_header(p, -sizeof(struct eth_hdr));
250     /* pass to network layer */
251     netif->input(p, netif);
252     break;
253      
254     case ETHTYPE_ARP:
255       /* pass p to ARP module  */
256       etharp_arp_input(netif, ethernetif->ethaddr, p);
257       break;
258     default:
259       pbuf_free(p);
260       p = NULL;
261       break;
262   }
263 }
264
265 static void
266 arp_timer(void *arg)
267 {
268   etharp_tmr();
269   sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
270 }
271
272 /*
273  * ethernetif_init():
274  *
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.
278  *
279  */
280
281 err_t
282 ethernetif_init(struct netif *netif)
283 {
284   struct ethernetif *ethernetif;
285    
286   ethernetif = mem_malloc(sizeof(struct ethernetif));
287  
288   if (ethernetif == NULL)
289   {
290         LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n"));
291         return ERR_MEM;
292   }
293
294 #if LWIP_SNMP
295   /* ifType ethernetCsmacd(6) @see RFC1213 */
296   netif->link_type = 6;
297   /* your link speed here */
298   netif->link_speed = ;
299   netif->ts = 0;
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;
308 #endif
309  
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;
315  
316   ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
317  
318   low_level_init(netif);
319
320   etharp_init();
321
322   sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
323
324   return ERR_OK;
325 }
326
Note: See TracBrowser for help on using the browser.