1a994d9037bcafabeebd91760c1210714f636fb7
[openwrt.git] / target / linux / brcm47xx / patches-3.3 / 029-bcm47xx-read-nvram-from-sflash.patch
1 --- a/arch/mips/bcm47xx/nvram.c
2 +++ b/arch/mips/bcm47xx/nvram.c
3 @@ -20,11 +20,12 @@
4  #include <asm/addrspace.h>
5  #include <asm/mach-bcm47xx/nvram.h>
6  #include <asm/mach-bcm47xx/bcm47xx.h>
7 +#include <asm/mach-bcm47xx/bus.h>
8  
9  static char nvram_buf[NVRAM_SPACE];
10  
11  /* Probe for NVRAM header */
12 -static void early_nvram_init(void)
13 +static void early_nvram_init_pflash(void)
14  {
15  #ifdef CONFIG_BCM47XX_SSB
16         struct ssb_chipcommon *ssb_cc;
17 @@ -50,9 +51,6 @@ static void early_nvram_init(void)
18  #ifdef CONFIG_BCM47XX_BCMA
19         case BCM47XX_BUS_TYPE_BCMA:
20                 bcma_cc = &bcm47xx_bus.bcma.bus.drv_cc;
21 -               if (bcma_cc->flash_type != BCMA_PFLASH)
22 -                       return;
23 -
24                 base = bcma_cc->pflash.window;
25                 lim = bcma_cc->pflash.window_size;
26                 break;
27 @@ -86,7 +84,115 @@ found:
28         for (i = 0; i < sizeof(struct nvram_header); i += 4)
29                 *dst++ = *src++;
30         for (; i < header->len && i < NVRAM_SPACE; i += 4)
31 -               *dst++ = le32_to_cpu(*src++);
32 +               *dst++ = *src++;
33 +}
34 +
35 +static int find_nvram_size(void)
36 +{
37 +       struct nvram_header header;
38 +       int nvram_sizes[] = {NVRAM_SPACE, 0xF000, 2 * NVRAM_SPACE};
39 +       int i;
40 +       int ret;
41 +
42 +       for (i = 0; i < sizeof(nvram_sizes); i++) {
43 +               ret = bcm47xx_sflash.read(&bcm47xx_sflash, bcm47xx_sflash.size - nvram_sizes[i], sizeof(header), (u8 *)&header);
44 +               if (ret != sizeof(header))
45 +                       return ret;
46 +               if (header.magic == NVRAM_HEADER)
47 +                       return nvram_sizes[i];
48 +       }
49 +       return -1;
50 +}
51 +
52 +static int early_nvram_init_sflash(void)
53 +{
54 +       u32 off;
55 +       int ret;
56 +       char *dst;
57 +       int len;
58 +       int size;
59 +
60 +       /* check if the struct is already initilized */
61 +       if (!bcm47xx_sflash.size)
62 +               return -1;
63 +
64 +       size = find_nvram_size();
65 +       if (size <= 0)
66 +               return size;
67 +
68 +       len = NVRAM_SPACE;
69 +       dst = nvram_buf;
70 +       off = bcm47xx_sflash.size;
71 +       if (size > len) {
72 +               printk(KERN_WARNING "nvram on flash is bigger than the reserved"
73 +                      " space in memory, will just copy the first %i bytes\n",
74 +                      len);
75 +       }
76 +       while (len) {
77 +               ret = bcm47xx_sflash.read(&bcm47xx_sflash, off - size, len, dst);
78 +               if (ret < 0)
79 +                       return ret;
80 +               off += ret;
81 +               len -= ret;
82 +               dst += ret;
83 +       }
84 +       return 0;
85 +}
86 +
87 +#ifdef CONFIG_BCM47XX_SSB
88 +static void early_nvram_init_ssb(void)
89 +{
90 +       int err;
91 +
92 +       switch (bcm47xx_bus.ssb.chipco.flash_type) {
93 +       case SSB_PFLASH:
94 +               early_nvram_init_pflash();
95 +               break;
96 +       case SSB_SFLASH:
97 +               err = early_nvram_init_sflash();
98 +               if (err < 0)
99 +                       printk(KERN_WARNING "can not read from flash: %i\n", err);
100 +               break;
101 +       default:
102 +               printk(KERN_WARNING "unknow flash type\n");
103 +       }
104 +}
105 +#endif
106 +
107 +#ifdef CONFIG_BCM47XX_BCMA
108 +static void early_nvram_init_bcma(void)
109 +{
110 +       int err;
111 +
112 +       switch (bcm47xx_bus.bcma.bus.drv_cc.flash_type) {
113 +       case BCMA_PFLASH:
114 +               early_nvram_init_pflash();
115 +               break;
116 +       case BCMA_SFLASH:
117 +               err = early_nvram_init_sflash();
118 +               if (err < 0)
119 +                       printk(KERN_WARNING "can not read from flash: %i\n", err);
120 +               break;
121 +       default:
122 +               printk(KERN_WARNING "unknow flash type\n");
123 +       }
124 +}
125 +#endif
126 +
127 +static void early_nvram_init(void)
128 +{
129 +       switch (bcm47xx_bus_type) {
130 +#ifdef CONFIG_BCM47XX_SSB
131 +       case BCM47XX_BUS_TYPE_SSB:
132 +               early_nvram_init_ssb();
133 +               break;
134 +#endif
135 +#ifdef CONFIG_BCM47XX_BCMA
136 +       case BCM47XX_BUS_TYPE_BCMA:
137 +               early_nvram_init_bcma();
138 +               break;
139 +#endif
140 +       }
141  }
142  
143  int nvram_getenv(char *name, char *val, size_t val_len)