OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [Common/] [ethernet/] [lwIP/] [netif/] [ethernetif.c] - Blame information for rev 606

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 606 jeremybenn
/*
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
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.