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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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