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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [Common/] [ethernet/] [lwIP_130/] [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
      read data into(q->payload, q->len);
192
    }
193
    acknowledge that packet has been read();
194
 
195
#if ETH_PAD_SIZE
196
    pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
197
#endif
198
 
199
    LINK_STATS_INC(link.recv);
200
  } else {
201
    drop packet();
202
    LINK_STATS_INC(link.memerr);
203
    LINK_STATS_INC(link.drop);
204
  }
205
 
206
  return p;
207
}
208
 
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. Then the type of the received packet is determined and
214
 * the appropriate input function is called.
215
 *
216
 * @param netif the lwip network interface structure for this ethernetif
217
 */
218
static void
219
ethernetif_input(struct netif *netif)
220
{
221
  struct ethernetif *ethernetif;
222
  struct eth_hdr *ethhdr;
223
  struct pbuf *p;
224
 
225
  ethernetif = netif->state;
226
 
227
  /* move received packet into a new pbuf */
228
  p = low_level_input(netif);
229
  /* no packet could be read, silently ignore this */
230
  if (p == NULL) return;
231
  /* points to packet payload, which starts with an Ethernet header */
232
  ethhdr = p->payload;
233
 
234
  switch (htons(ethhdr->type)) {
235
  /* IP or ARP packet? */
236
  case ETHTYPE_IP:
237
  case ETHTYPE_ARP:
238
#if PPPOE_SUPPORT
239
  /* PPPoE packet? */
240
  case ETHTYPE_PPPOEDISC:
241
  case ETHTYPE_PPPOE:
242
#endif /* PPPOE_SUPPORT */
243
    /* full packet send to tcpip_thread to process */
244
    if (netif->input(p, netif)!=ERR_OK)
245
     { LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
246
       pbuf_free(p);
247
       p = NULL;
248
     }
249
    break;
250
 
251
  default:
252
    pbuf_free(p);
253
    p = NULL;
254
    break;
255
  }
256
}
257
 
258
/**
259
 * Should be called at the beginning of the program to set up the
260
 * network interface. It calls the function low_level_init() to do the
261
 * actual setup of the hardware.
262
 *
263
 * This function should be passed as a parameter to netif_add().
264
 *
265
 * @param netif the lwip network interface structure for this ethernetif
266
 * @return ERR_OK if the loopif is initialized
267
 *         ERR_MEM if private data couldn't be allocated
268
 *         any other err_t on error
269
 */
270
err_t
271
ethernetif_init(struct netif *netif)
272
{
273
  struct ethernetif *ethernetif;
274
 
275
  LWIP_ASSERT("netif != NULL", (netif != NULL));
276
 
277
  ethernetif = mem_malloc(sizeof(struct ethernetif));
278
  if (ethernetif == NULL) {
279
    LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n"));
280
    return ERR_MEM;
281
  }
282
 
283
#if LWIP_NETIF_HOSTNAME
284
  /* Initialize interface hostname */
285
  netif->hostname = "lwip";
286
#endif /* LWIP_NETIF_HOSTNAME */
287
 
288
  /*
289
   * Initialize the snmp variables and counters inside the struct netif.
290
   * The last argument should be replaced with your link speed, in units
291
   * of bits per second.
292
   */
293
  NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, ???);
294
 
295
  netif->state = ethernetif;
296
  netif->name[0] = IFNAME0;
297
  netif->name[1] = IFNAME1;
298
  /* We directly use etharp_output() here to save a function call.
299
   * You can instead declare your own function an call etharp_output()
300
   * from it if you have to do some checks before sending (e.g. if link
301
   * is available...) */
302
  netif->output = etharp_output;
303
  netif->linkoutput = low_level_output;
304
 
305
  ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
306
 
307
  /* initialize the hardware */
308
  low_level_init(netif);
309
 
310
  return ERR_OK;
311
}
312
 
313
#endif /* 0 */

powered by: WebSVN 2.1.0

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