summaryrefslogtreecommitdiff
path: root/target/linux/brcm63xx/patches-3.7/004-MIPS-BCM63XX-move-nvram-functions-into-their-own-fil.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/brcm63xx/patches-3.7/004-MIPS-BCM63XX-move-nvram-functions-into-their-own-fil.patch')
-rw-r--r--target/linux/brcm63xx/patches-3.7/004-MIPS-BCM63XX-move-nvram-functions-into-their-own-fil.patch344
1 files changed, 344 insertions, 0 deletions
diff --git a/target/linux/brcm63xx/patches-3.7/004-MIPS-BCM63XX-move-nvram-functions-into-their-own-fil.patch b/target/linux/brcm63xx/patches-3.7/004-MIPS-BCM63XX-move-nvram-functions-into-their-own-fil.patch
new file mode 100644
index 0000000000..4167e57433
--- /dev/null
+++ b/target/linux/brcm63xx/patches-3.7/004-MIPS-BCM63XX-move-nvram-functions-into-their-own-fil.patch
@@ -0,0 +1,344 @@
+From a4304adb62af528957ed8858c9eb4f2630abe6d7 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski@gmail.com>
+Date: Sat, 12 May 2012 22:51:08 +0200
+Subject: [PATCH] MIPS: BCM63XX: move nvram functions into their own file
+
+Refactor nvram related functions into its own unit for easier expansion
+and exposure of the values to other drivers.
+
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+---
+
+This patch depends on the previous reset helper patch series or the
+Makefile change needs to be merged manually. It has no real functional
+dependencies.
+
+ arch/mips/bcm63xx/Makefile | 7 +-
+ arch/mips/bcm63xx/boards/board_bcm963xx.c | 71 ++-----------
+ arch/mips/bcm63xx/nvram.c | 104 ++++++++++++++++++++
+ arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h | 35 +++++++
+ .../mips/include/asm/mach-bcm63xx/board_bcm963xx.h | 17 ---
+ 5 files changed, 154 insertions(+), 80 deletions(-)
+ create mode 100644 arch/mips/bcm63xx/nvram.c
+ create mode 100644 arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h
+
+--- a/arch/mips/bcm63xx/Makefile
++++ b/arch/mips/bcm63xx/Makefile
+@@ -1,6 +1,7 @@
+-obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o reset.o setup.o \
+- timer.o dev-dsp.o dev-enet.o dev-flash.o dev-pcmcia.o \
+- dev-rng.o dev-spi.o dev-uart.o dev-wdt.o dev-usb-usbd.o
++obj-y += clk.o cpu.o cs.o gpio.o irq.o nvram.o prom.o reset.o \
++ setup.o timer.o dev-dsp.o dev-enet.o dev-flash.o \
++ dev-pcmcia.o dev-rng.o dev-spi.o dev-uart.o dev-wdt.o \
++ dev-usb-usbd.o
+ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+
+ obj-y += boards/
+--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
+@@ -18,6 +18,7 @@
+ #include <bcm63xx_dev_uart.h>
+ #include <bcm63xx_regs.h>
+ #include <bcm63xx_io.h>
++#include <bcm63xx_nvram.h>
+ #include <bcm63xx_dev_pci.h>
+ #include <bcm63xx_dev_enet.h>
+ #include <bcm63xx_dev_dsp.h>
+@@ -29,8 +30,6 @@
+
+ #define PFX "board_bcm963xx: "
+
+-static struct bcm963xx_nvram nvram;
+-static unsigned int mac_addr_used;
+ static struct board_info board;
+
+ /*
+@@ -716,50 +715,14 @@ const char *board_get_name(void)
+ }
+
+ /*
+- * register & return a new board mac address
+- */
+-static int board_get_mac_address(u8 *mac)
+-{
+- u8 *oui;
+- int count;
+-
+- if (mac_addr_used >= nvram.mac_addr_count) {
+- printk(KERN_ERR PFX "not enough mac address\n");
+- return -ENODEV;
+- }
+-
+- memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
+- oui = mac + ETH_ALEN/2 - 1;
+- count = mac_addr_used;
+-
+- while (count--) {
+- u8 *p = mac + ETH_ALEN - 1;
+-
+- do {
+- (*p)++;
+- if (*p != 0)
+- break;
+- p--;
+- } while (p != oui);
+-
+- if (p == oui) {
+- printk(KERN_ERR PFX "unable to fetch mac address\n");
+- return -ENODEV;
+- }
+- }
+-
+- mac_addr_used++;
+- return 0;
+-}
+-
+-/*
+ * early init callback, read nvram data from flash and checksum it
+ */
+ void __init board_prom_init(void)
+ {
+- unsigned int check_len, i;
+- u8 *boot_addr, *cfe, *p;
++ unsigned int i;
++ u8 *boot_addr, *cfe;
+ char cfe_version[32];
++ char *board_name;
+ u32 val;
+
+ /* read base address of boot chip select (0)
+@@ -782,27 +745,15 @@ void __init board_prom_init(void)
+ strcpy(cfe_version, "unknown");
+ printk(KERN_INFO PFX "CFE version: %s\n", cfe_version);
+
+- /* extract nvram data */
+- memcpy(&nvram, boot_addr + BCM963XX_NVRAM_OFFSET, sizeof(nvram));
+-
+- /* check checksum before using data */
+- if (nvram.version <= 4)
+- check_len = offsetof(struct bcm963xx_nvram, checksum_old);
+- else
+- check_len = sizeof(nvram);
+- val = 0;
+- p = (u8 *)&nvram;
+- while (check_len--)
+- val += *p;
+- if (val) {
++ if (bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET)) {
+ printk(KERN_ERR PFX "invalid nvram checksum\n");
+ return;
+ }
+
++ board_name = bcm63xx_nvram_get_name();
+ /* find board by name */
+ for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) {
+- if (strncmp(nvram.name, bcm963xx_boards[i]->name,
+- sizeof(nvram.name)))
++ if (strncmp(board_name, bcm963xx_boards[i]->name, 16))
+ continue;
+ /* copy, board desc array is marked initdata */
+ memcpy(&board, bcm963xx_boards[i], sizeof(board));
+@@ -812,7 +763,7 @@ void __init board_prom_init(void)
+ /* bail out if board is not found, will complain later */
+ if (!board.name[0]) {
+ char name[17];
+- memcpy(name, nvram.name, 16);
++ memcpy(name, board_name, 16);
+ name[16] = 0;
+ printk(KERN_ERR PFX "unknown bcm963xx board: %s\n",
+ name);
+@@ -890,11 +841,11 @@ int __init board_register_devices(void)
+ bcm63xx_pcmcia_register();
+
+ if (board.has_enet0 &&
+- !board_get_mac_address(board.enet0.mac_addr))
++ !bcm63xx_nvram_get_mac_address(board.enet0.mac_addr))
+ bcm63xx_enet_register(0, &board.enet0);
+
+ if (board.has_enet1 &&
+- !board_get_mac_address(board.enet1.mac_addr))
++ !bcm63xx_nvram_get_mac_address(board.enet1.mac_addr))
+ bcm63xx_enet_register(1, &board.enet1);
+
+ if (board.has_usbd)
+@@ -907,7 +858,7 @@ int __init board_register_devices(void)
+ * do this after registering enet devices
+ */
+ #ifdef CONFIG_SSB_PCIHOST
+- if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
++ if (!bcm63xx_nvram_get_mac_address(bcm63xx_sprom.il0mac)) {
+ memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
+ memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
+ if (ssb_arch_register_fallback_sprom(
+--- /dev/null
++++ b/arch/mips/bcm63xx/nvram.c
+@@ -0,0 +1,104 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License. See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
++ * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
++ * Copyright (C) 2012 Jonas Gorski <jonas.gorski@gmail.com>
++ */
++
++#define pr_fmt(fmt) "bcm63xx_nvram: " fmt
++
++#include <linux/init.h>
++#include <linux/export.h>
++#include <linux/kernel.h>
++#include <linux/if_ether.h>
++
++#include <bcm63xx_nvram.h>
++
++/*
++ * nvram structure
++ */
++struct bcm963xx_nvram {
++ u32 version;
++ u8 reserved1[256];
++ u8 name[16];
++ u32 main_tp_number;
++ u32 psi_size;
++ u32 mac_addr_count;
++ u8 mac_addr_base[ETH_ALEN];
++ u8 reserved2[2];
++ u32 checksum_old;
++ u8 reserved3[720];
++ u32 checksum_high;
++};
++
++static struct bcm963xx_nvram nvram;
++static int mac_addr_used;
++
++int __init bcm63xx_nvram_init(void *addr)
++{
++ unsigned int check_len;
++ u8 *p;
++ u32 val;
++
++ /* extract nvram data */
++ memcpy(&nvram, addr, sizeof(nvram));
++
++ /* check checksum before using data */
++ if (nvram.version <= 4)
++ check_len = offsetof(struct bcm963xx_nvram, checksum_old);
++ else
++ check_len = sizeof(nvram);
++ val = 0;
++ p = (u8 *)&nvram;
++
++ while (check_len--)
++ val += *p;
++ if (val)
++ return -EINVAL;
++
++ return 0;
++}
++
++u8 *bcm63xx_nvram_get_name(void)
++{
++ return nvram.name;
++}
++EXPORT_SYMBOL(bcm63xx_nvram_get_name);
++
++int bcm63xx_nvram_get_mac_address(u8 *mac)
++{
++ u8 *oui;
++ int count;
++
++ if (mac_addr_used >= nvram.mac_addr_count) {
++ pr_err("not enough mac addresses\n");
++ return -ENODEV;
++ }
++
++ memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
++ oui = mac + ETH_ALEN/2 - 1;
++ count = mac_addr_used;
++
++ while (count--) {
++ u8 *p = mac + ETH_ALEN - 1;
++
++ do {
++ (*p)++;
++ if (*p != 0)
++ break;
++ p--;
++ } while (p != oui);
++
++ if (p == oui) {
++ pr_err("unable to fetch mac address\n");
++ return -ENODEV;
++ }
++ }
++
++ mac_addr_used++;
++ return 0;
++}
++EXPORT_SYMBOL(bcm63xx_nvram_get_mac_address);
+--- /dev/null
++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h
+@@ -0,0 +1,35 @@
++#ifndef BCM63XX_NVRAM_H
++#define BCM63XX_NVRAM_H
++
++#include <linux/types.h>
++
++/**
++ * bcm63xx_nvram_init() - initializes nvram
++ * @nvram: address of the nvram data
++ *
++ * Initialized the local nvram copy from the target address and checks
++ * its checksum.
++ *
++ * Returns 0 on success.
++ */
++int __init bcm63xx_nvram_init(void *nvram);
++
++/**
++ * bcm63xx_nvram_get_name() - returns the board name according to nvram
++ *
++ * Returns the board name field from nvram. Note that it might not be
++ * null terminated if it is exactly 16 bytes long.
++ */
++u8 *bcm63xx_nvram_get_name(void);
++
++/**
++ * bcm63xx_nvram_get_mac_address() - register & return a new mac address
++ * @mac: pointer to array for allocated mac
++ *
++ * Registers and returns a mac address from the allocated macs from nvram.
++ *
++ * Returns 0 on success.
++ */
++int bcm63xx_nvram_get_mac_address(u8 *mac);
++
++#endif /* BCM63XX_NVRAM_H */
+--- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
++++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
+@@ -15,23 +15,6 @@
+ #define BCM963XX_NVRAM_OFFSET 0x580
+
+ /*
+- * nvram structure
+- */
+-struct bcm963xx_nvram {
+- u32 version;
+- u8 reserved1[256];
+- u8 name[16];
+- u32 main_tp_number;
+- u32 psi_size;
+- u32 mac_addr_count;
+- u8 mac_addr_base[6];
+- u8 reserved2[2];
+- u32 checksum_old;
+- u8 reserved3[720];
+- u32 checksum_high;
+-};
+-
+-/*
+ * board definition
+ */
+ struct board_info {