Blame view

net/net.c 36.6 KB
f739fcd83   Tom Rini   SPDX: Convert a f...
1
  // SPDX-License-Identifier: GPL-2.0
2d966958c   wdenk   Initial revision
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
  /*
   *	Copied from Linux Monitor (LiMon) - Networking.
   *
   *	Copyright 1994 - 2000 Neil Russell.
   *	(See License)
   *	Copyright 2000 Roland Borde
   *	Copyright 2000 Paolo Scaffardi
   *	Copyright 2000-2002 Wolfgang Denk, wd@denx.de
   */
  
  /*
   * General Desription:
   *
   * The user interface supports commands for BOOTP, RARP, and TFTP.
   * Also, we support ARP internally. Depending on available data,
   * these interact as follows:
   *
   * BOOTP:
   *
   *	Prerequisites:	- own ethernet address
   *	We want:	- own IP address
   *			- TFTP server IP address
   *			- name of bootfile
   *	Next step:	ARP
   *
d22c338e0   Joe Hershberger   net: Add link-loc...
27
28
29
30
31
32
   * LINK_LOCAL:
   *
   *	Prerequisites:	- own ethernet address
   *	We want:	- own IP address
   *	Next step:	ARP
   *
2d966958c   wdenk   Initial revision
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
   * RARP:
   *
   *	Prerequisites:	- own ethernet address
   *	We want:	- own IP address
   *			- TFTP server IP address
   *	Next step:	ARP
   *
   * ARP:
   *
   *	Prerequisites:	- own ethernet address
   *			- own IP address
   *			- TFTP server IP address
   *	We want:	- TFTP server ethernet address
   *	Next step:	TFTP
   *
   * DHCP:
   *
b2f508075   Wolfgang Denk   Minor code cleanup
50
51
52
53
   *     Prerequisites:	- own ethernet address
   *     We want:		- IP, Netmask, ServerIP, Gateway IP
   *			- bootfilename, lease time
   *     Next step:	- TFTP
2d966958c   wdenk   Initial revision
54
55
56
57
58
59
60
61
62
63
64
   *
   * TFTP:
   *
   *	Prerequisites:	- own ethernet address
   *			- own IP address
   *			- TFTP server IP address
   *			- TFTP server ethernet address
   *			- name of bootfile (if unknown, we use a default name
   *			  derived from our own IP address)
   *	We want:	- load the boot file
   *	Next step:	none
cbd8a35c6   wdenk   * Patch by Masami...
65
66
67
68
69
70
71
72
73
   *
   * NFS:
   *
   *	Prerequisites:	- own ethernet address
   *			- own IP address
   *			- name of bootfile (if unknown, we use a default name
   *			  derived from our own IP address)
   *	We want:	- load the boot file
   *	Next step:	none
ea287debe   wdenk   * Patch by Masami...
74
75
76
   *
   * SNTP:
   *
b2f508075   Wolfgang Denk   Minor code cleanup
77
   *	Prerequisites:	- own ethernet address
ea287debe   wdenk   * Patch by Masami...
78
79
80
   *			- own IP address
   *	We want:	- network time
   *	Next step:	none
d8970dae2   Lothar Felten   net: Add new wol ...
81
82
83
84
85
86
   *
   * WOL:
   *
   *	Prerequisites:	- own ethernet address
   *	We want:	- magic packet or timeout
   *	Next step:	none
2d966958c   wdenk   Initial revision
87
88
89
90
   */
  
  
  #include <common.h>
2d966958c   wdenk   Initial revision
91
  #include <command.h>
24b852a7a   Simon Glass   Move console defi...
92
  #include <console.h>
a9f51c9b4   Joe Hershberger   env: Add a bootfi...
93
  #include <environment.h>
60304592b   Joe Hershberger   net: Improve erro...
94
  #include <errno.h>
2d966958c   wdenk   Initial revision
95
  #include <net.h>
f73a7df98   Alex Kiernan   net: fastboot: Me...
96
  #include <net/fastboot.h>
346969584   Lukasz Majewski   net: tftp: Move t...
97
  #include <net/tftp.h>
2d8d190c8   Uri Mashiach   status_led: Kconf...
98
  #if defined(CONFIG_LED_STATUS)
fc3e2165e   wdenk   * Patch by Sangmo...
99
  #include <miiphy.h>
4545f4e6d   Joe Hershberger   net: cosmetic: Al...
100
  #include <status_led.h>
fc3e2165e   wdenk   * Patch by Sangmo...
101
  #endif
4545f4e6d   Joe Hershberger   net: cosmetic: Al...
102
103
104
105
  #include <watchdog.h>
  #include <linux/compiler.h>
  #include "arp.h"
  #include "bootp.h"
f575ae1f7   Joe Hershberger   net: Move CDP out...
106
  #include "cdp.h"
1a32bf418   Robin Getz   Add DNS support
107
108
109
  #if defined(CONFIG_CMD_DNS)
  #include "dns.h"
  #endif
d22c338e0   Joe Hershberger   net: Add link-loc...
110
  #include "link_local.h"
4545f4e6d   Joe Hershberger   net: cosmetic: Al...
111
  #include "nfs.h"
a36b12f95   Joe Hershberger   net: Move PING ou...
112
  #include "ping.h"
4545f4e6d   Joe Hershberger   net: cosmetic: Al...
113
114
115
116
  #include "rarp.h"
  #if defined(CONFIG_CMD_SNTP)
  #include "sntp.h"
  #endif
d8970dae2   Lothar Felten   net: Add new wol ...
117
118
119
  #if defined(CONFIG_CMD_WOL)
  #include "wol.h"
  #endif
2d966958c   wdenk   Initial revision
120

2d966958c   wdenk   Initial revision
121
  /** BOOTP EXTENTIONS **/
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
122
  /* Our subnet mask (0=unknown) */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
123
  struct in_addr net_netmask;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
124
  /* Our gateways IP address */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
125
  struct in_addr net_gateway;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
126
  /* Our DNS IP address */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
127
  struct in_addr net_dns_server;
1fe80d79c   Jon Loeliger   Finally retire cm...
128
  #if defined(CONFIG_BOOTP_DNS2)
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
129
  /* Our 2nd DNS IP address */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
130
  struct in_addr net_dns_server2;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
131
  #endif
2d966958c   wdenk   Initial revision
132
133
  
  /** END OF BOOTP EXTENTIONS **/
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
134
  /* Our ethernet address */
0adb5b761   Joe Hershberger   net: cosmetic: Na...
135
  u8 net_ethaddr[6];
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
136
  /* Boot server enet address */
0adb5b761   Joe Hershberger   net: cosmetic: Na...
137
  u8 net_server_ethaddr[6];
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
138
  /* Our IP addr (0 = unknown) */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
139
  struct in_addr	net_ip;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
140
  /* Server IP addr (0 = unknown) */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
141
  struct in_addr	net_server_ip;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
142
  /* Current receive packet */
1203fccee   Joe Hershberger   net: cosmetic: Cl...
143
  uchar *net_rx_packet;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
144
  /* Current rx packet length */
1203fccee   Joe Hershberger   net: cosmetic: Cl...
145
  int		net_rx_packet_len;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
146
  /* IP packet ID */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
147
  static unsigned	net_ip_id;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
148
  /* Ethernet bcast address */
0adb5b761   Joe Hershberger   net: cosmetic: Na...
149
150
  const u8 net_bcast_ethaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  const u8 net_null_ethaddr[6];
0efe1bcf5   Alexander Graf   efi_loader: Add n...
151
  #if defined(CONFIG_API) || defined(CONFIG_EFI_LOADER)
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
152
  void (*push_packet)(void *, int len) = 0;
f85b60710   Rafal Jaworowski   Introduce new eth...
153
  #endif
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
154
  /* Network loop state */
22f6e99d5   Joe Hershberger   net: Refactor to ...
155
  enum net_loop_state net_state;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
156
  /* Tried all network devices */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
157
  int		net_restart_wrap;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
158
  /* Network loop restarted */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
159
  static int	net_restarted;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
160
  /* At least one device configured */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
161
  static int	net_dev_exists;
2d966958c   wdenk   Initial revision
162

6e5923851   wdenk   * Cleanup, minor ...
163
  /* XXX in both little & big endian machines 0xFFFF == ntohs(-1) */
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
164
  /* default is without VLAN */
4fd5055f5   Joe Hershberger   net: cosmetic: Cl...
165
  ushort		net_our_vlan = 0xFFFF;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
166
  /* ditto */
4fd5055f5   Joe Hershberger   net: cosmetic: Cl...
167
  ushort		net_native_vlan = 0xFFFF;
a3d991bd0   wdenk   Patches by Pantel...
168

3e38e429f   Luca Ceresoli   net/net.c: cosmet...
169
  /* Boot File name */
11a69ff85   Jacob Stiffler   net: Increase the...
170
  char net_boot_file_name[1024];
449312c1c   Alexander Graf   net: Prefer comma...
171
172
  /* Indicates whether the file name was specified on the command line */
  bool net_boot_file_name_explicit;
1411157d8   Joe Hershberger   net: cosmetic: Fi...
173
174
175
176
  /* The actual transferred size of the bootfile (in bytes) */
  u32 net_boot_file_size;
  /* Boot file size in blocks as reported by the DHCP server */
  u32 net_boot_file_expected_size_in_blocks;
2d966958c   wdenk   Initial revision
177

643d1ab23   Jon Loeliger   net/: Remove obso...
178
  #if defined(CONFIG_CMD_SNTP)
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
179
  /* NTP server IP address */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
180
  struct in_addr	net_ntp_server;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
181
  /* offset time from UTC */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
182
  int		net_ntp_time_offset;
ea287debe   wdenk   * Patch by Masami...
183
  #endif
1203fccee   Joe Hershberger   net: cosmetic: Cl...
184
  static uchar net_pkt_buf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN];
2a504df00   Joe Hershberger   net: Clean up net...
185
186
  /* Receive packets */
  uchar *net_rx_packets[PKTBUFSRX];
ece223b52   Joe Hershberger   net: Refactor to ...
187
188
189
190
  /* Current UDP RX packet handler */
  static rxhand_f *udp_packet_handler;
  /* Current ARP RX packet handler */
  static rxhand_f *arp_packet_handler;
39bccd21d   Simon Glass   net: Hide more co...
191
  #ifdef CONFIG_CMD_TFTPPUT
ece223b52   Joe Hershberger   net: Refactor to ...
192
193
  /* Current ICMP rx handler */
  static rxhand_icmp_f *packet_icmp_handler;
39bccd21d   Simon Glass   net: Hide more co...
194
  #endif
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
195
  /* Current timeout handler */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
196
  static thand_f *time_handler;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
197
  /* Time base value */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
198
  static ulong	time_start;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
199
  /* Current timeout value */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
200
  static ulong	time_delta;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
201
  /* THE transmit packet */
1203fccee   Joe Hershberger   net: cosmetic: Cl...
202
  uchar *net_tx_packet;
2d966958c   wdenk   Initial revision
203

e4bf0c5cf   Simon Glass   net: tftpput: Ren...
204
  static int net_check_prereq(enum proto_t protocol);
2d966958c   wdenk   Initial revision
205

bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
206
  static int net_try_count;
67b96e87d   Remy Bohmer   Repair the 'netre...
207

b63056d6a   Jim Lin   NET: Add net_busy...
208
  int __maybe_unused net_busy_flag;
2d966958c   wdenk   Initial revision
209
  /**********************************************************************/
73a8b27c5   wdenk   * Add support for...
210

fd3056337   Joe Hershberger   net: Use env call...
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
  static int on_ipaddr(const char *name, const char *value, enum env_op op,
  	int flags)
  {
  	if (flags & H_PROGRAMMATIC)
  		return 0;
  
  	net_ip = string_to_ip(value);
  
  	return 0;
  }
  U_BOOT_ENV_CALLBACK(ipaddr, on_ipaddr);
  
  static int on_gatewayip(const char *name, const char *value, enum env_op op,
  	int flags)
  {
  	if (flags & H_PROGRAMMATIC)
  		return 0;
  
  	net_gateway = string_to_ip(value);
  
  	return 0;
  }
  U_BOOT_ENV_CALLBACK(gatewayip, on_gatewayip);
  
  static int on_netmask(const char *name, const char *value, enum env_op op,
  	int flags)
  {
  	if (flags & H_PROGRAMMATIC)
  		return 0;
  
  	net_netmask = string_to_ip(value);
  
  	return 0;
  }
  U_BOOT_ENV_CALLBACK(netmask, on_netmask);
  
  static int on_serverip(const char *name, const char *value, enum env_op op,
  	int flags)
  {
  	if (flags & H_PROGRAMMATIC)
  		return 0;
  
  	net_server_ip = string_to_ip(value);
  
  	return 0;
  }
  U_BOOT_ENV_CALLBACK(serverip, on_serverip);
  
  static int on_nvlan(const char *name, const char *value, enum env_op op,
  	int flags)
  {
  	if (flags & H_PROGRAMMATIC)
  		return 0;
  
  	net_native_vlan = string_to_vlan(value);
  
  	return 0;
  }
  U_BOOT_ENV_CALLBACK(nvlan, on_nvlan);
  
  static int on_vlan(const char *name, const char *value, enum env_op op,
  	int flags)
  {
  	if (flags & H_PROGRAMMATIC)
  		return 0;
  
  	net_our_vlan = string_to_vlan(value);
  
  	return 0;
  }
  U_BOOT_ENV_CALLBACK(vlan, on_vlan);
  
  #if defined(CONFIG_CMD_DNS)
  static int on_dnsip(const char *name, const char *value, enum env_op op,
  	int flags)
  {
  	if (flags & H_PROGRAMMATIC)
  		return 0;
  
  	net_dns_server = string_to_ip(value);
  
  	return 0;
  }
  U_BOOT_ENV_CALLBACK(dnsip, on_dnsip);
  #endif
e4a3d57dc   Simon Glass   net: Export auto_...
296
297
298
299
300
301
  /*
   * Check if autoload is enabled. If so, use either NFS or TFTP to download
   * the boot file.
   */
  void net_auto_load(void)
  {
ec8a252cd   Joe Hershberger   env: Use getenv_y...
302
  #if defined(CONFIG_CMD_NFS)
00caae6d4   Simon Glass   env: Rename geten...
303
  	const char *s = env_get("autoload");
e4a3d57dc   Simon Glass   net: Export auto_...
304

ec8a252cd   Joe Hershberger   env: Use getenv_y...
305
  	if (s != NULL && strcmp(s, "NFS") == 0) {
3855cad62   Joe Hershberger   net: Re-check pre...
306
307
308
309
310
311
312
313
314
315
316
  		if (net_check_prereq(NFS)) {
  /* We aren't expecting to get a serverip, so just accept the assigned IP */
  #ifdef CONFIG_BOOTP_SERVERIP
  			net_set_state(NETLOOP_SUCCESS);
  #else
  			printf("Cannot autoload with NFS
  ");
  			net_set_state(NETLOOP_FAIL);
  #endif
  			return;
  		}
ec8a252cd   Joe Hershberger   env: Use getenv_y...
317
318
319
  		/*
  		 * Use NFS to load the bootfile.
  		 */
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
320
  		nfs_start();
ec8a252cd   Joe Hershberger   env: Use getenv_y...
321
322
  		return;
  	}
e4a3d57dc   Simon Glass   net: Export auto_...
323
  #endif
bfebc8c96   Simon Glass   env: Rename geten...
324
  	if (env_get_yesno("autoload") == 0) {
ec8a252cd   Joe Hershberger   env: Use getenv_y...
325
326
327
328
329
330
  		/*
  		 * Just use BOOTP/RARP to configure system;
  		 * Do not use TFTP to load the bootfile.
  		 */
  		net_set_state(NETLOOP_SUCCESS);
  		return;
e4a3d57dc   Simon Glass   net: Export auto_...
331
  	}
3855cad62   Joe Hershberger   net: Re-check pre...
332
333
334
335
336
337
338
339
340
341
342
  	if (net_check_prereq(TFTPGET)) {
  /* We aren't expecting to get a serverip, so just accept the assigned IP */
  #ifdef CONFIG_BOOTP_SERVERIP
  		net_set_state(NETLOOP_SUCCESS);
  #else
  		printf("Cannot autoload with TFTPGET
  ");
  		net_set_state(NETLOOP_FAIL);
  #endif
  		return;
  	}
8885c5fe9   Joe Hershberger   net: cosmetic: Cl...
343
  	tftp_start(TFTPGET);
e4a3d57dc   Simon Glass   net: Export auto_...
344
  }
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
345
  static void net_init_loop(void)
2f70c49e5   Heiko Schocher   netloop: speed up...
346
  {
7315cfd9e   Jim Lin   NET: Fix system h...
347
  	if (eth_get_dev())
0adb5b761   Joe Hershberger   net: cosmetic: Na...
348
  		memcpy(net_ethaddr, eth_get_ethaddr(), 6);
3c172c4fd   Michael Zaidman   NetLoop initializ...
349

da95427ce   Heiko Schocher   netloop: updates ...
350
  	return;
2f70c49e5   Heiko Schocher   netloop: speed up...
351
  }
ece223b52   Joe Hershberger   net: Refactor to ...
352
353
354
355
  static void net_clear_handlers(void)
  {
  	net_set_udp_handler(NULL);
  	net_set_arp_handler(NULL);
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
356
  	net_set_timeout_handler(0, NULL);
ece223b52   Joe Hershberger   net: Refactor to ...
357
358
359
360
361
362
  }
  
  static void net_cleanup_loop(void)
  {
  	net_clear_handlers();
  }
46c495d52   Joe Hershberger   net: Fix net buff...
363
364
365
366
367
368
369
370
371
  void net_init(void)
  {
  	static int first_call = 1;
  
  	if (first_call) {
  		/*
  		 *	Setup packet buffers, aligned correctly.
  		 */
  		int i;
1203fccee   Joe Hershberger   net: cosmetic: Cl...
372
373
  		net_tx_packet = &net_pkt_buf[0] + (PKTALIGN - 1);
  		net_tx_packet -= (ulong)net_tx_packet % PKTALIGN;
2a504df00   Joe Hershberger   net: Clean up net...
374
  		for (i = 0; i < PKTBUFSRX; i++) {
1203fccee   Joe Hershberger   net: cosmetic: Cl...
375
376
  			net_rx_packets[i] = net_tx_packet +
  				(i + 1) * PKTSIZE_ALIGN;
2a504df00   Joe Hershberger   net: Clean up net...
377
  		}
85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
378
  		arp_init();
46c495d52   Joe Hershberger   net: Fix net buff...
379
380
381
382
383
  		net_clear_handlers();
  
  		/* Only need to setup buffer pointers once. */
  		first_call = 0;
  	}
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
384
  	net_init_loop();
46c495d52   Joe Hershberger   net: Fix net buff...
385
  }
73a8b27c5   wdenk   * Add support for...
386
  /**********************************************************************/
2d966958c   wdenk   Initial revision
387
388
389
  /*
   *	Main network processing loop.
   */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
390
  int net_loop(enum proto_t protocol)
2d966958c   wdenk   Initial revision
391
  {
60304592b   Joe Hershberger   net: Improve erro...
392
  	int ret = -EINVAL;
60177b261   Leonid Iziumtsev   net: Protect net_...
393
  	enum net_loop_state prev_net_state = net_state;
2d966958c   wdenk   Initial revision
394

bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
395
396
397
398
399
  	net_restarted = 0;
  	net_dev_exists = 0;
  	net_try_count = 1;
  	debug_cond(DEBUG_INT_STATE, "--- net_loop Entry
  ");
73a8b27c5   wdenk   * Add support for...
400

573f14fe4   Simon Glass   bootstage: Plumb ...
401
  	bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start");
46c495d52   Joe Hershberger   net: Fix net buff...
402
  	net_init();
f8be7d659   Joe Hershberger   net: Improve the ...
403
  	if (eth_is_on_demand_init() || protocol != NETCONS) {
b1bf6f2c9   wdenk   * Patch by Richar...
404
  		eth_halt();
f8be7d659   Joe Hershberger   net: Improve the ...
405
  		eth_set_current();
60304592b   Joe Hershberger   net: Improve erro...
406
407
  		ret = eth_init();
  		if (ret < 0) {
f8be7d659   Joe Hershberger   net: Improve the ...
408
  			eth_halt();
60304592b   Joe Hershberger   net: Improve erro...
409
  			return ret;
f8be7d659   Joe Hershberger   net: Improve the ...
410
  		}
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
411
  	} else {
d2eaec600   Joe Hershberger   net: Remove the b...
412
  		eth_init_state_only();
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
413
  	}
2d966958c   wdenk   Initial revision
414
  restart:
b63056d6a   Jim Lin   NET: Add net_busy...
415
416
417
  #ifdef CONFIG_USB_KEYBOARD
  	net_busy_flag = 0;
  #endif
22f6e99d5   Joe Hershberger   net: Refactor to ...
418
  	net_set_state(NETLOOP_CONTINUE);
2d966958c   wdenk   Initial revision
419
420
421
422
423
424
  
  	/*
  	 *	Start the ball rolling with the given start function.  From
  	 *	here on, this code is a state machine driven by received
  	 *	packets and timer events.
  	 */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
425
426
427
  	debug_cond(DEBUG_INT_STATE, "--- net_loop Init
  ");
  	net_init_loop();
2d966958c   wdenk   Initial revision
428

4f63acd06   Luca Ceresoli   net/net.c: cosmet...
429
  	switch (net_check_prereq(protocol)) {
2d966958c   wdenk   Initial revision
430
431
  	case 1:
  		/* network not configured */
b1bf6f2c9   wdenk   * Patch by Richar...
432
  		eth_halt();
60177b261   Leonid Iziumtsev   net: Protect net_...
433
  		net_set_state(prev_net_state);
60304592b   Joe Hershberger   net: Improve erro...
434
  		return -ENODEV;
2d966958c   wdenk   Initial revision
435

2d966958c   wdenk   Initial revision
436
437
438
  	case 2:
  		/* network device not configured */
  		break;
2d966958c   wdenk   Initial revision
439
440
  
  	case 0:
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
441
  		net_dev_exists = 1;
1411157d8   Joe Hershberger   net: cosmetic: Fi...
442
  		net_boot_file_size = 0;
2d966958c   wdenk   Initial revision
443
  		switch (protocol) {
e4bf0c5cf   Simon Glass   net: tftpput: Ren...
444
  		case TFTPGET:
1fb7cd498   Simon Glass   net: tftpput: imp...
445
446
447
  #ifdef CONFIG_CMD_TFTPPUT
  		case TFTPPUT:
  #endif
2d966958c   wdenk   Initial revision
448
  			/* always use ARP to get server ethernet address */
8885c5fe9   Joe Hershberger   net: cosmetic: Cl...
449
  			tftp_start(protocol);
2d966958c   wdenk   Initial revision
450
  			break;
7a83af07a   Luca Ceresoli   TFTP: add tftpsrv...
451
452
  #ifdef CONFIG_CMD_TFTPSRV
  		case TFTPSRV:
8885c5fe9   Joe Hershberger   net: cosmetic: Cl...
453
  			tftp_start_server();
7a83af07a   Luca Ceresoli   TFTP: add tftpsrv...
454
455
  			break;
  #endif
f73a7df98   Alex Kiernan   net: fastboot: Me...
456
457
458
459
460
  #ifdef CONFIG_UDP_FUNCTION_FASTBOOT
  		case FASTBOOT:
  			fastboot_start_server();
  			break;
  #endif
643d1ab23   Jon Loeliger   net/: Remove obso...
461
  #if defined(CONFIG_CMD_DHCP)
2d966958c   wdenk   Initial revision
462
  		case DHCP:
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
463
  			bootp_reset();
049a95a77   Joe Hershberger   net: cosmetic: Ch...
464
  			net_ip.s_addr = 0;
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
465
  			dhcp_request();		/* Basically same as BOOTP */
2d966958c   wdenk   Initial revision
466
  			break;
610f2e9c2   Jon Loeliger   net/: Remove ling...
467
  #endif
2d966958c   wdenk   Initial revision
468
469
  
  		case BOOTP:
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
470
  			bootp_reset();
049a95a77   Joe Hershberger   net: cosmetic: Ch...
471
  			net_ip.s_addr = 0;
7044c6bb6   Joe Hershberger   net: cosmetic: Cl...
472
  			bootp_request();
2d966958c   wdenk   Initial revision
473
  			break;
bf6cb247a   Peter Tyser   rarp: Condtionall...
474
  #if defined(CONFIG_CMD_RARP)
2d966958c   wdenk   Initial revision
475
  		case RARP:
698d78e54   Joe Hershberger   net: cosmetic: Cl...
476
  			rarp_try = 0;
049a95a77   Joe Hershberger   net: cosmetic: Ch...
477
  			net_ip.s_addr = 0;
698d78e54   Joe Hershberger   net: cosmetic: Cl...
478
  			rarp_request();
2d966958c   wdenk   Initial revision
479
  			break;
bf6cb247a   Peter Tyser   rarp: Condtionall...
480
  #endif
643d1ab23   Jon Loeliger   net/: Remove obso...
481
  #if defined(CONFIG_CMD_PING)
73a8b27c5   wdenk   * Add support for...
482
  		case PING:
a36b12f95   Joe Hershberger   net: Move PING ou...
483
  			ping_start();
73a8b27c5   wdenk   * Add support for...
484
485
  			break;
  #endif
643d1ab23   Jon Loeliger   net/: Remove obso...
486
  #if defined(CONFIG_CMD_NFS)
cbd8a35c6   wdenk   * Patch by Masami...
487
  		case NFS:
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
488
  			nfs_start();
cbd8a35c6   wdenk   * Patch by Masami...
489
490
  			break;
  #endif
643d1ab23   Jon Loeliger   net/: Remove obso...
491
  #if defined(CONFIG_CMD_CDP)
a3d991bd0   wdenk   Patches by Pantel...
492
  		case CDP:
6aede5b75   Joe Hershberger   net: cosmetic: Cl...
493
  			cdp_start();
a3d991bd0   wdenk   Patches by Pantel...
494
495
  			break;
  #endif
66c89ee31   Holger Dengler   net: Fix compile ...
496
  #if defined(CONFIG_NETCONSOLE) && !defined(CONFIG_SPL_BUILD)
68ceb29e7   wdenk   Add support for c...
497
  		case NETCONS:
6a38a5f3d   Joe Hershberger   net: cosmetic: Cl...
498
  			nc_start();
68ceb29e7   wdenk   Add support for c...
499
500
  			break;
  #endif
643d1ab23   Jon Loeliger   net/: Remove obso...
501
  #if defined(CONFIG_CMD_SNTP)
ea287debe   wdenk   * Patch by Masami...
502
  		case SNTP:
38ba25587   Joe Hershberger   net: cosmetic: Cl...
503
  			sntp_start();
ea287debe   wdenk   * Patch by Masami...
504
505
  			break;
  #endif
1a32bf418   Robin Getz   Add DNS support
506
507
  #if defined(CONFIG_CMD_DNS)
  		case DNS:
786eac5f9   Joe Hershberger   net: cosmetic: Cl...
508
  			dns_start();
1a32bf418   Robin Getz   Add DNS support
509
510
  			break;
  #endif
d22c338e0   Joe Hershberger   net: Add link-loc...
511
512
513
514
515
  #if defined(CONFIG_CMD_LINK_LOCAL)
  		case LINKLOCAL:
  			link_local_start();
  			break;
  #endif
d8970dae2   Lothar Felten   net: Add new wol ...
516
517
518
519
520
  #if defined(CONFIG_CMD_WOL)
  		case WOL:
  			wol_start();
  			break;
  #endif
2d966958c   wdenk   Initial revision
521
522
523
  		default:
  			break;
  		}
2d966958c   wdenk   Initial revision
524
525
  		break;
  	}
643d1ab23   Jon Loeliger   net/: Remove obso...
526
  #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
527
  #if	defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)	&& \
2d8d190c8   Uri Mashiach   status_led: Kconf...
528
529
  	defined(CONFIG_LED_STATUS)			&& \
  	defined(CONFIG_LED_STATUS_RED)
fc3e2165e   wdenk   * Patch by Sangmo...
530
  	/*
42d1f0394   wdenk   * Patches by Xian...
531
  	 * Echo the inverted link state to the fault LED.
fc3e2165e   wdenk   * Patch by Sangmo...
532
  	 */
d3c65b015   Luca Ceresoli   net/net.c: cosmet...
533
  	if (miiphy_link(eth_get_dev()->name, CONFIG_SYS_FAULT_MII_ADDR))
2d8d190c8   Uri Mashiach   status_led: Kconf...
534
  		status_led_set(CONFIG_LED_STATUS_RED, CONFIG_LED_STATUS_OFF);
d3c65b015   Luca Ceresoli   net/net.c: cosmet...
535
  	else
2d8d190c8   Uri Mashiach   status_led: Kconf...
536
  		status_led_set(CONFIG_LED_STATUS_RED, CONFIG_LED_STATUS_ON);
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
537
  #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */
fc3e2165e   wdenk   * Patch by Sangmo...
538
  #endif /* CONFIG_MII, ... */
b63056d6a   Jim Lin   NET: Add net_busy...
539
540
541
  #ifdef CONFIG_USB_KEYBOARD
  	net_busy_flag = 1;
  #endif
2d966958c   wdenk   Initial revision
542
543
544
  
  	/*
  	 *	Main packet reception loop.  Loop receiving packets until
22f6e99d5   Joe Hershberger   net: Refactor to ...
545
  	 *	someone sets `net_state' to a state that terminates.
2d966958c   wdenk   Initial revision
546
547
548
549
  	 */
  	for (;;) {
  		WATCHDOG_RESET();
  #ifdef CONFIG_SHOW_ACTIVITY
48522bb50   Joe Hershberger   net: cosmetic: ne...
550
  		show_activity(1);
2d966958c   wdenk   Initial revision
551
  #endif
c5a75339c   Joe Hershberger   net: Fix delay in...
552
553
  		if (arp_timeout_check() > 0)
  			time_start = get_timer(0);
2d966958c   wdenk   Initial revision
554
555
556
  		/*
  		 *	Check the ethernet for a new packet.  The ethernet
  		 *	receive routine will process it.
60304592b   Joe Hershberger   net: Improve erro...
557
558
  		 *	Most drivers return the most recent packet size, but not
  		 *	errors that may have happened.
2d966958c   wdenk   Initial revision
559
  		 */
40cb90ee2   Guennadi Liakhovetski   net: make ARP tim...
560
  		eth_rx();
2d966958c   wdenk   Initial revision
561
562
563
564
565
  
  		/*
  		 *	Abort if ctrl-c was pressed.
  		 */
  		if (ctrlc()) {
e94070c44   Joe Hershberger   net: Don't copy e...
566
  			/* cancel any ARP that may not have completed */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
567
  			net_arp_wait_packet_ip.s_addr = 0;
e94070c44   Joe Hershberger   net: Don't copy e...
568

ece223b52   Joe Hershberger   net: Refactor to ...
569
  			net_cleanup_loop();
8bde7f776   wdenk   * Code cleanup:
570
  			eth_halt();
f8be7d659   Joe Hershberger   net: Improve the ...
571
572
  			/* Invalidate the last protocol */
  			eth_set_last_protocol(BOOTP);
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
573
574
575
  			puts("
  Abort
  ");
4ef8d53ca   Joe Hershberger   net: Allow filter...
576
577
  			/* include a debug print as well incase the debug
  			   messages are directed to stderr */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
578
579
  			debug_cond(DEBUG_INT_STATE, "--- net_loop Abort!
  ");
19a4fbaad   Michal Simek   net: Return -EINT...
580
  			ret = -EINTR;
4793ee652   Simon Glass   net: tftpput: Add...
581
  			goto done;
2d966958c   wdenk   Initial revision
582
  		}
2d966958c   wdenk   Initial revision
583
584
585
586
  		/*
  		 *	Check for a timeout, and run the timeout handler
  		 *	if we have one.
  		 */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
587
588
  		if (time_handler &&
  		    ((get_timer(0) - time_start) > time_delta)) {
2d966958c   wdenk   Initial revision
589
  			thand_f *x;
643d1ab23   Jon Loeliger   net/: Remove obso...
590
  #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
591
  #if	defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)	&& \
2d8d190c8   Uri Mashiach   status_led: Kconf...
592
593
  	defined(CONFIG_LED_STATUS)			&& \
  	defined(CONFIG_LED_STATUS_RED)
fc3e2165e   wdenk   * Patch by Sangmo...
594
  			/*
42d1f0394   wdenk   * Patches by Xian...
595
  			 * Echo the inverted link state to the fault LED.
fc3e2165e   wdenk   * Patch by Sangmo...
596
  			 */
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
597
  			if (miiphy_link(eth_get_dev()->name,
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
598
  					CONFIG_SYS_FAULT_MII_ADDR))
2d8d190c8   Uri Mashiach   status_led: Kconf...
599
600
  				status_led_set(CONFIG_LED_STATUS_RED,
  					       CONFIG_LED_STATUS_OFF);
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
601
  			else
2d8d190c8   Uri Mashiach   status_led: Kconf...
602
603
  				status_led_set(CONFIG_LED_STATUS_RED,
  					       CONFIG_LED_STATUS_ON);
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
604
  #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */
fc3e2165e   wdenk   * Patch by Sangmo...
605
  #endif /* CONFIG_MII, ... */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
606
607
608
609
  			debug_cond(DEBUG_INT_STATE, "--- net_loop timeout
  ");
  			x = time_handler;
  			time_handler = (thand_f *)0;
2d966958c   wdenk   Initial revision
610
611
  			(*x)();
  		}
5c421331d   Joe Hershberger   net: Make netretr...
612
  		if (net_state == NETLOOP_FAIL)
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
613
  			ret = net_start_again();
2d966958c   wdenk   Initial revision
614

22f6e99d5   Joe Hershberger   net: Refactor to ...
615
  		switch (net_state) {
2d966958c   wdenk   Initial revision
616
  		case NETLOOP_RESTART:
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
617
  			net_restarted = 1;
2d966958c   wdenk   Initial revision
618
619
620
  			goto restart;
  
  		case NETLOOP_SUCCESS:
ece223b52   Joe Hershberger   net: Refactor to ...
621
  			net_cleanup_loop();
1411157d8   Joe Hershberger   net: cosmetic: Fi...
622
623
624
625
  			if (net_boot_file_size > 0) {
  				printf("Bytes transferred = %d (%x hex)
  ",
  				       net_boot_file_size, net_boot_file_size);
018f53032   Simon Glass   env: Rename commo...
626
627
  				env_set_hex("filesize", net_boot_file_size);
  				env_set_hex("fileaddr", load_addr);
2d966958c   wdenk   Initial revision
628
  			}
f8be7d659   Joe Hershberger   net: Improve the ...
629
630
631
632
633
634
  			if (protocol != NETCONS)
  				eth_halt();
  			else
  				eth_halt_state_only();
  
  			eth_set_last_protocol(protocol);
1411157d8   Joe Hershberger   net: cosmetic: Fi...
635
  			ret = net_boot_file_size;
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
636
637
  			debug_cond(DEBUG_INT_STATE, "--- net_loop Success!
  ");
4793ee652   Simon Glass   net: tftpput: Add...
638
  			goto done;
2d966958c   wdenk   Initial revision
639
640
  
  		case NETLOOP_FAIL:
ece223b52   Joe Hershberger   net: Refactor to ...
641
  			net_cleanup_loop();
f8be7d659   Joe Hershberger   net: Improve the ...
642
643
  			/* Invalidate the last protocol */
  			eth_set_last_protocol(BOOTP);
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
644
645
  			debug_cond(DEBUG_INT_STATE, "--- net_loop Fail!
  ");
a735e6e9d   Thomas RIENOESSL   net: explicitly a...
646
  			ret = -ENONET;
4793ee652   Simon Glass   net: tftpput: Add...
647
  			goto done;
22f6e99d5   Joe Hershberger   net: Refactor to ...
648
649
650
  
  		case NETLOOP_CONTINUE:
  			continue;
2d966958c   wdenk   Initial revision
651
652
  		}
  	}
4793ee652   Simon Glass   net: tftpput: Add...
653
654
  
  done:
b63056d6a   Jim Lin   NET: Add net_busy...
655
656
657
  #ifdef CONFIG_USB_KEYBOARD
  	net_busy_flag = 0;
  #endif
39bccd21d   Simon Glass   net: Hide more co...
658
  #ifdef CONFIG_CMD_TFTPPUT
4793ee652   Simon Glass   net: tftpput: Add...
659
  	/* Clear out the handlers */
ece223b52   Joe Hershberger   net: Refactor to ...
660
  	net_set_udp_handler(NULL);
4793ee652   Simon Glass   net: tftpput: Add...
661
  	net_set_icmp_handler(NULL);
39bccd21d   Simon Glass   net: Hide more co...
662
  #endif
60177b261   Leonid Iziumtsev   net: Protect net_...
663
  	net_set_state(prev_net_state);
4793ee652   Simon Glass   net: tftpput: Add...
664
  	return ret;
2d966958c   wdenk   Initial revision
665
666
667
  }
  
  /**********************************************************************/
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
668
  static void start_again_timeout_handler(void)
2d966958c   wdenk   Initial revision
669
  {
22f6e99d5   Joe Hershberger   net: Refactor to ...
670
  	net_set_state(NETLOOP_RESTART);
2d966958c   wdenk   Initial revision
671
  }
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
672
  int net_start_again(void)
2d966958c   wdenk   Initial revision
673
  {
6e5923851   wdenk   * Cleanup, minor ...
674
  	char *nretry;
67b96e87d   Remy Bohmer   Repair the 'netre...
675
676
  	int retry_forever = 0;
  	unsigned long retrycnt = 0;
60304592b   Joe Hershberger   net: Improve erro...
677
  	int ret;
67b96e87d   Remy Bohmer   Repair the 'netre...
678

00caae6d4   Simon Glass   env: Rename geten...
679
  	nretry = env_get("netretry");
67b96e87d   Remy Bohmer   Repair the 'netre...
680
681
682
683
684
685
686
687
688
  	if (nretry) {
  		if (!strcmp(nretry, "yes"))
  			retry_forever = 1;
  		else if (!strcmp(nretry, "no"))
  			retrycnt = 0;
  		else if (!strcmp(nretry, "once"))
  			retrycnt = 1;
  		else
  			retrycnt = simple_strtoul(nretry, NULL, 0);
5c421331d   Joe Hershberger   net: Make netretr...
689
690
691
692
  	} else {
  		retrycnt = 0;
  		retry_forever = 0;
  	}
67b96e87d   Remy Bohmer   Repair the 'netre...
693

17d413b25   Leonid Iziumtsev   net: Fix netretry...
694
  	if ((!retry_forever) && (net_try_count > retrycnt)) {
67b96e87d   Remy Bohmer   Repair the 'netre...
695
  		eth_halt();
22f6e99d5   Joe Hershberger   net: Refactor to ...
696
  		net_set_state(NETLOOP_FAIL);
60304592b   Joe Hershberger   net: Improve erro...
697
698
699
700
701
  		/*
  		 * We don't provide a way for the protocol to return an error,
  		 * but this is almost always the reason.
  		 */
  		return -ETIMEDOUT;
a3d991bd0   wdenk   Patches by Pantel...
702
  	}
67b96e87d   Remy Bohmer   Repair the 'netre...
703

bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
704
  	net_try_count++;
67b96e87d   Remy Bohmer   Repair the 'netre...
705

4f63acd06   Luca Ceresoli   net/net.c: cosmet...
706
  	eth_halt();
8b0c5c127   Matthias Fuchs   net: Add CONFIG_N...
707
  #if !defined(CONFIG_NET_DO_NOT_TRY_ANOTHER)
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
708
  	eth_try_another(!net_restarted);
8b0c5c127   Matthias Fuchs   net: Add CONFIG_N...
709
  #endif
60304592b   Joe Hershberger   net: Improve erro...
710
  	ret = eth_init();
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
711
712
713
714
715
  	if (net_restart_wrap) {
  		net_restart_wrap = 0;
  		if (net_dev_exists) {
  			net_set_timeout_handler(10000UL,
  						start_again_timeout_handler);
ece223b52   Joe Hershberger   net: Refactor to ...
716
  			net_set_udp_handler(NULL);
6e5923851   wdenk   * Cleanup, minor ...
717
  		} else {
22f6e99d5   Joe Hershberger   net: Refactor to ...
718
  			net_set_state(NETLOOP_FAIL);
2d966958c   wdenk   Initial revision
719
  		}
6e5923851   wdenk   * Cleanup, minor ...
720
  	} else {
22f6e99d5   Joe Hershberger   net: Refactor to ...
721
  		net_set_state(NETLOOP_RESTART);
2d966958c   wdenk   Initial revision
722
  	}
60304592b   Joe Hershberger   net: Improve erro...
723
  	return ret;
2d966958c   wdenk   Initial revision
724
725
726
727
728
729
  }
  
  /**********************************************************************/
  /*
   *	Miscelaneous bits.
   */
ece223b52   Joe Hershberger   net: Refactor to ...
730
  static void dummy_handler(uchar *pkt, unsigned dport,
049a95a77   Joe Hershberger   net: cosmetic: Ch...
731
  			struct in_addr sip, unsigned sport,
ece223b52   Joe Hershberger   net: Refactor to ...
732
  			unsigned len)
d280d3f43   Joe Hershberger   net: Move ARP out...
733
  {
d280d3f43   Joe Hershberger   net: Move ARP out...
734
  }
ece223b52   Joe Hershberger   net: Refactor to ...
735
736
737
738
  rxhand_f *net_get_udp_handler(void)
  {
  	return udp_packet_handler;
  }
d280d3f43   Joe Hershberger   net: Move ARP out...
739

ece223b52   Joe Hershberger   net: Refactor to ...
740
741
  void net_set_udp_handler(rxhand_f *f)
  {
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
742
743
  	debug_cond(DEBUG_INT_STATE, "--- net_loop UDP handler set (%p)
  ", f);
ece223b52   Joe Hershberger   net: Refactor to ...
744
745
746
747
748
749
750
  	if (f == NULL)
  		udp_packet_handler = dummy_handler;
  	else
  		udp_packet_handler = f;
  }
  
  rxhand_f *net_get_arp_handler(void)
2d966958c   wdenk   Initial revision
751
  {
ece223b52   Joe Hershberger   net: Refactor to ...
752
753
754
755
756
  	return arp_packet_handler;
  }
  
  void net_set_arp_handler(rxhand_f *f)
  {
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
757
758
  	debug_cond(DEBUG_INT_STATE, "--- net_loop ARP handler set (%p)
  ", f);
ece223b52   Joe Hershberger   net: Refactor to ...
759
760
761
762
  	if (f == NULL)
  		arp_packet_handler = dummy_handler;
  	else
  		arp_packet_handler = f;
2d966958c   wdenk   Initial revision
763
  }
39bccd21d   Simon Glass   net: Hide more co...
764
  #ifdef CONFIG_CMD_TFTPPUT
4793ee652   Simon Glass   net: tftpput: Add...
765
766
767
768
  void net_set_icmp_handler(rxhand_icmp_f *f)
  {
  	packet_icmp_handler = f;
  }
39bccd21d   Simon Glass   net: Hide more co...
769
  #endif
2d966958c   wdenk   Initial revision
770

bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
771
  void net_set_timeout_handler(ulong iv, thand_f *f)
2d966958c   wdenk   Initial revision
772
773
  {
  	if (iv == 0) {
4ef8d53ca   Joe Hershberger   net: Allow filter...
774
  		debug_cond(DEBUG_INT_STATE,
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
775
776
777
  			   "--- net_loop timeout handler cancelled
  ");
  		time_handler = (thand_f *)0;
2d966958c   wdenk   Initial revision
778
  	} else {
4ef8d53ca   Joe Hershberger   net: Allow filter...
779
  		debug_cond(DEBUG_INT_STATE,
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
780
781
782
783
784
  			   "--- net_loop timeout handler set (%p)
  ", f);
  		time_handler = f;
  		time_start = get_timer(0);
  		time_delta = iv * CONFIG_SYS_HZ / 1000;
2d966958c   wdenk   Initial revision
785
786
  	}
  }
ac3f26cc1   Joe Hershberger   net: Don't overwr...
787
788
789
790
791
792
793
  uchar *net_get_async_tx_pkt_buf(void)
  {
  	if (arp_is_waiting())
  		return arp_tx_packet; /* If we are waiting, we already sent */
  	else
  		return net_tx_packet;
  }
1203fccee   Joe Hershberger   net: cosmetic: Cl...
794
  int net_send_udp_packet(uchar *ether, struct in_addr dest, int dport, int sport,
206d07fd7   Joe Hershberger   net: cosmetic: Re...
795
  		int payload_len)
73a8b27c5   wdenk   * Add support for...
796
  {
5d457ecbe   Duncan Hare   net: Consolidate ...
797
798
799
800
801
802
803
804
  	return net_send_ip_packet(ether, dest, dport, sport, payload_len,
  				  IPPROTO_UDP, 0, 0, 0);
  }
  
  int net_send_ip_packet(uchar *ether, struct in_addr dest, int dport, int sport,
  		       int payload_len, int proto, u8 action, u32 tcp_seq_num,
  		       u32 tcp_ack_num)
  {
a3d991bd0   wdenk   Patches by Pantel...
805
  	uchar *pkt;
9214637a5   Joe Hershberger   net: Refactor Net...
806
807
  	int eth_hdr_size;
  	int pkt_hdr_size;
a3d991bd0   wdenk   Patches by Pantel...
808

bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
809
  	/* make sure the net_tx_packet is initialized (net_init() was called) */
1203fccee   Joe Hershberger   net: cosmetic: Cl...
810
811
  	assert(net_tx_packet != NULL);
  	if (net_tx_packet == NULL)
46c495d52   Joe Hershberger   net: Fix net buff...
812
  		return -1;
73a8b27c5   wdenk   * Add support for...
813
  	/* convert to new style broadcast */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
814
815
  	if (dest.s_addr == 0)
  		dest.s_addr = 0xFFFFFFFF;
73a8b27c5   wdenk   * Add support for...
816
817
  
  	/* if broadcast, make the ether address a broadcast and don't do ARP */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
818
  	if (dest.s_addr == 0xFFFFFFFF)
0adb5b761   Joe Hershberger   net: cosmetic: Na...
819
  		ether = (uchar *)net_bcast_ethaddr;
73a8b27c5   wdenk   * Add support for...
820

1203fccee   Joe Hershberger   net: cosmetic: Cl...
821
  	pkt = (uchar *)net_tx_packet;
9214637a5   Joe Hershberger   net: Refactor Net...
822

1203fccee   Joe Hershberger   net: cosmetic: Cl...
823
  	eth_hdr_size = net_set_ether(pkt, ether, PROT_IP);
5d457ecbe   Duncan Hare   net: Consolidate ...
824
825
826
827
828
829
830
831
832
833
  
  	switch (proto) {
  	case IPPROTO_UDP:
  		net_set_udp_header(pkt + eth_hdr_size, dest, dport, sport,
  				   payload_len);
  		pkt_hdr_size = eth_hdr_size + IP_UDP_HDR_SIZE;
  		break;
  	default:
  		return -EINVAL;
  	}
73a8b27c5   wdenk   * Add support for...
834

e94070c44   Joe Hershberger   net: Don't copy e...
835
  	/* if MAC address was not discovered yet, do an ARP request */
0adb5b761   Joe Hershberger   net: cosmetic: Na...
836
  	if (memcmp(ether, net_null_ethaddr, 6) == 0) {
4ef8d53ca   Joe Hershberger   net: Allow filter...
837
838
  		debug_cond(DEBUG_DEV_PKT, "sending ARP for %pI4
  ", &dest);
0ebf04c60   Robin Getz   minor debug clean...
839

9214637a5   Joe Hershberger   net: Refactor Net...
840
  		/* save the ip and eth addr for the packet to send after arp */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
841
  		net_arp_wait_packet_ip = dest;
85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
842
  		arp_wait_packet_ethaddr = ether;
a3d991bd0   wdenk   Patches by Pantel...
843

73a8b27c5   wdenk   * Add support for...
844
  		/* size of the waiting packet */
85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
845
  		arp_wait_tx_packet_size = pkt_hdr_size + payload_len;
73a8b27c5   wdenk   * Add support for...
846
847
  
  		/* and do the ARP request */
85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
848
849
850
  		arp_wait_try = 1;
  		arp_wait_timer_start = get_timer(0);
  		arp_request();
73a8b27c5   wdenk   * Add support for...
851
  		return 1;	/* waiting */
9214637a5   Joe Hershberger   net: Refactor Net...
852
  	} else {
4ef8d53ca   Joe Hershberger   net: Allow filter...
853
854
  		debug_cond(DEBUG_DEV_PKT, "sending UDP to %pI4/%pM
  ",
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
855
  			   &dest, ether);
1203fccee   Joe Hershberger   net: cosmetic: Cl...
856
  		net_send_packet(net_tx_packet, pkt_hdr_size + payload_len);
9214637a5   Joe Hershberger   net: Refactor Net...
857
  		return 0;	/* transmitted */
73a8b27c5   wdenk   * Add support for...
858
  	}
73a8b27c5   wdenk   * Add support for...
859
  }
5cfaa4e54   Alessandro Rubini   net: defragment I...
860
861
862
863
864
865
866
867
868
  #ifdef CONFIG_IP_DEFRAG
  /*
   * This function collects fragments in a single packet, according
   * to the algorithm in RFC815. It returns NULL or the pointer to
   * a complete packet, in static storage
   */
  #ifndef CONFIG_NET_MAXDEFRAG
  #define CONFIG_NET_MAXDEFRAG 16384
  #endif
aa7a64874   Joe Hershberger   net: Stop includi...
869
  #define IP_PKTSIZE (CONFIG_NET_MAXDEFRAG)
5cfaa4e54   Alessandro Rubini   net: defragment I...
870

c5c59df04   Joe Hershberger   net: cosmetic: Sp...
871
  #define IP_MAXUDP (IP_PKTSIZE - IP_HDR_SIZE)
5cfaa4e54   Alessandro Rubini   net: defragment I...
872
873
874
875
876
877
878
879
880
881
882
883
  
  /*
   * this is the packet being assembled, either data or frag control.
   * Fragments go by 8 bytes, so this union must be 8 bytes long
   */
  struct hole {
  	/* first_byte is address of this structure */
  	u16 last_byte;	/* last byte in this hole + 1 (begin of next hole) */
  	u16 next_hole;	/* index of next (in 8-b blocks), 0 == none */
  	u16 prev_hole;	/* index of prev, 0 == none */
  	u16 unused;
  };
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
884
  static struct ip_udp_hdr *__net_defragment(struct ip_udp_hdr *ip, int *lenp)
5cfaa4e54   Alessandro Rubini   net: defragment I...
885
  {
48522bb50   Joe Hershberger   net: cosmetic: ne...
886
  	static uchar pkt_buff[IP_PKTSIZE] __aligned(PKTALIGN);
5cfaa4e54   Alessandro Rubini   net: defragment I...
887
888
  	static u16 first_hole, total_len;
  	struct hole *payload, *thisfrag, *h, *newh;
594c26f8a   Joe Hershberger   net: cosmetic: Un...
889
  	struct ip_udp_hdr *localip = (struct ip_udp_hdr *)pkt_buff;
5cfaa4e54   Alessandro Rubini   net: defragment I...
890
891
892
893
894
  	uchar *indata = (uchar *)ip;
  	int offset8, start, len, done = 0;
  	u16 ip_off = ntohs(ip->ip_off);
  
  	/* payload starts after IP header, this fragment is in there */
c5c59df04   Joe Hershberger   net: cosmetic: Sp...
895
  	payload = (struct hole *)(pkt_buff + IP_HDR_SIZE);
5cfaa4e54   Alessandro Rubini   net: defragment I...
896
897
898
  	offset8 =  (ip_off & IP_OFFS);
  	thisfrag = payload + offset8;
  	start = offset8 * 8;
c5c59df04   Joe Hershberger   net: cosmetic: Sp...
899
  	len = ntohs(ip->ip_len) - IP_HDR_SIZE;
5cfaa4e54   Alessandro Rubini   net: defragment I...
900
901
902
903
904
905
906
907
908
909
910
911
  
  	if (start + len > IP_MAXUDP) /* fragment extends too far */
  		return NULL;
  
  	if (!total_len || localip->ip_id != ip->ip_id) {
  		/* new (or different) packet, reset structs */
  		total_len = 0xffff;
  		payload[0].last_byte = ~0;
  		payload[0].next_hole = 0;
  		payload[0].prev_hole = 0;
  		first_hole = 0;
  		/* any IP header will work, copy the first we received */
c5c59df04   Joe Hershberger   net: cosmetic: Sp...
912
  		memcpy(localip, ip, IP_HDR_SIZE);
5cfaa4e54   Alessandro Rubini   net: defragment I...
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
  	}
  
  	/*
  	 * What follows is the reassembly algorithm. We use the payload
  	 * array as a linked list of hole descriptors, as each hole starts
  	 * at a multiple of 8 bytes. However, last byte can be whatever value,
  	 * so it is represented as byte count, not as 8-byte blocks.
  	 */
  
  	h = payload + first_hole;
  	while (h->last_byte < start) {
  		if (!h->next_hole) {
  			/* no hole that far away */
  			return NULL;
  		}
  		h = payload + h->next_hole;
  	}
e397e59e8   Fillod Stephane   ip/defrag: fix pr...
930
931
  	/* last fragment may be 1..7 bytes, the "+7" forces acceptance */
  	if (offset8 + ((len + 7) / 8) <= h - payload) {
5cfaa4e54   Alessandro Rubini   net: defragment I...
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
  		/* no overlap with holes (dup fragment?) */
  		return NULL;
  	}
  
  	if (!(ip_off & IP_FLAGS_MFRAG)) {
  		/* no more fragmentss: truncate this (last) hole */
  		total_len = start + len;
  		h->last_byte = start + len;
  	}
  
  	/*
  	 * There is some overlap: fix the hole list. This code doesn't
  	 * deal with a fragment that overlaps with two different holes
  	 * (thus being a superset of a previously-received fragment).
  	 */
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
947
  	if ((h >= thisfrag) && (h->last_byte <= start + len)) {
5cfaa4e54   Alessandro Rubini   net: defragment I...
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
  		/* complete overlap with hole: remove hole */
  		if (!h->prev_hole && !h->next_hole) {
  			/* last remaining hole */
  			done = 1;
  		} else if (!h->prev_hole) {
  			/* first hole */
  			first_hole = h->next_hole;
  			payload[h->next_hole].prev_hole = 0;
  		} else if (!h->next_hole) {
  			/* last hole */
  			payload[h->prev_hole].next_hole = 0;
  		} else {
  			/* in the middle of the list */
  			payload[h->next_hole].prev_hole = h->prev_hole;
  			payload[h->prev_hole].next_hole = h->next_hole;
  		}
  
  	} else if (h->last_byte <= start + len) {
  		/* overlaps with final part of the hole: shorten this hole */
  		h->last_byte = start;
  
  	} else if (h >= thisfrag) {
  		/* overlaps with initial part of the hole: move this hole */
  		newh = thisfrag + (len / 8);
  		*newh = *h;
  		h = newh;
  		if (h->next_hole)
  			payload[h->next_hole].prev_hole = (h - payload);
  		if (h->prev_hole)
  			payload[h->prev_hole].next_hole = (h - payload);
  		else
  			first_hole = (h - payload);
  
  	} else {
  		/* fragment sits in the middle: split the hole */
  		newh = thisfrag + (len / 8);
  		*newh = *h;
  		h->last_byte = start;
  		h->next_hole = (newh - payload);
  		newh->prev_hole = (h - payload);
  		if (newh->next_hole)
  			payload[newh->next_hole].prev_hole = (newh - payload);
  	}
  
  	/* finally copy this fragment and possibly return whole packet */
c5c59df04   Joe Hershberger   net: cosmetic: Sp...
993
  	memcpy((uchar *)thisfrag, indata + IP_HDR_SIZE, len);
5cfaa4e54   Alessandro Rubini   net: defragment I...
994
995
996
997
  	if (!done)
  		return NULL;
  
  	localip->ip_len = htons(total_len);
c5c59df04   Joe Hershberger   net: cosmetic: Sp...
998
  	*lenp = total_len + IP_HDR_SIZE;
5cfaa4e54   Alessandro Rubini   net: defragment I...
999
1000
  	return localip;
  }
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1001
1002
  static inline struct ip_udp_hdr *net_defragment(struct ip_udp_hdr *ip,
  	int *lenp)
5cfaa4e54   Alessandro Rubini   net: defragment I...
1003
1004
1005
1006
  {
  	u16 ip_off = ntohs(ip->ip_off);
  	if (!(ip_off & (IP_OFFS | IP_FLAGS_MFRAG)))
  		return ip; /* not a fragment */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1007
  	return __net_defragment(ip, lenp);
5cfaa4e54   Alessandro Rubini   net: defragment I...
1008
1009
1010
  }
  
  #else /* !CONFIG_IP_DEFRAG */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1011
1012
  static inline struct ip_udp_hdr *net_defragment(struct ip_udp_hdr *ip,
  	int *lenp)
5cfaa4e54   Alessandro Rubini   net: defragment I...
1013
1014
1015
1016
1017
1018
1019
  {
  	u16 ip_off = ntohs(ip->ip_off);
  	if (!(ip_off & (IP_OFFS | IP_FLAGS_MFRAG)))
  		return ip; /* not a fragment */
  	return NULL;
  }
  #endif
a3d991bd0   wdenk   Patches by Pantel...
1020

8f79bb17a   Simon Glass   net: tftpput: Mov...
1021
1022
1023
1024
1025
1026
  /**
   * Receive an ICMP packet. We deal with REDIRECT and PING here, and silently
   * drop others.
   *
   * @parma ip	IP packet containing the ICMP
   */
594c26f8a   Joe Hershberger   net: cosmetic: Un...
1027
  static void receive_icmp(struct ip_udp_hdr *ip, int len,
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1028
  			struct in_addr src_ip, struct ethernet_hdr *et)
8f79bb17a   Simon Glass   net: tftpput: Mov...
1029
  {
e0a630795   Joe Hershberger   net: cosmetic: Un...
1030
  	struct icmp_hdr *icmph = (struct icmp_hdr *)&ip->udp_src;
8f79bb17a   Simon Glass   net: tftpput: Mov...
1031
1032
1033
1034
1035
1036
  
  	switch (icmph->type) {
  	case ICMP_REDIRECT:
  		if (icmph->code != ICMP_REDIR_HOST)
  			return;
  		printf(" ICMP Host Redirect to %pI4 ",
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1037
  		       &icmph->un.gateway);
8f79bb17a   Simon Glass   net: tftpput: Mov...
1038
  		break;
a36b12f95   Joe Hershberger   net: Move PING ou...
1039
  	default:
8f79bb17a   Simon Glass   net: tftpput: Mov...
1040
  #if defined(CONFIG_CMD_PING)
a36b12f95   Joe Hershberger   net: Move PING ou...
1041
  		ping_receive(et, ip, len);
8f79bb17a   Simon Glass   net: tftpput: Mov...
1042
  #endif
39bccd21d   Simon Glass   net: Hide more co...
1043
  #ifdef CONFIG_CMD_TFTPPUT
4793ee652   Simon Glass   net: tftpput: Add...
1044
1045
  		if (packet_icmp_handler)
  			packet_icmp_handler(icmph->type, icmph->code,
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1046
1047
1048
  					    ntohs(ip->udp_dst), src_ip,
  					    ntohs(ip->udp_src), icmph->un.data,
  					    ntohs(ip->udp_len));
39bccd21d   Simon Glass   net: Hide more co...
1049
  #endif
8f79bb17a   Simon Glass   net: tftpput: Mov...
1050
1051
1052
  		break;
  	}
  }
2a504df00   Joe Hershberger   net: Clean up net...
1053
  void net_process_received_packet(uchar *in_packet, int len)
2d966958c   wdenk   Initial revision
1054
  {
cb487f566   Joe Hershberger   net: cosmetic: Un...
1055
  	struct ethernet_hdr *et;
594c26f8a   Joe Hershberger   net: cosmetic: Un...
1056
  	struct ip_udp_hdr *ip;
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1057
1058
  	struct in_addr dst_ip;
  	struct in_addr src_ip;
8d353eb86   Joe Hershberger   net: cosmetic: Re...
1059
  	int eth_proto;
643d1ab23   Jon Loeliger   net/: Remove obso...
1060
  #if defined(CONFIG_CMD_CDP)
a3d991bd0   wdenk   Patches by Pantel...
1061
1062
1063
  	int iscdp;
  #endif
  	ushort cti = 0, vlanid = VLAN_NONE, myvlanid, mynvlanid;
4ef8d53ca   Joe Hershberger   net: Allow filter...
1064
1065
  	debug_cond(DEBUG_NET_PKT, "packet received
  ");
2d966958c   wdenk   Initial revision
1066

1203fccee   Joe Hershberger   net: cosmetic: Cl...
1067
1068
  	net_rx_packet = in_packet;
  	net_rx_packet_len = len;
2a504df00   Joe Hershberger   net: Clean up net...
1069
  	et = (struct ethernet_hdr *)in_packet;
a3d991bd0   wdenk   Patches by Pantel...
1070
1071
1072
1073
  
  	/* too small packet? */
  	if (len < ETHER_HDR_SIZE)
  		return;
0efe1bcf5   Alexander Graf   efi_loader: Add n...
1074
  #if defined(CONFIG_API) || defined(CONFIG_EFI_LOADER)
f85b60710   Rafal Jaworowski   Introduce new eth...
1075
  	if (push_packet) {
2a504df00   Joe Hershberger   net: Clean up net...
1076
  		(*push_packet)(in_packet, len);
f85b60710   Rafal Jaworowski   Introduce new eth...
1077
1078
1079
  		return;
  	}
  #endif
643d1ab23   Jon Loeliger   net/: Remove obso...
1080
  #if defined(CONFIG_CMD_CDP)
a3d991bd0   wdenk   Patches by Pantel...
1081
  	/* keep track if packet is CDP */
173518832   Joe Hershberger   net: Encapsulate ...
1082
  	iscdp = is_cdp_packet(et->et_dest);
a3d991bd0   wdenk   Patches by Pantel...
1083
  #endif
4fd5055f5   Joe Hershberger   net: cosmetic: Cl...
1084
  	myvlanid = ntohs(net_our_vlan);
a3d991bd0   wdenk   Patches by Pantel...
1085
1086
  	if (myvlanid == (ushort)-1)
  		myvlanid = VLAN_NONE;
4fd5055f5   Joe Hershberger   net: cosmetic: Cl...
1087
  	mynvlanid = ntohs(net_native_vlan);
a3d991bd0   wdenk   Patches by Pantel...
1088
1089
  	if (mynvlanid == (ushort)-1)
  		mynvlanid = VLAN_NONE;
2d966958c   wdenk   Initial revision
1090

8d353eb86   Joe Hershberger   net: cosmetic: Re...
1091
  	eth_proto = ntohs(et->et_protlen);
2d966958c   wdenk   Initial revision
1092

8d353eb86   Joe Hershberger   net: cosmetic: Re...
1093
  	if (eth_proto < 1514) {
cb487f566   Joe Hershberger   net: cosmetic: Un...
1094
  		struct e802_hdr *et802 = (struct e802_hdr *)et;
2d966958c   wdenk   Initial revision
1095
  		/*
da5ebe2c9   Joe Hershberger   net: cosmetic: Ad...
1096
1097
  		 *	Got a 802.2 packet.  Check the other protocol field.
  		 *	XXX VLAN over 802.2+SNAP not implemented!
2d966958c   wdenk   Initial revision
1098
  		 */
8d353eb86   Joe Hershberger   net: cosmetic: Re...
1099
  		eth_proto = ntohs(et802->et_prot);
a3d991bd0   wdenk   Patches by Pantel...
1100

2a504df00   Joe Hershberger   net: Clean up net...
1101
  		ip = (struct ip_udp_hdr *)(in_packet + E802_HDR_SIZE);
2d966958c   wdenk   Initial revision
1102
  		len -= E802_HDR_SIZE;
a3d991bd0   wdenk   Patches by Pantel...
1103

8d353eb86   Joe Hershberger   net: cosmetic: Re...
1104
  	} else if (eth_proto != PROT_VLAN) {	/* normal packet */
2a504df00   Joe Hershberger   net: Clean up net...
1105
  		ip = (struct ip_udp_hdr *)(in_packet + ETHER_HDR_SIZE);
2d966958c   wdenk   Initial revision
1106
  		len -= ETHER_HDR_SIZE;
a3d991bd0   wdenk   Patches by Pantel...
1107
1108
  
  	} else {			/* VLAN packet */
c68cca35b   Joe Hershberger   net: cosmetic: Un...
1109
1110
  		struct vlan_ethernet_hdr *vet =
  			(struct vlan_ethernet_hdr *)et;
a3d991bd0   wdenk   Patches by Pantel...
1111

4ef8d53ca   Joe Hershberger   net: Allow filter...
1112
1113
  		debug_cond(DEBUG_NET_PKT, "VLAN packet received
  ");
0ebf04c60   Robin Getz   minor debug clean...
1114

a3d991bd0   wdenk   Patches by Pantel...
1115
1116
1117
1118
1119
  		/* too small packet? */
  		if (len < VLAN_ETHER_HDR_SIZE)
  			return;
  
  		/* if no VLAN active */
4fd5055f5   Joe Hershberger   net: cosmetic: Cl...
1120
  		if ((ntohs(net_our_vlan) & VLAN_IDMASK) == VLAN_NONE
643d1ab23   Jon Loeliger   net/: Remove obso...
1121
  #if defined(CONFIG_CMD_CDP)
a3d991bd0   wdenk   Patches by Pantel...
1122
1123
1124
1125
1126
1127
1128
  				&& iscdp == 0
  #endif
  				)
  			return;
  
  		cti = ntohs(vet->vet_tag);
  		vlanid = cti & VLAN_IDMASK;
8d353eb86   Joe Hershberger   net: cosmetic: Re...
1129
  		eth_proto = ntohs(vet->vet_type);
a3d991bd0   wdenk   Patches by Pantel...
1130

2a504df00   Joe Hershberger   net: Clean up net...
1131
  		ip = (struct ip_udp_hdr *)(in_packet + VLAN_ETHER_HDR_SIZE);
a3d991bd0   wdenk   Patches by Pantel...
1132
  		len -= VLAN_ETHER_HDR_SIZE;
2d966958c   wdenk   Initial revision
1133
  	}
4ef8d53ca   Joe Hershberger   net: Allow filter...
1134
1135
  	debug_cond(DEBUG_NET_PKT, "Receive from protocol 0x%x
  ", eth_proto);
2d966958c   wdenk   Initial revision
1136

643d1ab23   Jon Loeliger   net/: Remove obso...
1137
  #if defined(CONFIG_CMD_CDP)
a3d991bd0   wdenk   Patches by Pantel...
1138
  	if (iscdp) {
0b4c5ff4a   Joe Hershberger   net: cosmetic: Re...
1139
  		cdp_receive((uchar *)ip, len);
a3d991bd0   wdenk   Patches by Pantel...
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
  		return;
  	}
  #endif
  
  	if ((myvlanid & VLAN_IDMASK) != VLAN_NONE) {
  		if (vlanid == VLAN_NONE)
  			vlanid = (mynvlanid & VLAN_IDMASK);
  		/* not matched? */
  		if (vlanid != (myvlanid & VLAN_IDMASK))
  			return;
  	}
8d353eb86   Joe Hershberger   net: cosmetic: Re...
1151
  	switch (eth_proto) {
2d966958c   wdenk   Initial revision
1152
  	case PROT_ARP:
85d25e0e7   Joe Hershberger   net: cosmetic: Cl...
1153
  		arp_receive(et, ip, len);
289f932c5   wdenk   * Some Cleanup.
1154
  		break;
2d966958c   wdenk   Initial revision
1155

bf6cb247a   Peter Tyser   rarp: Condtionall...
1156
  #ifdef CONFIG_CMD_RARP
2d966958c   wdenk   Initial revision
1157
  	case PROT_RARP:
8b9c53221   Joe Hershberger   net: Move RARP re...
1158
  		rarp_receive(ip, len);
2d966958c   wdenk   Initial revision
1159
  		break;
bf6cb247a   Peter Tyser   rarp: Condtionall...
1160
  #endif
2d966958c   wdenk   Initial revision
1161
  	case PROT_IP:
4ef8d53ca   Joe Hershberger   net: Allow filter...
1162
1163
  		debug_cond(DEBUG_NET_PKT, "Got IP
  ");
5cfaa4e54   Alessandro Rubini   net: defragment I...
1164
  		/* Before we start poking the header, make sure it is there */
594c26f8a   Joe Hershberger   net: cosmetic: Un...
1165
1166
1167
  		if (len < IP_UDP_HDR_SIZE) {
  			debug("len bad %d < %lu
  ", len,
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1168
  			      (ulong)IP_UDP_HDR_SIZE);
2d966958c   wdenk   Initial revision
1169
1170
  			return;
  		}
5cfaa4e54   Alessandro Rubini   net: defragment I...
1171
  		/* Check the packet length */
2d966958c   wdenk   Initial revision
1172
  		if (len < ntohs(ip->ip_len)) {
4ef8d53ca   Joe Hershberger   net: Allow filter...
1173
1174
  			debug("len bad %d < %d
  ", len, ntohs(ip->ip_len));
2d966958c   wdenk   Initial revision
1175
1176
1177
  			return;
  		}
  		len = ntohs(ip->ip_len);
4ef8d53ca   Joe Hershberger   net: Allow filter...
1178
1179
  		debug_cond(DEBUG_NET_PKT, "len=%d, v=%02x
  ",
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1180
  			   len, ip->ip_hl_v & 0xff);
0ebf04c60   Robin Getz   minor debug clean...
1181

5cfaa4e54   Alessandro Rubini   net: defragment I...
1182
  		/* Can't deal with anything except IPv4 */
d3c65b015   Luca Ceresoli   net/net.c: cosmet...
1183
  		if ((ip->ip_hl_v & 0xf0) != 0x40)
2d966958c   wdenk   Initial revision
1184
  			return;
5cfaa4e54   Alessandro Rubini   net: defragment I...
1185
  		/* Can't deal with IP options (headers != 20 bytes) */
d3c65b015   Luca Ceresoli   net/net.c: cosmet...
1186
  		if ((ip->ip_hl_v & 0x0f) > 0x05)
6b52cfe16   Remy Bohmer   Get rid of annoyi...
1187
  			return;
5cfaa4e54   Alessandro Rubini   net: defragment I...
1188
  		/* Check the Checksum of the header */
0da0fcd51   Simon Glass   net: Use new chec...
1189
  		if (!ip_checksum_ok((uchar *)ip, IP_HDR_SIZE)) {
4ef8d53ca   Joe Hershberger   net: Allow filter...
1190
1191
  			debug("checksum bad
  ");
2d966958c   wdenk   Initial revision
1192
1193
  			return;
  		}
5cfaa4e54   Alessandro Rubini   net: defragment I...
1194
  		/* If it is not for us, ignore it */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1195
1196
1197
  		dst_ip = net_read_ip(&ip->ip_dst);
  		if (net_ip.s_addr && dst_ip.s_addr != net_ip.s_addr &&
  		    dst_ip.s_addr != 0xFFFFFFFF) {
c819abeef   Luca Ceresoli   net/net.c: cosmet...
1198
  				return;
2d966958c   wdenk   Initial revision
1199
  		}
03eb129f8   Luca Ceresoli   NET: pass source ...
1200
  		/* Read source IP address for later use */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1201
  		src_ip = net_read_ip(&ip->ip_src);
2d966958c   wdenk   Initial revision
1202
  		/*
5cfaa4e54   Alessandro Rubini   net: defragment I...
1203
1204
1205
1206
  		 * The function returns the unchanged packet if it's not
  		 * a fragment, and either the complete packet or NULL if
  		 * it is a fragment (if !CONFIG_IP_DEFRAG, it returns NULL)
  		 */
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1207
  		ip = net_defragment(ip, &len);
ccb9ebefb   Luca Ceresoli   net/net.c: cosmet...
1208
  		if (!ip)
5cfaa4e54   Alessandro Rubini   net: defragment I...
1209
1210
  			return;
  		/*
2d966958c   wdenk   Initial revision
1211
1212
  		 * watch for ICMP host redirects
  		 *
8bde7f776   wdenk   * Code cleanup:
1213
1214
1215
1216
1217
  		 * There is no real handler code (yet). We just watch
  		 * for ICMP host redirect messages. In case anybody
  		 * sees these messages: please contact me
  		 * (wd@denx.de), or - even better - send me the
  		 * necessary fixes :-)
2d966958c   wdenk   Initial revision
1218
  		 *
8bde7f776   wdenk   * Code cleanup:
1219
1220
1221
1222
1223
1224
1225
  		 * Note: in all cases where I have seen this so far
  		 * it was a problem with the router configuration,
  		 * for instance when a router was configured in the
  		 * BOOTP reply, but the TFTP server was on the same
  		 * subnet. So this is probably a warning that your
  		 * configuration might be wrong. But I'm not really
  		 * sure if there aren't any other situations.
4793ee652   Simon Glass   net: tftpput: Add...
1226
1227
1228
1229
  		 *
  		 * Simon Glass <sjg@chromium.org>: We get an ICMP when
  		 * we send a tftp packet to a dead connection, or when
  		 * there is no server at the other end.
2d966958c   wdenk   Initial revision
1230
1231
  		 */
  		if (ip->ip_p == IPPROTO_ICMP) {
8f79bb17a   Simon Glass   net: tftpput: Mov...
1232
1233
  			receive_icmp(ip, len, src_ip, et);
  			return;
2d966958c   wdenk   Initial revision
1234
1235
1236
  		} else if (ip->ip_p != IPPROTO_UDP) {	/* Only UDP packets */
  			return;
  		}
4ef8d53ca   Joe Hershberger   net: Allow filter...
1237
  		debug_cond(DEBUG_DEV_PKT,
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1238
1239
1240
  			   "received UDP (to=%pI4, from=%pI4, len=%d)
  ",
  			   &dst_ip, &src_ip, len);
4ef8d53ca   Joe Hershberger   net: Allow filter...
1241

8534bf9ac   Stefan Roese   Add UPD-Checksum ...
1242
1243
  #ifdef CONFIG_UDP_CHECKSUM
  		if (ip->udp_xsum != 0) {
b2f508075   Wolfgang Denk   Minor code cleanup
1244
  			ulong   xsum;
8534bf9ac   Stefan Roese   Add UPD-Checksum ...
1245
1246
1247
1248
1249
  			ushort *sumptr;
  			ushort  sumlen;
  
  			xsum  = ip->ip_p;
  			xsum += (ntohs(ip->udp_len));
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1250
1251
1252
1253
  			xsum += (ntohl(ip->ip_src.s_addr) >> 16) & 0x0000ffff;
  			xsum += (ntohl(ip->ip_src.s_addr) >>  0) & 0x0000ffff;
  			xsum += (ntohl(ip->ip_dst.s_addr) >> 16) & 0x0000ffff;
  			xsum += (ntohl(ip->ip_dst.s_addr) >>  0) & 0x0000ffff;
8534bf9ac   Stefan Roese   Add UPD-Checksum ...
1254
1255
  
  			sumlen = ntohs(ip->udp_len);
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1256
  			sumptr = (ushort *)&(ip->udp_src);
8534bf9ac   Stefan Roese   Add UPD-Checksum ...
1257
1258
  
  			while (sumlen > 1) {
b2f508075   Wolfgang Denk   Minor code cleanup
1259
  				ushort sumdata;
8534bf9ac   Stefan Roese   Add UPD-Checksum ...
1260
1261
1262
1263
1264
1265
  
  				sumdata = *sumptr++;
  				xsum += ntohs(sumdata);
  				sumlen -= 2;
  			}
  			if (sumlen > 0) {
b2f508075   Wolfgang Denk   Minor code cleanup
1266
  				ushort sumdata;
8534bf9ac   Stefan Roese   Add UPD-Checksum ...
1267

bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1268
  				sumdata = *(unsigned char *)sumptr;
b2f508075   Wolfgang Denk   Minor code cleanup
1269
  				sumdata = (sumdata << 8) & 0xff00;
8534bf9ac   Stefan Roese   Add UPD-Checksum ...
1270
1271
1272
  				xsum += sumdata;
  			}
  			while ((xsum >> 16) != 0) {
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
1273
1274
  				xsum = (xsum & 0x0000ffff) +
  				       ((xsum >> 16) & 0x0000ffff);
8534bf9ac   Stefan Roese   Add UPD-Checksum ...
1275
1276
  			}
  			if ((xsum != 0x00000000) && (xsum != 0x0000ffff)) {
9b55a2536   Wolfgang Denk   Fix some more pri...
1277
1278
  				printf(" UDP wrong checksum %08lx %08x
  ",
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1279
  				       xsum, ntohs(ip->udp_xsum));
8534bf9ac   Stefan Roese   Add UPD-Checksum ...
1280
1281
1282
1283
  				return;
  			}
  		}
  #endif
66c89ee31   Holger Dengler   net: Fix compile ...
1284
  #if defined(CONFIG_NETCONSOLE) && !defined(CONFIG_SPL_BUILD)
594c26f8a   Joe Hershberger   net: cosmetic: Un...
1285
  		nc_input_packet((uchar *)ip + IP_UDP_HDR_SIZE,
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1286
1287
1288
1289
  				src_ip,
  				ntohs(ip->udp_dst),
  				ntohs(ip->udp_src),
  				ntohs(ip->udp_len) - UDP_HDR_SIZE);
68ceb29e7   wdenk   Add support for c...
1290
  #endif
2d966958c   wdenk   Initial revision
1291
  		/*
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1292
  		 * IP header OK.  Pass the packet to the current handler.
2d966958c   wdenk   Initial revision
1293
  		 */
ece223b52   Joe Hershberger   net: Refactor to ...
1294
  		(*udp_packet_handler)((uchar *)ip + IP_UDP_HDR_SIZE,
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1295
1296
1297
1298
  				      ntohs(ip->udp_dst),
  				      src_ip,
  				      ntohs(ip->udp_src),
  				      ntohs(ip->udp_len) - UDP_HDR_SIZE);
2d966958c   wdenk   Initial revision
1299
  		break;
d8970dae2   Lothar Felten   net: Add new wol ...
1300
1301
1302
1303
1304
  #ifdef CONFIG_CMD_WOL
  	case PROT_WOL:
  		wol_receive(ip, len);
  		break;
  #endif
2d966958c   wdenk   Initial revision
1305
1306
  	}
  }
2d966958c   wdenk   Initial revision
1307
  /**********************************************************************/
e4bf0c5cf   Simon Glass   net: tftpput: Ren...
1308
  static int net_check_prereq(enum proto_t protocol)
2d966958c   wdenk   Initial revision
1309
1310
  {
  	switch (protocol) {
6e5923851   wdenk   * Cleanup, minor ...
1311
  		/* Fall through */
643d1ab23   Jon Loeliger   net/: Remove obso...
1312
  #if defined(CONFIG_CMD_PING)
73a8b27c5   wdenk   * Add support for...
1313
  	case PING:
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1314
  		if (net_ping_ip.s_addr == 0) {
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
1315
1316
  			puts("*** ERROR: ping address not given
  ");
92895de97   Luca Ceresoli   net/net.c: cosmet...
1317
  			return 1;
6e5923851   wdenk   * Cleanup, minor ...
1318
1319
  		}
  		goto common;
73a8b27c5   wdenk   * Add support for...
1320
  #endif
643d1ab23   Jon Loeliger   net/: Remove obso...
1321
  #if defined(CONFIG_CMD_SNTP)
ea287debe   wdenk   * Patch by Masami...
1322
  	case SNTP:
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1323
  		if (net_ntp_server.s_addr == 0) {
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
1324
1325
  			puts("*** ERROR: NTP server address not given
  ");
92895de97   Luca Ceresoli   net/net.c: cosmet...
1326
  			return 1;
ea287debe   wdenk   * Patch by Masami...
1327
1328
1329
  		}
  		goto common;
  #endif
1a32bf418   Robin Getz   Add DNS support
1330
1331
  #if defined(CONFIG_CMD_DNS)
  	case DNS:
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1332
  		if (net_dns_server.s_addr == 0) {
1a32bf418   Robin Getz   Add DNS support
1333
1334
1335
1336
1337
1338
  			puts("*** ERROR: DNS server address not given
  ");
  			return 1;
  		}
  		goto common;
  #endif
643d1ab23   Jon Loeliger   net/: Remove obso...
1339
  #if defined(CONFIG_CMD_NFS)
cbd8a35c6   wdenk   * Patch by Masami...
1340
1341
  	case NFS:
  #endif
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1342
  		/* Fall through */
e4bf0c5cf   Simon Glass   net: tftpput: Ren...
1343
  	case TFTPGET:
1fb7cd498   Simon Glass   net: tftpput: imp...
1344
  	case TFTPPUT:
3a66fcb7c   Joe Hershberger   net: When checkin...
1345
  		if (net_server_ip.s_addr == 0 && !is_serverip_in_cmd()) {
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
1346
1347
  			puts("*** ERROR: `serverip' not set
  ");
92895de97   Luca Ceresoli   net/net.c: cosmet...
1348
  			return 1;
6e5923851   wdenk   * Cleanup, minor ...
1349
  		}
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
1350
1351
1352
  #if	defined(CONFIG_CMD_PING) || defined(CONFIG_CMD_SNTP) || \
  	defined(CONFIG_CMD_DNS)
  common:
73a8b27c5   wdenk   * Add support for...
1353
  #endif
8b6bbe104   Simon Guinot   netconsole: remov...
1354
  		/* Fall through */
73a8b27c5   wdenk   * Add support for...
1355

8b6bbe104   Simon Guinot   netconsole: remov...
1356
  	case NETCONS:
f73a7df98   Alex Kiernan   net: fastboot: Me...
1357
  	case FASTBOOT:
7a83af07a   Luca Ceresoli   TFTP: add tftpsrv...
1358
  	case TFTPSRV:
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1359
  		if (net_ip.s_addr == 0) {
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
1360
1361
  			puts("*** ERROR: `ipaddr' not set
  ");
92895de97   Luca Ceresoli   net/net.c: cosmet...
1362
  			return 1;
6e5923851   wdenk   * Cleanup, minor ...
1363
1364
  		}
  		/* Fall through */
2d966958c   wdenk   Initial revision
1365

bf6cb247a   Peter Tyser   rarp: Condtionall...
1366
  #ifdef CONFIG_CMD_RARP
2d966958c   wdenk   Initial revision
1367
  	case RARP:
bf6cb247a   Peter Tyser   rarp: Condtionall...
1368
  #endif
2d966958c   wdenk   Initial revision
1369
  	case BOOTP:
a3d991bd0   wdenk   Patches by Pantel...
1370
  	case CDP:
bf6cb247a   Peter Tyser   rarp: Condtionall...
1371
  	case DHCP:
d22c338e0   Joe Hershberger   net: Add link-loc...
1372
  	case LINKLOCAL:
0adb5b761   Joe Hershberger   net: cosmetic: Na...
1373
  		if (memcmp(net_ethaddr, "\0\0\0\0\0\0", 6) == 0) {
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
1374
  			int num = eth_get_dev_index();
2d966958c   wdenk   Initial revision
1375

6e5923851   wdenk   * Cleanup, minor ...
1376
1377
  			switch (num) {
  			case -1:
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
1378
1379
  				puts("*** ERROR: No ethernet found.
  ");
92895de97   Luca Ceresoli   net/net.c: cosmet...
1380
  				return 1;
6e5923851   wdenk   * Cleanup, minor ...
1381
  			case 0:
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
1382
1383
  				puts("*** ERROR: `ethaddr' not set
  ");
2d966958c   wdenk   Initial revision
1384
  				break;
6e5923851   wdenk   * Cleanup, minor ...
1385
  			default:
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
1386
1387
  				printf("*** ERROR: `eth%daddr' not set
  ",
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1388
  				       num);
2d966958c   wdenk   Initial revision
1389
  				break;
6e5923851   wdenk   * Cleanup, minor ...
1390
  			}
2d966958c   wdenk   Initial revision
1391

bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1392
  			net_start_again();
92895de97   Luca Ceresoli   net/net.c: cosmet...
1393
  			return 2;
6e5923851   wdenk   * Cleanup, minor ...
1394
1395
1396
  		}
  		/* Fall through */
  	default:
92895de97   Luca Ceresoli   net/net.c: cosmet...
1397
  		return 0;
2d966958c   wdenk   Initial revision
1398
  	}
92895de97   Luca Ceresoli   net/net.c: cosmet...
1399
  	return 0;		/* OK */
2d966958c   wdenk   Initial revision
1400
1401
1402
1403
  }
  /**********************************************************************/
  
  int
1203fccee   Joe Hershberger   net: cosmetic: Cl...
1404
  net_eth_hdr_size(void)
a3d991bd0   wdenk   Patches by Pantel...
1405
1406
  {
  	ushort myvlanid;
2d966958c   wdenk   Initial revision
1407

4fd5055f5   Joe Hershberger   net: cosmetic: Cl...
1408
  	myvlanid = ntohs(net_our_vlan);
a3d991bd0   wdenk   Patches by Pantel...
1409
1410
  	if (myvlanid == (ushort)-1)
  		myvlanid = VLAN_NONE;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
1411
1412
  	return ((myvlanid & VLAN_IDMASK) == VLAN_NONE) ? ETHER_HDR_SIZE :
  		VLAN_ETHER_HDR_SIZE;
a3d991bd0   wdenk   Patches by Pantel...
1413
  }
1203fccee   Joe Hershberger   net: cosmetic: Cl...
1414
  int net_set_ether(uchar *xet, const uchar *dest_ethaddr, uint prot)
2d966958c   wdenk   Initial revision
1415
  {
cb487f566   Joe Hershberger   net: cosmetic: Un...
1416
  	struct ethernet_hdr *et = (struct ethernet_hdr *)xet;
a3d991bd0   wdenk   Patches by Pantel...
1417
  	ushort myvlanid;
4fd5055f5   Joe Hershberger   net: cosmetic: Cl...
1418
  	myvlanid = ntohs(net_our_vlan);
a3d991bd0   wdenk   Patches by Pantel...
1419
1420
  	if (myvlanid == (ushort)-1)
  		myvlanid = VLAN_NONE;
2d966958c   wdenk   Initial revision
1421

0adb5b761   Joe Hershberger   net: cosmetic: Na...
1422
1423
  	memcpy(et->et_dest, dest_ethaddr, 6);
  	memcpy(et->et_src, net_ethaddr, 6);
a3d991bd0   wdenk   Patches by Pantel...
1424
  	if ((myvlanid & VLAN_IDMASK) == VLAN_NONE) {
c819abeef   Luca Ceresoli   net/net.c: cosmet...
1425
  		et->et_protlen = htons(prot);
a3d991bd0   wdenk   Patches by Pantel...
1426
1427
  		return ETHER_HDR_SIZE;
  	} else {
c68cca35b   Joe Hershberger   net: cosmetic: Un...
1428
1429
  		struct vlan_ethernet_hdr *vet =
  			(struct vlan_ethernet_hdr *)xet;
2d966958c   wdenk   Initial revision
1430

a3d991bd0   wdenk   Patches by Pantel...
1431
1432
1433
1434
1435
1436
  		vet->vet_vlan_type = htons(PROT_VLAN);
  		vet->vet_tag = htons((0 << 5) | (myvlanid & VLAN_IDMASK));
  		vet->vet_type = htons(prot);
  		return VLAN_ETHER_HDR_SIZE;
  	}
  }
2d966958c   wdenk   Initial revision
1437

e71110158   Joe Hershberger   net: Add net_upda...
1438
1439
1440
1441
1442
  int net_update_ether(struct ethernet_hdr *et, uchar *addr, uint prot)
  {
  	ushort protlen;
  
  	memcpy(et->et_dest, addr, 6);
0adb5b761   Joe Hershberger   net: cosmetic: Na...
1443
  	memcpy(et->et_src, net_ethaddr, 6);
e71110158   Joe Hershberger   net: Add net_upda...
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
  	protlen = ntohs(et->et_protlen);
  	if (protlen == PROT_VLAN) {
  		struct vlan_ethernet_hdr *vet =
  			(struct vlan_ethernet_hdr *)et;
  		vet->vet_type = htons(prot);
  		return VLAN_ETHER_HDR_SIZE;
  	} else if (protlen > 1514) {
  		et->et_protlen = htons(prot);
  		return ETHER_HDR_SIZE;
  	} else {
  		/* 802.2 + SNAP */
  		struct e802_hdr *et802 = (struct e802_hdr *)et;
  		et802->et_prot = htons(prot);
  		return E802_HDR_SIZE;
  	}
  }
5d457ecbe   Duncan Hare   net: Consolidate ...
1460
1461
  void net_set_ip_header(uchar *pkt, struct in_addr dest, struct in_addr source,
  		       u16 pkt_len, u8 proto)
2d966958c   wdenk   Initial revision
1462
  {
4b11c9166   Joe Hershberger   net: Refactor IP,...
1463
  	struct ip_udp_hdr *ip = (struct ip_udp_hdr *)pkt;
2d966958c   wdenk   Initial revision
1464
1465
  
  	/*
4b11c9166   Joe Hershberger   net: Refactor IP,...
1466
  	 *	Construct an IP header.
2d966958c   wdenk   Initial revision
1467
  	 */
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
1468
1469
  	/* IP_HDR_SIZE / 4 (not including UDP) */
  	ip->ip_hl_v  = 0x45;
2d966958c   wdenk   Initial revision
1470
  	ip->ip_tos   = 0;
5d457ecbe   Duncan Hare   net: Consolidate ...
1471
1472
  	ip->ip_len   = htons(pkt_len);
  	ip->ip_p     = proto;
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
1473
  	ip->ip_id    = htons(net_ip_id++);
e0c07b868   Peter Tyser   net: Define IP fl...
1474
  	ip->ip_off   = htons(IP_FLAGS_DFRAG);	/* Don't fragment */
2d966958c   wdenk   Initial revision
1475
  	ip->ip_ttl   = 255;
2d966958c   wdenk   Initial revision
1476
  	ip->ip_sum   = 0;
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
1477
  	/* already in network byte order */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1478
  	net_copy_ip((void *)&ip->ip_src, &source);
4b11c9166   Joe Hershberger   net: Refactor IP,...
1479
  	/* already in network byte order */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1480
  	net_copy_ip((void *)&ip->ip_dst, &dest);
5d457ecbe   Duncan Hare   net: Consolidate ...
1481
1482
  
  	ip->ip_sum   = compute_ip_checksum(ip, IP_HDR_SIZE);
4b11c9166   Joe Hershberger   net: Refactor IP,...
1483
  }
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1484
  void net_set_udp_header(uchar *pkt, struct in_addr dest, int dport, int sport,
4b11c9166   Joe Hershberger   net: Refactor IP,...
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
  			int len)
  {
  	struct ip_udp_hdr *ip = (struct ip_udp_hdr *)pkt;
  
  	/*
  	 *	If the data is an odd number of bytes, zero the
  	 *	byte after the last byte so that the checksum
  	 *	will work.
  	 */
  	if (len & 1)
  		pkt[IP_UDP_HDR_SIZE + len] = 0;
5d457ecbe   Duncan Hare   net: Consolidate ...
1496
1497
  	net_set_ip_header(pkt, dest, net_ip, IP_UDP_HDR_SIZE + len,
  			  IPPROTO_UDP);
4b11c9166   Joe Hershberger   net: Refactor IP,...
1498

2d966958c   wdenk   Initial revision
1499
1500
  	ip->udp_src  = htons(sport);
  	ip->udp_dst  = htons(dport);
594c26f8a   Joe Hershberger   net: cosmetic: Un...
1501
  	ip->udp_len  = htons(UDP_HDR_SIZE + len);
2d966958c   wdenk   Initial revision
1502
  	ip->udp_xsum = 0;
2d966958c   wdenk   Initial revision
1503
  }
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
1504
  void copy_filename(char *dst, const char *src, int size)
2d966958c   wdenk   Initial revision
1505
  {
16cf145fd   Joe Hershberger   net: Make copy_fi...
1506
  	if (src && *src && (*src == '"')) {
2d966958c   wdenk   Initial revision
1507
1508
1509
  		++src;
  		--size;
  	}
16cf145fd   Joe Hershberger   net: Make copy_fi...
1510
  	while ((--size > 0) && src && *src && (*src != '"'))
2d966958c   wdenk   Initial revision
1511
  		*dst++ = *src++;
2d966958c   wdenk   Initial revision
1512
1513
  	*dst = '\0';
  }
3a66fcb7c   Joe Hershberger   net: When checkin...
1514
1515
1516
1517
  int is_serverip_in_cmd(void)
  {
  	return !!strchr(net_boot_file_name, ':');
  }
6ab128309   Joe Hershberger   net: Consolidate ...
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
  int net_parse_bootfile(struct in_addr *ipaddr, char *filename, int max_len)
  {
  	char *colon;
  
  	if (net_boot_file_name[0] == '\0')
  		return 0;
  
  	colon = strchr(net_boot_file_name, ':');
  	if (colon) {
  		if (ipaddr)
  			*ipaddr = string_to_ip(net_boot_file_name);
  		strncpy(filename, colon + 1, max_len);
  	} else {
  		strncpy(filename, net_boot_file_name, max_len);
  	}
  	filename[max_len - 1] = '\0';
  
  	return 1;
  }
3e38e429f   Luca Ceresoli   net/net.c: cosmet...
1537
1538
1539
  #if	defined(CONFIG_CMD_NFS)		|| \
  	defined(CONFIG_CMD_SNTP)	|| \
  	defined(CONFIG_CMD_DNS)
1a32bf418   Robin Getz   Add DNS support
1540
  /*
9739946cc   Robin Getz   ./net/net.c - mak...
1541
1542
1543
   * make port a little random (1024-17407)
   * This keeps the math somewhat trivial to compute, and seems to work with
   * all supported protocols/clients/servers
1a32bf418   Robin Getz   Add DNS support
1544
1545
1546
   */
  unsigned int random_port(void)
  {
9739946cc   Robin Getz   ./net/net.c - mak...
1547
  	return 1024 + (get_timer(0) % 0x4000);
1a32bf418   Robin Getz   Add DNS support
1548
1549
  }
  #endif
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1550
  void ip_to_string(struct in_addr x, char *s)
2d966958c   wdenk   Initial revision
1551
  {
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1552
  	x.s_addr = ntohl(x.s_addr);
4f63acd06   Luca Ceresoli   net/net.c: cosmet...
1553
  	sprintf(s, "%d.%d.%d.%d",
049a95a77   Joe Hershberger   net: cosmetic: Ch...
1554
1555
1556
1557
  		(int) ((x.s_addr >> 24) & 0xff),
  		(int) ((x.s_addr >> 16) & 0xff),
  		(int) ((x.s_addr >> 8) & 0xff),
  		(int) ((x.s_addr >> 0) & 0xff)
6e5923851   wdenk   * Cleanup, minor ...
1558
  	);
2d966958c   wdenk   Initial revision
1559
  }
4fd5055f5   Joe Hershberger   net: cosmetic: Cl...
1560
  void vlan_to_string(ushort x, char *s)
a3d991bd0   wdenk   Patches by Pantel...
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
  {
  	x = ntohs(x);
  
  	if (x == (ushort)-1)
  		x = VLAN_NONE;
  
  	if (x == VLAN_NONE)
  		strcpy(s, "none");
  	else
  		sprintf(s, "%d", x & VLAN_IDMASK);
  }
4fd5055f5   Joe Hershberger   net: cosmetic: Cl...
1572
  ushort string_to_vlan(const char *s)
a3d991bd0   wdenk   Patches by Pantel...
1573
1574
1575
1576
  {
  	ushort id;
  
  	if (s == NULL)
b9711de10   wdenk   * Patch by John K...
1577
  		return htons(VLAN_NONE);
a3d991bd0   wdenk   Patches by Pantel...
1578
1579
1580
1581
1582
  
  	if (*s < '0' || *s > '9')
  		id = VLAN_NONE;
  	else
  		id = (ushort)simple_strtoul(s, NULL, 10);
b9711de10   wdenk   * Patch by John K...
1583
  	return htons(id);
a3d991bd0   wdenk   Patches by Pantel...
1584
  }
723806cc5   Simon Glass   env: Rename some ...
1585
  ushort env_get_vlan(char *var)
a3d991bd0   wdenk   Patches by Pantel...
1586
  {
00caae6d4   Simon Glass   env: Rename geten...
1587
  	return string_to_vlan(env_get(var));
a3d991bd0   wdenk   Patches by Pantel...
1588
  }