aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/brcm47xx/patches-3.3/029-bcm47xx-read-nvram-from-sflash.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/brcm47xx/patches-3.3/029-bcm47xx-read-nvram-from-sflash.patch')
-rw-r--r--target/linux/brcm47xx/patches-3.3/029-bcm47xx-read-nvram-from-sflash.patch143
1 files changed, 143 insertions, 0 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
new file mode 100644
index 000000000..1a994d903
--- /dev/null
+++ b/target/linux/brcm47xx/patches-3.3/029-bcm47xx-read-nvram-from-sflash.patch
@@ -0,0 +1,143 @@
+--- a/arch/mips/bcm47xx/nvram.c
++++ b/arch/mips/bcm47xx/nvram.c
+@@ -20,11 +20,12 @@
+ #include <asm/addrspace.h>
+ #include <asm/mach-bcm47xx/nvram.h>
+ #include <asm/mach-bcm47xx/bcm47xx.h>
++#include <asm/mach-bcm47xx/bus.h>
+
+ static char nvram_buf[NVRAM_SPACE];
+
+ /* Probe for NVRAM header */
+-static void early_nvram_init(void)
++static void early_nvram_init_pflash(void)
+ {
+ #ifdef CONFIG_BCM47XX_SSB
+ struct ssb_chipcommon *ssb_cc;
+@@ -50,9 +51,6 @@ static void early_nvram_init(void)
+ #ifdef CONFIG_BCM47XX_BCMA
+ case BCM47XX_BUS_TYPE_BCMA:
+ bcma_cc = &bcm47xx_bus.bcma.bus.drv_cc;
+- if (bcma_cc->flash_type != BCMA_PFLASH)
+- return;
+-
+ base = bcma_cc->pflash.window;
+ lim = bcma_cc->pflash.window_size;
+ break;
+@@ -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)
+- *dst++ = le32_to_cpu(*src++);
++ *dst++ = *src++;
++}
++
++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;
++
++ size = find_nvram_size();
++ if (size <= 0)
++ return size;
++
++ 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 - size, len, dst);
++ if (ret < 0)
++ return ret;
++ off += ret;
++ len -= ret;
++ dst += ret;
++ }
++ return 0;
++}
++
++#ifdef CONFIG_BCM47XX_SSB
++static void early_nvram_init_ssb(void)
++{
++ int err;
++
++ switch (bcm47xx_bus.ssb.chipco.flash_type) {
++ case SSB_PFLASH:
++ early_nvram_init_pflash();
++ break;
++ case SSB_SFLASH:
++ err = early_nvram_init_sflash();
++ if (err < 0)
++ printk(KERN_WARNING "can not read from flash: %i\n", err);
++ break;
++ default:
++ printk(KERN_WARNING "unknow flash type\n");
++ }
++}
++#endif
++
++#ifdef CONFIG_BCM47XX_BCMA
++static void early_nvram_init_bcma(void)
++{
++ int err;
++
++ switch (bcm47xx_bus.bcma.bus.drv_cc.flash_type) {
++ case BCMA_PFLASH:
++ early_nvram_init_pflash();
++ break;
++ case BCMA_SFLASH:
++ err = early_nvram_init_sflash();
++ if (err < 0)
++ printk(KERN_WARNING "can not read from flash: %i\n", err);
++ break;
++ default:
++ printk(KERN_WARNING "unknow flash type\n");
++ }
++}
++#endif
++
++static void early_nvram_init(void)
++{
++ switch (bcm47xx_bus_type) {
++#ifdef CONFIG_BCM47XX_SSB
++ case BCM47XX_BUS_TYPE_SSB:
++ early_nvram_init_ssb();
++ break;
++#endif
++#ifdef CONFIG_BCM47XX_BCMA
++ case BCM47XX_BUS_TYPE_BCMA:
++ early_nvram_init_bcma();
++ break;
++#endif
++ }
+ }
+
+ int nvram_getenv(char *name, char *val, size_t val_len)