2 * NVRAM variable manipulation (common)
4 * Copyright 2004, Broadcom Corporation
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.
16 #include <bcmendian.h>
21 extern struct nvram_tuple
* BCMINIT(_nvram_realloc
)(struct nvram_tuple
*t
, const char *name
, const char *value
);
22 extern void BCMINIT(_nvram_free
)(struct nvram_tuple
*t
);
23 extern int BCMINIT(_nvram_read
)(void *buf
);
25 char * BCMINIT(_nvram_get
)(const char *name
);
26 int BCMINIT(_nvram_set
)(const char *name
, const char *value
);
27 int BCMINIT(_nvram_unset
)(const char *name
);
28 int BCMINIT(_nvram_getall
)(char *buf
, int count
);
29 int BCMINIT(_nvram_commit
)(struct nvram_header
*header
);
30 int BCMINIT(_nvram_init
)(void);
31 void BCMINIT(_nvram_exit
)(void);
33 static struct nvram_tuple
* BCMINITDATA(nvram_hash
)[257];
34 static struct nvram_tuple
* nvram_dead
;
36 /* Free all tuples. Should be locked. */
38 BCMINITFN(nvram_free
)(void)
41 struct nvram_tuple
*t
, *next
;
44 for (i
= 0; i
< ARRAYSIZE(BCMINIT(nvram_hash
)); i
++) {
45 for (t
= BCMINIT(nvram_hash
)[i
]; t
; t
= next
) {
47 BCMINIT(_nvram_free
)(t
);
49 BCMINIT(nvram_hash
)[i
] = NULL
;
53 for (t
= nvram_dead
; t
; t
= next
) {
55 BCMINIT(_nvram_free
)(t
);
59 /* Indicate to per-port code that all tuples have been freed */
60 BCMINIT(_nvram_free
)(NULL
);
70 hash
= 31 * hash
+ *s
++;
75 /* (Re)initialize the hash table. Should be locked. */
77 BCMINITFN(nvram_rehash
)(struct nvram_header
*header
)
79 char buf
[] = "0xXXXXXXXX", *name
, *value
, *end
, *eq
;
81 /* (Re)initialize hash table */
82 BCMINIT(nvram_free
)();
84 /* Parse and set "name=value\0 ... \0\0" */
85 name
= (char *) &header
[1];
86 end
= (char *) header
+ NVRAM_SPACE
- 2;
87 end
[0] = end
[1] = '\0';
88 for (; *name
; name
= value
+ strlen(value
) + 1) {
89 if (!(eq
= strchr(name
, '=')))
93 BCMINIT(_nvram_set
)(name
, value
);
97 /* Set special SDRAM parameters */
98 if (!BCMINIT(_nvram_get
)("sdram_init")) {
99 sprintf(buf
, "0x%04X", (uint16
)(header
->crc_ver_init
>> 16));
100 BCMINIT(_nvram_set
)("sdram_init", buf
);
102 if (!BCMINIT(_nvram_get
)("sdram_config")) {
103 sprintf(buf
, "0x%04X", (uint16
)(header
->config_refresh
& 0xffff));
104 BCMINIT(_nvram_set
)("sdram_config", buf
);
106 if (!BCMINIT(_nvram_get
)("sdram_refresh")) {
107 sprintf(buf
, "0x%04X", (uint16
)((header
->config_refresh
>> 16) & 0xffff));
108 BCMINIT(_nvram_set
)("sdram_refresh", buf
);
110 if (!BCMINIT(_nvram_get
)("sdram_ncdl")) {
111 sprintf(buf
, "0x%08X", header
->config_ncdl
);
112 BCMINIT(_nvram_set
)("sdram_ncdl", buf
);
118 /* Get the value of an NVRAM variable. Should be locked. */
120 BCMINITFN(_nvram_get
)(const char *name
)
123 struct nvram_tuple
*t
;
130 i
= hash(name
) % ARRAYSIZE(BCMINIT(nvram_hash
));
132 /* Find the associated tuple in the hash table */
133 for (t
= BCMINIT(nvram_hash
)[i
]; t
&& strcmp(t
->name
, name
); t
= t
->next
);
135 value
= t
? t
->value
: NULL
;
140 /* Get the value of an NVRAM variable. Should be locked. */
142 BCMINITFN(_nvram_set
)(const char *name
, const char *value
)
145 struct nvram_tuple
*t
, *u
, **prev
;
148 i
= hash(name
) % ARRAYSIZE(BCMINIT(nvram_hash
));
150 /* Find the associated tuple in the hash table */
151 for (prev
= &BCMINIT(nvram_hash
)[i
], t
= *prev
; t
&& strcmp(t
->name
, name
); prev
= &t
->next
, t
= *prev
);
153 /* (Re)allocate tuple */
154 if (!(u
= BCMINIT(_nvram_realloc
)(t
, name
, value
)))
155 return -12; /* -ENOMEM */
157 /* Value reallocated */
161 /* Move old tuple to the dead table */
164 t
->next
= nvram_dead
;
168 /* Add new tuple to the hash table */
169 u
->next
= BCMINIT(nvram_hash
)[i
];
170 BCMINIT(nvram_hash
)[i
] = u
;
175 /* Unset the value of an NVRAM variable. Should be locked. */
177 BCMINITFN(_nvram_unset
)(const char *name
)
180 struct nvram_tuple
*t
, **prev
;
186 i
= hash(name
) % ARRAYSIZE(BCMINIT(nvram_hash
));
188 /* Find the associated tuple in the hash table */
189 for (prev
= &BCMINIT(nvram_hash
)[i
], t
= *prev
; t
&& strcmp(t
->name
, name
); prev
= &t
->next
, t
= *prev
);
191 /* Move it to the dead table */
194 t
->next
= nvram_dead
;
201 /* Get all NVRAM variables. Should be locked. */
203 BCMINITFN(_nvram_getall
)(char *buf
, int count
)
206 struct nvram_tuple
*t
;
211 /* Write name=value\0 ... \0\0 */
212 for (i
= 0; i
< ARRAYSIZE(BCMINIT(nvram_hash
)); i
++) {
213 for (t
= BCMINIT(nvram_hash
)[i
]; t
; t
= t
->next
) {
214 if ((count
- len
) > (strlen(t
->name
) + 1 + strlen(t
->value
) + 1))
215 len
+= sprintf(buf
+ len
, "%s=%s", t
->name
, t
->value
) + 1;
224 /* Regenerate NVRAM. Should be locked. */
226 BCMINITFN(_nvram_commit
)(struct nvram_header
*header
)
228 char *init
, *config
, *refresh
, *ncdl
;
231 struct nvram_tuple
*t
;
232 struct nvram_header tmp
;
235 /* Regenerate header */
236 header
->magic
= NVRAM_MAGIC
;
237 header
->crc_ver_init
= (NVRAM_VERSION
<< 8);
238 if (!(init
= BCMINIT(_nvram_get
)("sdram_init")) ||
239 !(config
= BCMINIT(_nvram_get
)("sdram_config")) ||
240 !(refresh
= BCMINIT(_nvram_get
)("sdram_refresh")) ||
241 !(ncdl
= BCMINIT(_nvram_get
)("sdram_ncdl"))) {
242 header
->crc_ver_init
|= SDRAM_INIT
<< 16;
243 header
->config_refresh
= SDRAM_CONFIG
;
244 header
->config_refresh
|= SDRAM_REFRESH
<< 16;
245 header
->config_ncdl
= 0;
247 header
->crc_ver_init
|= (bcm_strtoul(init
, NULL
, 0) & 0xffff) << 16;
248 header
->config_refresh
= bcm_strtoul(config
, NULL
, 0) & 0xffff;
249 header
->config_refresh
|= (bcm_strtoul(refresh
, NULL
, 0) & 0xffff) << 16;
250 header
->config_ncdl
= bcm_strtoul(ncdl
, NULL
, 0);
253 /* Clear data area */
254 ptr
= (char *) header
+ sizeof(struct nvram_header
);
255 bzero(ptr
, NVRAM_SPACE
- sizeof(struct nvram_header
));
257 /* Leave space for a double NUL at the end */
258 end
= (char *) header
+ NVRAM_SPACE
- 2;
260 /* Write out all tuples */
261 for (i
= 0; i
< ARRAYSIZE(BCMINIT(nvram_hash
)); i
++) {
262 for (t
= BCMINIT(nvram_hash
)[i
]; t
; t
= t
->next
) {
263 if ((ptr
+ strlen(t
->name
) + 1 + strlen(t
->value
) + 1) > end
)
265 ptr
+= sprintf(ptr
, "%s=%s", t
->name
, t
->value
) + 1;
269 /* End with a double NUL */
273 header
->len
= ROUNDUP(ptr
- (char *) header
, 4);
275 /* Little-endian CRC8 over the last 11 bytes of the header */
276 tmp
.crc_ver_init
= htol32(header
->crc_ver_init
);
277 tmp
.config_refresh
= htol32(header
->config_refresh
);
278 tmp
.config_ncdl
= htol32(header
->config_ncdl
);
279 crc
= hndcrc8((char *) &tmp
+ 9, sizeof(struct nvram_header
) - 9, CRC8_INIT_VALUE
);
281 /* Continue CRC8 over data bytes */
282 crc
= hndcrc8((char *) &header
[1], header
->len
- sizeof(struct nvram_header
), crc
);
285 header
->crc_ver_init
|= crc
;
287 /* Reinitialize hash table */
288 return BCMINIT(nvram_rehash
)(header
);
291 /* Initialize hash table. Should be locked. */
293 BCMINITFN(_nvram_init
)(void)
295 struct nvram_header
*header
;
298 if (!(header
= (struct nvram_header
*) kmalloc(NVRAM_SPACE
, GFP_ATOMIC
))) {
299 return -12; /* -ENOMEM */
302 if ((ret
= BCMINIT(_nvram_read
)(header
)) == 0 &&
303 header
->magic
== NVRAM_MAGIC
)
304 BCMINIT(nvram_rehash
)(header
);
310 /* Free hash table. Should be locked. */
312 BCMINITFN(_nvram_exit
)(void)
314 BCMINIT(nvram_free
)();
This page took 0.060812 seconds and 5 git commands to generate.