TomatoVPN 1.27vpn3.6 release
[tomato.git] / release / src / shared / nvram / nvram_vx.c
blob5c8c0ee82794be43e93b8765bb58f4cdf9673a0e
1 /*
2 * NVRAM variable manipulation (direct mapped flash)
4 * Copyright 2005, Broadcom Corporation
5 * All Rights Reserved.
6 *
7 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
8 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
10 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
12 * $Id: nvram_vx.c,v 1.5.18.1 2005/09/23 06:27:05 honor Exp $
15 #include <typedefs.h>
16 #include <osl.h>
17 #include <mipsinc.h>
18 #include <bcmnvram.h>
19 #include <bcmendian.h>
20 #include <bcmutils.h>
21 #include <flashutl.h>
22 #include <sbconfig.h>
23 #include <sbchipc.h>
24 #include <sbutils.h>
26 struct nvram_tuple * BCMINIT(_nvram_realloc)(struct nvram_tuple *t, const char *name, const char *value);
27 void BCMINIT(_nvram_free)(struct nvram_tuple *t);
28 int BCMINIT(_nvram_read)(void *buf);
30 extern char * BCMINIT(_nvram_get)(const char *name);
31 extern int BCMINIT(_nvram_set)(const char *name, const char *value);
32 extern int BCMINIT(_nvram_unset)(const char *name);
33 extern int BCMINIT(_nvram_getall)(char *buf, int count);
34 extern int BCMINIT(_nvram_commit)(struct nvram_header *header);
35 extern int BCMINIT(_nvram_init)(void);
36 extern void BCMINIT(_nvram_exit)(void);
38 static struct nvram_header *nvram_header = NULL;
39 static ulong flash_base = 0;
41 #define NVRAM_LOCK() do {} while (0)
42 #define NVRAM_UNLOCK() do {} while (0)
44 /* Convenience */
45 #define KB * 1024
46 #define MB * 1024 * 1024
48 char *
49 BCMINITFN(nvram_get)(const char *name)
51 char *value;
53 NVRAM_LOCK();
54 value = BCMINIT(_nvram_get)(name);
55 NVRAM_UNLOCK();
57 return value;
60 int
61 BCMINITFN(nvram_getall)(char *buf, int count)
63 int ret;
65 NVRAM_LOCK();
66 ret = BCMINIT(_nvram_getall)(buf, count);
67 NVRAM_UNLOCK();
69 return ret;
72 int
73 BCMINITFN(nvram_set)(const char *name, const char *value)
75 int ret;
77 NVRAM_LOCK();
78 ret = BCMINIT(_nvram_set)(name, value);
79 NVRAM_UNLOCK();
81 return ret;
84 int
85 BCMINITFN(nvram_unset)(const char *name)
87 int ret;
89 NVRAM_LOCK();
90 ret = BCMINIT(_nvram_unset)(name);
91 NVRAM_UNLOCK();
93 return ret;
96 static bool
97 BCMINITFN(nvram_reset)(void *sbh)
99 chipcregs_t *cc;
100 char *value;
101 uint32 watchdog = 0, gpio;
102 uint idx, msec;
104 idx = sb_coreidx(sbh);
106 /* Check if we were soft reset */
107 if ((cc = sb_setcore(sbh, SB_CC, 0))) {
108 watchdog = R_REG(&cc->intstatus) & CI_WDRESET;
109 sb_setcoreidx(sbh, idx);
111 if (watchdog)
112 return FALSE;
114 value = BCMINIT(nvram_get)("reset_gpio");
115 if (!value)
116 return FALSE;
118 gpio = (uint32) bcm_atoi(value);
119 if (gpio > 7)
120 return FALSE;
122 /* Setup GPIO input */
123 sb_gpioouten(sbh, (1 << gpio), 0);
125 /* GPIO reset is asserted low */
126 for (msec = 0; msec < 5000; msec++) {
127 if (sb_gpioin(sbh) & (1 << gpio))
128 return FALSE;
129 OSL_DELAY(1000);
132 return TRUE;
135 extern unsigned char embedded_nvram[];
137 static struct nvram_header *
138 BCMINITFN(find_nvram)(bool embonly, bool *isemb)
140 struct nvram_header *nvh, tmp;
141 uint32 off, lim;
142 uint8 crc;
145 if (!embonly) {
146 *isemb = FALSE;
147 if (flash_base == SB_FLASH1)
148 lim = SB_FLASH1_SZ;
149 else
150 lim = SB_FLASH2_SZ;
151 off = FLASH_MIN;
152 while (off <= lim) {
153 nvh = (struct nvram_header *)KSEG1ADDR(flash_base + off - NVRAM_SPACE);
154 if (nvh->magic == NVRAM_MAGIC)
156 /* now check data integrity, checksum entire NVRAM */
157 tmp.crc_ver_init = htol32(nvh->crc_ver_init);
158 tmp.config_refresh = htol32(nvh->config_refresh);
159 tmp.config_ncdl = htol32(nvh->config_ncdl);
160 crc = hndcrc8((char *) &tmp + 9, sizeof(struct nvram_header) - 9, CRC8_INIT_VALUE);
161 crc = hndcrc8((char *) &nvh[1], nvh->len - sizeof(struct nvram_header), crc);
162 /* now compare calculated checksum with one stored in NVRAM */
163 if (crc == (nvh->crc_ver_init & 0xff))
164 return (nvh); /* return if crc's match */
166 off <<= 1;
170 /* Now check embedded nvram */
171 *isemb = TRUE;
172 nvh = (struct nvram_header *)KSEG1ADDR(flash_base + (4 * 1024));
173 if (nvh->magic == NVRAM_MAGIC)
174 return (nvh);
175 nvh = (struct nvram_header *)KSEG1ADDR(flash_base + 1024);
176 if (nvh->magic == NVRAM_MAGIC)
177 return (nvh);
178 #ifdef _CFE_
179 nvh = (struct nvram_header *)embedded_nvram;
180 if (nvh->magic == NVRAM_MAGIC)
181 return (nvh);
182 #endif
183 return (NULL);
186 int
187 BCMINITFN(nvram_init)(void *sbh)
189 uint idx;
190 bool isemb;
191 int ret;
194 idx = sb_coreidx(sbh);
195 if (sb_setcore(sbh, SB_CC, 0) != NULL) {
196 flash_base = SB_FLASH2;
197 sb_setcoreidx(sbh, idx);
198 } else
199 flash_base = SB_FLASH1;
201 /* Temporarily initialize with embedded NVRAM */
202 nvram_header = BCMINIT(find_nvram)(TRUE, &isemb);
203 ret = BCMINIT(_nvram_init)();
204 if (ret == 0) {
205 /* Restore defaults from embedded NVRAM if button held down */
206 if (BCMINIT(nvram_reset)(sbh)) {
207 return 1;
210 BCMINIT(_nvram_exit)();
213 /* Find NVRAM */
214 nvram_header = BCMINIT(find_nvram)(FALSE, &isemb);
215 ret = BCMINIT(_nvram_init)();
216 if (ret == 0) {
217 /* Restore defaults if embedded NVRAM used */
218 if (nvram_header && isemb) {
219 ret = 1;
222 return ret;
225 void
226 BCMINITFN(nvram_exit)(void)
228 BCMINIT(_nvram_exit)();
231 int
232 BCMINITFN(_nvram_read)(void *buf)
234 uint32 *src, *dst;
235 uint i;
237 if (!nvram_header)
238 return -19; /* -ENODEV */
240 src = (uint32 *) nvram_header;
241 dst = (uint32 *) buf;
243 for (i = 0; i < sizeof(struct nvram_header); i += 4)
244 *dst++ = *src++;
246 for (; i < nvram_header->len && i < NVRAM_SPACE; i += 4)
247 *dst++ = ltoh32(*src++);
249 return 0;
252 struct nvram_tuple *
253 BCMINITFN(_nvram_realloc)(struct nvram_tuple *t, const char *name, const char *value)
255 if (!(t = MALLOC(NULL, sizeof(struct nvram_tuple) + strlen(name) + 1 + strlen(value) + 1))) {
256 printf("_nvram_realloc: our of memory\n");
257 return NULL;
260 /* Copy name */
261 t->name = (char *) &t[1];
262 strcpy(t->name, name);
264 /* Copy value */
265 t->value = t->name + strlen(name) + 1;
266 strcpy(t->value, value);
268 return t;
271 void
272 BCMINITFN(_nvram_free)(struct nvram_tuple *t)
274 if (t)
275 MFREE(NULL, t, sizeof(struct nvram_tuple) + strlen(t->name) + 1 + strlen(t->value) + 1);
278 int
279 BCMINITFN(nvram_commit)(void)
281 struct nvram_header *header;
282 int ret;
283 uint32 *src, *dst;
284 uint i;
286 if (!(header = (struct nvram_header *) MALLOC(NULL, NVRAM_SPACE))) {
287 printf("nvram_commit: out of memory\n");
288 return -12; /* -ENOMEM */
291 NVRAM_LOCK();
293 /* Regenerate NVRAM */
294 ret = BCMINIT(_nvram_commit)(header);
295 if (ret)
296 goto done;
298 src = (uint32 *) &header[1];
299 dst = src;
301 for (i = sizeof(struct nvram_header); i < header->len && i < NVRAM_SPACE; i += 4)
302 *dst++ = htol32(*src++);
304 #ifdef _CFE_
305 if ((ret = cfe_open("flash0.nvram")) >= 0) {
306 cfe_writeblk(ret, 0, (unsigned char *) header, header->len);
307 cfe_close(ret);
309 #else
310 if (sysFlashInit(NULL) == 0)
311 nvWrite((unsigned short *) header, NVRAM_SPACE);
312 #endif
314 done:
315 NVRAM_UNLOCK();
316 MFREE(NULL, header, NVRAM_SPACE);
317 return ret;