root/ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/enet.c

Revision 12368, 6.1 kB (checked in by BrainSlayer, 5 months ago)

tftp server added, supports wiligear, ubiquiti and dd-wrt webflash format

Line 
1 //==========================================================================
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 __eth_install_listener(int eth_type, pkt_handler_t handler)
82 {
83         int i, empty;
84         pkt_handler_t old;
85
86         if (eth_type > 0x800 || handler != (pkt_handler_t) 0) {
87                 empty = -1;
88                 for (i = 0; i < NUM_EXTRA_HANDLERS; i++) {
89                         if (eth_handlers[i].type == eth_type) {
90                                 // Replace existing handler
91                                 old = eth_handlers[i].handler;
92                                 eth_handlers[i].handler = handler;
93                                 return old;
94                         }
95                         if (eth_handlers[i].type == 0) {
96                                 empty = i;
97                         }
98                 }
99                 if (empty >= 0) {
100                         // Found a free slot
101                         eth_handlers[empty].type = eth_type;
102                         eth_handlers[empty].handler = handler;
103                         return (pkt_handler_t) 0;
104                 }
105         }
106         diag_printf
107             ("** Warning: can't install listener for ethernet type 0x%02x\n",
108              eth_type);
109         return (pkt_handler_t) 0;
110 }
111
112 void __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 __enet_poll(void)
128 {
129         pktbuf_t *pkt;
130         eth_header_t eth_hdr;
131         int i, type;
132 #ifdef DEBUG_PKT_EXHAUSTION
133         static bool was_exhausted = false;
134 #endif
135
136         while (true) {
137                 /*
138                  * Try to get a free pktbuf and return if none
139                  * are available.
140                  */
141                 if ((pkt = __pktbuf_alloc(ETH_MAX_PKTLEN)) == NULL) {
142 #ifdef DEBUG_PKT_EXHAUSTION
143                         if (!was_exhausted) {
144                                 int old = start_console();      // Force output to standard port
145                                 diag_printf("__enet_poll: no more buffers\n");
146                                 __pktbuf_dump();
147                                 was_exhausted = true;
148                                 end_console(old);
149                         }
150 #endif
151                         return;
152                 }
153 #ifdef DEBUG_PKT_EXHAUSTION
154                 was_exhausted = false;  // Report the next time we're out of buffers
155 #endif
156
157                 if ((pkt->pkt_bytes =
158                      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 ==
195                                                     type) {
196                                                         (eth_handlers
197                                                          [i].handler) (pkt,
198                                                                        &eth_hdr);
199                                                 }
200                                         }
201                                 }
202                                 __pktbuf_free(pkt);
203                                 break;
204                         }
205                 } else {
206                         __pktbuf_free(pkt);
207                         break;
208                 }
209         }
210 }
211
212 /*
213  * Send an ethernet packet.
214  */
215 void __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 ntohl(unsigned long x)
233 {
234         return (((x & 0x000000FF) << 24) |
235                 ((x & 0x0000FF00) << 8) |
236                 ((x & 0x00FF0000) >> 8) | ((x & 0xFF000000) >> 24));
237 }
238
239 unsigned long ntohs(unsigned short x)
240 {
241         return (((x & 0x00FF) << 8) | ((x & 0xFF00) >> 8));
242 }
243
244 #endif
Note: See TracBrowser for help on using the browser.