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>
This commit is contained in:
Jonas Gorski 2012-11-07 08:25:28 +00:00 committed by John Crispin
parent ba00e2e5c2
commit e7e333cb22
5 changed files with 154 additions and 80 deletions

View File

@ -1,6 +1,7 @@
obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o reset.o setup.o \ obj-y += clk.o cpu.o cs.o gpio.o irq.o nvram.o prom.o reset.o \
timer.o dev-dsp.o dev-enet.o dev-flash.o dev-pcmcia.o \ setup.o timer.o dev-dsp.o dev-enet.o dev-flash.o \
dev-rng.o dev-spi.o dev-uart.o dev-wdt.o dev-usb-usbd.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-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-y += boards/ obj-y += boards/

View File

@ -18,6 +18,7 @@
#include <bcm63xx_dev_uart.h> #include <bcm63xx_dev_uart.h>
#include <bcm63xx_regs.h> #include <bcm63xx_regs.h>
#include <bcm63xx_io.h> #include <bcm63xx_io.h>
#include <bcm63xx_nvram.h>
#include <bcm63xx_dev_pci.h> #include <bcm63xx_dev_pci.h>
#include <bcm63xx_dev_enet.h> #include <bcm63xx_dev_enet.h>
#include <bcm63xx_dev_dsp.h> #include <bcm63xx_dev_dsp.h>
@ -29,8 +30,6 @@
#define PFX "board_bcm963xx: " #define PFX "board_bcm963xx: "
static struct bcm963xx_nvram nvram;
static unsigned int mac_addr_used;
static struct board_info board; static struct board_info board;
/* /*
@ -715,51 +714,15 @@ const char *board_get_name(void)
return board.name; return board.name;
} }
/*
* 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 * early init callback, read nvram data from flash and checksum it
*/ */
void __init board_prom_init(void) void __init board_prom_init(void)
{ {
unsigned int check_len, i; unsigned int i;
u8 *boot_addr, *cfe, *p; u8 *boot_addr, *cfe;
char cfe_version[32]; char cfe_version[32];
char *board_name;
u32 val; u32 val;
/* read base address of boot chip select (0) /* read base address of boot chip select (0)
@ -782,27 +745,15 @@ void __init board_prom_init(void)
strcpy(cfe_version, "unknown"); strcpy(cfe_version, "unknown");
printk(KERN_INFO PFX "CFE version: %s\n", cfe_version); printk(KERN_INFO PFX "CFE version: %s\n", cfe_version);
/* extract nvram data */ if (bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET)) {
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) {
printk(KERN_ERR PFX "invalid nvram checksum\n"); printk(KERN_ERR PFX "invalid nvram checksum\n");
return; return;
} }
board_name = bcm63xx_nvram_get_name();
/* find board by name */ /* find board by name */
for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) { for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) {
if (strncmp(nvram.name, bcm963xx_boards[i]->name, if (strncmp(board_name, bcm963xx_boards[i]->name, 16))
sizeof(nvram.name)))
continue; continue;
/* copy, board desc array is marked initdata */ /* copy, board desc array is marked initdata */
memcpy(&board, bcm963xx_boards[i], sizeof(board)); 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 */ /* bail out if board is not found, will complain later */
if (!board.name[0]) { if (!board.name[0]) {
char name[17]; char name[17];
memcpy(name, nvram.name, 16); memcpy(name, board_name, 16);
name[16] = 0; name[16] = 0;
printk(KERN_ERR PFX "unknown bcm963xx board: %s\n", printk(KERN_ERR PFX "unknown bcm963xx board: %s\n",
name); name);
@ -890,11 +841,11 @@ int __init board_register_devices(void)
bcm63xx_pcmcia_register(); bcm63xx_pcmcia_register();
if (board.has_enet0 && 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); bcm63xx_enet_register(0, &board.enet0);
if (board.has_enet1 && 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); bcm63xx_enet_register(1, &board.enet1);
if (board.has_usbd) if (board.has_usbd)
@ -907,7 +858,7 @@ int __init board_register_devices(void)
* do this after registering enet devices * do this after registering enet devices
*/ */
#ifdef CONFIG_SSB_PCIHOST #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.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN); memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
if (ssb_arch_register_fallback_sprom( if (ssb_arch_register_fallback_sprom(

104
arch/mips/bcm63xx/nvram.c Normal file
View File

@ -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);

View File

@ -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 */

View File

@ -14,23 +14,6 @@
#define BCM963XX_CFE_VERSION_OFFSET 0x570 #define BCM963XX_CFE_VERSION_OFFSET 0x570
#define BCM963XX_NVRAM_OFFSET 0x580 #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 * board definition
*/ */