nvram.patch 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. --- a/arch/mips/bcm47xx/Makefile
  2. +++ b/arch/mips/bcm47xx/Makefile
  3. @@ -3,4 +3,4 @@
  4. # under Linux.
  5. #
  6. -obj-y := gpio.o irq.o prom.o serial.o setup.o time.o wgt634u.o
  7. +obj-y := gpio.o irq.o nvram.o prom.o serial.o setup.o time.o wgt634u.o
  8. --- /dev/null
  9. +++ b/arch/mips/bcm47xx/nvram.c
  10. @@ -0,0 +1,98 @@
  11. +/*
  12. + * BCM947xx nvram variable access
  13. + *
  14. + * Copyright 2005, Broadcom Corporation
  15. + * Copyright 2006, Felix Fietkau <nbd@openwrt.org>
  16. + *
  17. + * This program is free software; you can redistribute it and/or modify it
  18. + * under the terms of the GNU General Public License as published by the
  19. + * Free Software Foundation; either version 2 of the License, or (at your
  20. + * option) any later version.
  21. + */
  22. +
  23. +#include <linux/init.h>
  24. +#include <linux/module.h>
  25. +#include <linux/ssb/ssb.h>
  26. +#include <linux/kernel.h>
  27. +#include <linux/string.h>
  28. +#include <linux/interrupt.h>
  29. +#include <linux/spinlock.h>
  30. +#include <linux/slab.h>
  31. +#include <asm/byteorder.h>
  32. +#include <asm/bootinfo.h>
  33. +#include <asm/addrspace.h>
  34. +#include <asm/io.h>
  35. +#include <asm/uaccess.h>
  36. +#include <asm/mach-bcm47xx/nvram.h>
  37. +#include <asm/mach-bcm47xx/bcm47xx.h>
  38. +
  39. +static char nvram_buf[NVRAM_SPACE];
  40. +
  41. +/* Probe for NVRAM header */
  42. +static void __init early_nvram_init(void)
  43. +{
  44. + struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore;
  45. + struct nvram_header *header;
  46. + int i;
  47. + u32 base, lim, off;
  48. + u32 *src, *dst;
  49. +
  50. + base = mcore->flash_window;
  51. + lim = mcore->flash_window_size;
  52. +
  53. + off = 0x20000;
  54. + while (off <= lim) {
  55. + /* Windowed flash access */
  56. + header = (struct nvram_header *) KSEG1ADDR(base + off - NVRAM_SPACE);
  57. + if (header->magic == NVRAM_HEADER)
  58. + goto found;
  59. + off <<= 1;
  60. + }
  61. +
  62. + /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
  63. + header = (struct nvram_header *) KSEG1ADDR(base + 4096);
  64. + if (header->magic == NVRAM_HEADER)
  65. + goto found;
  66. +
  67. + header = (struct nvram_header *) KSEG1ADDR(base + 1024);
  68. + if (header->magic == NVRAM_HEADER)
  69. + goto found;
  70. +
  71. + return;
  72. +
  73. +found:
  74. + src = (u32 *) header;
  75. + dst = (u32 *) nvram_buf;
  76. + for (i = 0; i < sizeof(struct nvram_header); i += 4)
  77. + *dst++ = *src++;
  78. + for (; i < header->len && i < NVRAM_SPACE; i += 4)
  79. + *dst++ = le32_to_cpu(*src++);
  80. +}
  81. +
  82. +char *nvram_get(const char *name)
  83. +{
  84. + char *var, *value, *end, *eq;
  85. +
  86. + if (!name)
  87. + return NULL;
  88. +
  89. + if (!nvram_buf[0])
  90. + early_nvram_init();
  91. +
  92. + /* Look for name=value and return value */
  93. + var = &nvram_buf[sizeof(struct nvram_header)];
  94. + end = nvram_buf + sizeof(nvram_buf) - 2;
  95. + end[0] = end[1] = '\0';
  96. + for (; *var; var = value + strlen(value) + 1) {
  97. + if (!(eq = strchr(var, '=')))
  98. + break;
  99. + value = eq + 1;
  100. + if ((eq - var) == strlen(name) &&
  101. + strncmp(var, name, (eq - var)) == 0)
  102. + return value;
  103. + }
  104. +
  105. + return NULL;
  106. +}
  107. +
  108. +EXPORT_SYMBOL(nvram_get);
  109. --- a/arch/mips/bcm47xx/setup.c
  110. +++ b/arch/mips/bcm47xx/setup.c
  111. @@ -33,6 +33,7 @@
  112. #include <asm/time.h>
  113. #include <bcm47xx.h>
  114. #include <asm/fw/cfe/cfe_api.h>
  115. +#include <asm/mach-bcm47xx/nvram.h>
  116. struct ssb_bus ssb_bcm47xx;
  117. EXPORT_SYMBOL(ssb_bcm47xx);
  118. @@ -77,6 +78,7 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus,
  119. struct ssb_init_invariants *iv)
  120. {
  121. char buf[100];
  122. + char *s;
  123. /* Fill boardinfo structure */
  124. memset(&(iv->boardinfo), 0 , sizeof(struct ssb_boardinfo));
  125. @@ -92,18 +94,47 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus,
  126. memset(&(iv->sprom), 0, sizeof(struct ssb_sprom));
  127. iv->sprom.revision = 3;
  128. - if (cfe_getenv("et0macaddr", buf, sizeof(buf)) >= 0)
  129. + if (cfe_getenv("et0macaddr", buf, sizeof(buf)) >= 0) {
  130. str2eaddr(buf, iv->sprom.et0mac);
  131. - if (cfe_getenv("et1macaddr", buf, sizeof(buf)) >= 0)
  132. + } else {
  133. + if ((s = nvram_get("et0macaddr")))
  134. + str2eaddr(s, iv->sprom.et0mac);
  135. + }
  136. +
  137. + if (cfe_getenv("et1macaddr", buf, sizeof(buf)) >= 0) {
  138. str2eaddr(buf, iv->sprom.et1mac);
  139. - if (cfe_getenv("et0phyaddr", buf, sizeof(buf)) >= 0)
  140. - iv->sprom.et0phyaddr = simple_strtoul(buf, NULL, 10);
  141. - if (cfe_getenv("et1phyaddr", buf, sizeof(buf)) >= 0)
  142. - iv->sprom.et1phyaddr = simple_strtoul(buf, NULL, 10);
  143. - if (cfe_getenv("et0mdcport", buf, sizeof(buf)) >= 0)
  144. + } else {
  145. + if ((s = nvram_get("et1macaddr")))
  146. + str2eaddr(s, iv->sprom.et1mac);
  147. + }
  148. +
  149. + if (cfe_getenv("et0phyaddr", buf, sizeof(buf)) >= 0) {
  150. + iv->sprom.et0phyaddr = simple_strtoul(buf, NULL, 0);
  151. + } else {
  152. + if ((s = nvram_get("et0phyaddr")))
  153. + iv->sprom.et0phyaddr = simple_strtoul(s, NULL, 0);
  154. + }
  155. +
  156. + if (cfe_getenv("et1phyaddr", buf, sizeof(buf)) >= 0) {
  157. + iv->sprom.et1phyaddr = simple_strtoul(buf, NULL, 0);
  158. + } else {
  159. + if ((s = nvram_get("et1phyaddr")))
  160. + iv->sprom.et1phyaddr = simple_strtoul(s, NULL, 0);
  161. + }
  162. +
  163. + if (cfe_getenv("et0mdcport", buf, sizeof(buf)) >= 0) {
  164. iv->sprom.et0mdcport = simple_strtoul(buf, NULL, 10);
  165. - if (cfe_getenv("et1mdcport", buf, sizeof(buf)) >= 0)
  166. + } else {
  167. + if ((s = nvram_get("et0mdcport")))
  168. + iv->sprom.et0mdcport = simple_strtoul(s, NULL, 10);
  169. + }
  170. +
  171. + if (cfe_getenv("et1mdcport", buf, sizeof(buf)) >= 0) {
  172. iv->sprom.et1mdcport = simple_strtoul(buf, NULL, 10);
  173. + } else {
  174. + if ((s = nvram_get("et1mdcport")))
  175. + iv->sprom.et1mdcport = simple_strtoul(s, NULL, 10);
  176. + }
  177. return 0;
  178. }
  179. --- /dev/null
  180. +++ b/arch/mips/include/asm/mach-bcm47xx/nvram.h
  181. @@ -0,0 +1,37 @@
  182. +/*
  183. + * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
  184. + *
  185. + * This program is free software; you can redistribute it and/or modify it
  186. + * under the terms of the GNU General Public License as published by the
  187. + * Free Software Foundation; either version 2 of the License, or (at your
  188. + * option) any later version.
  189. + */
  190. +
  191. +#ifndef __NVRAM_H
  192. +#define __NVRAM_H
  193. +
  194. +struct nvram_header {
  195. + u32 magic;
  196. + u32 len;
  197. + u32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */
  198. + u32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */
  199. + u32 config_ncdl; /* ncdl values for memc */
  200. +};
  201. +
  202. +struct nvram_tuple {
  203. + char *name;
  204. + char *value;
  205. + struct nvram_tuple *next;
  206. +};
  207. +
  208. +#define NVRAM_HEADER 0x48534C46 /* 'FLSH' */
  209. +#define NVRAM_VERSION 1
  210. +#define NVRAM_HEADER_SIZE 20
  211. +#define NVRAM_SPACE 0x8000
  212. +
  213. +#define NVRAM_MAX_VALUE_LEN 255
  214. +#define NVRAM_MAX_PARAM_LEN 64
  215. +
  216. +char *nvram_get(const char *name);
  217. +
  218. +#endif