From bb05601a5f7644b90b3244e0e2ba376f254cac63 Mon Sep 17 00:00:00 2001 From: hwg Date: Thu, 21 Mar 2013 16:31:51 +0800 Subject: [PATCH] ethernet: support mac from idb --- arch/arm/mach-rk30/board-rk30-sdk-vmac.c | 2 +- drivers/net/Kconfig | 1 + drivers/net/Makefile | 2 + drivers/net/eth_mac/Kconfig | 58 +++++++ drivers/net/eth_mac/Makefile | 1 + drivers/net/eth_mac/eth_mac.c | 208 +++++++++++++++++++++++ drivers/net/eth_mac/eth_mac.h | 17 ++ drivers/net/rk29_vmac.c | 53 +++++- 8 files changed, 339 insertions(+), 3 deletions(-) mode change 100644 => 100755 drivers/net/Makefile create mode 100755 drivers/net/eth_mac/Kconfig create mode 100755 drivers/net/eth_mac/Makefile create mode 100755 drivers/net/eth_mac/eth_mac.c create mode 100755 drivers/net/eth_mac/eth_mac.h diff --git a/arch/arm/mach-rk30/board-rk30-sdk-vmac.c b/arch/arm/mach-rk30/board-rk30-sdk-vmac.c index 35d45119d3cc..0a43c75aca87 100755 --- a/arch/arm/mach-rk30/board-rk30-sdk-vmac.c +++ b/arch/arm/mach-rk30/board-rk30-sdk-vmac.c @@ -75,7 +75,7 @@ static int rk30_rmii_power_control(int enable) #define BIT_EMAC_SPEED (1 << 1) static int rk29_vmac_speed_switch(int speed) { - printk("%s--speed=%d\n", __FUNCTION__, speed); + //printk("%s--speed=%d\n", __FUNCTION__, speed); if (10 == speed) { writel_relaxed(readl_relaxed(RK30_GRF_BASE + GRF_SOC_CON1) & (~BIT_EMAC_SPEED), RK30_GRF_BASE + GRF_SOC_CON1); } else { diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 0a47cad72580..f17b3b0c1c28 100755 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -260,6 +260,7 @@ config RK29_VMAC help MAC device present on rockchip rk29xx +source "drivers/net/eth_mac/Kconfig" config MACE tristate "MACE (Power Mac ethernet) support" diff --git a/drivers/net/Makefile b/drivers/net/Makefile old mode 100644 new mode 100755 index 59693f5cbd85..61fd9d2567ae --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -310,3 +310,5 @@ obj-$(CONFIG_CAIF) += caif/ obj-$(CONFIG_OCTEON_MGMT_ETHERNET) += octeon/ obj-$(CONFIG_PCH_GBE) += pch_gbe/ obj-$(CONFIG_TILE_NET) += tile/ + +obj-$(CONFIG_RK29_VMAC) += eth_mac/ diff --git a/drivers/net/eth_mac/Kconfig b/drivers/net/eth_mac/Kconfig new file mode 100755 index 000000000000..055416421c0d --- /dev/null +++ b/drivers/net/eth_mac/Kconfig @@ -0,0 +1,58 @@ +# +# set Ethernet mac source +# +choice + prompt "Ethernet mac source" + depends on NETDEV_10000 ||NETDEV_1000 ||NET_ETHERNET + default ETH_MAC_FROM_RANDOM + + config ETH_MAC_FROM_RANDOM + bool "Random Ethernet mac " + ---help--- + Say Y here if you want to set Random mac to Ethernet mac. + + This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. + + config ETH_MAC_FROM_EEPROM + bool "Ethernet mac from EEPROM" + depends on EEPROM_AT24C16 + ---help--- + Say Y here if you want to set EEPROM mac to Ethernet mac, + when the EEPROM exsits and mac has been written in. + + This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. + + config ETH_MAC_FROM_IDB + bool "Ethernet mac from IDB" + ---help--- + Say Y here if you want to set IDB mac to Ethernet mac, + when the IDB mac has been written in. + + This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. + + config ETH_MAC_FROM_WIFI_MAC + bool "Ethernet mac from Wifi mac" + ---help--- + Say Y here if you want to set Wifi mac to Ethernet mac, + when the Wifi device exsits. + This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. + + config ETH_MAC_FROM_SECURE_CHIP + bool "Ethernet mac from Secure chip" + ---help--- + Say Y here if you want to set Secure chip mac to Ethernet mac, + when the Secure chip exsits and mac has been written in. + This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. + +endchoice + diff --git a/drivers/net/eth_mac/Makefile b/drivers/net/eth_mac/Makefile new file mode 100755 index 000000000000..c745b3d64a34 --- /dev/null +++ b/drivers/net/eth_mac/Makefile @@ -0,0 +1 @@ +obj-y += eth_mac.o diff --git a/drivers/net/eth_mac/eth_mac.c b/drivers/net/eth_mac/eth_mac.c new file mode 100755 index 000000000000..7f2c64f564a2 --- /dev/null +++ b/drivers/net/eth_mac/eth_mac.c @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2010 ROCKCHIP, Inc. + * Author: roger_chen + * + * This program is the virtual flash device + * used to store bd_addr or MAC + * + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "eth_mac.h" + +#if 1 +#define DBG(x...) printk("eth_mac:" x) +#else +#define DBG(x...) +#endif + +#define VERSION "0.1" + +#define WLAN_MAC_FILE "/data/misc/wifi/wlan_mac" + +//extern char GetSNSectorInfo(char * pbuf); + +char GetSNSectorInfoBeforeNandInit(char * pbuf) +{ + char * sn_addr = ioremap(0x10501600,0x200); + memcpy(pbuf,sn_addr,0x200); + iounmap(sn_addr); + //print_hex_dump(KERN_WARNING, "sn:", DUMP_PREFIX_NONE, 16,1, sn_addr, 16, 0); + return 0; +} + +int eth_mac_read_from_IDB(u8 *mac) +{ + int i; + char *tempBuf = kmalloc(512, GFP_KERNEL); + + if(mac == NULL) + return -EFAULT; + + GetSNSectorInfoBeforeNandInit(tempBuf); + /*for (i = 0; i < 512; i++) { + printk("%02x, ", tempBuf[i]); + if(((i+1)%16) == 0) printk("\n"); + }*/ + + for (i = 506; i <= 511; i++) + mac[i-506] = tempBuf[i]; + + kfree(tempBuf); + + return 0; +} + +int eth_mac_idb(u8 *eth_mac) +{ + int i; + int err = 0; + memset(eth_mac, 0, 6); + err = eth_mac_read_from_IDB(eth_mac); + if (err) + return -1; + printk("Read the Ethernet MAC address from IDB:"); + for (i = 0; i < 5; i++) + printk("%2.2x:", eth_mac[i]); + printk("%2.2x\n", eth_mac[i]); + + return 0; +} + +/** +*大写转小写 +* +*/ +void to_lower(char *str) +{ + int i=0; + while(str[i]!=0) + { + if((str[i] >= 'A')&&(str[i] <= 'Z')) + str[i]+=32; + i++; + } +} + + +/** + *字符串格式转为mac 格式. + * + * + */ +void trans( char *src ,int * k) +{ + char c; + int i; + int temp; + int temp2; + + if( (src == NULL) ||(strlen(src) <16 ) ) // 参数检查 + { + printk( "Arg Error\n" ); + return ; + } + + for( i = 0; i < 6; i++ ) + { + temp = 0; + temp2 = 0; + c = *src; + if( c == ':' ){ + src++; + c = *src; + } + if( c >= 'a' && c <= 'f' ) // 两个字符中的第一个 比如 "0f" ,则表示是字符 '0' + temp = ( c - 'a' ) + 10; + else + temp = ( c - '0' ) ; + src++; + + c = *src; + if( i == 5){ //wifi mac 末尾加1 + if(c =='f'){ + c = '0'; + } if (c == '9'){ + c = 'a'; + }else{ + c = c + 1; + } + } + if( c >= 'a' && c <= 'f' ) // 两个字符中的第二个,如 "f8" ,那么表示字符 '8' + temp2 = ( c - 'a' ) + 10; + else + temp2 = ( c - '0' ) ; + + temp = temp * 16; + temp += temp2; + src++; + *(k+i) = temp; + + } + +} + +int eth_mac_wifi(u8 *eth_mac){ + int i; + struct file *file = NULL; + char wifi_mac[32]; + mm_segment_t old_fs; + ssize_t ret; + + int *maci=(int *)kmalloc(6, GFP_KERNEL); + + memset(eth_mac, 0, 6); + + file = filp_open(WLAN_MAC_FILE, O_RDWR,0); + if (IS_ERR(file)) + { + printk("open %s failed.", WLAN_MAC_FILE); + return -ENOENT; + } + + old_fs = get_fs(); + set_fs(get_ds()); + + file->f_op->llseek(file,0,0); + ret = file->f_op->read(file, wifi_mac, 32, &file->f_pos); + + set_fs(old_fs); + + if(ret > 0){ + //printk("mac read from %s: %s\n", WLAN_MAC_FILE,wifi_mac); + + to_lower(wifi_mac); + trans(wifi_mac,maci); + for (i = 0;i< 6;i++){ + eth_mac[i] = maci[i]; + } + + } + else if(ret == 0) + printk("read nothing from %s........\n",WLAN_MAC_FILE); + else + { + printk("read wifi mac error\n"); + return -ENOENT; + } + + kfree(maci); + filp_close(file,NULL); + return 0; + +} + + + + + diff --git a/drivers/net/eth_mac/eth_mac.h b/drivers/net/eth_mac/eth_mac.h new file mode 100755 index 000000000000..03db62788352 --- /dev/null +++ b/drivers/net/eth_mac/eth_mac.h @@ -0,0 +1,17 @@ +#ifndef _ETH_MAC_H_ +#define _ETH_MAC_H_ +/* + * eth_mac/eth_mac.h + * + * Copyright (C) 2001 Russell King. + * + * This file is placed under the LGPL. + * + * + * + */ +//int eth_mac_read_from_IDB(u8 *mac) + +int eth_mac_idb(u8 *eth_mac); +int eth_mac_wifi(u8 *eth_mac); +#endif /* _ETH_MAC_H_ */ diff --git a/drivers/net/rk29_vmac.c b/drivers/net/rk29_vmac.c index f64bb4e8a5f2..42683cfb3673 100755 --- a/drivers/net/rk29_vmac.c +++ b/drivers/net/rk29_vmac.c @@ -53,6 +53,7 @@ #include #include "rk29_vmac.h" +#include "eth_mac/eth_mac.h" static struct wake_lock idlelock; /* add by lyx @ 20110302 */ @@ -1548,8 +1549,56 @@ static int __devinit vmac_probe(struct platform_device *pdev) /* mac address intialize, set vmac_open */ read_mac_reg(dev, dev->dev_addr); - if (!is_valid_ether_addr(dev->dev_addr)) - random_ether_addr(dev->dev_addr); + if (!is_valid_ether_addr(dev->dev_addr)) { + //add by cx@rock-chips.com + + #ifdef CONFIG_ETH_MAC_FROM_EEPROM + ret = eeprom_read_data(0,dev->dev_addr,6); + if (ret != 6){ + printk("read mac from Eeprom fail.\n"); + }else { + if (is_valid_ether_addr(dev->dev_addr)){ + printk("eth_mac_from_eeprom***********:%X:%X:%X:%X:%X:%X\n",dev->dev_addr[0], + dev->dev_addr[1],dev->dev_addr[2],dev->dev_addr[3], + dev->dev_addr[4],dev->dev_addr[5] ); + } + } + #endif + + #ifdef CONFIG_ETH_MAC_FROM_IDB + err = eth_mac_idb(dev->dev_addr); + if (err) { + printk("read mac from IDB fail.\n"); + } else { + if (is_valid_ether_addr(dev->dev_addr)) { + printk("eth_mac_from_idb***********:%X:%X:%X:%X:%X:%X\n",dev->dev_addr[0], + dev->dev_addr[1],dev->dev_addr[2],dev->dev_addr[3], + dev->dev_addr[4],dev->dev_addr[5] ); + } + } + #endif + + #ifdef CONFIG_ETH_MAC_FROM_WIFI_MAC + err = eth_mac_wifi(dev->dev_addr); + if (err) { + printk("read mac from Wifi fail.\n"); + } else { + if (is_valid_ether_addr(dev->dev_addr)) { + printk("eth_mac_from_wifi_mac***********:%X:%X:%X:%X:%X:%X\n",dev->dev_addr[0], + dev->dev_addr[1],dev->dev_addr[2],dev->dev_addr[3], + dev->dev_addr[4],dev->dev_addr[5] ); + } + } + #endif + + #ifdef CONFIG_ETH_MAC_FROM_RANDOM + random_ether_addr(dev->dev_addr); + printk("random_ether_addr***********:%X:%X:%X:%X:%X:%X\n",dev->dev_addr[0], + dev->dev_addr[1],dev->dev_addr[2],dev->dev_addr[3], + dev->dev_addr[4],dev->dev_addr[5] ); + #endif + //add end + } err = register_netdev(dev); if (err) { -- 2.34.1