Commit 0790ad78 authored by Kevin Hilman's avatar Kevin Hilman

ARM: DaVinci: Use new EEPROM interface for MAC address

When EEPROM is detected by board init code, read MAC out of EEPROM and
call the EMAC init routine passing the MAC address.  If EEPROM is not
found, then device code has a backup call to EMAC init.

Also, original i2c-emac code removed.
Signed-off-by: default avatarKevin Hilman <khilman@deeprootsystems.com>
parent 890854d0
......@@ -8,6 +8,6 @@ obj-y := time.o irq.o clock.o serial.o io.o id.o psc.o \
gpio.o mux.o dma.o devices.o common.o
# Board specific
obj-$(CONFIG_MACH_DAVINCI_EVM) += board-evm.o i2c-emac.o
obj-$(CONFIG_MACH_DAVINCI_EVM) += board-evm.o
obj-$(CONFIG_DAVINCI_MCBSP) += mcbsp.o
obj-$(CONFIG_DAVINCI_I2C_EXPANDER) += i2c-client.o
......@@ -18,7 +18,7 @@
#include <linux/i2c/pcf857x.h>
#include <linux/i2c/at24.h>
#include <linux/leds.h>
#include <linux/etherdevice.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
......@@ -35,6 +35,7 @@
#include <mach/common.h>
#include <mach/board.h>
#include <mach/emac.h>
/* other misc. init functions */
void __init davinci_psc_init(void);
......@@ -378,12 +379,49 @@ static struct pcf857x_platform_data pcf_data_u35 = {
* - 0x0039, 1 byte NTSC vs PAL (bit 0x80 == PAL)
* - ... newer boards may have more
*/
static struct at24_iface *at24_if;
static int at24_setup(struct at24_iface *iface, void *context)
{
DECLARE_MAC_BUF(mac_str);
char mac_addr[6];
at24_if = iface;
/* Read MAC addr from EEPROM */
if (at24_if->read(at24_if, mac_addr, 0x7f00, 6) == 6) {
printk(KERN_INFO "Read MAC addr from EEPROM: %s\n",
print_mac(mac_str, mac_addr));
davinci_init_emac(mac_addr);
}
return 0;
}
static struct at24_platform_data eeprom_info = {
.byte_len = (256*1024) / 8,
.page_size = 64,
.flags = AT24_FLAG_ADDR16,
.setup = at24_setup,
};
int dm6446evm_eeprom_read(void *buf, off_t off, size_t count)
{
if (at24_if)
return at24_if->read(at24_if, buf, off, count);
return -ENODEV;
}
EXPORT_SYMBOL(dm6446evm_eeprom_read);
int dm6446evm_eeprom_write(void *buf, off_t off, size_t count)
{
if (at24_if)
return at24_if->write(at24_if, buf, off, count);
return -ENODEV;
}
EXPORT_SYMBOL(dm6446evm_eeprom_write);
static struct i2c_board_info __initdata i2c_info[] = {
{
I2C_BOARD_INFO("pcf857x", 0x38),
......
......@@ -14,12 +14,15 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/random.h>
#include <linux/etherdevice.h>
#include <asm/io.h>
#include <asm/mach-types.h>
#include <asm/mach/map.h>
#include <mach/hardware.h>
#include <mach/emac.h>
#if defined(CONFIG_I2C_DAVINCI) || defined(CONFIG_I2C_DAVINCI_MODULE)
......@@ -108,22 +111,42 @@ static struct resource emac_resources[] = {
};
static struct emac_platform_data emac_pdata;
static struct platform_device davinci_emac_device = {
.name = "davinci_emac",
.id = 1,
.num_resources = ARRAY_SIZE(emac_resources),
.resource = emac_resources,
.dev = {
.platform_data = &emac_pdata,
}
};
static void davinci_init_emac(void)
void davinci_init_emac(char *mac_addr)
{
(void) platform_device_register(&davinci_emac_device);
DECLARE_MAC_BUF(buf);
/* if valid MAC exists, don't re-register */
if (is_valid_ether_addr(emac_pdata.mac_addr))
return;
if (mac_addr && is_valid_ether_addr(mac_addr))
memcpy(emac_pdata.mac_addr, mac_addr, 6);
else {
/* Use random MAC if none passed */
random_ether_addr(emac_pdata.mac_addr);
printk(KERN_WARNING "%s: using random MAC addr: %s\n",
__func__, print_mac(buf, emac_pdata.mac_addr));
}
(void) platform_device_register(&davinci_emac_device);
}
#else
static void davinci_init_emac(void) {}
void davinci_init_emac(char *unused) {}
#endif
......@@ -136,9 +159,16 @@ static int __init davinci_init_devices(void)
*/
davinci_init_i2c();
davinci_init_mmcsd();
davinci_init_emac();
return 0;
}
arch_initcall(davinci_init_devices);
static int __init davinci_init_devices_late(void)
{
/* This is a backup call in case board code did not call init func */
davinci_init_emac(NULL);
return 0;
}
late_initcall(davinci_init_devices_late);
/*
* <arch/arm/mach-davinci/i2c-emac.c
*
* Read MAC address from i2c-attached EEPROM
* FIXME: Move into network driver once stabilized
*
* Author: Texas Instruments
*
* 2006 (c) Texas Instruments, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <mach/i2c-client.h>
/* Get Ethernet address from kernel boot params */
static unsigned char cpmac_eth_string[20] = "deadbeef";
/* This function gets the Ethernet MAC address from EEPROM
* Input buffer to be of atlease 20 bytes in length
*/
int davinci_get_macaddr (char *ptr)
{
#ifndef CONFIG_I2C_DAVINCI
printk(KERN_INFO "DaVinci EMAC: Unable to read MAC from EEPROM, "
"no i2c support in kernel.\n");
#else
char data[2] = { 0x7f, 0 };
char temp[20];
int i = 0;
if (ptr == NULL) {
return -EFAULT;
}
/* If already assigned via cmdline, just use it */
if (strncmp(cpmac_eth_string, "deadbeef", 8)) {
strncpy (ptr, cpmac_eth_string, 20);
return 0;
}
davinci_i2c_write (2, data, 0x50);
davinci_i2c_read (8, temp, 0x50);
/* check whether MAC address is available in ERPROM else try to
* to get it from bootparams for now. From Delta EVM MAC address
* should be available from I2C EEPROM.
*/
if ((temp [0] != 0xFF) |
(temp [1] != 0xFF) |
(temp [2] != 0xFF) |
(temp [3] != 0xFF) |
(temp [4] != 0xFF) |
(temp [5] != 0xFF) |
(temp [6] != 0xFF) )
{
ptr[0] = (*(temp+0) & 0xF0) >> 4;
ptr[1] = (*(temp+0) & 0x0F);
ptr[2] = ':';
ptr[3] = (*(temp+1) & 0xF0) >> 4;
ptr[4] = (*(temp+1) & 0x0F);
ptr[5] = ':';
ptr[6] = (*(temp+2) & 0xF0) >> 4;
ptr[7] = (*(temp+2) & 0x0F);
ptr[8] = ':';
ptr[9] = (*(temp+3) & 0xF0) >> 4;
ptr[10]= (*(temp+3) & 0x0F);
ptr[11]= ':';
ptr[12]= (*(temp+4) & 0xF0) >> 4;
ptr[13]= (*(temp+4) & 0x0F);
ptr[14]= ':';
ptr[15]= (*(temp+5) & 0xF0) >> 4;
ptr[16]= (*(temp+5) & 0x0F);
for (i = 0; i < 17; i++)
{
if (ptr[i] == ':')
continue;
else if (ptr[i] <= 9)
ptr[i] = ptr[i] + 48;
else
ptr[i] = ptr[i] + 87;
}
} else
#endif
{
strncpy (ptr, cpmac_eth_string, 20);
}
return 0;
}
EXPORT_SYMBOL(davinci_get_macaddr);
static int davinci_cpmac_eth_setup(char *str)
{
/* The first char passed from the bootloader is '=', so ignore it */
strcpy(&cpmac_eth_string[0], &str[1]);
printk("TI DaVinci EMAC: Kernel Boot params Eth address: %s\n",
cpmac_eth_string);
return (1);
}
__setup("eth", davinci_cpmac_eth_setup);
/*
* DaVinci DM6446 EVM board specific headers
*
* Author: Kevin Hilman, Deep Root Systems, LLC
*
* 2007 (c) Deep Root Systems, LLC. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or ifndef.
*/
#ifndef _MACH_DAVINCI_DM6446EVM_H
#define _MACH_DAVINCI_DM6446EVM_H
#include <linux/types.h>
int dm6446evm_eeprom_read(char *buf, off_t off, size_t count);
int dm6446evm_eeprom_write(char *buf, off_t off, size_t count);
#endif
/*
* TI DaVinci EMAC platform support
*
* Author: Kevin Hilman, Deep Root Systems, LLC
*
* 2007 (c) Deep Root Systems, LLC. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#ifndef _MACH_DAVINCI_EMAC_H
#define _MACH_DAVINCI_EMAC_H
struct emac_platform_data {
char mac_addr[6];
};
void davinci_init_emac(char *mac_addr);
#endif
......@@ -67,6 +67,7 @@
#include <mach/memory.h>
#include <mach/cpu.h>
#include <mach/hardware.h>
#include <mach/emac.h>
#include "davinci_emac_phy.h"
......@@ -483,7 +484,6 @@ struct emac_priv {
struct platform_device *pdev;
struct napi_struct napi;
char mac_addr[6];
char mac_str[20];
spinlock_t tx_lock;
spinlock_t rx_lock;
u32 emac_base_regs;
......@@ -1142,77 +1142,6 @@ static void emac_dev_mcast_set(struct net_device *ndev)
emac_write(EMAC_RXMBPENABLE, mbp_enable);
}
/**
* emac_str_to_hexnum: String to hex number conversion (Internal)
* @c: string to convert to hex number
*
* Internal helper function to convert string to hex number
*/
static unsigned char emac_str_to_hexnum(unsigned char c)
{
if (c >= '0' && c <= '9')
return c - '0';
else if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
else if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
else
return 0;
}
/**
* emac_str_to_ethaddr: ConvertGet EMAC mac address from platform
* @priv: The DaVinci EMAC private adapter structure
*
* Invokes a board specific function that provides MAC address for this
* adapter. For DaVinci EVM, the function invoked is
* davinci_get_macaddr()
*
* @TODO: use platform parameter to pass mac address in future
*
*/static void emac_str_to_ethaddr(unsigned char *ea, unsigned char *str)
{
int i;
unsigned char num;
for (i = 0; i < 6; i++) {
if ((*str == '.') || (*str == ':'))
str++;
num = emac_str_to_hexnum(*str) << 4;
++str;
num |= (emac_str_to_hexnum(*str));
++str;
ea[i] = num;
}
}
/* TODO: External function in init code - move this to platform config */
extern int davinci_get_macaddr(char *ptr);
/**
* emac_eth_setup: Get EMAC mac address from platform
* @priv: The DaVinci EMAC private adapter structure
*
* Iinvokes a board specific function that provides MAC address for this
* adapter. For DaVinci EVM, the function invoked is
* davinci_get_macaddr()
*
* TODO: use platform parameter to pass mac address in future
*
*/
static void emac_eth_setup(struct emac_priv *priv)
{
/* TODO: Try to use platform structure for this */
strcpy(priv->mac_str, "deadbeef");
if (davinci_get_macaddr(&priv->mac_str[0]) != 0) {
dev_warn(EMAC_DEV, "DaVinci EMAC: Error getting MAC addr\n");
dev_warn(EMAC_DEV, "Def MAC address: 08.00.28.32.06.08");
}
emac_str_to_ethaddr(priv->mac_addr, priv->mac_str);
return;
}
/**
* emac_timer_cb: EMAC Phy timer callback
* @priv: The DaVinci EMAC private adapter structure
......@@ -2524,7 +2453,6 @@ static int emac_dev_open(struct net_device *ndev)
struct emac_priv *priv = netdev_priv(ndev);
netif_carrier_off(ndev);
emac_eth_setup(priv);
for (cnt = 0; cnt <= ETH_ALEN; cnt++)
ndev->dev_addr[cnt] = priv->mac_addr[cnt];
......@@ -2710,6 +2638,13 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev)
priv->ndev = ndev;
priv->msg_enable = netif_msg_init(debug_level, DAVINCI_EMAC_DEBUG);
/* MAC addr: from platform_data */
if (pdev->dev.platform_data) {
struct emac_platform_data *pdata = pdev->dev.platform_data;
memcpy(priv->mac_addr, pdata->mac_addr, 6);
}
/* Get EMAC platform data */
base_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment