diff options
author | Jonas Gorski <jonas.gorski@gmail.com> | 2012-11-07 03:25:28 -0500 |
---|---|---|
committer | John Crispin <blogic@openwrt.org> | 2012-11-09 05:37:18 -0500 |
commit | e7e333cb22e5e34e7a0792f262df52026815662e (patch) | |
tree | cad138b38d58b55f72106a50f0cba7eebb3148ef /arch/mips | |
parent | ba00e2e5c24f447fb09437a99df697787103f0cd (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')
-rw-r--r-- | arch/mips/bcm63xx/Makefile | 7 | ||||
-rw-r--r-- | arch/mips/bcm63xx/boards/board_bcm963xx.c | 71 | ||||
-rw-r--r-- | arch/mips/bcm63xx/nvram.c | 104 | ||||
-rw-r--r-- | arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h | 35 | ||||
-rw-r--r-- | arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h | 17 |
5 files changed, 154 insertions, 80 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 @@ | |||
1 | obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o reset.o setup.o \ | 1 | obj-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 | ||
4 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | 5 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o |
5 | 6 | ||
6 | obj-y += boards/ | 7 | obj-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 | ||
32 | static struct bcm963xx_nvram nvram; | ||
33 | static unsigned int mac_addr_used; | ||
34 | static struct board_info board; | 33 | static 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 | */ | ||
721 | static 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 | */ |
758 | void __init board_prom_init(void) | 720 | void __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 | */ | ||
23 | struct 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 | |||
37 | static struct bcm963xx_nvram nvram; | ||
38 | static int mac_addr_used; | ||
39 | |||
40 | int __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 | |||
65 | u8 *bcm63xx_nvram_get_name(void) | ||
66 | { | ||
67 | return nvram.name; | ||
68 | } | ||
69 | EXPORT_SYMBOL(bcm63xx_nvram_get_name); | ||
70 | |||
71 | int 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 | } | ||
104 | EXPORT_SYMBOL(bcm63xx_nvram_get_mac_address); | ||
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h new file mode 100644 index 000000000000..62d6a3b4d3b7 --- /dev/null +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h | |||
@@ -0,0 +1,35 @@ | |||
1 | #ifndef BCM63XX_NVRAM_H | ||
2 | #define BCM63XX_NVRAM_H | ||
3 | |||
4 | #include <linux/types.h> | ||
5 | |||
6 | /** | ||
7 | * bcm63xx_nvram_init() - initializes nvram | ||
8 | * @nvram: address of the nvram data | ||
9 | * | ||
10 | * Initialized the local nvram copy from the target address and checks | ||
11 | * its checksum. | ||
12 | * | ||
13 | * Returns 0 on success. | ||
14 | */ | ||
15 | int __init bcm63xx_nvram_init(void *nvram); | ||
16 | |||
17 | /** | ||
18 | * bcm63xx_nvram_get_name() - returns the board name according to nvram | ||
19 | * | ||
20 | * Returns the board name field from nvram. Note that it might not be | ||
21 | * null terminated if it is exactly 16 bytes long. | ||
22 | */ | ||
23 | u8 *bcm63xx_nvram_get_name(void); | ||
24 | |||
25 | /** | ||
26 | * bcm63xx_nvram_get_mac_address() - register & return a new mac address | ||
27 | * @mac: pointer to array for allocated mac | ||
28 | * | ||
29 | * Registers and returns a mac address from the allocated macs from nvram. | ||
30 | * | ||
31 | * Returns 0 on success. | ||
32 | */ | ||
33 | int bcm63xx_nvram_get_mac_address(u8 *mac); | ||
34 | |||
35 | #endif /* BCM63XX_NVRAM_H */ | ||
diff --git a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h index b0dd4bb53f7e..682bcf3b492a 100644 --- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h +++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h | |||
@@ -15,23 +15,6 @@ | |||
15 | #define BCM963XX_NVRAM_OFFSET 0x580 | 15 | #define BCM963XX_NVRAM_OFFSET 0x580 |
16 | 16 | ||
17 | /* | 17 | /* |
18 | * nvram structure | ||
19 | */ | ||
20 | struct bcm963xx_nvram { | ||
21 | u32 version; | ||
22 | u8 reserved1[256]; | ||
23 | u8 name[16]; | ||
24 | u32 main_tp_number; | ||
25 | u32 psi_size; | ||
26 | u32 mac_addr_count; | ||
27 | u8 mac_addr_base[6]; | ||
28 | u8 reserved2[2]; | ||
29 | u32 checksum_old; | ||
30 | u8 reserved3[720]; | ||
31 | u32 checksum_high; | ||
32 | }; | ||
33 | |||
34 | /* | ||
35 | * board definition | 18 | * board definition |
36 | */ | 19 | */ |
37 | struct board_info { | 20 | struct board_info { |