net.h 26.8 KB
Newer Older
1
/* SPDX-License-Identifier: GPL-2.0 */
wdenk's avatar
wdenk committed
2
3
4
5
6
7
8
9
10
11
12
13
14
/*
 *	LiMon Monitor (LiMon) - Network.
 *
 *	Copyright 1994 - 2000 Neil Russell.
 *	(See License)
 *
 * History
 *	9/16/00	  bor  adapted to TQM823L/STK8xxL board, RARP/TFTP boot added
 */

#ifndef __NET_H__
#define __NET_H__

15
#include <asm/cache.h>
wdenk's avatar
wdenk committed
16
#include <asm/byteorder.h>	/* for nton* / ntoh* stuff */
Simon Glass's avatar
Simon Glass committed
17
#include <env.h>
18
#include <linux/if_ether.h>
wdenk's avatar
wdenk committed
19

20
21
22
23
#define DEBUG_LL_STATE 0	/* Link local state machine changes */
#define DEBUG_DEV_PKT 0		/* Packets or info directed to the device */
#define DEBUG_NET_PKT 0		/* Packets on info on the network at large */
#define DEBUG_INT_STATE 0	/* Internal network state changes */
wdenk's avatar
wdenk committed
24
25
26
27
28
29
30

/*
 *	The number of receive packet buffers, and the required packet buffer
 *	alignment in memory.
 *
 */

31
32
#ifdef CONFIG_SYS_RX_ETH_BUFFER
# define PKTBUFSRX	CONFIG_SYS_RX_ETH_BUFFER
wdenk's avatar
wdenk committed
33
#else
stroese's avatar
stroese committed
34
# define PKTBUFSRX	4
wdenk's avatar
wdenk committed
35
36
#endif

37
#define PKTALIGN	ARCH_DMA_MINALIGN
wdenk's avatar
wdenk committed
38

39
40
/* ARP hardware address length */
#define ARP_HLEN 6
41
42
43
44
45
/*
 * The size of a MAC address in string form, each digit requires two chars
 * and five separator characters to form '00:00:00:00:00:00'.
 */
#define ARP_HLEN_ASCII (ARP_HLEN * 2) + (ARP_HLEN - 1)
46

47
/* IPv4 addresses are always 32 bits in size */
48
49
50
struct in_addr {
	__be32 s_addr;
};
wdenk's avatar
wdenk committed
51

52
53
54
55
56
57
58
/**
 * An incoming packet handler.
 * @param pkt    pointer to the application packet
 * @param dport  destination UDP port
 * @param sip    source IP address
 * @param sport  source UDP port
 * @param len    packet length
wdenk's avatar
wdenk committed
59
 */
60
typedef void rxhand_f(uchar *pkt, unsigned dport,
61
		      struct in_addr sip, unsigned sport,
62
		      unsigned len);
wdenk's avatar
wdenk committed
63

64
65
66
67
68
69
70
71
72
73
74
/**
 * An incoming ICMP packet handler.
 * @param type	ICMP type
 * @param code	ICMP code
 * @param dport	destination UDP port
 * @param sip	source IP address
 * @param sport	source UDP port
 * @param pkt	pointer to the ICMP packet data
 * @param len	packet length
 */
typedef void rxhand_icmp_f(unsigned type, unsigned code, unsigned dport,
75
		struct in_addr sip, unsigned sport, uchar *pkt, unsigned len);
76

wdenk's avatar
wdenk committed
77
78
79
80
81
82
83
84
85
86
87
/*
 *	A timeout handler.  Called after time interval has expired.
 */
typedef void	thand_f(void);

enum eth_state_t {
	ETH_STATE_INIT,
	ETH_STATE_PASSIVE,
	ETH_STATE_ACTIVE
};

88
89
90
91
92
93
#ifdef CONFIG_DM_ETH
/**
 * struct eth_pdata - Platform data for Ethernet MAC controllers
 *
 * @iobase: The base address of the hardware registers
 * @enetaddr: The Ethernet MAC address that is loaded from EEPROM or env
94
 * @phy_interface: PHY interface to use - see PHY_INTERFACE_MODE_...
95
 * @max_speed: Maximum speed of Ethernet connection supported by MAC
Faiz Abbas's avatar
Faiz Abbas committed
96
 * @priv_pdata: device specific platdata
97
98
99
 */
struct eth_pdata {
	phys_addr_t iobase;
100
	unsigned char enetaddr[ARP_HLEN];
101
	int phy_interface;
102
	int max_speed;
Faiz Abbas's avatar
Faiz Abbas committed
103
	void *priv_pdata;
104
105
};

106
107
108
109
110
111
112
113
enum eth_recv_flags {
	/*
	 * Check hardware device for new packets (otherwise only return those
	 * which are already in the memory buffer ready to process)
	 */
	ETH_RECV_CHECK_DEVICE		= 1 << 0,
};

114
115
116
117
118
/**
 * struct eth_ops - functions of Ethernet MAC controllers
 *
 * start: Prepare the hardware to send and receive packets
 * send: Send the bytes passed in "packet" as a packet on the wire
119
120
 * recv: Check if the hardware received a packet. If so, set the pointer to the
 *	 packet buffer in the packetp parameter. If not, return an error or 0 to
121
122
123
124
125
126
 *	 indicate that the hardware receive FIFO is empty. If 0 is returned, the
 *	 network stack will not process the empty packet, but free_pkt() will be
 *	 called if supplied
 * free_pkt: Give the driver an opportunity to manage its packet buffer memory
 *	     when the network stack is finished processing it. This will only be
 *	     called when no error was returned from recv - optional
127
128
129
130
131
 * stop: Stop the hardware from looking for packets - may be called even if
 *	 state == PASSIVE
 * mcast: Join or leave a multicast group (for TFTP) - optional
 * write_hwaddr: Write a MAC address to the hardware (used to pass it to Linux
 *		 on some platforms like ARM). This function expects the
132
133
134
 *		 eth_pdata::enetaddr field to be populated. The method can
 *		 return -ENOSYS to indicate that this is not implemented for
		 this hardware - optional.
135
136
137
138
139
140
141
142
 * read_rom_hwaddr: Some devices have a backup of the MAC address stored in a
 *		    ROM on the board. This is how the driver should expose it
 *		    to the network stack. This function should fill in the
 *		    eth_pdata::enetaddr field - optional
 */
struct eth_ops {
	int (*start)(struct udevice *dev);
	int (*send)(struct udevice *dev, void *packet, int length);
143
	int (*recv)(struct udevice *dev, int flags, uchar **packetp);
144
	int (*free_pkt)(struct udevice *dev, uchar *packet, int length);
145
146
147
148
149
150
151
152
153
	void (*stop)(struct udevice *dev);
	int (*mcast)(struct udevice *dev, const u8 *enetaddr, int join);
	int (*write_hwaddr)(struct udevice *dev);
	int (*read_rom_hwaddr)(struct udevice *dev);
};

#define eth_get_ops(dev) ((struct eth_ops *)(dev)->driver->ops)

struct udevice *eth_get_dev(void); /* get the current device */
154
155
156
157
158
/*
 * The devname can be either an exact name given by the driver or device tree
 * or it can be an alias of the form "eth%d"
 */
struct udevice *eth_get_dev_by_name(const char *devname);
159
unsigned char *eth_get_ethaddr(void); /* get the current device MAC */
160

161
/* Used only when NetConsole is enabled */
162
int eth_is_active(struct udevice *dev); /* Test device for active state */
163
164
165
166
167
int eth_init_state_only(void); /* Set active state */
void eth_halt_state_only(void); /* Set passive state */
#endif

#ifndef CONFIG_DM_ETH
wdenk's avatar
wdenk committed
168
struct eth_device {
169
#define ETH_NAME_LEN 20
170
	char name[ETH_NAME_LEN];
171
	unsigned char enetaddr[ARP_HLEN];
172
	phys_addr_t iobase;
wdenk's avatar
wdenk committed
173
174
	int state;

175
176
177
178
	int (*init)(struct eth_device *, bd_t *);
	int (*send)(struct eth_device *, void *packet, int length);
	int (*recv)(struct eth_device *);
	void (*halt)(struct eth_device *);
Chris Packham's avatar
Chris Packham committed
179
	int (*mcast)(struct eth_device *, const u8 *enetaddr, int join);
180
	int (*write_hwaddr)(struct eth_device *);
wdenk's avatar
wdenk committed
181
	struct eth_device *next;
182
	int index;
wdenk's avatar
wdenk committed
183
184
185
	void *priv;
};

186
187
int eth_register(struct eth_device *dev);/* Register network device */
int eth_unregister(struct eth_device *dev);/* Remove network device */
Kim Phillips's avatar
Kim Phillips committed
188
189
190

extern struct eth_device *eth_current;

191
static __always_inline struct eth_device *eth_get_dev(void)
192
193
194
{
	return eth_current;
}
195
196
struct eth_device *eth_get_dev_by_name(const char *devname);
struct eth_device *eth_get_dev_by_index(int index); /* get dev @ index */
197

198
/* get the current device MAC */
199
200
201
202
203
204
205
static inline unsigned char *eth_get_ethaddr(void)
{
	if (eth_current)
		return eth_current->enetaddr;
	return NULL;
}

206
207
/* Used only when NetConsole is enabled */
int eth_is_active(struct eth_device *dev); /* Test device for active state */
208
/* Set active state */
209
static __always_inline int eth_init_state_only(void)
210
211
212
213
214
215
{
	eth_get_dev()->state = ETH_STATE_ACTIVE;

	return 0;
}
/* Set passive state */
216
static __always_inline void eth_halt_state_only(void)
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
{
	eth_get_dev()->state = ETH_STATE_PASSIVE;
}

/*
 * Set the hardware address for an ethernet interface based on 'eth%daddr'
 * environment variable (or just 'ethaddr' if eth_number is 0).
 * Args:
 *	base_name - base name for device (normally "eth")
 *	eth_number - value of %d (0 for first device of this type)
 * Returns:
 *	0 is success, non-zero is error status from driver.
 */
int eth_write_hwaddr(struct eth_device *dev, const char *base_name,
		     int eth_number);

int usb_eth_initialize(bd_t *bi);
234
#endif
235

236
int eth_initialize(void);		/* Initialize network subsystem */
237
238
239
void eth_try_another(int first_restart);	/* Change the device */
void eth_set_current(void);		/* set nterface to ethcur var */

240
int eth_get_dev_index(void);		/* get the device index */
241

242
/**
243
 * eth_env_set_enetaddr_by_index() - set the MAC address environment variable
244
245
246
247
248
249
250
251
252
253
254
 *
 * This sets up an environment variable with the given MAC address (@enetaddr).
 * The environment variable to be set is defined by <@base_name><@index>addr.
 * If @index is 0 it is omitted. For common Ethernet this means ethaddr,
 * eth1addr, etc.
 *
 * @base_name:  Base name for variable, typically "eth"
 * @index:      Index of interface being updated (>=0)
 * @enetaddr:   Pointer to MAC address to put into the variable
 * @return 0 if OK, other value on error
 */
255
int eth_env_set_enetaddr_by_index(const char *base_name, int index,
256
257
258
				 uchar *enetaddr);


259
260
261
262
263
264
265
/*
 * Initialize USB ethernet device with CONFIG_DM_ETH
 * Returns:
 *	0 is success, non-zero is error status.
 */
int usb_ether_init(void);

266
267
268
269
270
271
272
273
274
/*
 * Get the hardware address for an ethernet interface .
 * Args:
 *	base_name - base name for device (normally "eth")
 *	index - device index number (0 for first)
 *	enetaddr - returns 6 byte hardware address
 * Returns:
 *	Return true if the address is valid.
 */
275
int eth_env_get_enetaddr_by_index(const char *base_name, int index,
276
				 uchar *enetaddr);
277

278
int eth_init(void);			/* Initialize the device */
279
int eth_send(void *packet, int length);	   /* Send a packet */
280

281
#if defined(CONFIG_API) || defined(CONFIG_EFI_LOADER)
282
int eth_receive(void *packet, int length); /* Receive a packet*/
283
extern void (*push_packet)(void *packet, int length);
284
#endif
285
286
int eth_rx(void);			/* Check for received packets */
void eth_halt(void);			/* stop SCC */
287
const char *eth_get_name(void);		/* get name of current device */
288
int eth_mcast_join(struct in_addr mcast_addr, int join);
wdenk's avatar
wdenk committed
289
290
291
292
293
294
295
296
297

/**********************************************************************/
/*
 *	Protocol headers.
 */

/*
 *	Ethernet header
 */
298
299

struct ethernet_hdr {
300
301
302
	u8		et_dest[ARP_HLEN];	/* Destination node	*/
	u8		et_src[ARP_HLEN];	/* Source node		*/
	u16		et_protlen;		/* Protocol or length	*/
303
} __attribute__((packed));
304
305
306
307

/* Ethernet header size */
#define ETHER_HDR_SIZE	(sizeof(struct ethernet_hdr))

308
309
#define ETH_FCS_LEN	4		/* Octets in the FCS		*/

310
struct e802_hdr {
311
312
313
314
315
316
317
	u8		et_dest[ARP_HLEN];	/* Destination node	*/
	u8		et_src[ARP_HLEN];	/* Source node		*/
	u16		et_protlen;		/* Protocol or length	*/
	u8		et_dsap;		/* 802 DSAP		*/
	u8		et_ssap;		/* 802 SSAP		*/
	u8		et_ctl;			/* 802 control		*/
	u8		et_snap1;		/* SNAP			*/
318
319
	u8		et_snap2;
	u8		et_snap3;
320
	u16		et_prot;		/* 802 protocol		*/
321
} __attribute__((packed));
wdenk's avatar
wdenk committed
322

323
/* 802 + SNAP + ethernet header size */
324
#define E802_HDR_SIZE	(sizeof(struct e802_hdr))
325
326

/*
327
 *	Virtual LAN Ethernet header
328
 */
329
struct vlan_ethernet_hdr {
330
331
332
333
334
	u8		vet_dest[ARP_HLEN];	/* Destination node	*/
	u8		vet_src[ARP_HLEN];	/* Source node		*/
	u16		vet_vlan_type;		/* PROT_VLAN		*/
	u16		vet_tag;		/* TAG of VLAN		*/
	u16		vet_type;		/* protocol type	*/
335
} __attribute__((packed));
336

337
338
/* VLAN Ethernet header size */
#define VLAN_ETHER_HDR_SIZE	(sizeof(struct vlan_ethernet_hdr))
339

wdenk's avatar
wdenk committed
340
341
#define PROT_IP		0x0800		/* IP protocol			*/
#define PROT_ARP	0x0806		/* IP ARP protocol		*/
342
#define PROT_WOL	0x0842		/* ether-wake WoL protocol	*/
wdenk's avatar
wdenk committed
343
#define PROT_RARP	0x8035		/* IP ARP protocol		*/
344
#define PROT_VLAN	0x8100		/* IEEE 802.1q protocol		*/
345
346
#define PROT_IPV6	0x86dd		/* IPv6 over bluebook		*/
#define PROT_PPP_SES	0x8864		/* PPPoE session messages	*/
wdenk's avatar
wdenk committed
347
348
349
350
351

#define IPPROTO_ICMP	 1	/* Internet Control Message Protocol	*/
#define IPPROTO_UDP	17	/* User Datagram Protocol		*/

/*
352
 *	Internet Protocol (IP) header.
wdenk's avatar
wdenk committed
353
 */
354
struct ip_hdr {
355
356
357
358
359
360
361
362
	u8		ip_hl_v;	/* header length and version	*/
	u8		ip_tos;		/* type of service		*/
	u16		ip_len;		/* total length			*/
	u16		ip_id;		/* identification		*/
	u16		ip_off;		/* fragment offset field	*/
	u8		ip_ttl;		/* time to live			*/
	u8		ip_p;		/* protocol			*/
	u16		ip_sum;		/* checksum			*/
363
364
	struct in_addr	ip_src;		/* Source IP address		*/
	struct in_addr	ip_dst;		/* Destination IP address	*/
365
} __attribute__((packed));
wdenk's avatar
wdenk committed
366

Peter Tyser's avatar
Peter Tyser committed
367
368
369
370
371
372
#define IP_OFFS		0x1fff /* ip offset *= 8 */
#define IP_FLAGS	0xe000 /* first 3 bits */
#define IP_FLAGS_RES	0x8000 /* reserved */
#define IP_FLAGS_DFRAG	0x4000 /* don't fragments */
#define IP_FLAGS_MFRAG	0x2000 /* more fragments */

373
374
375
376
377
378
#define IP_HDR_SIZE		(sizeof(struct ip_hdr))

/*
 *	Internet Protocol (IP) + UDP header.
 */
struct ip_udp_hdr {
379
380
381
382
383
384
385
386
	u8		ip_hl_v;	/* header length and version	*/
	u8		ip_tos;		/* type of service		*/
	u16		ip_len;		/* total length			*/
	u16		ip_id;		/* identification		*/
	u16		ip_off;		/* fragment offset field	*/
	u8		ip_ttl;		/* time to live			*/
	u8		ip_p;		/* protocol			*/
	u16		ip_sum;		/* checksum			*/
387
388
	struct in_addr	ip_src;		/* Source IP address		*/
	struct in_addr	ip_dst;		/* Destination IP address	*/
389
390
391
392
	u16		udp_src;	/* UDP source port		*/
	u16		udp_dst;	/* UDP destination port		*/
	u16		udp_len;	/* Length of UDP packet		*/
	u16		udp_xsum;	/* Checksum			*/
393
} __attribute__((packed));
wdenk's avatar
wdenk committed
394

395
#define IP_UDP_HDR_SIZE		(sizeof(struct ip_udp_hdr))
396
#define UDP_HDR_SIZE		(IP_UDP_HDR_SIZE - IP_HDR_SIZE)
wdenk's avatar
wdenk committed
397
398
399
400

/*
 *	Address Resolution Protocol (ARP) header.
 */
401
struct arp_hdr {
402
	u16		ar_hrd;		/* Format of hardware address	*/
wdenk's avatar
wdenk committed
403
#   define ARP_ETHER	    1		/* Ethernet  hardware address	*/
404
405
406
	u16		ar_pro;		/* Format of protocol address	*/
	u8		ar_hln;		/* Length of hardware address	*/
	u8		ar_pln;		/* Length of protocol address	*/
407
#   define ARP_PLEN	4
408
	u16		ar_op;		/* Operation			*/
wdenk's avatar
wdenk committed
409
410
411
412
413
414
415
#   define ARPOP_REQUEST    1		/* Request  to resolve  address	*/
#   define ARPOP_REPLY	    2		/* Response to previous request	*/

#   define RARPOP_REQUEST   3		/* Request  to resolve  address	*/
#   define RARPOP_REPLY	    4		/* Response to previous request */

	/*
wdenk's avatar
wdenk committed
416
417
418
	 * The remaining fields are variable in size, according to
	 * the sizes above, and are defined as appropriate for
	 * specific hardware/protocol combinations.
wdenk's avatar
wdenk committed
419
	 */
420
	u8		ar_data[0];
421
422
423
424
#define ar_sha		ar_data[0]
#define ar_spa		ar_data[ARP_HLEN]
#define ar_tha		ar_data[ARP_HLEN + ARP_PLEN]
#define ar_tpa		ar_data[ARP_HLEN + ARP_PLEN + ARP_HLEN]
wdenk's avatar
wdenk committed
425
#if 0
426
427
428
429
	u8		ar_sha[];	/* Sender hardware address	*/
	u8		ar_spa[];	/* Sender protocol address	*/
	u8		ar_tha[];	/* Target hardware address	*/
	u8		ar_tpa[];	/* Target protocol address	*/
wdenk's avatar
wdenk committed
430
#endif /* 0 */
431
} __attribute__((packed));
wdenk's avatar
wdenk committed
432
433
434
435
436
437

#define ARP_HDR_SIZE	(8+20)		/* Size assuming ethernet	*/

/*
 * ICMP stuff (just enough to handle (host) redirect messages)
 */
Wolfgang Denk's avatar
Wolfgang Denk committed
438
#define ICMP_ECHO_REPLY		0	/* Echo reply			*/
439
#define ICMP_NOT_REACH		3	/* Detination unreachable	*/
wdenk's avatar
wdenk committed
440
#define ICMP_REDIRECT		5	/* Redirect (change route)	*/
wdenk's avatar
wdenk committed
441
#define ICMP_ECHO_REQUEST	8	/* Echo request			*/
wdenk's avatar
wdenk committed
442
443
444
445
446

/* Codes for REDIRECT. */
#define ICMP_REDIR_NET		0	/* Redirect Net			*/
#define ICMP_REDIR_HOST		1	/* Redirect Host		*/

447
448
449
/* Codes for NOT_REACH */
#define ICMP_NOT_REACH_PORT	3	/* Port unreachable		*/

450
struct icmp_hdr {
451
452
453
	u8		type;
	u8		code;
	u16		checksum;
wdenk's avatar
wdenk committed
454
455
	union {
		struct {
456
457
			u16	id;
			u16	sequence;
wdenk's avatar
wdenk committed
458
		} echo;
459
		u32	gateway;
wdenk's avatar
wdenk committed
460
		struct {
461
462
			u16	unused;
			u16	mtu;
wdenk's avatar
wdenk committed
463
		} frag;
464
		u8 data[0];
wdenk's avatar
wdenk committed
465
	} un;
466
} __attribute__((packed));
wdenk's avatar
wdenk committed
467

468
469
#define ICMP_HDR_SIZE		(sizeof(struct icmp_hdr))
#define IP_ICMP_HDR_SIZE	(IP_HDR_SIZE + ICMP_HDR_SIZE)
wdenk's avatar
wdenk committed
470
471

/*
472
473
474
475
 * Maximum packet size; used to allocate packet storage. Use
 * the maxium Ethernet frame size as specified by the Ethernet
 * standard including the 802.1Q tag (VLAN tagging).
 * maximum packet size =  1522
wdenk's avatar
wdenk committed
476
477
 * maximum packet size and multiple of 32 bytes =  1536
 */
478
#define PKTSIZE			1522
wdenk's avatar
wdenk committed
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
#define PKTSIZE_ALIGN		1536

/*
 * Maximum receive ring size; that is, the number of packets
 * we can buffer before overflow happens. Basically, this just
 * needs to be enough to prevent a packet being discarded while
 * we are processing the previous one.
 */
#define RINGSZ		4
#define RINGSZ_LOG2	2

/**********************************************************************/
/*
 *	Globals.
 *
 * Note:
 *
496
 * All variables of type struct in_addr are stored in NETWORK byte order
wdenk's avatar
wdenk committed
497
498
499
500
501
 * (big endian).
 */

/* net.c */
/** BOOTP EXTENTIONS **/
502
503
504
505
extern struct in_addr net_gateway;	/* Our gateway IP address */
extern struct in_addr net_netmask;	/* Our subnet mask (0 = unknown) */
/* Our Domain Name Server (0 = unknown) */
extern struct in_addr net_dns_server;
506
#if defined(CONFIG_BOOTP_DNS2)
507
508
/* Our 2nd Domain Name Server (0 = unknown) */
extern struct in_addr net_dns_server2;
509
#endif
510
511
512
extern char	net_nis_domain[32];	/* Our IS domain */
extern char	net_hostname[32];	/* Our hostname */
extern char	net_root_path[64];	/* Our root path */
wdenk's avatar
wdenk committed
513
/** END OF BOOTP EXTENTIONS **/
514
515
extern u8		net_ethaddr[ARP_HLEN];		/* Our ethernet address */
extern u8		net_server_ethaddr[ARP_HLEN];	/* Boot server enet address */
516
517
extern struct in_addr	net_ip;		/* Our    IP addr (0 = unknown) */
extern struct in_addr	net_server_ip;	/* Server IP addr (0 = unknown) */
518
extern uchar		*net_tx_packet;		/* THE transmit packet */
519
extern uchar		*net_rx_packets[PKTBUFSRX]; /* Receive packets */
520
521
extern uchar		*net_rx_packet;		/* Current receive packet */
extern int		net_rx_packet_len;	/* Current rx packet length */
522
523
extern const u8		net_bcast_ethaddr[ARP_HLEN];	/* Ethernet broadcast address */
extern const u8		net_null_ethaddr[ARP_HLEN];
wdenk's avatar
wdenk committed
524

525
526
#define VLAN_NONE	4095			/* untagged */
#define VLAN_IDMASK	0x0fff			/* mask of valid vlan id */
527
528
extern ushort		net_our_vlan;		/* Our VLAN */
extern ushort		net_native_vlan;	/* Our Native VLAN */
529

530
extern int		net_restart_wrap;	/* Tried all network devices */
wdenk's avatar
wdenk committed
531

532
533
enum proto_t {
	BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
534
	TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL
535
};
wdenk's avatar
wdenk committed
536

537
extern char	net_boot_file_name[1024];/* Boot File name */
538
539
/* Indicates whether the file name was specified on the command line */
extern bool	net_boot_file_name_explicit;
540
541
542
543
/* The actual transferred size of the bootfile (in bytes) */
extern u32	net_boot_file_size;
/* Boot file size in blocks as reported by the DHCP server */
extern u32	net_boot_file_expected_size_in_blocks;
wdenk's avatar
wdenk committed
544

Robin Getz's avatar
Robin Getz committed
545
#if defined(CONFIG_CMD_DNS)
546
547
extern char *net_dns_resolve;		/* The host to resolve  */
extern char *net_dns_env_var;		/* the env var to put the ip into */
Robin Getz's avatar
Robin Getz committed
548
549
#endif

550
#if defined(CONFIG_CMD_PING)
551
extern struct in_addr net_ping_ip;	/* the ip address to ping */
wdenk's avatar
wdenk committed
552
553
#endif

554
#if defined(CONFIG_CMD_CDP)
555
/* when CDP completes these hold the return values */
556
557
extern ushort cdp_native_vlan;		/* CDP returned native VLAN */
extern ushort cdp_appliance_vlan;	/* CDP returned appliance VLAN */
558
559
560
561

/*
 * Check for a CDP packet by examining the received MAC address field
 */
562
static inline int is_cdp_packet(const uchar *ethaddr)
563
{
564
	extern const u8 net_cdp_ethaddr[ARP_HLEN];
565

566
	return memcmp(ethaddr, net_cdp_ethaddr, ARP_HLEN) == 0;
567
}
568
569
#endif

570
#if defined(CONFIG_CMD_SNTP)
571
extern struct in_addr	net_ntp_server;		/* the ip address to NTP */
572
extern int net_ntp_time_offset;			/* offset time from UTC */
wdenk's avatar
wdenk committed
573
574
#endif

wdenk's avatar
wdenk committed
575
/* Initialize the network adapter */
576
void net_init(void);
577
int net_loop(enum proto_t);
wdenk's avatar
wdenk committed
578
579

/* Load failed.	 Start again. */
580
int net_start_again(void);
wdenk's avatar
wdenk committed
581

582
/* Get size of the ethernet header when we send */
583
int net_eth_hdr_size(void);
584
585

/* Set ethernet header; returns the size of the header */
586
int net_set_ether(uchar *xet, const uchar *dest_ethaddr, uint prot);
587
int net_update_ether(struct ethernet_hdr *et, uchar *addr, uint prot);
wdenk's avatar
wdenk committed
588
589

/* Set IP header */
590
591
void net_set_ip_header(uchar *pkt, struct in_addr dest, struct in_addr source,
		       u16 pkt_len, u8 proto);
592
void net_set_udp_header(uchar *pkt, struct in_addr dest, int dport,
593
				int sport, int len);
wdenk's avatar
wdenk committed
594

595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
/**
 * compute_ip_checksum() - Compute IP checksum
 *
 * @addr:	Address to check (must be 16-bit aligned)
 * @nbytes:	Number of bytes to check (normally a multiple of 2)
 * @return 16-bit IP checksum
 */
unsigned compute_ip_checksum(const void *addr, unsigned nbytes);

/**
 * add_ip_checksums() - add two IP checksums
 *
 * @offset:	Offset of first sum (if odd we do a byte-swap)
 * @sum:	First checksum
 * @new_sum:	New checksum to add
 * @return updated 16-bit IP checksum
 */
unsigned add_ip_checksums(unsigned offset, unsigned sum, unsigned new_sum);

/**
 * ip_checksum_ok() - check if a checksum is correct
 *
 * This works by making sure the checksum sums to 0
 *
 * @addr:	Address to check (must be 16-bit aligned)
 * @nbytes:	Number of bytes to check (normally a multiple of 2)
 * @return true if the checksum matches, false if not
 */
int ip_checksum_ok(const void *addr, unsigned nbytes);

Joe Hershberger's avatar
Joe Hershberger committed
625
/* Callbacks */
626
627
628
629
rxhand_f *net_get_udp_handler(void);	/* Get UDP RX packet handler */
void net_set_udp_handler(rxhand_f *);	/* Set UDP RX packet handler */
rxhand_f *net_get_arp_handler(void);	/* Get ARP RX packet handler */
void net_set_arp_handler(rxhand_f *);	/* Set ARP RX packet handler */
630
bool arp_is_waiting(void);		/* Waiting for ARP reply? */
631
void net_set_icmp_handler(rxhand_icmp_f *f); /* Set ICMP RX handler */
632
void net_set_timeout_handler(ulong, thand_f *);/* Set timeout handler */
wdenk's avatar
wdenk committed
633

634
635
636
637
638
639
640
/* Network loop state */
enum net_loop_state {
	NETLOOP_CONTINUE,
	NETLOOP_RESTART,
	NETLOOP_SUCCESS,
	NETLOOP_FAIL
};
Kim Phillips's avatar
Kim Phillips committed
641
642
extern enum net_loop_state net_state;

643
644
static inline void net_set_state(enum net_loop_state state)
{
645
	debug_cond(DEBUG_INT_STATE, "--- NetState set to %d\n", state);
646
647
648
	net_state = state;
}

649
650
651
652
653
654
655
656
/*
 * net_get_async_tx_pkt_buf - Get a packet buffer that is not in use for
 *			      sending an asynchronous reply
 *
 * returns - ptr to packet buffer
 */
uchar * net_get_async_tx_pkt_buf(void);

657
/* Transmit a packet */
658
static inline void net_send_packet(uchar *pkt, int len)
659
{
Joe Hershberger's avatar
Joe Hershberger committed
660
	/* Currently no way to return errors from eth_send() */
661
662
	(void) eth_send(pkt, len);
}
wdenk's avatar
wdenk committed
663

664
/*
665
 * Transmit "net_tx_packet" as UDP packet, performing ARP request if needed
666
 *  (ether will be populated)
667
668
669
670
671
672
673
 *
 * @param ether Raw packet buffer
 * @param dest IP address to send the datagram to
 * @param dport Destination UDP port
 * @param sport Source UDP port
 * @param payload_len Length of data after the UDP header
 */
674
675
676
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);
677
int net_send_udp_packet(uchar *ether, struct in_addr dest, int dport,
678
			int sport, int payload_len);
wdenk's avatar
wdenk committed
679

wdenk's avatar
wdenk committed
680
/* Processes a received packet */
681
void net_process_received_packet(uchar *in_packet, int len);
wdenk's avatar
wdenk committed
682

683
#if defined(CONFIG_NETCONSOLE) && !defined(CONFIG_SPL_BUILD)
684
void nc_start(void);
685
int nc_input_packet(uchar *pkt, struct in_addr src_ip, unsigned dest_port,
686
	unsigned src_port, unsigned len);
687
688
#endif

689
static __always_inline int eth_is_on_demand_init(void)
690
{
691
#if defined(CONFIG_NETCONSOLE) && !defined(CONFIG_SPL_BUILD)
692
693
694
695
696
697
698
699
700
701
	extern enum proto_t net_loop_last_protocol;

	return net_loop_last_protocol != NETCONS;
#else
	return 1;
#endif
}

static inline void eth_set_last_protocol(int protocol)
{
702
#if defined(CONFIG_NETCONSOLE) && !defined(CONFIG_SPL_BUILD)
703
704
705
706
707
708
	extern enum proto_t net_loop_last_protocol;

	net_loop_last_protocol = protocol;
#endif
}

709
710
711
712
713
714
/*
 * Check if autoload is enabled. If so, use either NFS or TFTP to download
 * the boot file.
 */
void net_auto_load(void);

wdenk's avatar
wdenk committed
715
716
717
718
719
720
721
722
/*
 * The following functions are a bit ugly, but necessary to deal with
 * alignment restrictions on ARM.
 *
 * We're using inline functions, which had the smallest memory
 * footprint in our tests.
 */
/* return IP *in network byteorder* */
723
static inline struct in_addr net_read_ip(void *from)
wdenk's avatar
wdenk committed
724
{
725
	struct in_addr ip;
726
727

	memcpy((void *)&ip, (void *)from, sizeof(ip));
wdenk's avatar
wdenk committed
728
729
730
731
	return ip;
}

/* return ulong *in network byteorder* */
732
static inline u32 net_read_u32(void *from)
wdenk's avatar
wdenk committed
733
{
734
	u32 l;
735
736

	memcpy((void *)&l, (void *)from, sizeof(l));
wdenk's avatar
wdenk committed
737
738
739
740
	return l;
}

/* write IP *in network byteorder* */
741
static inline void net_write_ip(void *to, struct in_addr ip)
wdenk's avatar
wdenk committed
742
{
743
	memcpy(to, (void *)&ip, sizeof(ip));
wdenk's avatar
wdenk committed
744
745
746
}

/* copy IP */
747
static inline void net_copy_ip(void *to, void *from)
wdenk's avatar
wdenk committed
748
{
749
	memcpy((void *)to, from, sizeof(struct in_addr));
wdenk's avatar
wdenk committed
750
751
752
}

/* copy ulong */
753
static inline void net_copy_u32(void *to, void *from)
wdenk's avatar
wdenk committed
754
{
755
	memcpy((void *)to, (void *)from, sizeof(u32));
wdenk's avatar
wdenk committed
756
757
}

758
/**
759
 * is_zero_ethaddr - Determine if give Ethernet address is all zeros.
760
761
762
763
 * @addr: Pointer to a six-byte array containing the Ethernet address
 *
 * Return true if the address is all zeroes.
 */
764
static inline int is_zero_ethaddr(const u8 *addr)
765
766
767
768
769
{
	return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]);
}

/**
770
 * is_multicast_ethaddr - Determine if the Ethernet address is a multicast.
771
772
773
774
775
 * @addr: Pointer to a six-byte array containing the Ethernet address
 *
 * Return true if the address is a multicast address.
 * By definition the broadcast address is also a multicast address.
 */
776
static inline int is_multicast_ethaddr(const u8 *addr)
777
{
778
	return 0x01 & addr[0];
779
780
}

781
/*
782
 * is_broadcast_ethaddr - Determine if the Ethernet address is broadcast
783
784
785
786
 * @addr: Pointer to a six-byte array containing the Ethernet address
 *
 * Return true if the address is the broadcast address.
 */
787
static inline int is_broadcast_ethaddr(const u8 *addr)
788
{
789
790
	return (addr[0] & addr[1] & addr[2] & addr[3] & addr[4] & addr[5]) ==
		0xff;
791
792
793
}

/*
794
 * is_valid_ethaddr - Determine if the given Ethernet address is valid
795
796
797
798
799
800
801
 * @addr: Pointer to a six-byte array containing the Ethernet address
 *
 * Check that the Ethernet address (MAC) is not 00:00:00:00:00:00, is not
 * a multicast address, and is not FF:FF:FF:FF:FF:FF.
 *
 * Return true if the address is valid.
 */
802
static inline int is_valid_ethaddr(const u8 *addr)
803
804
805
{
	/* FF:FF:FF:FF:FF:FF is a multicast address so we don't need to
	 * explicitly check for it here. */
806
	return !is_multicast_ethaddr(addr) && !is_zero_ethaddr(addr);
807
808
}

809
/**
810
 * net_random_ethaddr - Generate software assigned random Ethernet address
811
812
813
814
815
 * @addr: Pointer to a six-byte array containing the Ethernet address
 *
 * Generate a random Ethernet address (MAC) that is not multicast
 * and has the local assigned bit set.
 */
816
static inline void net_random_ethaddr(uchar *addr)
817
818
{
	int i;
819
	unsigned int seed = get_ticks();
820
821
822
823
824
825
826
827

	for (i = 0; i < 6; i++)
		addr[i] = rand_r(&seed);

	addr[0] &= 0xfe;	/* clear multicast bit */
	addr[0] |= 0x02;	/* set local assignment bit (IEEE802) */
}

wdenk's avatar
wdenk committed
828
/* Convert an IP address to a string */
829
void ip_to_string(struct in_addr x, char *s);
wdenk's avatar
wdenk committed
830

wdenk's avatar
wdenk committed
831
/* Convert a string to ip address */
832
struct in_addr string_to_ip(const char *s);
wdenk's avatar
wdenk committed
833

834
/* Convert a VLAN id to a string */
835
void vlan_to_string(ushort x, char *s);
836
837

/* Convert a string to a vlan id */
838
ushort string_to_vlan(const char *s);
839
840

/* read a VLAN id from an environment variable */
841
ushort env_get_vlan(char *);
842

wdenk's avatar
wdenk committed
843
/* copy a filename (allow for "..." notation, limit length) */
844
void copy_filename(char *dst, const char *src, int size);
wdenk's avatar
wdenk committed
845

846
847
848
/* check if serverip is specified in filename from the command line */
int is_serverip_in_cmd(void);

849
850
851
852
853
854
855
856
857
858
859
/**
 * net_parse_bootfile - Parse the bootfile env var / cmd line param
 *
 * @param ipaddr - a pointer to the ipaddr to populate if included in bootfile
 * @param filename - a pointer to the string to save the filename part
 * @param max_len - The longest - 1 that the filename part can be
 *
 * return 1 if parsed, 0 if bootfile is empty
 */
int net_parse_bootfile(struct in_addr *ipaddr, char *filename, int max_len);

860
/* get a random source port */
861
unsigned int random_port(void);
862

863
864
865
866
867
868
869
870
871
872
873
874
/**
 * update_tftp - Update firmware over TFTP (via DFU)
 *
 * This function updates board's firmware via TFTP
 *
 * @param addr - memory address where data is stored
 * @param interface - the DFU medium name - e.g. "mmc"
 * @param devstring - the DFU medium number - e.g. "1"
 *
 * @return - 0 on success, other value on failure
 */
int update_tftp(ulong addr, char *interface, char *devstring);
875

wdenk's avatar
wdenk committed
876
877
/**********************************************************************/

878
879
880
881
882
883
884
885
886
887
888
/**
 * eth_parse_enetaddr() - Parse a MAC address
 *
 * Convert a string MAC address
 *
 * @addr: MAC address in aa:bb:cc:dd:ee:ff format, where each part is a 2-digit
 *	hex value
 * @enetaddr: Place to put MAC address (6 bytes)
 */
void eth_parse_enetaddr(const char *addr, uint8_t *enetaddr);

wdenk's avatar
wdenk committed
889
#endif /* __NET_H__ */