From c63ef048747629cde1be29cb9eda4b2c5b10ee93 Mon Sep 17 00:00:00 2001
From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Fri, 18 May 2012 16:04:10 +0000
Subject: [PATCH] brcm47xx: fix nvram read out on devices with serial flash

detect nvram on Linksys E3200

SVN-Revision: 31790
---
 .../029-bcm47xx-read-nvram-from-sflash.patch  | 53 ++++++++++---------
 .../030-bcm47xx-bcma-nandflash.patch          |  6 +--
 ...urn-number-of-written-bytes-in-nvram.patch |  2 +-
 .../patches-3.3/400-arch-bcm47xx.patch        |  2 +-
 .../patches-3.3/820-wgt634u-nvram-fix.patch   |  4 +-
 5 files changed, 36 insertions(+), 31 deletions(-)

diff --git a/target/linux/brcm47xx/patches-3.3/029-bcm47xx-read-nvram-from-sflash.patch b/target/linux/brcm47xx/patches-3.3/029-bcm47xx-read-nvram-from-sflash.patch
index b3d13df39f..1a994d9037 100644
--- a/target/linux/brcm47xx/patches-3.3/029-bcm47xx-read-nvram-from-sflash.patch
+++ b/target/linux/brcm47xx/patches-3.3/029-bcm47xx-read-nvram-from-sflash.patch
@@ -24,7 +24,7 @@
  		base = bcma_cc->pflash.window;
  		lim = bcma_cc->pflash.window_size;
  		break;
-@@ -86,7 +84,110 @@ found:
+@@ -86,7 +84,115 @@ found:
  	for (i = 0; i < sizeof(struct nvram_header); i += 4)
  		*dst++ = *src++;
  	for (; i < header->len && i < NVRAM_SPACE; i += 4)
@@ -32,44 +32,49 @@
 +		*dst++ = *src++;
 +}
 +
-+static int early_nvram_init_sflash(void)
++static int find_nvram_size(void)
 +{
 +	struct nvram_header header;
++	int nvram_sizes[] = {NVRAM_SPACE, 0xF000, 2 * NVRAM_SPACE};
++	int i;
++	int ret;
++
++	for (i = 0; i < sizeof(nvram_sizes); i++) {
++		ret = bcm47xx_sflash.read(&bcm47xx_sflash, bcm47xx_sflash.size - nvram_sizes[i], sizeof(header), (u8 *)&header);
++		if (ret != sizeof(header))
++			return ret;
++		if (header.magic == NVRAM_HEADER)
++			return nvram_sizes[i];
++	}
++	return -1;
++}
++
++static int early_nvram_init_sflash(void)
++{
 +	u32 off;
 +	int ret;
 +	char *dst;
 +	int len;
++	int size;
 +
 +	/* check if the struct is already initilized */
 +	if (!bcm47xx_sflash.size)
 +		return -1;
 +
-+	off = FLASH_MIN;
-+	while (off <= bcm47xx_sflash.size) {
-+		ret = bcm47xx_sflash.read(&bcm47xx_sflash, off - NVRAM_SPACE, sizeof(header), (u8 *)&header);
-+		if (ret != sizeof(header))
-+			return ret;
-+		if (header.magic == NVRAM_HEADER)
-+			goto found;
-+		off <<= 1;
-+	}
++	size = find_nvram_size();
++	if (size <= 0)
++		return size;
 +
-+	off = FLASH_MIN;
-+	while (off <= bcm47xx_sflash.size) {
-+		ret = bcm47xx_sflash.read(&bcm47xx_sflash, off - (2 * NVRAM_SPACE), sizeof(header), (u8 *)&header);
-+		if (ret != sizeof(header))
-+			return ret;
-+		if (header.magic == NVRAM_HEADER)
-+			goto found;
-+		off <<= 1;
-+	}
-+	return -1;
-+
-+found:
 +	len = NVRAM_SPACE;
 +	dst = nvram_buf;
++	off = bcm47xx_sflash.size;
++	if (size > len) {
++		printk(KERN_WARNING "nvram on flash is bigger than the reserved"
++		       " space in memory, will just copy the first %i bytes\n",
++		       len);
++	}
 +	while (len) {
-+		ret = bcm47xx_sflash.read(&bcm47xx_sflash, off - (2 * NVRAM_SPACE), len, dst);
++		ret = bcm47xx_sflash.read(&bcm47xx_sflash, off - size, len, dst);
 +		if (ret < 0)
 +			return ret;
 +		off += ret;
diff --git a/target/linux/brcm47xx/patches-3.3/030-bcm47xx-bcma-nandflash.patch b/target/linux/brcm47xx/patches-3.3/030-bcm47xx-bcma-nandflash.patch
index 03dd321b16..00f3311a0d 100644
--- a/target/linux/brcm47xx/patches-3.3/030-bcm47xx-bcma-nandflash.patch
+++ b/target/linux/brcm47xx/patches-3.3/030-bcm47xx-bcma-nandflash.patch
@@ -46,7 +46,7 @@
  
  static char nvram_buf[NVRAM_SPACE];
  
-@@ -134,6 +136,51 @@ found:
+@@ -139,6 +141,51 @@ static int early_nvram_init_sflash(void)
  	return 0;
  }
  
@@ -64,7 +64,7 @@
 +	/* check if the struct is already initilized */
 +	if (!flash_size)
 +		return -1;
-+	
++
 +	cfe_env = 0;
 +
 +	off = FLASH_MIN;
@@ -98,7 +98,7 @@
  #ifdef CONFIG_BCM47XX_SSB
  static void early_nvram_init_ssb(void)
  {
-@@ -168,6 +215,11 @@ static void early_nvram_init_bcma(void)
+@@ -173,6 +220,11 @@ static void early_nvram_init_bcma(void)
  		if (err < 0)
  			printk(KERN_WARNING "can not read from flash: %i\n", err);
  		break;
diff --git a/target/linux/brcm47xx/patches-3.3/197-MIPS-BCM47XX-return-number-of-written-bytes-in-nvram.patch b/target/linux/brcm47xx/patches-3.3/197-MIPS-BCM47XX-return-number-of-written-bytes-in-nvram.patch
index 4c4507c2db..0a8c0a386f 100644
--- a/target/linux/brcm47xx/patches-3.3/197-MIPS-BCM47XX-return-number-of-written-bytes-in-nvram.patch
+++ b/target/linux/brcm47xx/patches-3.3/197-MIPS-BCM47XX-return-number-of-written-bytes-in-nvram.patch
@@ -1,7 +1,7 @@
 
 --- a/arch/mips/bcm47xx/nvram.c
 +++ b/arch/mips/bcm47xx/nvram.c
-@@ -263,8 +263,7 @@ int nvram_getenv(char *name, char *val,
+@@ -268,8 +268,7 @@ int nvram_getenv(char *name, char *val,
  		value = eq + 1;
  		if ((eq - var) == strlen(name) &&
  			strncmp(var, name, (eq - var)) == 0) {
diff --git a/target/linux/brcm47xx/patches-3.3/400-arch-bcm47xx.patch b/target/linux/brcm47xx/patches-3.3/400-arch-bcm47xx.patch
index 796a98aa82..c3c7aea541 100644
--- a/target/linux/brcm47xx/patches-3.3/400-arch-bcm47xx.patch
+++ b/target/linux/brcm47xx/patches-3.3/400-arch-bcm47xx.patch
@@ -1,6 +1,6 @@
 --- a/arch/mips/bcm47xx/nvram.c
 +++ b/arch/mips/bcm47xx/nvram.c
-@@ -269,3 +269,30 @@ int nvram_getenv(char *name, char *val,
+@@ -274,3 +274,30 @@ int nvram_getenv(char *name, char *val,
  	return NVRAM_ERR_ENVNOTFOUND;
  }
  EXPORT_SYMBOL(nvram_getenv);
diff --git a/target/linux/brcm47xx/patches-3.3/820-wgt634u-nvram-fix.patch b/target/linux/brcm47xx/patches-3.3/820-wgt634u-nvram-fix.patch
index baf339dca5..933aad2966 100644
--- a/target/linux/brcm47xx/patches-3.3/820-wgt634u-nvram-fix.patch
+++ b/target/linux/brcm47xx/patches-3.3/820-wgt634u-nvram-fix.patch
@@ -280,7 +280,7 @@ out the configuration than the in kernel cfe config reader.
  
  	off = FLASH_MIN;
  	while (off <= lim) {
-@@ -252,6 +273,12 @@ int nvram_getenv(char *name, char *val,
+@@ -257,6 +278,12 @@ int nvram_getenv(char *name, char *val,
  	if (!nvram_buf[0])
  		early_nvram_init();
  
@@ -293,7 +293,7 @@ out the configuration than the in kernel cfe config reader.
  	/* Look for name=value and return value */
  	var = &nvram_buf[sizeof(struct nvram_header)];
  	end = nvram_buf + sizeof(nvram_buf) - 2;
-@@ -280,6 +307,9 @@ char *nvram_get(const char *name)
+@@ -285,6 +312,9 @@ char *nvram_get(const char *name)
  	if (!nvram_buf[0])
  		early_nvram_init();
  
-- 
GitLab