123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- From 2536295c2aeafc769215a6b2883126fa94c90b9a Mon Sep 17 00:00:00 2001
- From: Hante Meuleman <meuleman@broadcom.com>
- Date: Thu, 21 May 2015 15:27:23 +0200
- Subject: [PATCH] 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>
- ---
- arch/mips/bcm47xx/nvram.c | 60 ++++++++++++++++++++++++++++++++-----------
- include/linux/bcm47xx_nvram.h | 15 +++++++++++
- 2 files changed, 60 insertions(+), 15 deletions(-)
- --- a/arch/mips/bcm47xx/nvram.c
- +++ b/arch/mips/bcm47xx/nvram.c
- @@ -94,17 +94,22 @@ static int nvram_find_and_copy(void __io
- 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 *n
- 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);
- --- a/include/linux/bcm47xx_nvram.h
- +++ b/include/linux/bcm47xx_nvram.h
- @@ -12,7 +12,7 @@
- #include <linux/kernel.h>
- #include <linux/vmalloc.h>
-
- -#ifdef CONFIG_BCM47XX_NVRAM
- +#ifdef CONFIG_BCM47XX
- int bcm47xx_nvram_init_from_mem(u32 base, u32 lim);
- int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len);
- int bcm47xx_nvram_gpio_pin(const char *name);
|