summaryrefslogtreecommitdiff
path: root/arch/mips/bcm47xx
diff options
context:
space:
mode:
authorHante Meuleman <meuleman@broadcom.com>2015-05-21 16:27:23 +0300
committerRalf Baechle <ralf@linux-mips.org>2015-06-21 22:54:00 +0300
commit55cab93bcf1422ab4298edc65c349c4304b4884e (patch)
tree451a5676b40487bfe56ee6a6ade53c4092e01dd5 /arch/mips/bcm47xx
parent30ad29bb48881ee11f5daf30c6fc50292ae08c57 (diff)
downloadlinux-55cab93bcf1422ab4298edc65c349c4304b4884e.tar.xz
mips: bcm47xx: allow retrieval of complete nvram contents
Host platforms such as routers supported by OpenWrt can support NVRAM reading directly from internal NVRAM store. The brcmfmac for one requires the complete nvram contents to select what needs to be sent to wireless device. Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: Hante Meuleman <meuleman@broadcom.com> Reviewed-by: Arend Van Spriel <arend@broadcom.com> Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/10093/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/bcm47xx')
-rw-r--r--arch/mips/bcm47xx/nvram.c60
1 files changed, 45 insertions, 15 deletions
diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c
index 95d028ca6f8a..2ed762ed4006 100644
--- a/arch/mips/bcm47xx/nvram.c
+++ b/arch/mips/bcm47xx/nvram.c
@@ -94,17 +94,22 @@ static int nvram_find_and_copy(void __iomem *iobase, u32 lim)
return -ENXIO;
found:
- if (header->len > size)
- pr_err("The nvram size accoridng to the header seems to be bigger than the partition on flash\n");
- if (header->len > NVRAM_SPACE)
- pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n",
- header->len, NVRAM_SPACE - 1);
-
src = (u32 *)header;
dst = (u32 *)nvram_buf;
for (i = 0; i < sizeof(struct nvram_header); i += 4)
*dst++ = __raw_readl(src++);
- for (; i < header->len && i < NVRAM_SPACE && i < size; i += 4)
+ header = (struct nvram_header *)nvram_buf;
+ if (header->len > size) {
+ pr_err("The nvram size according to the header seems to be bigger than the partition on flash\n");
+ header->len = size;
+ }
+ if (header->len >= NVRAM_SPACE) {
+ pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n",
+ header->len, NVRAM_SPACE - 1);
+ header->len = NVRAM_SPACE - 1;
+ }
+ /* proceed reading data after header */
+ for (; i < header->len; i += 4)
*dst++ = readl(src++);
nvram_buf[NVRAM_SPACE - 1] = '\0';
@@ -139,6 +144,7 @@ static int nvram_init(void)
#ifdef CONFIG_MTD
struct mtd_info *mtd;
struct nvram_header header;
+ struct nvram_header *pheader;
size_t bytes_read;
int err;
@@ -147,20 +153,21 @@ static int nvram_init(void)
return -ENODEV;
err = mtd_read(mtd, 0, sizeof(header), &bytes_read, (uint8_t *)&header);
- if (!err && header.magic == NVRAM_MAGIC) {
- u8 *dst = (uint8_t *)nvram_buf;
- size_t len = header.len;
-
- if (len >= NVRAM_SPACE) {
- len = NVRAM_SPACE - 1;
+ if (!err && header.magic == NVRAM_MAGIC &&
+ header.len > sizeof(header)) {
+ if (header.len >= NVRAM_SPACE) {
pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n",
- header.len, len);
+ header.len, NVRAM_SPACE);
+ header.len = NVRAM_SPACE - 1;
}
- err = mtd_read(mtd, 0, len, &bytes_read, dst);
+ err = mtd_read(mtd, 0, header.len, &bytes_read,
+ (u8 *)nvram_buf);
if (err)
return err;
+ pheader = (struct nvram_header *)nvram_buf;
+ pheader->len = header.len;
return 0;
}
#endif
@@ -219,3 +226,26 @@ int bcm47xx_nvram_gpio_pin(const char *name)
return -ENOENT;
}
EXPORT_SYMBOL(bcm47xx_nvram_gpio_pin);
+
+char *bcm47xx_nvram_get_contents(size_t *nvram_size)
+{
+ int err;
+ char *nvram;
+ struct nvram_header *header;
+
+ if (!nvram_buf[0]) {
+ err = nvram_init();
+ if (err)
+ return NULL;
+ }
+
+ header = (struct nvram_header *)nvram_buf;
+ *nvram_size = header->len - sizeof(struct nvram_header);
+ nvram = vmalloc(*nvram_size);
+ if (!nvram)
+ return NULL;
+ memcpy(nvram, &nvram_buf[sizeof(struct nvram_header)], *nvram_size);
+
+ return nvram;
+}
+EXPORT_SYMBOL(bcm47xx_nvram_get_contents);