Fix 'Interference Mitigation' option
[tomato.git] / release / src-rt / shared / nvram / nvram_vx.c
blob74518b96880c60b97af45e843066cc53185a8e9d
1 /*
2 * NVRAM variable manipulation (direct mapped flash)
4 * Copyright 2004, 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$
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;
141 uint32 off, lim;
144 if (!embonly) {
145 *isemb = FALSE;
146 if (flash_base == SB_FLASH1)
147 lim = SB_FLASH1_SZ;
148 else
149 lim = SB_FLASH2_SZ;
150 off = FLASH_MIN;
151 while (off <= lim) {
152 nvh = (struct nvram_header *)KSEG1ADDR(flash_base + off - NVRAM_SPACE);
153 if (nvh->magic == NVRAM_MAGIC)
154 return (nvh);
155 off <<= 1;
159 /* Now check embedded nvram */
160 *isemb = TRUE;
161 nvh = (struct nvram_header *)KSEG1ADDR(flash_base + (4 * 1024));
162 if (nvh->magic == NVRAM_MAGIC)
163 return (nvh);
164 nvh = (struct nvram_header *)KSEG1ADDR(flash_base + 1024);
165 if (nvh->magic == NVRAM_MAGIC)
166 return (nvh);
167 #ifdef _CFE_
168 nvh = (struct nvram_header *)embedded_nvram;
169 if (nvh->magic == NVRAM_MAGIC)
170 return (nvh);
171 #endif
172 return (NULL);
175 int
176 BCMINITFN(nvram_init)(void *sbh)
178 uint idx;
179 bool isemb;
180 int ret;
183 idx = sb_coreidx(sbh);
184 if (sb_setcore(sbh, SB_CC, 0) != NULL) {
185 flash_base = SB_FLASH2;
186 sb_setcoreidx(sbh, idx);
187 } else
188 flash_base = SB_FLASH1;
190 /* Temporarily initialize with embedded NVRAM */
191 nvram_header = BCMINIT(find_nvram)(TRUE, &isemb);
192 ret = BCMINIT(_nvram_init)();
193 if (ret == 0) {
194 /* Restore defaults from embedded NVRAM if button held down */
195 if (BCMINIT(nvram_reset)(sbh)) {
196 return 1;
199 BCMINIT(_nvram_exit)();
202 /* Find NVRAM */
203 nvram_header = BCMINIT(find_nvram)(FALSE, &isemb);
204 ret = BCMINIT(_nvram_init)();
205 if (ret == 0) {
206 /* Restore defaults if embedded NVRAM used */
207 if (nvram_header && isemb) {
208 ret = 1;
211 return ret;
214 void
215 BCMINITFN(nvram_exit)(void)
217 BCMINIT(_nvram_exit)();
220 int
221 BCMINITFN(_nvram_read)(void *buf)
223 uint32 *src, *dst;
224 uint i;
226 if (!nvram_header)
227 return -19; /* -ENODEV */
229 src = (uint32 *) nvram_header;
230 dst = (uint32 *) buf;
232 for (i = 0; i < sizeof(struct nvram_header); i += 4)
233 *dst++ = *src++;
235 for (; i < nvram_header->len && i < NVRAM_SPACE; i += 4)
236 *dst++ = ltoh32(*src++);
238 return 0;
241 struct nvram_tuple *
242 BCMINITFN(_nvram_realloc)(struct nvram_tuple *t, const char *name, const char *value)
244 if (!(t = MALLOC(NULL, sizeof(struct nvram_tuple) + strlen(name) + 1 + strlen(value) + 1))) {
245 printf("_nvram_realloc: our of memory\n");
246 return NULL;
249 /* Copy name */
250 t->name = (char *) &t[1];
251 strcpy(t->name, name);
253 /* Copy value */
254 t->value = t->name + strlen(name) + 1;
255 strcpy(t->value, value);
257 return t;
260 void
261 BCMINITFN(_nvram_free)(struct nvram_tuple *t)
263 if (t)
264 MFREE(NULL, t, sizeof(struct nvram_tuple) + strlen(t->name) + 1 + strlen(t->value) + 1);
267 int
268 BCMINITFN(nvram_commit)(void)
270 struct nvram_header *header;
271 int ret;
272 uint32 *src, *dst;
273 uint i;
275 if (!(header = (struct nvram_header *) MALLOC(NULL, NVRAM_SPACE))) {
276 printf("nvram_commit: out of memory\n");
277 return -12; /* -ENOMEM */
280 NVRAM_LOCK();
282 /* Regenerate NVRAM */
283 ret = BCMINIT(_nvram_commit)(header);
284 if (ret)
285 goto done;
287 src = (uint32 *) &header[1];
288 dst = src;
290 for (i = sizeof(struct nvram_header); i < header->len && i < NVRAM_SPACE; i += 4)
291 *dst++ = htol32(*src++);
293 #ifdef _CFE_
294 if ((ret = cfe_open("flash0.nvram")) >= 0) {
295 cfe_writeblk(ret, 0, (unsigned char *) header, header->len);
296 cfe_close(ret);
298 #else
299 if (sysFlashInit(NULL) == 0)
300 nvWrite((unsigned short *) header, NVRAM_SPACE);
301 #endif
303 done:
304 NVRAM_UNLOCK();
305 MFREE(NULL, header, NVRAM_SPACE);
306 return ret;