Merge branch 'misc' of https://source.denx.de/u-boot/custodians/u-boot-tegra

Improvements for PMIC GPIO children, tegra20 pinmux driver fix, tegra
dts updates, various small adjustments and tweaks.
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 1f9b269..a04fcaa 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -2161,6 +2161,7 @@
 	depends on CMD_WGET
 	depends on PROT_TCP_LWIP
 	depends on MBEDTLS_LIB
+	depends on DM_RNG
 	select SHA256
 	select RSA
 	select ASYMMETRIC_KEY_TYPE
diff --git a/include/linux/string.h b/include/linux/string.h
index 27b2beb..d943fcc 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -72,6 +72,9 @@
 #ifndef __HAVE_ARCH_STRSTR
 extern char * strstr(const char *,const char *);
 #endif
+#ifndef __HAVE_ARCH_STRNSTR
+extern char *strnstr(const char *, const char *, size_t);
+#endif
 #ifndef __HAVE_ARCH_STRLEN
 extern __kernel_size_t strlen(const char *);
 #endif
diff --git a/include/net-lwip.h b/include/net-lwip.h
index 4d7f938..64e5c72 100644
--- a/include/net-lwip.h
+++ b/include/net-lwip.h
@@ -10,6 +10,7 @@
 	TFTPGET
 };
 
+void net_lwip_set_current(void);
 struct netif *net_lwip_new_netif(struct udevice *udev);
 struct netif *net_lwip_new_netif_noip(struct udevice *udev);
 void net_lwip_remove_netif(struct netif *netif);
diff --git a/lib/lwip/lwip/src/apps/tftp/tftp.c b/lib/lwip/lwip/src/apps/tftp/tftp.c
index 56aeabc..63b1e0e 100644
--- a/lib/lwip/lwip/src/apps/tftp/tftp.c
+++ b/lib/lwip/lwip/src/apps/tftp/tftp.c
@@ -264,19 +264,55 @@
   return TFTP_DEFAULT_BLOCK_SIZE;
 }
 
+/**
+ * find_option() - check if OACK message contains option
+ *
+ * @p:		message buffer
+ * @option:	option key
+ * Return:	option value
+ */
 static const char *
 find_option(struct pbuf *p, const char *option)
 {
-  int i;
-  u16_t optlen = strlen(option);
-  const char *b = p->payload;
+	const char *pos = p->payload;
+	int rem = p->len;
 
-  for (i = 0; i + optlen + 1 < p->len; i++) {
-    if (lwip_strnstr(b + i, option, optlen))
-      return b + i + optlen + 2;
-  }
+	/*
+	 * According to RFC 2347 the OACK packet has the following format:
+	 *
+	 * +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+
+	 * |  opc  |  opt1  | 0 | value1 | 0 |  optN  | 0 | valueN | 0 |
+	 * +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+
+	 */
+
+	/* Skip opc */
+	pos += 2;
+	rem -= 2;
+	if (rem <= 0)
+		return NULL;
+
+	for (;;) {
+		int len;
+		int diff;
+
+		len = strnlen(pos, rem) + 1;
+		if (rem < len)
+			break;
+		diff = strcmp(pos, option);
+		/* Skip option */
+		pos += len;
+		rem -= len;
+		len = strnlen(pos, rem) + 1;
+		if (rem < len)
+			break;
+		if (!diff)
+			return pos;
+		/* Skip value */
+		pos += len;
+		rem -= len;
+	}
 
-  return NULL;
+	return NULL;
 }
 
 static void
diff --git a/lib/lwip/u-boot/arch/cc.h b/lib/lwip/u-boot/arch/cc.h
index de13884..6104c29 100644
--- a/lib/lwip/u-boot/arch/cc.h
+++ b/lib/lwip/u-boot/arch/cc.h
@@ -34,7 +34,7 @@
 	       x, __LINE__, __FILE__); } while (0)
 
 #define atoi(str) (int)dectoul(str, NULL)
-#define lwip_strnstr(a, b, c)  strstr(a, b)
+#define lwip_strnstr(a, b, c)  strnstr(a, b, c)
 
 #define LWIP_ERR_T int
 #define LWIP_CONST_CAST(target_type, val) ((target_type)((uintptr_t)val))
diff --git a/lib/mbedtls/external/mbedtls/framework b/lib/mbedtls/external/mbedtls/framework
deleted file mode 160000
index 750634d..0000000
--- a/lib/mbedtls/external/mbedtls/framework
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 750634d3a51eb9d61b59fd5d801546927c946588
diff --git a/lib/string.c b/lib/string.c
index 0e0900d..d56f88d 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -15,13 +15,14 @@
  *    reentrant and should be faster). Use only strsep() in new code, please.
  */
 
+#include <asm/sections.h>
 #include <config.h>
+#include <limits.h>
 #include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/string.h>
 #include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/types.h>
 #include <malloc.h>
-#include <asm/sections.h>
 
 /**
  * strncasecmp - Case insensitive, length-limited string comparison
@@ -679,30 +680,48 @@
 	return p;
 }
 
-#ifndef __HAVE_ARCH_STRSTR
+#ifndef __HAVE_ARCH_STRNSTR
 /**
- * strstr - Find the first substring in a %NUL terminated string
- * @s1: The string to be searched
- * @s2: The string to search for
+ * strnstr() - find the first substring occurrence in a NUL terminated string
+ *
+ * @s1:		string to be searched
+ * @s2:		string to search for
+ * @len:	maximum number of characters in s2 to consider
+ *
+ * Return:	pointer to the first occurrence or NULL
  */
-char * strstr(const char * s1,const char * s2)
+char *strnstr(const char *s1, const char *s2, size_t len)
 {
-	int l1, l2;
+	size_t l1, l2;
 
+	l1 = strnlen(s1, len);
 	l2 = strlen(s2);
-	if (!l2)
-		return (char *) s1;
-	l1 = strlen(s1);
-	while (l1 >= l2) {
-		l1--;
-		if (!memcmp(s1,s2,l2))
+
+	for (; l1 >= l2; --l1, ++s1) {
+		if (!memcmp(s1, s2, l2))
 			return (char *) s1;
-		s1++;
 	}
+
 	return NULL;
 }
 #endif
 
+#ifndef __HAVE_ARCH_STRSTR
+/**
+ * strstr() - find the first substring occurrence in a NUL terminated string
+ *
+ * @s1:		string to be searched
+ * @s2:		string to search for
+ * @len:	maximum number of characters in s2 to consider
+ *
+ * Return:	pointer to the first occurrence or NULL
+ */
+char *strstr(const char *s1, const char *s2)
+{
+	return strnstr(s1, s2, SIZE_MAX);
+}
+#endif
+
 #ifndef __HAVE_ARCH_MEMCHR
 /**
  * memchr - Find a character in an area of memory.
diff --git a/net/lwip/dhcp.c b/net/lwip/dhcp.c
index e7d9147..3b7e470 100644
--- a/net/lwip/dhcp.c
+++ b/net/lwip/dhcp.c
@@ -115,7 +115,7 @@
 	int ret;
 	struct udevice *dev;
 
-	eth_set_current();
+	net_lwip_set_current();
 
 	dev = eth_get_dev();
 	if (!dev) {
diff --git a/net/lwip/dns.c b/net/lwip/dns.c
index 1de63c9..149bdb7 100644
--- a/net/lwip/dns.c
+++ b/net/lwip/dns.c
@@ -121,7 +121,7 @@
 	if (argc == 3)
 		var = argv[2];
 
-	eth_set_current();
+	net_lwip_set_current();
 
 	return dns_loop(eth_get_dev(), name, var);
 }
diff --git a/net/lwip/net-lwip.c b/net/lwip/net-lwip.c
index b863047..cab1dd7 100644
--- a/net/lwip/net-lwip.c
+++ b/net/lwip/net-lwip.c
@@ -127,6 +127,20 @@
 	return 0;
 }
 
+/* Initialize the lwIP stack and the ethernet devices and set current device  */
+void net_lwip_set_current(void)
+{
+	static bool init_done;
+
+	if (!init_done) {
+		eth_init_rings();
+		eth_init();
+		lwip_init();
+		init_done = true;
+	}
+	eth_set_current();
+}
+
 static struct netif *new_netif(struct udevice *udev, bool with_ip)
 {
 	unsigned char enetaddr[ARP_HLEN];
@@ -134,19 +148,10 @@
 	ip4_addr_t ip, mask, gw;
 	struct netif *netif;
 	int ret = 0;
-	static bool first_call = true;
 
 	if (!udev)
 		return NULL;
 
-	if (first_call) {
-		eth_init_rings();
-		/* Pick a valid active device, if any */
-		eth_init();
-		lwip_init();
-		first_call = false;
-	}
-
 	if (eth_start_udev(udev) < 0) {
 		log_err("Could not start %s\n", udev->name);
 		return NULL;
diff --git a/net/lwip/ping.c b/net/lwip/ping.c
index aa61753..200a702 100644
--- a/net/lwip/ping.c
+++ b/net/lwip/ping.c
@@ -168,7 +168,7 @@
 	if (!ipaddr_aton(argv[1], &addr))
 		return CMD_RET_USAGE;
 
-	eth_set_current();
+	net_lwip_set_current();
 
 	if (ping_loop(eth_get_dev(), &addr) < 0)
 		return CMD_RET_FAILURE;
diff --git a/net/lwip/tftp.c b/net/lwip/tftp.c
index fc4aff5..123d66b 100644
--- a/net/lwip/tftp.c
+++ b/net/lwip/tftp.c
@@ -280,7 +280,7 @@
 		goto out;
 	}
 
-	eth_set_current();
+	net_lwip_set_current();
 
 	if (tftp_loop(eth_get_dev(), laddr, fname, srvip, port) < 0)
 		ret = CMD_RET_FAILURE;
diff --git a/net/lwip/wget.c b/net/lwip/wget.c
index b76f6c0..14f27d4 100644
--- a/net/lwip/wget.c
+++ b/net/lwip/wget.c
@@ -354,7 +354,7 @@
 
 int wget_do_request(ulong dst_addr, char *uri)
 {
-	eth_set_current();
+	net_lwip_set_current();
 
 	if (!wget_info)
 		wget_info = &default_wget_info;
@@ -433,10 +433,15 @@
 
 	if (!strncmp(uri, "http://", strlen("http://"))) {
 		prefix_len = strlen("http://");
-	} else if (!strncmp(uri, "https://", strlen("https://"))) {
-		prefix_len = strlen("https://");
+	} else if (CONFIG_IS_ENABLED(WGET_HTTPS)) {
+		if (!strncmp(uri, "https://", strlen("https://"))) {
+			prefix_len = strlen("https://");
+		} else {
+			log_err("only http(s):// is supported\n");
+			return false;
+		}
 	} else {
-		log_err("only http(s):// is supported\n");
+		log_err("only http:// is supported\n");
 		return false;
 	}
 
diff --git a/test/lib/string.c b/test/lib/string.c
index 8d22f3f..31391a3 100644
--- a/test/lib/string.c
+++ b/test/lib/string.c
@@ -11,6 +11,7 @@
 
 #include <command.h>
 #include <log.h>
+#include <string.h>
 #include <test/lib.h>
 #include <test/test.h>
 #include <test/ut.h>
@@ -221,3 +222,42 @@
 	return 0;
 }
 LIB_TEST(lib_memdup, 0);
+
+/** lib_strnstr() - unit test for strnstr() */
+static int lib_strnstr(struct unit_test_state *uts)
+{
+	const char *s1 = "Itsy Bitsy Teenie Weenie";
+	const char *s2 = "eenie";
+	const char *s3 = "eery";
+
+	ut_asserteq_ptr(&s1[12], strnstr(s1, s2, SIZE_MAX));
+	ut_asserteq_ptr(&s1[12], strnstr(s1, s2, 17));
+	ut_assertnull(strnstr(s1, s2, 16));
+	ut_assertnull(strnstr(s1, s2, 0));
+	ut_asserteq_ptr(&s1[13], strnstr(&s1[3], &s2[1], SIZE_MAX));
+	ut_asserteq_ptr(&s1[13], strnstr(&s1[3], &s2[1], 14));
+	ut_assertnull(strnstr(&s1[3], &s2[1], 13));
+	ut_assertnull(strnstr(&s1[3], &s2[1], 0));
+	ut_assertnull(strnstr(s1, s3, SIZE_MAX));
+	ut_assertnull(strnstr(s1, s3, 0));
+
+	return 0;
+}
+LIB_TEST(lib_strnstr, 0);
+
+/** lib_strstr() - unit test for strstr() */
+static int lib_strstr(struct unit_test_state *uts)
+{
+	const char *s1 = "Itsy Bitsy Teenie Weenie";
+	const char *s2 = "eenie";
+	const char *s3 = "easy";
+
+	ut_asserteq_ptr(&s1[12], strstr(s1, s2));
+	ut_asserteq_ptr(&s1[13], strstr(&s1[3], &s2[1]));
+	ut_assertnull(strstr(s1, s3));
+	ut_asserteq_ptr(&s1[2], strstr(s1, &s3[2]));
+	ut_asserteq_ptr(&s1[8], strstr(&s1[5], &s3[2]));
+
+	return 0;
+}
+LIB_TEST(lib_strstr, 0);