brcm47xx: fix nvram read out on devices with serial flash

detect nvram on Linksys E3200

SVN-Revision: 31790
This commit is contained in:
Hauke Mehrtens 2012-05-18 16:04:10 +00:00
parent 7ad663dda6
commit c63ef04874
5 changed files with 36 additions and 31 deletions

View File

@ -24,7 +24,7 @@
base = bcma_cc->pflash.window; base = bcma_cc->pflash.window;
lim = bcma_cc->pflash.window_size; lim = bcma_cc->pflash.window_size;
break; break;
@@ -86,7 +84,110 @@ found: @@ -86,7 +84,115 @@ found:
for (i = 0; i < sizeof(struct nvram_header); i += 4) for (i = 0; i < sizeof(struct nvram_header); i += 4)
*dst++ = *src++; *dst++ = *src++;
for (; i < header->len && i < NVRAM_SPACE; i += 4) for (; i < header->len && i < NVRAM_SPACE; i += 4)
@ -32,44 +32,49 @@
+ *dst++ = *src++; + *dst++ = *src++;
+} +}
+ +
+static int early_nvram_init_sflash(void) +static int find_nvram_size(void)
+{ +{
+ struct nvram_header header; + 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; + u32 off;
+ int ret; + int ret;
+ char *dst; + char *dst;
+ int len; + int len;
+ int size;
+ +
+ /* check if the struct is already initilized */ + /* check if the struct is already initilized */
+ if (!bcm47xx_sflash.size) + if (!bcm47xx_sflash.size)
+ return -1; + return -1;
+ +
+ off = FLASH_MIN; + size = find_nvram_size();
+ while (off <= bcm47xx_sflash.size) { + if (size <= 0)
+ ret = bcm47xx_sflash.read(&bcm47xx_sflash, off - NVRAM_SPACE, sizeof(header), (u8 *)&header); + return size;
+ if (ret != sizeof(header))
+ return ret;
+ if (header.magic == NVRAM_HEADER)
+ goto found;
+ off <<= 1;
+ }
+ +
+ 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; + len = NVRAM_SPACE;
+ dst = nvram_buf; + 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) { + 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) + if (ret < 0)
+ return ret; + return ret;
+ off += ret; + off += ret;

View File

@ -46,7 +46,7 @@
static char nvram_buf[NVRAM_SPACE]; static char nvram_buf[NVRAM_SPACE];
@@ -134,6 +136,51 @@ found: @@ -139,6 +141,51 @@ static int early_nvram_init_sflash(void)
return 0; return 0;
} }
@ -64,7 +64,7 @@
+ /* check if the struct is already initilized */ + /* check if the struct is already initilized */
+ if (!flash_size) + if (!flash_size)
+ return -1; + return -1;
+ +
+ cfe_env = 0; + cfe_env = 0;
+ +
+ off = FLASH_MIN; + off = FLASH_MIN;
@ -98,7 +98,7 @@
#ifdef CONFIG_BCM47XX_SSB #ifdef CONFIG_BCM47XX_SSB
static void early_nvram_init_ssb(void) 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) if (err < 0)
printk(KERN_WARNING "can not read from flash: %i\n", err); printk(KERN_WARNING "can not read from flash: %i\n", err);
break; break;

View File

@ -1,7 +1,7 @@
--- a/arch/mips/bcm47xx/nvram.c --- a/arch/mips/bcm47xx/nvram.c
+++ b/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; value = eq + 1;
if ((eq - var) == strlen(name) && if ((eq - var) == strlen(name) &&
strncmp(var, name, (eq - var)) == 0) { strncmp(var, name, (eq - var)) == 0) {

View File

@ -1,6 +1,6 @@
--- a/arch/mips/bcm47xx/nvram.c --- a/arch/mips/bcm47xx/nvram.c
+++ b/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; return NVRAM_ERR_ENVNOTFOUND;
} }
EXPORT_SYMBOL(nvram_getenv); EXPORT_SYMBOL(nvram_getenv);

View File

@ -280,7 +280,7 @@ out the configuration than the in kernel cfe config reader.
off = FLASH_MIN; off = FLASH_MIN;
while (off <= lim) { 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]) if (!nvram_buf[0])
early_nvram_init(); early_nvram_init();
@ -293,7 +293,7 @@ out the configuration than the in kernel cfe config reader.
/* Look for name=value and return value */ /* Look for name=value and return value */
var = &nvram_buf[sizeof(struct nvram_header)]; var = &nvram_buf[sizeof(struct nvram_header)];
end = nvram_buf + sizeof(nvram_buf) - 2; 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]) if (!nvram_buf[0])
early_nvram_init(); early_nvram_init();