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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [ecos-2.0/] [packages/] [redboot/] [v2_0/] [src/] [net/] [enet.c] - Blame information for rev 1773

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1254 phoenix
//==========================================================================
2
//
3
//      net/enet.c
4
//
5
//      Stand-alone ethernet [link-layer] support for RedBoot
6
//
7
//==========================================================================
8
//####ECOSGPLCOPYRIGHTBEGIN####
9
// -------------------------------------------
10
// This file is part of eCos, the Embedded Configurable Operating System.
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under
14
// the terms of the GNU General Public License as published by the Free
15
// Software Foundation; either version 2 or (at your option) any later version.
16
//
17
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20
// for more details.
21
//
22
// You should have received a copy of the GNU General Public License along
23
// with eCos; if not, write to the Free Software Foundation, Inc.,
24
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25
//
26
// As a special exception, if other files instantiate templates or use macros
27
// or inline functions from this file, or you compile this file and link it
28
// with other works to produce a work based on this file, this file does not
29
// by itself cause the resulting work to be covered by the GNU General Public
30
// License. However the source code for this file must still be made available
31
// in accordance with section (3) of the GNU General Public License.
32
//
33
// This exception does not invalidate any other reasons why a work based on
34
// this file might be covered by the GNU General Public License.
35
//
36
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37
// at http://sources.redhat.com/ecos/ecos-license/
38
// -------------------------------------------
39
//####ECOSGPLCOPYRIGHTEND####
40
//==========================================================================
41
//#####DESCRIPTIONBEGIN####
42
//
43
// Author(s):    gthomas
44
// Contributors: gthomas
45
// Date:         2000-07-14
46
// Purpose:      
47
// Description:  
48
//              
49
// This code is part of RedBoot (tm).
50
//
51
//####DESCRIPTIONEND####
52
//
53
//==========================================================================
54
 
55
#include <redboot.h>
56
#include <net/net.h>
57
#include <cyg/io/eth/eth_drv.h>       // Logical driver interfaces
58
 
59
//#define ENET_STATS 1
60
 
61
#ifdef ENET_STATS
62
static int num_ip = 0;
63
static int num_arp = 0;
64
#ifdef NET_SUPPORT_RARP
65
static int num_rarp = 0;
66
#endif
67
static int num_received = 0;
68
static int num_transmitted = 0;
69
#endif
70
 
71
//
72
// Support for user handlers of additional ethernet packets (nonIP)
73
//
74
 
75
#define NUM_EXTRA_HANDLERS 4
76
static struct {
77
    int type;
78
    pkt_handler_t handler;
79
} eth_handlers[NUM_EXTRA_HANDLERS];
80
 
81
pkt_handler_t
82
__eth_install_listener(int eth_type, pkt_handler_t handler)
83
{
84
    int i, empty;
85
    pkt_handler_t old;
86
 
87
    if (eth_type > 0x800 || handler != (pkt_handler_t)0) {
88
        empty = -1;
89
        for (i = 0;  i < NUM_EXTRA_HANDLERS;  i++) {
90
            if (eth_handlers[i].type == eth_type) {
91
                // Replace existing handler
92
                old = eth_handlers[i].handler;
93
                eth_handlers[i].handler = handler;
94
                return old;
95
            }
96
            if (eth_handlers[i].type == 0) {
97
                empty = i;
98
            }
99
        }
100
        if (empty >= 0) {
101
            // Found a free slot
102
            eth_handlers[empty].type = eth_type;
103
            eth_handlers[empty].handler = handler;
104
            return (pkt_handler_t)0;
105
        }
106
    }
107
    diag_printf("** Warning: can't install listener for ethernet type 0x%02x\n", eth_type);
108
    return (pkt_handler_t)0;
109
}
110
 
111
void
112
__eth_remove_listener(int eth_type)
113
{
114
    int i;
115
 
116
    for (i = 0;  i < NUM_EXTRA_HANDLERS;  i++) {
117
        if (eth_handlers[i].type == eth_type) {
118
            eth_handlers[i].type = 0;
119
        }
120
    }
121
}
122
 
123
/*
124
 * Non-blocking poll of ethernet link. Process packets until no more
125
 * are available.
126
 */
127
void
128
__enet_poll(void)
129
{
130
    pktbuf_t *pkt;
131
    eth_header_t eth_hdr;
132
    int i, type;
133
#ifdef DEBUG_PKT_EXHAUSTION
134
    static bool was_exhausted = false;
135
#endif
136
 
137
    while (true) {
138
        /*
139
         * Try to get a free pktbuf and return if none
140
         * are available.
141
         */
142
        if ((pkt = __pktbuf_alloc(ETH_MAX_PKTLEN)) == NULL) {
143
#ifdef DEBUG_PKT_EXHAUSTION
144
            if (!was_exhausted) {
145
                int old = start_console();  // Force output to standard port
146
                diag_printf("__enet_poll: no more buffers\n");
147
                __pktbuf_dump();
148
                was_exhausted = true;
149
                end_console(old);
150
            }
151
#endif
152
            return;
153
        }
154
#ifdef DEBUG_PKT_EXHAUSTION
155
        was_exhausted = false;  // Report the next time we're out of buffers
156
#endif
157
 
158
        if ((pkt->pkt_bytes = eth_drv_read((char *)&eth_hdr, (char *)pkt->buf,
159
                                           ETH_MAX_PKTLEN)) > 0) {
160
#ifdef ENET_STATS
161
            ++num_received;
162
#endif
163
            switch (type = ntohs(eth_hdr.type)) {
164
 
165
            case ETH_TYPE_IP:
166
#ifdef ENET_STATS
167
                ++num_ip;
168
#endif
169
                pkt->ip_hdr = (ip_header_t *)pkt->buf;
170
                __ip_handler(pkt, &eth_hdr.source);
171
                break;
172
 
173
            case ETH_TYPE_ARP:
174
#ifdef ENET_STATS
175
                ++num_arp;
176
#endif
177
                pkt->arp_hdr = (arp_header_t *)pkt->buf;
178
                __arp_handler(pkt);
179
                break;
180
 
181
#ifdef NET_SUPPORT_RARP
182
            case ETH_TYPE_RARP:
183
#ifdef ENET_STATS
184
                ++num_rarp;
185
#endif
186
                pkt->arp_hdr = (arp_header_t *)pkt->buf;
187
                __rarp_handler(pkt);
188
                break;
189
#endif
190
 
191
            default:
192
                if (type > 0x800) {
193
                    for (i = 0;  i < NUM_EXTRA_HANDLERS;  i++) {
194
                        if (eth_handlers[i].type == type) {
195
                            (eth_handlers[i].handler)(pkt, &eth_hdr);
196
                        }
197
                    }
198
                }
199
                __pktbuf_free(pkt);
200
                break;
201
            }
202
        } else {
203
            __pktbuf_free(pkt);
204
            break;
205
        }
206
    }
207
}
208
 
209
 
210
 
211
/*
212
 * Send an ethernet packet.
213
 */
214
void
215
__enet_send(pktbuf_t *pkt, enet_addr_t *dest, int eth_type)
216
{
217
    eth_header_t eth_hdr;
218
 
219
    // Set up ethernet header
220
    memcpy(&eth_hdr.destination, dest, sizeof(enet_addr_t));
221
    memcpy(&eth_hdr.source, __local_enet_addr, sizeof(enet_addr_t));
222
    eth_hdr.type = htons(eth_type);
223
 
224
    eth_drv_write((char *)&eth_hdr, (char *)pkt->buf, pkt->pkt_bytes);
225
#ifdef ENET_STATS
226
    ++num_transmitted;
227
#endif
228
}
229
 
230
#ifdef __LITTLE_ENDIAN__
231
 
232
unsigned long
233
ntohl(unsigned long x)
234
{
235
    return (((x & 0x000000FF) << 24) |
236
            ((x & 0x0000FF00) <<  8) |
237
            ((x & 0x00FF0000) >>  8) |
238
            ((x & 0xFF000000) >> 24));
239
}
240
 
241
unsigned long
242
ntohs(unsigned short x)
243
{
244
    return (((x & 0x00FF) << 8) |
245
            ((x & 0xFF00) >> 8));
246
}
247
 
248
#endif

powered by: WebSVN 2.1.0

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