Revert "BCM SDK: driver "downgrade" ver. 5.10.142.0: shared sources"
[tomato.git] / release / src-rt / shared / nvram / nvram_rw.c
blob163677fa9c9bcd1ab0a1698ccc8df635db7a1fcf
1 /*
2 * NVRAM variable manipulation (direct mapped flash)
4 * Copyright (C) 2009, 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_rw.c,v 1.51 2010/01/05 19:11:25 Exp $
15 #include <typedefs.h>
16 #include <bcmdefs.h>
17 #include <osl.h>
18 #include <bcmutils.h>
19 #include <siutils.h>
20 #include <mipsinc.h>
21 #include <bcmnvram.h>
22 #include <bcmendian.h>
23 #include <flashutl.h>
24 #include <hndsoc.h>
25 #include <sbchipc.h>
27 struct nvram_tuple *_nvram_realloc(struct nvram_tuple *t, const char *name, const char *value);
28 void _nvram_free(struct nvram_tuple *t);
29 int _nvram_read(void *buf);
31 extern char *_nvram_get(const char *name);
32 extern int _nvram_set(const char *name, const char *value);
33 extern int _nvram_unset(const char *name);
34 extern int _nvram_getall(char *buf, int count);
35 extern int _nvram_commit(struct nvram_header *header);
36 extern int _nvram_init(void *si);
37 extern void _nvram_exit(void);
39 #ifdef __ECOS
40 extern int kernel_initial;
41 #endif
43 static struct nvram_header *nvram_header = NULL;
44 static int nvram_do_reset = FALSE;
46 #define NVRAM_LOCK() do {} while (0)
47 #define NVRAM_UNLOCK() do {} while (0)
49 /* Convenience */
50 #define KB * 1024
51 #define MB * 1024 * 1024
53 char *
54 nvram_get(const char *name)
56 char *value;
58 #ifdef __ECOS
59 if (!kernel_initial)
60 return NULL;
61 #endif
63 NVRAM_LOCK();
64 value = _nvram_get(name);
65 NVRAM_UNLOCK();
67 return value;
70 int
71 nvram_getall(char *buf, int count)
73 int ret;
75 NVRAM_LOCK();
76 ret = _nvram_getall(buf, count);
77 NVRAM_UNLOCK();
79 return ret;
82 int
83 BCMINITFN(nvram_set)(const char *name, const char *value)
85 int ret;
87 NVRAM_LOCK();
88 ret = _nvram_set(name, value);
89 NVRAM_UNLOCK();
91 return ret;
94 int
95 BCMINITFN(nvram_unset)(const char *name)
97 int ret;
99 NVRAM_LOCK();
100 ret = _nvram_unset(name);
101 NVRAM_UNLOCK();
103 return ret;
107 BCMINITFN(nvram_resetgpio_init)(void *si)
109 char *value;
110 int gpio;
111 si_t *sih;
113 sih = (si_t *)si;
115 value = nvram_get("reset_gpio");
116 if (!value)
117 return -1;
119 gpio = (int) bcm_atoi(value);
120 if (gpio > 7)
121 return -1;
123 /* Setup GPIO input */
124 si_gpioouten(sih, ((uint32) 1 << gpio), 0, GPIO_DRV_PRIORITY);
126 return gpio;
130 BCMINITFN(nvram_reset)(void *si)
132 int gpio;
133 uint msec;
134 si_t * sih = (si_t *)si;
136 if ((gpio = nvram_resetgpio_init((void *)sih)) < 0)
137 return FALSE;
139 /* GPIO reset is asserted low */
140 for (msec = 0; msec < 5000; msec++) {
141 if (si_gpioin(sih) & ((uint32) 1 << gpio))
142 return FALSE;
143 OSL_DELAY(1000);
146 nvram_do_reset = TRUE;
147 return TRUE;
150 extern unsigned char embedded_nvram[];
152 static struct nvram_header *
153 BCMINITFN(find_nvram)(bool embonly, bool *isemb)
155 struct nvram_header *nvh;
156 uint32 off, lim;
159 if (!embonly) {
160 *isemb = FALSE;
161 lim = SI_FLASH2_SZ;
162 off = FLASH_MIN;
163 while (off <= lim) {
164 nvh = (struct nvram_header *)KSEG1ADDR(SI_FLASH2 + off - NVRAM_SPACE);
165 if (nvh->magic == NVRAM_MAGIC)
166 /* if (nvram_calc_crc(nvh) == (uint8) nvh->crc_ver_init) */{
167 return (nvh);
169 off <<= 1;
171 #ifdef BCMDBG
172 printf("find_nvram: nvram not found, trying embedded nvram next\n");
173 #endif /* BCMDBG */
176 /* Now check embedded nvram */
177 *isemb = TRUE;
178 nvh = (struct nvram_header *)KSEG1ADDR(SI_FLASH2 + (4 * 1024));
179 if (nvh->magic == NVRAM_MAGIC)
180 return (nvh);
181 nvh = (struct nvram_header *)KSEG1ADDR(SI_FLASH2 + 1024);
182 if (nvh->magic == NVRAM_MAGIC)
183 return (nvh);
184 #ifdef _CFE_
185 nvh = (struct nvram_header *)embedded_nvram;
186 if (nvh->magic == NVRAM_MAGIC)
187 return (nvh);
188 #endif
189 printf("find_nvram: no nvram found\n");
190 return (NULL);
194 BCMATTACHFN(nvram_init)(void *si)
196 bool isemb;
197 int ret;
198 si_t *sih;
199 static int nvram_status = -1;
201 #ifdef __ECOS
202 if (!kernel_initial)
203 return 0;
204 #endif
206 /* Check for previous 'restore defaults' condition */
207 if (nvram_status == 1)
208 return 1;
210 /* Check whether nvram already initilized */
211 if (nvram_status == 0 && !nvram_do_reset)
212 return 0;
214 sih = (si_t *)si;
216 /* Restore defaults from embedded NVRAM if button held down */
217 if (nvram_do_reset) {
218 /* Initialize with embedded NVRAM */
219 nvram_header = find_nvram(TRUE, &isemb);
220 ret = _nvram_init(si);
221 if (ret == 0) {
222 nvram_status = 1;
223 return 1;
225 nvram_status = -1;
226 _nvram_exit();
229 /* Find NVRAM */
230 nvram_header = find_nvram(FALSE, &isemb);
231 ret = _nvram_init(si);
232 if (ret == 0) {
233 /* Restore defaults if embedded NVRAM used */
234 if (nvram_header && isemb) {
235 ret = 1;
238 nvram_status = ret;
239 return ret;
243 BCMINITFN(nvram_append)(void *si, char *vars, uint varsz)
245 return 0;
248 void
249 BCMINITFN(nvram_exit)(void *si)
251 si_t *sih;
253 sih = (si_t *)si;
255 _nvram_exit();
259 BCMINITFN(_nvram_read)(void *buf)
261 uint32 *src, *dst;
262 uint i;
264 if (!nvram_header)
265 return -19; /* -ENODEV */
267 src = (uint32 *) nvram_header;
268 dst = (uint32 *) buf;
270 for (i = 0; i < sizeof(struct nvram_header); i += 4)
271 *dst++ = *src++;
273 for (; i < nvram_header->len && i < NVRAM_SPACE; i += 4)
274 *dst++ = ltoh32(*src++);
276 return 0;
279 struct nvram_tuple *
280 BCMINITFN(_nvram_realloc)(struct nvram_tuple *t, const char *name, const char *value)
282 if (!(t = MALLOC(NULL, sizeof(struct nvram_tuple) + strlen(name) + 1 +
283 strlen(value) + 1))) {
284 printf("_nvram_realloc: our of memory\n");
285 return NULL;
288 /* Copy name */
289 t->name = (char *) &t[1];
290 strcpy(t->name, name);
292 /* Copy value */
293 t->value = t->name + strlen(name) + 1;
294 strcpy(t->value, value);
296 return t;
299 void
300 BCMINITFN(_nvram_free)(struct nvram_tuple *t)
302 if (t)
303 MFREE(NULL, t, sizeof(struct nvram_tuple) + strlen(t->name) + 1 +
304 strlen(t->value) + 1);
308 BCMINITFN(nvram_commit)(void)
310 struct nvram_header *header;
311 int ret;
312 uint32 *src, *dst;
313 uint i;
315 if (!(header = (struct nvram_header *) MALLOC(NULL, NVRAM_SPACE))) {
316 printf("nvram_commit: out of memory\n");
317 return -12; /* -ENOMEM */
320 NVRAM_LOCK();
322 /* Regenerate NVRAM */
323 ret = _nvram_commit(header);
324 if (ret)
325 goto done;
327 src = (uint32 *) &header[1];
328 dst = src;
330 for (i = sizeof(struct nvram_header); i < header->len && i < NVRAM_SPACE; i += 4)
331 *dst++ = htol32(*src++);
333 #ifdef _CFE_
334 if ((ret = cfe_open("flash0.nvram")) >= 0) {
335 cfe_writeblk(ret, 0, (unsigned char *) header, header->len);
336 cfe_close(ret);
338 #else
339 if (sysFlashInit(NULL) == 0) {
340 /* set/write invalid MAGIC # (in case writing image fails/is interrupted)
341 * write the NVRAM image to flash(with invalid magic)
342 * set/write valid MAGIC #
344 header->magic = NVRAM_CLEAR_MAGIC;
345 nvWriteChars((unsigned char *)&header->magic, sizeof(header->magic));
347 header->magic = NVRAM_INVALID_MAGIC;
348 nvWrite((unsigned short *) header, NVRAM_SPACE);
350 header->magic = NVRAM_MAGIC;
351 nvWriteChars((unsigned char *)&header->magic, sizeof(header->magic));
353 #endif /* ifdef _CFE_ */
355 done:
356 NVRAM_UNLOCK();
357 MFREE(NULL, header, NVRAM_SPACE);
358 return ret;