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>
20 extern struct nvram_tuple
* BCMINIT(_nvram_realloc
)(struct nvram_tuple
*t
, const char *name
, const char *value
);
21 extern void BCMINIT(_nvram_free
)(struct nvram_tuple
*t
);
22 extern int BCMINIT(_nvram_read
)(void *buf
);
24 char * BCMINIT(_nvram_get
)(const char *name
);
25 int BCMINIT(_nvram_set
)(const char *name
, const char *value
);
26 int BCMINIT(_nvram_unset
)(const char *name
);
27 int BCMINIT(_nvram_getall
)(char *buf
, int count
);
28 int BCMINIT(_nvram_commit
)(struct nvram_header
*header
);
29 int BCMINIT(_nvram_init
)(void);
30 void BCMINIT(_nvram_exit
)(void);
32 static struct nvram_tuple
* BCMINITDATA(nvram_hash
)[257];
33 static struct nvram_tuple
* nvram_dead
;
35 /* Free all tuples. Should be locked. */
37 BCMINITFN(nvram_free
)(void)
40 struct nvram_tuple
*t
, *next
;
43 for (i
= 0; i
< ARRAYSIZE(BCMINIT(nvram_hash
)); i
++) {
44 for (t
= BCMINIT(nvram_hash
)[i
]; t
; t
= next
) {
46 BCMINIT(_nvram_free
)(t
);
48 BCMINIT(nvram_hash
)[i
] = NULL
;
52 for (t
= nvram_dead
; t
; t
= next
) {
54 BCMINIT(_nvram_free
)(t
);
58 /* Indicate to per-port code that all tuples have been freed */
59 BCMINIT(_nvram_free
)(NULL
);
69 hash
= 31 * hash
+ *s
++;
74 /* (Re)initialize the hash table. Should be locked. */
76 BCMINITFN(nvram_rehash
)(struct nvram_header
*header
)
78 char buf
[] = "0xXXXXXXXX", *name
, *value
, *end
, *eq
;
80 /* (Re)initialize hash table */
81 BCMINIT(nvram_free
)();
83 /* Parse and set "name=value\0 ... \0\0" */
84 name
= (char *) &header
[1];
85 end
= (char *) header
+ NVRAM_SPACE
- 2;
86 end
[0] = end
[1] = '\0';
87 for (; *name
; name
= value
+ strlen(value
) + 1) {
88 if (!(eq
= strchr(name
, '=')))
92 BCMINIT(_nvram_set
)(name
, value
);
96 /* Set special SDRAM parameters */
97 if (!BCMINIT(_nvram_get
)("sdram_init")) {
98 sprintf(buf
, "0x%04X", (uint16
)(header
->crc_ver_init
>> 16));
99 BCMINIT(_nvram_set
)("sdram_init", buf
);
101 if (!BCMINIT(_nvram_get
)("sdram_config")) {
102 sprintf(buf
, "0x%04X", (uint16
)(header
->config_refresh
& 0xffff));
103 BCMINIT(_nvram_set
)("sdram_config", buf
);
105 if (!BCMINIT(_nvram_get
)("sdram_refresh")) {
106 sprintf(buf
, "0x%04X", (uint16
)((header
->config_refresh
>> 16) & 0xffff));
107 BCMINIT(_nvram_set
)("sdram_refresh", buf
);
109 if (!BCMINIT(_nvram_get
)("sdram_ncdl")) {
110 sprintf(buf
, "0x%08X", header
->config_ncdl
);
111 BCMINIT(_nvram_set
)("sdram_ncdl", buf
);
117 /* Get the value of an NVRAM variable. Should be locked. */
119 BCMINITFN(_nvram_get
)(const char *name
)
122 struct nvram_tuple
*t
;
129 i
= hash(name
) % ARRAYSIZE(BCMINIT(nvram_hash
));
131 /* Find the associated tuple in the hash table */
132 for (t
= BCMINIT(nvram_hash
)[i
]; t
&& strcmp(t
->name
, name
); t
= t
->next
);
134 value
= t
? t
->value
: NULL
;
139 /* Get the value of an NVRAM variable. Should be locked. */
141 BCMINITFN(_nvram_set
)(const char *name
, const char *value
)
144 struct nvram_tuple
*t
, *u
, **prev
;
147 i
= hash(name
) % ARRAYSIZE(BCMINIT(nvram_hash
));
149 /* Find the associated tuple in the hash table */
150 for (prev
= &BCMINIT(nvram_hash
)[i
], t
= *prev
; t
&& strcmp(t
->name
, name
); prev
= &t
->next
, t
= *prev
);
152 /* (Re)allocate tuple */
153 if (!(u
= BCMINIT(_nvram_realloc
)(t
, name
, value
)))
154 return -12; /* -ENOMEM */
156 /* Value reallocated */
160 /* Move old tuple to the dead table */
163 t
->next
= nvram_dead
;
167 /* Add new tuple to the hash table */
168 u
->next
= BCMINIT(nvram_hash
)[i
];
169 BCMINIT(nvram_hash
)[i
] = u
;
174 /* Unset the value of an NVRAM variable. Should be locked. */
176 BCMINITFN(_nvram_unset
)(const char *name
)
179 struct nvram_tuple
*t
, **prev
;
185 i
= hash(name
) % ARRAYSIZE(BCMINIT(nvram_hash
));
187 /* Find the associated tuple in the hash table */
188 for (prev
= &BCMINIT(nvram_hash
)[i
], t
= *prev
; t
&& strcmp(t
->name
, name
); prev
= &t
->next
, t
= *prev
);
190 /* Move it to the dead table */
193 t
->next
= nvram_dead
;
200 /* Get all NVRAM variables. Should be locked. */
202 BCMINITFN(_nvram_getall
)(char *buf
, int count
)
205 struct nvram_tuple
*t
;
210 /* Write name=value\0 ... \0\0 */
211 for (i
= 0; i
< ARRAYSIZE(BCMINIT(nvram_hash
)); i
++) {
212 for (t
= BCMINIT(nvram_hash
)[i
]; t
; t
= t
->next
) {
213 if ((count
- len
) > (strlen(t
->name
) + 1 + strlen(t
->value
) + 1))
214 len
+= sprintf(buf
+ len
, "%s=%s", t
->name
, t
->value
) + 1;
223 /* Regenerate NVRAM. Should be locked. */
225 BCMINITFN(_nvram_commit
)(struct nvram_header
*header
)
227 char *init
, *config
, *refresh
, *ncdl
;
230 struct nvram_tuple
*t
;
231 struct nvram_header tmp
;
234 /* Regenerate header */
235 header
->magic
= NVRAM_MAGIC
;
236 header
->crc_ver_init
= (NVRAM_VERSION
<< 8);
237 if (!(init
= BCMINIT(_nvram_get
)("sdram_init")) ||
238 !(config
= BCMINIT(_nvram_get
)("sdram_config")) ||
239 !(refresh
= BCMINIT(_nvram_get
)("sdram_refresh")) ||
240 !(ncdl
= BCMINIT(_nvram_get
)("sdram_ncdl"))) {
241 header
->crc_ver_init
|= SDRAM_INIT
<< 16;
242 header
->config_refresh
= SDRAM_CONFIG
;
243 header
->config_refresh
|= SDRAM_REFRESH
<< 16;
244 header
->config_ncdl
= 0;
246 header
->crc_ver_init
|= (simple_strtoul(init
, NULL
, 0) & 0xffff) << 16;
247 header
->config_refresh
= simple_strtoul(config
, NULL
, 0) & 0xffff;
248 header
->config_refresh
|= (simple_strtoul(refresh
, NULL
, 0) & 0xffff) << 16;
249 header
->config_ncdl
= simple_strtoul(ncdl
, NULL
, 0);
252 /* Clear data area */
253 ptr
= (char *) header
+ sizeof(struct nvram_header
);
254 bzero(ptr
, NVRAM_SPACE
- sizeof(struct nvram_header
));
256 /* Leave space for a double NUL at the end */
257 end
= (char *) header
+ NVRAM_SPACE
- 2;
259 /* Write out all tuples */
260 for (i
= 0; i
< ARRAYSIZE(BCMINIT(nvram_hash
)); i
++) {
261 for (t
= BCMINIT(nvram_hash
)[i
]; t
; t
= t
->next
) {
262 if ((ptr
+ strlen(t
->name
) + 1 + strlen(t
->value
) + 1) > end
)
264 ptr
+= sprintf(ptr
, "%s=%s", t
->name
, t
->value
) + 1;
268 /* End with a double NUL */
272 header
->len
= ROUNDUP(ptr
- (char *) header
, 4);
274 /* Little-endian CRC8 over the last 11 bytes of the header */
275 tmp
.crc_ver_init
= htol32(header
->crc_ver_init
);
276 tmp
.config_refresh
= htol32(header
->config_refresh
);
277 tmp
.config_ncdl
= htol32(header
->config_ncdl
);
278 crc
= hndcrc8((char *) &tmp
+ 9, sizeof(struct nvram_header
) - 9, 0xff);
280 /* Continue CRC8 over data bytes */
281 crc
= hndcrc8((char *) &header
[1], header
->len
- sizeof(struct nvram_header
), crc
);
284 header
->crc_ver_init
|= crc
;
286 /* Reinitialize hash table */
287 return BCMINIT(nvram_rehash
)(header
);
290 /* Initialize hash table. Should be locked. */
292 BCMINITFN(_nvram_init
)(void)
294 struct nvram_header
*header
;
297 if (!(header
= (struct nvram_header
*) kmalloc(NVRAM_SPACE
, GFP_ATOMIC
))) {
298 return -12; /* -ENOMEM */
301 if ((ret
= BCMINIT(_nvram_read
)(header
)) == 0 &&
302 header
->magic
== NVRAM_MAGIC
)
303 BCMINIT(nvram_rehash
)(header
);
309 /* Free hash table. Should be locked. */
311 BCMINITFN(_nvram_exit
)(void)
313 BCMINIT(nvram_free
)();
317 * Search the name=value vars for a specific one and return its value.
318 * Returns NULL if not found.
321 getvar(char *vars
, const char *name
)
328 /* first look in vars[] */
329 for (s
= vars
; s
&& *s
;) {
331 if ((memcmp(s
, name
, len
) == 0) && (s
[len
] == '='))
338 /* then query nvram */
339 return (nvram_get(name
));
343 * Search the vars for a specific one and return its value as
344 * an integer. Returns 0 if not found.
347 getintvar(char *vars
, const char *name
)
351 if ((val
= getvar(vars
, name
)) == NULL
)
354 return (simple_strtoul(val
, NULL
, 0));
This page took 0.084533 seconds and 5 git commands to generate.