aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/bcm63xx
diff options
context:
space:
mode:
authorJonas Gorski <jonas.gorski@gmail.com>2012-11-07 03:25:28 -0500
committerJohn Crispin <blogic@openwrt.org>2012-11-09 05:37:18 -0500
commite7e333cb22e5e34e7a0792f262df52026815662e (patch)
treecad138b38d58b55f72106a50f0cba7eebb3148ef /arch/mips/bcm63xx
parentba00e2e5c24f447fb09437a99df697787103f0cd (diff)
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> Patchwork: http://patchwork.linux-mips.org/patch/4516 Signed-off-by: John Crispin <blogic@openwrt.org>
Diffstat (limited to 'arch/mips/bcm63xx')
-rw-r--r--arch/mips/bcm63xx/Makefile7
-rw-r--r--arch/mips/bcm63xx/boards/board_bcm963xx.c71
-rw-r--r--arch/mips/bcm63xx/nvram.c104
3 files changed, 119 insertions, 63 deletions
diff --git a/arch/mips/bcm63xx/Makefile b/arch/mips/bcm63xx/Makefile
index bfc9b8422718..ac2807397c1c 100644
--- a/arch/mips/bcm63xx/Makefile
+++ b/arch/mips/bcm63xx/Makefile
@@ -1,6 +1,7 @@
1obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o reset.o setup.o \ 1obj-y += clk.o cpu.o cs.o gpio.o irq.o nvram.o prom.o reset.o \
2 timer.o dev-dsp.o dev-enet.o dev-flash.o dev-pcmcia.o \ 2 setup.o timer.o dev-dsp.o dev-enet.o dev-flash.o \
3 dev-rng.o dev-spi.o dev-uart.o dev-wdt.o dev-usb-usbd.o 3 dev-pcmcia.o dev-rng.o dev-spi.o dev-uart.o dev-wdt.o \
4 dev-usb-usbd.o
4obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 5obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
5 6
6obj-y += boards/ 7obj-y += boards/
diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c
index 1cd4d73f23c7..73be9b349690 100644
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -18,6 +18,7 @@
18#include <bcm63xx_dev_uart.h> 18#include <bcm63xx_dev_uart.h>
19#include <bcm63xx_regs.h> 19#include <bcm63xx_regs.h>
20#include <bcm63xx_io.h> 20#include <bcm63xx_io.h>
21#include <bcm63xx_nvram.h>
21#include <bcm63xx_dev_pci.h> 22#include <bcm63xx_dev_pci.h>
22#include <bcm63xx_dev_enet.h> 23#include <bcm63xx_dev_enet.h>
23#include <bcm63xx_dev_dsp.h> 24#include <bcm63xx_dev_dsp.h>
@@ -29,8 +30,6 @@
29 30
30#define PFX "board_bcm963xx: " 31#define PFX "board_bcm963xx: "
31 32
32static struct bcm963xx_nvram nvram;
33static unsigned int mac_addr_used;
34static struct board_info board; 33static struct board_info board;
35 34
36/* 35/*
@@ -716,50 +715,14 @@ const char *board_get_name(void)
716} 715}
717 716
718/* 717/*
719 * register & return a new board mac address
720 */
721static int board_get_mac_address(u8 *mac)
722{
723 u8 *oui;
724 int count;
725
726 if (mac_addr_used >= nvram.mac_addr_count) {
727 printk(KERN_ERR PFX "not enough mac address\n");
728 return -ENODEV;
729 }
730
731 memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
732 oui = mac + ETH_ALEN/2 - 1;
733 count = mac_addr_used;
734
735 while (count--) {
736 u8 *p = mac + ETH_ALEN - 1;
737
738 do {
739 (*p)++;
740 if (*p != 0)
741 break;
742 p--;
743 } while (p != oui);
744
745 if (p == oui) {
746 printk(KERN_ERR PFX "unable to fetch mac address\n");
747 return -ENODEV;
748 }
749 }
750
751 mac_addr_used++;
752 return 0;
753}
754
755/*
756 * early init callback, read nvram data from flash and checksum it 718 * early init callback, read nvram data from flash and checksum it
757 */ 719 */
758void __init board_prom_init(void) 720void __init board_prom_init(void)
759{ 721{
760 unsigned int check_len, i; 722 unsigned int i;
761 u8 *boot_addr, *cfe, *p; 723 u8 *boot_addr, *cfe;
762 char cfe_version[32]; 724 char cfe_version[32];
725 char *board_name;
763 u32 val; 726 u32 val;
764 727
765 /* read base address of boot chip select (0) 728 /* read base address of boot chip select (0)
@@ -782,27 +745,15 @@ void __init board_prom_init(void)
782 strcpy(cfe_version, "unknown"); 745 strcpy(cfe_version, "unknown");
783 printk(KERN_INFO PFX "CFE version: %s\n", cfe_version); 746 printk(KERN_INFO PFX "CFE version: %s\n", cfe_version);
784 747
785 /* extract nvram data */ 748 if (bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET)) {
786 memcpy(&nvram, boot_addr + BCM963XX_NVRAM_OFFSET, sizeof(nvram));
787
788 /* check checksum before using data */
789 if (nvram.version <= 4)
790 check_len = offsetof(struct bcm963xx_nvram, checksum_old);
791 else
792 check_len = sizeof(nvram);
793 val = 0;
794 p = (u8 *)&nvram;
795 while (check_len--)
796 val += *p;
797 if (val) {
798 printk(KERN_ERR PFX "invalid nvram checksum\n"); 749 printk(KERN_ERR PFX "invalid nvram checksum\n");
799 return; 750 return;
800 } 751 }
801 752
753 board_name = bcm63xx_nvram_get_name();
802 /* find board by name */ 754 /* find board by name */
803 for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) { 755 for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) {
804 if (strncmp(nvram.name, bcm963xx_boards[i]->name, 756 if (strncmp(board_name, bcm963xx_boards[i]->name, 16))
805 sizeof(nvram.name)))
806 continue; 757 continue;
807 /* copy, board desc array is marked initdata */ 758 /* copy, board desc array is marked initdata */
808 memcpy(&board, bcm963xx_boards[i], sizeof(board)); 759 memcpy(&board, bcm963xx_boards[i], sizeof(board));
@@ -812,7 +763,7 @@ void __init board_prom_init(void)
812 /* bail out if board is not found, will complain later */ 763 /* bail out if board is not found, will complain later */
813 if (!board.name[0]) { 764 if (!board.name[0]) {
814 char name[17]; 765 char name[17];
815 memcpy(name, nvram.name, 16); 766 memcpy(name, board_name, 16);
816 name[16] = 0; 767 name[16] = 0;
817 printk(KERN_ERR PFX "unknown bcm963xx board: %s\n", 768 printk(KERN_ERR PFX "unknown bcm963xx board: %s\n",
818 name); 769 name);
@@ -890,11 +841,11 @@ int __init board_register_devices(void)
890 bcm63xx_pcmcia_register(); 841 bcm63xx_pcmcia_register();
891 842
892 if (board.has_enet0 && 843 if (board.has_enet0 &&
893 !board_get_mac_address(board.enet0.mac_addr)) 844 !bcm63xx_nvram_get_mac_address(board.enet0.mac_addr))
894 bcm63xx_enet_register(0, &board.enet0); 845 bcm63xx_enet_register(0, &board.enet0);
895 846
896 if (board.has_enet1 && 847 if (board.has_enet1 &&
897 !board_get_mac_address(board.enet1.mac_addr)) 848 !bcm63xx_nvram_get_mac_address(board.enet1.mac_addr))
898 bcm63xx_enet_register(1, &board.enet1); 849 bcm63xx_enet_register(1, &board.enet1);
899 850
900 if (board.has_usbd) 851 if (board.has_usbd)
@@ -907,7 +858,7 @@ int __init board_register_devices(void)
907 * do this after registering enet devices 858 * do this after registering enet devices
908 */ 859 */
909#ifdef CONFIG_SSB_PCIHOST 860#ifdef CONFIG_SSB_PCIHOST
910 if (!board_get_mac_address(bcm63xx_sprom.il0mac)) { 861 if (!bcm63xx_nvram_get_mac_address(bcm63xx_sprom.il0mac)) {
911 memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN); 862 memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
912 memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN); 863 memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
913 if (ssb_arch_register_fallback_sprom( 864 if (ssb_arch_register_fallback_sprom(
diff --git a/arch/mips/bcm63xx/nvram.c b/arch/mips/bcm63xx/nvram.c
new file mode 100644
index 000000000000..b57a10db7c98
--- /dev/null
+++ b/arch/mips/bcm63xx/nvram.c
@@ -0,0 +1,104 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
7 * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
8 * Copyright (C) 2012 Jonas Gorski <jonas.gorski@gmail.com>
9 */
10
11#define pr_fmt(fmt) "bcm63xx_nvram: " fmt
12
13#include <linux/init.h>
14#include <linux/export.h>
15#include <linux/kernel.h>
16#include <linux/if_ether.h>
17
18#include <bcm63xx_nvram.h>
19
20/*
21 * nvram structure
22 */
23struct bcm963xx_nvram {
24 u32 version;
25 u8 reserved1[256];
26 u8 name[16];
27 u32 main_tp_number;
28 u32 psi_size;
29 u32 mac_addr_count;
30 u8 mac_addr_base[ETH_ALEN];
31 u8 reserved2[2];
32 u32 checksum_old;
33 u8 reserved3[720];
34 u32 checksum_high;
35};
36
37static struct bcm963xx_nvram nvram;
38static int mac_addr_used;
39
40int __init bcm63xx_nvram_init(void *addr)
41{
42 unsigned int check_len;
43 u8 *p;
44 u32 val;
45
46 /* extract nvram data */
47 memcpy(&nvram, addr, sizeof(nvram));
48
49 /* check checksum before using data */
50 if (nvram.version <= 4)
51 check_len = offsetof(struct bcm963xx_nvram, checksum_old);
52 else
53 check_len = sizeof(nvram);
54 val = 0;
55 p = (u8 *)&nvram;
56
57 while (check_len--)
58 val += *p;
59 if (val)
60 return -EINVAL;
61
62 return 0;
63}
64
65u8 *bcm63xx_nvram_get_name(void)
66{
67 return nvram.name;
68}
69EXPORT_SYMBOL(bcm63xx_nvram_get_name);
70
71int bcm63xx_nvram_get_mac_address(u8 *mac)
72{
73 u8 *oui;
74 int count;
75
76 if (mac_addr_used >= nvram.mac_addr_count) {
77 pr_err("not enough mac addresses\n");
78 return -ENODEV;
79 }
80
81 memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
82 oui = mac + ETH_ALEN/2 - 1;
83 count = mac_addr_used;
84
85 while (count--) {
86 u8 *p = mac + ETH_ALEN - 1;
87
88 do {
89 (*p)++;
90 if (*p != 0)
91 break;
92 p--;
93 } while (p != oui);
94
95 if (p == oui) {
96 pr_err("unable to fetch mac address\n");
97 return -ENODEV;
98 }
99 }
100
101 mac_addr_used++;
102 return 0;
103}
104EXPORT_SYMBOL(bcm63xx_nvram_get_mac_address);