Kaynağa Gözat

Merge branch 'master' of git://git.denx.de/u-boot-net

Tom Rini 6 yıl önce
ebeveyn
işleme
d4c7a9348f

+ 15 - 0
cmd/Kconfig

@@ -1121,6 +1121,16 @@ config BOOTP_HOSTNAME
 	help
 	  The name may or may not be qualified with the local domain name.
 
+config BOOTP_PREFER_SERVERIP
+	bool "serverip variable takes precedent over DHCP server IP."
+	depends on CMD_BOOTP
+	help
+	  By default a BOOTP/DHCP reply will overwrite the 'serverip' variable.
+
+	  With this option enabled, the 'serverip' variable in the environment
+	  takes precedence over DHCP server IP and will only be set by the DHCP
+	  server if not already set in the environment.
+
 config BOOTP_SUBNETMASK
 	bool "Request & store 'netmask' from BOOTP/DHCP server"
 	default y
@@ -1239,6 +1249,11 @@ config CMD_PXE
 	help
 	  Boot image via network using PXE protocol
 
+config CMD_WOL
+	bool "wol"
+	help
+	  Wait for wake-on-lan Magic Packet
+
 endif
 
 menu "Misc commands"

+ 1 - 0
cmd/Makefile

@@ -100,6 +100,7 @@ obj-$(CONFIG_CMD_PCI) += pci.o
 endif
 obj-y += pcmcia.o
 obj-$(CONFIG_CMD_PXE) += pxe.o
+obj-$(CONFIG_CMD_WOL) += wol.o
 obj-$(CONFIG_CMD_QFW) += qfw.o
 obj-$(CONFIG_CMD_READ) += read.o
 obj-$(CONFIG_CMD_REGINFO) += reginfo.o

+ 8 - 2
cmd/net.c

@@ -183,6 +183,8 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc,
 	int   size;
 	ulong addr;
 
+	net_boot_file_name_explicit = false;
+
 	/* pre-set load_addr */
 	s = env_get("loadaddr");
 	if (s != NULL)
@@ -199,15 +201,18 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc,
 		 * mis-interpreted as a valid number.
 		 */
 		addr = simple_strtoul(argv[1], &end, 16);
-		if (end == (argv[1] + strlen(argv[1])))
+		if (end == (argv[1] + strlen(argv[1]))) {
 			load_addr = addr;
-		else
+		} else {
+			net_boot_file_name_explicit = true;
 			copy_filename(net_boot_file_name, argv[1],
 				      sizeof(net_boot_file_name));
+		}
 		break;
 
 	case 3:
 		load_addr = simple_strtoul(argv[1], NULL, 16);
+		net_boot_file_name_explicit = true;
 		copy_filename(net_boot_file_name, argv[2],
 			      sizeof(net_boot_file_name));
 
@@ -220,6 +225,7 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc,
 			printf("Invalid address/size\n");
 			return CMD_RET_USAGE;
 		}
+		net_boot_file_name_explicit = true;
 		copy_filename(net_boot_file_name, argv[3],
 			      sizeof(net_boot_file_name));
 		break;

+ 33 - 0
cmd/wol.c

@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2018
+ * Lothar Felte, lothar.felten@gmail.com
+ */
+
+/*
+ * Wake-on-LAN support
+ */
+#include <common.h>
+#include <command.h>
+#include <net.h>
+
+#if defined(CONFIG_CMD_WOL)
+void wol_set_timeout(ulong);
+
+int do_wol(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	/* Validate arguments */
+	if (argc < 2)
+		return CMD_RET_USAGE;
+	wol_set_timeout(simple_strtol(argv[1], NULL, 10) * 1000);
+	if (net_loop(WOL) < 0)
+		return CMD_RET_FAILURE;
+	return CMD_RET_SUCCESS;
+}
+
+U_BOOT_CMD(
+	wol,	2,	1,	do_wol,
+	"wait for an incoming wake-on-lan packet",
+	"Timeout"
+);
+#endif

+ 1 - 0
configs/ax25-ae350_defconfig

@@ -40,3 +40,4 @@ CONFIG_DM_SPI=y
 CONFIG_ATCSPI200_SPI=y
 CONFIG_TIMER=y
 CONFIG_ATCPIT100_TIMER=y
+CONFIG_BOOTP_PREFER_SERVERIP=y

+ 1 - 0
configs/pengwyn_defconfig

@@ -37,6 +37,7 @@ CONFIG_CMD_MMC=y
 CONFIG_CMD_NAND=y
 CONFIG_CMD_SPI=y
 CONFIG_CMD_USB=y
+CONFIG_CMD_WOL=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_MTDPARTS=y

+ 2 - 0
drivers/net/mvneta.c

@@ -1702,11 +1702,13 @@ static int mvneta_probe(struct udevice *dev)
 
 		/* Align buffer area for descs and rx_buffers to 1MiB */
 		bd_space = memalign(1 << MMU_SECTION_SHIFT, BD_SPACE);
+		flush_dcache_range((ulong)bd_space, (ulong)bd_space + BD_SPACE);
 		mmu_set_region_dcache_behaviour((phys_addr_t)bd_space, BD_SPACE,
 						DCACHE_OFF);
 		buffer_loc.tx_descs = (struct mvneta_tx_desc *)bd_space;
 		size = roundup(MVNETA_MAX_TXD * sizeof(struct mvneta_tx_desc),
 				ARCH_DMA_MINALIGN);
+		memset(buffer_loc.tx_descs, 0, size);
 		buffer_loc.rx_descs = (struct mvneta_rx_desc *)
 			((phys_addr_t)bd_space + size);
 		size += roundup(MVNETA_MAX_RXD * sizeof(struct mvneta_rx_desc),

+ 1 - 1
drivers/net/zynq_gem.c

@@ -609,7 +609,7 @@ static int zynq_gem_miiphy_read(struct mii_dev *bus, int addr,
 {
 	struct zynq_gem_priv *priv = bus->priv;
 	int ret;
-	u16 val;
+	u16 val = 0;
 
 	ret = phyread(priv, addr, reg, &val);
 	debug("%s 0x%x, 0x%x, 0x%x, 0x%x\n", __func__, addr, reg, val, ret);

+ 0 - 1
include/configs/ax25-ae350.h

@@ -11,7 +11,6 @@
  * CPU and Board Configuration Options
  */
 #define CONFIG_BOOTP_SEND_HOSTNAME
-#define CONFIG_BOOTP_SERVERIP
 
 /*
  * Miscellaneous configurable options

+ 4 - 1
include/net.h

@@ -344,6 +344,7 @@ struct vlan_ethernet_hdr {
 
 #define PROT_IP		0x0800		/* IP protocol			*/
 #define PROT_ARP	0x0806		/* IP ARP protocol		*/
+#define PROT_WOL	0x0842		/* ether-wake WoL protocol	*/
 #define PROT_RARP	0x8035		/* IP ARP protocol		*/
 #define PROT_VLAN	0x8100		/* IEEE 802.1q protocol		*/
 #define PROT_IPV6	0x86dd		/* IPv6 over bluebook		*/
@@ -535,10 +536,12 @@ extern int		net_restart_wrap;	/* Tried all network devices */
 
 enum proto_t {
 	BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
-	TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT
+	TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL
 };
 
 extern char	net_boot_file_name[1024];/* Boot File name */
+/* Indicates whether the file name was specified on the command line */
+extern bool	net_boot_file_name_explicit;
 /* 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 */

+ 1 - 0
net/Makefile

@@ -24,6 +24,7 @@ obj-$(CONFIG_CMD_RARP) += rarp.o
 obj-$(CONFIG_CMD_SNTP) += sntp.o
 obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o
 obj-$(CONFIG_UDP_FUNCTION_FASTBOOT)  += fastboot.o
+obj-$(CONFIG_CMD_WOL)  += wol.o
 
 # Disable this warning as it is triggered by:
 # sprintf(buf, index ? "foo%d" : "foo", index)

+ 15 - 6
net/bootp.c

@@ -147,9 +147,14 @@ static void store_net_params(struct bootp_hdr *bp)
 {
 #if !defined(CONFIG_BOOTP_SERVERIP)
 	struct in_addr tmp_ip;
+	bool overwrite_serverip = true;
+
+#if defined(CONFIG_BOOTP_PREFER_SERVERIP)
+	overwrite_serverip = false;
+#endif
 
 	net_copy_ip(&tmp_ip, &bp->bp_siaddr);
-	if (tmp_ip.s_addr != 0)
+	if (tmp_ip.s_addr != 0 && (overwrite_serverip || !net_server_ip.s_addr))
 		net_copy_ip(&net_server_ip, &bp->bp_siaddr);
 	memcpy(net_server_ethaddr,
 	       ((struct ethernet_hdr *)net_rx_packet)->et_src, 6);
@@ -157,7 +162,8 @@ static void store_net_params(struct bootp_hdr *bp)
 #if defined(CONFIG_CMD_DHCP)
 	    !(dhcp_option_overload & OVERLOAD_FILE) &&
 #endif
-	    (strlen(bp->bp_file) > 0)) {
+	    (strlen(bp->bp_file) > 0) &&
+	    !net_boot_file_name_explicit) {
 		copy_filename(net_boot_file_name, bp->bp_file,
 			      sizeof(net_boot_file_name));
 	}
@@ -889,10 +895,13 @@ static void dhcp_process_options(uchar *popt, uchar *end)
 		case 66:	/* Ignore TFTP server name */
 			break;
 		case 67:	/* Bootfile option */
-			size = truncate_sz("Bootfile",
-					   sizeof(net_boot_file_name), oplen);
-			memcpy(&net_boot_file_name, popt + 2, size);
-			net_boot_file_name[size] = 0;
+			if (!net_boot_file_name_explicit) {
+				size = truncate_sz("Bootfile",
+						   sizeof(net_boot_file_name),
+						   oplen);
+				memcpy(&net_boot_file_name, popt + 2, size);
+				net_boot_file_name[size] = 0;
+			}
 			break;
 		default:
 #if defined(CONFIG_BOOTP_VENDOREX)

+ 2 - 0
net/fastboot.c

@@ -309,7 +309,9 @@ void fastboot_start_server(void)
 
 	fastboot_our_port = WELL_KNOWN_PORT;
 
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
 	fastboot_set_progress_callback(fastboot_timed_send_info);
+#endif
 	net_set_udp_handler(fastboot_handler);
 
 	/* zero out server ether in case the server ip has changed */

+ 21 - 0
net/net.c

@@ -78,6 +78,12 @@
  *			- own IP address
  *	We want:	- network time
  *	Next step:	none
+ *
+ * WOL:
+ *
+ *	Prerequisites:	- own ethernet address
+ *	We want:	- magic packet or timeout
+ *	Next step:	none
  */
 
 
@@ -108,6 +114,9 @@
 #if defined(CONFIG_CMD_SNTP)
 #include "sntp.h"
 #endif
+#if defined(CONFIG_CMD_WOL)
+#include "wol.h"
+#endif
 
 /** BOOTP EXTENTIONS **/
 
@@ -165,6 +174,8 @@ ushort		net_native_vlan = 0xFFFF;
 
 /* Boot File name */
 char net_boot_file_name[1024];
+/* Indicates whether the file name was specified on the command line */
+bool net_boot_file_name_explicit;
 /* 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 */
@@ -514,6 +525,11 @@ restart:
 		case LINKLOCAL:
 			link_local_start();
 			break;
+#endif
+#if defined(CONFIG_CMD_WOL)
+		case WOL:
+			wol_start();
+			break;
 #endif
 		default:
 			break;
@@ -1281,6 +1297,11 @@ void net_process_received_packet(uchar *in_packet, int len)
 				      ntohs(ip->udp_src),
 				      ntohs(ip->udp_len) - UDP_HDR_SIZE);
 		break;
+#ifdef CONFIG_CMD_WOL
+	case PROT_WOL:
+		wol_receive(ip, len);
+		break;
+#endif
 	}
 }
 

+ 96 - 0
net/wol.c

@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 Lothar Felten, lothar.felten@gmail.com
+ */
+
+#include <common.h>
+#include <command.h>
+#include <net.h>
+#include <environment.h>
+#include "wol.h"
+
+static ulong wol_timeout = WOL_DEFAULT_TIMEOUT;
+
+/*
+ * Check incoming Wake-on-LAN packet for:
+ * - sync bytes
+ * - sixteen copies of the target MAC address
+ *
+ * @param wol Wake-on-LAN packet
+ * @param len Packet length
+ */
+static int wol_check_magic(struct wol_hdr *wol, unsigned int len)
+{
+	int i;
+
+	if (len < sizeof(struct wol_hdr))
+		return 0;
+
+	for (i = 0; i < WOL_SYNC_COUNT; i++)
+		if (wol->wol_sync[i] != WOL_SYNC_BYTE)
+			return 0;
+
+	for (i = 0; i < WOL_MAC_REPETITIONS; i++)
+		if (memcmp(&wol->wol_dest[i * ARP_HLEN],
+			   net_ethaddr, ARP_HLEN) != 0)
+			return 0;
+
+	return 1;
+}
+
+void wol_receive(struct ip_udp_hdr *ip, unsigned int len)
+{
+	struct wol_hdr *wol;
+
+	wol = (struct wol_hdr *)ip;
+
+	if (!wol_check_magic(wol, len))
+		return;
+
+	/* save the optional password using the ether-wake formats */
+	/* don't check for exact length, the packet might have padding */
+	if (len >= (sizeof(struct wol_hdr) + WOL_PASSWORD_6B)) {
+		eth_env_set_enetaddr("wolpassword", wol->wol_passwd);
+	} else if (len >= (sizeof(struct wol_hdr) + WOL_PASSWORD_4B)) {
+		char buffer[16];
+		struct in_addr *ip = (struct in_addr *)(wol->wol_passwd);
+
+		ip_to_string(*ip, buffer);
+		env_set("wolpassword", buffer);
+	}
+	net_set_state(NETLOOP_SUCCESS);
+}
+
+static void wol_udp_handler(uchar *pkt, unsigned int dest, struct in_addr sip,
+			    unsigned int src, unsigned int len)
+{
+	struct wol_hdr *wol;
+
+	wol = (struct wol_hdr *)pkt;
+
+	/* UDP destination port must be 0, 7 or 9 */
+	if (dest != 0 && dest != 7 && dest != 9)
+		return;
+
+	if (!wol_check_magic(wol, len))
+		return;
+
+	net_set_state(NETLOOP_SUCCESS);
+}
+
+void wol_set_timeout(ulong timeout)
+{
+	wol_timeout = timeout;
+}
+
+static void wol_timeout_handler(void)
+{
+	eth_halt();
+	net_set_state(NETLOOP_FAIL);
+}
+
+void wol_start(void)
+{
+	net_set_timeout_handler(wol_timeout, wol_timeout_handler);
+	net_set_udp_handler(wol_udp_handler);
+}

+ 65 - 0
net/wol.h

@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * wol - Wake-on-LAN
+ *
+ * Supports both Wake-on-LAN packet types:
+ * - EtherType 0x0842 packets
+ * - UDP packets on ports 0, 7 and 9.
+ *
+ * Copyright 2018 Lothar Felten, lothar.felten@gmail.com
+ */
+
+#if defined(CONFIG_CMD_WOL)
+
+#ifndef __WOL_H__
+#define __WOL_H__
+
+#include <net.h>
+
+/**********************************************************************/
+
+#define WOL_SYNC_BYTE			0xFF
+#define WOL_SYNC_COUNT			6
+#define WOL_MAC_REPETITIONS		16
+#define WOL_DEFAULT_TIMEOUT		5000
+#define WOL_PASSWORD_4B			4
+#define WOL_PASSWORD_6B			6
+
+/*
+ * Wake-on-LAN header
+ */
+struct wol_hdr {
+	u8	wol_sync[WOL_SYNC_COUNT];			/* sync bytes */
+	u8	wol_dest[WOL_MAC_REPETITIONS * ARP_HLEN];	/* 16x MAC */
+	u8	wol_passwd[0];					/* optional */
+};
+
+/*
+ * Initialize wol (beginning of netloop)
+ */
+void wol_start(void);
+
+/*
+ * Check incoming Wake-on-LAN packet for:
+ * - sync bytes
+ * - sixteen copies of the target MAC address
+ *
+ * Optionally store the four or six byte password in the environment
+ * variable "wolpassword"
+ *
+ * @param ip IP header in the packet
+ * @param len Packet length
+ */
+void wol_receive(struct ip_udp_hdr *ip, unsigned int len);
+
+/*
+ * Set the timeout for the reception of a Wake-on-LAN packet
+ *
+ * @param timeout in milliseconds
+ */
+void wol_set_timeout(ulong timeout);
+
+/**********************************************************************/
+
+#endif /* __WOL_H__ */
+#endif