/*********************************************************************
* I.MX6 Ethernet MAC (ENET) MAC Address hacking
* 说明:
* Lee对相关的一些代码进行了修改,所以这边跟一下这边相关的设置原理,
* 主要是为了知道MAC address在Uboot、Linux kernel阶段的的设置,获取的
* 工作机制。
*
* 2016-7-27 深圳 南山平山村 曾剑锋
********************************************************************/ 参考文档:
Freescale i.MX6 Linux Ethernet Driver驱动源码分析
http://blog.163.com/thinki_cao/blog/static/8394487520146308450620/ cat lib_arm/board.c
void start_armboot (void)
{
......
stdio_init (); /* get the devices list going. */ ---------+
...... |
eth_initialize(gd->bd); ----------------*-+
...... | |
} | |
| |
int stdio_init (void) <-----------------------------+ |
{ |
...... |
#ifdef CONFIG_LCD |
drv_lcd_init (); ------------+ |
#endif | |
...... | |
| |
return (); | |
} | |
| |
int drv_lcd_init (void) <------------+ |
{ |
...... |
lcd_init (lcd_base); /* LCD initialization */ --------+ |
...... | |
} | |
| |
static int lcd_init (void *lcdbase) <--------+ |
{ |
...... |
lcd_enable (); --------+ |
...... | |
} | |
| |
#ifdef CONFIG_LCD | |
void lcd_enable(void) <--------+ |
{ |
...... |
setenv("ethaddr",buffer); |
...... |
} |
|
int eth_initialize(bd_t *bis) <----------------------+
{
......
/* Try board-specific initialization first. If it fails or isn't
* present, try the cpu-specific initialization */
if (board_eth_init(bis) < )
cpu_eth_init(bis); -------+
|
...... |
} |
|
|
int cpu_eth_init(bd_t *bis) <------+
{
int rc = -ENODEV;
#if defined(CONFIG_MXC_FEC)
rc = mxc_fec_initialize(bis); -------+
|
/* Board level init */ |
enet_board_init(); |
|
#endif |
return rc; |
} |
|
int mxc_fec_initialize(bd_t *bis) <-------+
{
struct eth_device *dev;
int i;
unsigned char ethaddr[]; for (i = ; i < sizeof(fec_info) / sizeof(fec_info[]); i++) {
#ifdef CONFIG_ARCH_MMU
int j;
#endif
dev =
(struct eth_device *)memalign(CONFIG_SYS_CACHELINE_SIZE,
sizeof *dev);
if (dev == NULL)
hang(); memset(dev, , sizeof(*dev)); sprintf(dev->name, "FEC%d", fec_info[i].index);
dev->priv = &fec_info[i]; ----------+
dev->init = fec_init; |
dev->halt = fec_halt; |
dev->send = fec_send; |
dev->recv = fec_recv; |
...... |
|
if (fec_get_hwaddr(dev, ethaddr) == ) { ------*-----+
printf("got MAC address from IIM: %pM\n", ethaddr); | |
memcpy(dev->enetaddr, ethaddr, ); | |
fec_set_hwaddr(dev); ------*-----*-+
} | | |
} | | |
| | |
return ; | | |
} | | |
| | |
struct fec_info_s fec_info[] = { <----------+ | |
{ | | |
, /* index */ | | |
CONFIG_FEC0_IOBASE, /* io base */ --------+-*-----*-*-+
CONFIG_FEC0_PHY_ADDR, /* phy_addr */ | | | | |
, /* duplex and speed */ | | | | |
, /* phy name */ | | | | |
, /* phyname init */ | | | | |
, /* RX BD */ | | | | |
, /* TX BD */ | | | | |
, /* rx Index */ | | | | |
, /* tx Index */ | | | | |
, /* tx buffer */ | | | | |
#ifdef CONFIG_ARCH_MMU | | | | |
{ }, /* rx buffer */ | | | | |
#endif | | | | |
, /* initialized flag */ | | | | |
}, | | | | |
}; | | | | |
| | | | |
/* FEC private information */ | | | | |
struct fec_info_s { <----------*-+ | | |
int index; | | | |
u32 iobase; | | | |
int phy_addr; | | | |
int dup_spd; | | | |
char *phy_name; | | | |
int phyname_init; | | | |
cbd_t *rxbd; /* Rx BD */ | | | |
cbd_t *txbd; /* Tx BD */ | | | |
uint rxIdx; | | | |
uint txIdx; | | | |
char *txbuf; | | | |
#ifdef CONFIG_ARCH_MMU | | | |
char *rxbuf[PKTBUFSRX]; | | | |
#endif | | | |
int initialized; | | | |
struct fec_info_s *next; | | | |
}; | | | |
| | | |
#define CONFIG_FEC0_IOBASE ENET_BASE_ADDR <------------+ | | |
#define ENET_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x8000) | | |
#define AIPS2_OFF_BASE_ADDR (ATZ2_BASE_ADDR + 0x80000) | | |
#define ATZ2_BASE_ADDR AIPS2_ARB_BASE_ADDR | | |
#define AIPS2_ARB_BASE_ADDR 0x02100000 | | |
| | |
extern int fec_get_mac_addr(unsigned char *mac); | | |
static int fec_get_hwaddr(struct eth_device *dev, unsigned char *mac) <-+ | |
{ | |
#ifdef CONFIG_GET_FEC_MAC_ADDR_FROM_IIM | |
fec_get_mac_addr(mac); ----------+ | |
| | |
return ; | | |
#else | | |
return -; | | |
#endif | | |
} | | |
| | |
#ifdef CONFIG_GET_FEC_MAC_ADDR_FROM_IIM | | |
int fec_get_mac_addr(unsigned char *mac) <----------+ | |
{ | |
#if 0 | |
unsigned int value; | |
| |
value = readl(OCOTP_BASE_ADDR + HW_OCOTP_MACn()); | |
mac[] = value & 0xff; | |
mac[] = (value >> ) & 0xff; | |
mac[] = (value >> ) & 0xff; | |
mac[] = (value >> ) & 0xff; | |
value = readl(OCOTP_BASE_ADDR + HW_OCOTP_MACn()); | |
mac[] = value & 0xff; | |
mac[] = (value >> ) & 0xff; | |
#else | |
eth_getenv_enetaddr("ethaddr", mac); ----------+ | |
#endif | | |
return ; | | |
} | | |
#endif | | |
| | |
static int fec_set_hwaddr(struct eth_device *dev) <----|-----------+ |
{ | |
uchar *mac = dev->enetaddr; | |
struct fec_info_s *info = dev->priv; | |
volatile fec_t *fecp = (fec_t *)(info->iobase); | |
| |
writel(, &fecp->iaur); | |
writel(, &fecp->ialr); | |
writel(, &fecp->gaur); | |
writel(, &fecp->galr); | |
| |
/* | |
* Set physical address | |
*/ V |
writel((mac[] << ) + (mac[] << ) + (mac[] << ) + mac[], ------*-+
&fecp->palr); | |
writel((mac[] << ) + (mac[] << ) + 0x8808, &fecp->paur); | |
| |
return ; | |
} | |
| |
| |
cat arch/arm/mach-mx6/board-mx6q_sabresd.c | |
MACHINE_START(MX6Q_SABRESD, "Freescale i.MX 6Quad/DualLite/Solo Sabre-SD Boa|"|)
/* Maintainer: Freescale Semiconductor, Inc. */ | |
.boot_params = MX6_PHYS_OFFSET + 0x100, | |
.fixup = fixup_mxc_board, | |
.map_io = mx6_map_io, | |
.init_irq = mx6_init_irq, | |
.init_machine = mx6_sabresd_board_init, ----------+ | |
.timer = &mx6_sabresd_timer, | | |
.reserve = mx6q_sabresd_reserve, | | |
MACHINE_END | | |
| | |
/*! | | |
* Board specific initialization. | | |
*/ | | |
static void __init mx6_sabresd_board_init(void) <---------+ | |
{ | |
...... | |
imx6_init_fec(fec_data); | |
...... | | |
} | | |
V | |
void __init imx6_init_fec(struct fec_platform_data fec_data) ---------+ | |
{ | | |
fec_get_mac_addr(fec_data.mac); | | |
/* | | |
if (!is_valid_ether_addr(fec_data.mac)) | | |
random_ether_addr(fec_data.mac); | | |
*/ | | |
| | |
if (cpu_is_mx6sl()) | | |
imx6sl_add_fec(&fec_data); | | |
else | | |
imx6q_add_fec(&fec_data); | | |
} | | |
| | |
extern const struct imx_fec_data imx6q_fec_data __initconst; | | |
#define imx6q_add_fec(pdata) \ <--------------------+ | |
imx_add_fec(&imx6q_fec_data, pdata) ---------------------+ | |
| | |
#ifdef CONFIG_SOC_IMX6Q | | |
const struct imx_fec_data imx6q_fec_data __initconst = | | |
imx_fec_data_entry_single(MX6Q, "enet"); | | |
| | |
const struct imx_fec_data imx6sl_fec_data __initconst = <----------+ | |
imx_fec_data_entry_single(MX6DL, "fec"); ----------+ | | |
#endif | | | |
| | | |
struct platform_device *__init imx_add_fec( <------------------*-+ | |
const struct imx_fec_data *data, | | |
const struct fec_platform_data *pdata) | | |
{ | | |
struct resource res[] = { | | |
{ | | |
.start = data->iobase, | | |
.end = data->iobase + SZ_4K - , | | |
.flags = IORESOURCE_MEM, | | |
}, { | | |
.start = data->irq, | | |
.end = data->irq, | | |
.flags = IORESOURCE_IRQ, | | |
}, | | |
}; | | |
| | |
if (!fuse_dev_is_available(MXC_DEV_ENET)) | | |
return ERR_PTR(-ENODEV); | | |
| | |
return imx_add_platform_device_dmamask(data->devid, , | | |
res, ARRAY_SIZE(res), | | |
pdata, sizeof(*pdata), DMA_BIT_MASK()); | | |
} | | |
| | |
#define imx_fec_data_entry_single(soc, _devid) \ <----+ | |
{ \ | |
.iobase = soc ## _FEC_BASE_ADDR, \ --------+ | |
.irq = soc ## _INT_FEC, \ | | |
.devid = _devid, \ | | |
} | | |
| | |
#define MX6DL_FEC_BASE_ADDR ENET_BASE_ADDR <-------+------+ |
#define ENET_BASE_ADDR (AIPS2_OFF_BASE_ADDR+0x8000) |
#define AIPS2_OFF_BASE_ADDR (ATZ2_BASE_ADDR + 0x80000) |
#define ATZ2_BASE_ADDR AIPS2_ARB_BASE_ADDR |
#define AIPS2_ARB_BASE_ADDR 0x02100000 |
|
cat drivers/net/fec.c |
static int __init |
fec_enet_module_init(void) |
{ |
printk(KERN_INFO "FEC Ethernet Driver\n"); |
|
return platform_driver_register(&fec_driver); ------+ |
} | |
| |
static void __exit | |
fec_enet_cleanup(void) | |
{ | |
platform_driver_unregister(&fec_driver); | |
} | |
| |
module_exit(fec_enet_cleanup); | |
module_init(fec_enet_module_init); | |
| |
MODULE_LICENSE("GPL"); | |
| |
static struct platform_driver fec_driver = { <-----+ |
.driver = { |
.name = DRIVER_NAME, |
.owner = THIS_MODULE, |
#ifdef CONFIG_PM |
.pm = &fec_pm_ops, |
#endif |
}, |
.id_table = fec_devtype, |
.probe = fec_probe, ------+ |
.remove = __devexit_p(fec_drv_remove), | |
}; | |
| |
static int __devinit | |
fec_probe(struct platform_device *pdev) <-----+ |
{ |
...... |
fep->hwp = ioremap(r->start, resource_size(r)); ---------------+ |
...... | |
ret = fec_enet_init(ndev); ------+ | |
if (ret) | | |
goto failed_init; | | |
...... | | |
} | | |
| | |
static int fec_enet_init(struct net_device *ndev) <-----+ | |
{ | |
...... | |
/* Get the Ethernet address */ | |
fec_get_mac(ndev); ----------------+ | |
...... | | |
} | | |
| | |
static void __inline__ fec_get_mac(struct net_device *ndev) <-----+ | |
{ | |
struct fec_enet_private *fep = netdev_priv(ndev); | |
struct fec_platform_data *pdata = fep->pdev->dev.platform_data; | |
unsigned char *iap, tmpaddr[ETH_ALEN]; | |
| |
/* | |
* try to get mac address in following order: | |
* | |
* 1) module parameter via kernel command line in form | |
* fec.macaddr=0x00,0x04,0x9f,0x01,0x30,0xe0 | |
*/ | |
iap = macaddr; | |
| |
/* | |
* 2) from flash or fuse (via platform data) | |
*/ | |
if (!is_valid_ether_addr(iap)) { | |
#ifdef CONFIG_M5272 | |
if (FEC_FLASHMAC) | |
iap = (unsigned char *)FEC_FLASHMAC; | |
#else | |
if (pdata) | |
memcpy(iap, pdata->mac, ETH_ALEN); | |
#endif | |
} | |
| |
/* | |
* 3) FEC mac registers set by bootloader | |
*/ | |
if (!is_valid_ether_addr(iap)) { | |
*((unsigned long *) &tmpaddr[]) = | |
be32_to_cpu(readl(fep->hwp + FEC_ADDR_LOW)); <----------+-----+
*((unsigned short *) &tmpaddr[]) =
be16_to_cpu(readl(fep->hwp + FEC_ADDR_HIGH) >> );
iap = &tmpaddr[];
} memcpy(ndev->dev_addr, iap, ETH_ALEN); /* Adjust MAC if using macaddr */
if (iap == macaddr)
ndev->dev_addr[ETH_ALEN-] = macaddr[ETH_ALEN-] + fep->pdev->id;
}

I.MX6 Ethernet MAC (ENET) MAC Address hacking的更多相关文章

  1. I.MX6 MAC Address hacking

    /************************************************************************** * I.MX6 MAC Address hack ...

  2. OK335xS mac address hacking

    /*********************************************************************** * OK335xS mac address hacki ...

  3. k64 datasheet学习笔记45---10/100-Mbps Ethernet MAC(ENET)之功能描述

    1.前言 本文是对K64 datasheet 之ENET部分的功能描述,将对每个部分进行详细说明 2.Ethernet MAC frame formats MAC帧组成格式 (1)7字节前导码:如按最 ...

  4. I.MX6 Ethernet UI patch failed

    /*********************************************************************** * I.MX6 Ethernet UI patch f ...

  5. VMware15安装MAC(MAC OS 10.13)(OS X 10.14)原版可升级最新可解锁macOS Unlocker3.0(OS X 10.13)

      目录树 1.1.2安装环境: 1.1.3所需资源: 1.1.4 Unlocker 3.0解锁 1.1.5 配置环境 1.1.6开始安装 1.1.7开启虚拟机进入MAC安装界面 1.1.8 macO ...

  6. windows远程连接Mac、Mac远程连接Mac、Mac连接Windows

    最近因为要进行学习交流,需要用到远程连接,所以找了三种不同的方式,记录如下 1.Windows远程连接Mac 1.mac os x电脑设置 系统偏好设置-共享-勾选“远端管理”,然后在电脑设置—VNC ...

  7. 第一篇 HTML5打包APP之VMware15安装MAC(MAC OS 10.13)(OS X 10.14)原版可升级最新可解锁macOS Unlocker3.0(OS X 10.13)

    1.1.2安装环境: 1.1.3所需资源: 1.1.4 Unlocker 3.0解锁 1.1.5 配置环境 1.1.6开始安装 1.1.7开启虚拟机进入MAC安装界面 1.1.8 macOS 10.1 ...

  8. I.MX6 天嵌 E9 U-boot menu hacking

    /************************************************************************************ * I.MX6 天嵌 E9 ...

  9. 开源一个Mac漂亮的小工具 PPRows for Mac, 在Mac上优雅的计算你写了多少行代码

    开源一个Mac漂亮的小工具 PPRows for Mac, 在Mac上优雅的计算你写了多少行代码. 开源地址: https://github.com/jkpang/PPRows

随机推荐

  1. java直接跳转页面

    public static String genForwardHtml(String url, Map<String, String> parameters, String charset ...

  2. Mysql -- Can’t connect to local MySQL server through socket ‘/var/lib/mysql/mysql.sock’解决方法

    启动mysql 报错: ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/var/lib/mysql/m ...

  3. php新浪云链接mysql与storage

    1.首先要有一个新浪云服务器 2.链接数据库获取数据 mysql CREATE TABLE Persons(FirstName varchar(255),LastName varchar(255)); ...

  4. crontab 写入文件目录

    一.crontab 目录 [root@next-cloud-server etc]# cd /var/spool/cron/ [root@next-cloud-server cron]# ls roo ...

  5. 推荐一个静态页面生成工具-mkdocs

    最近需要找一个生成api文档的工具,找来找去发现mkdocs特别符合需求. 部署只需python和pip 直接生成静态html 用markdown编写 不需要再markdown里指明日期.标题等信息 ...

  6. netty handlers模式

    netty的handler模式真的挺方便的,可以像插件一样随意的插入自己新增的功能而不用队系统进行大的变动. 下面我们来看一下这个模式是如何实现和运行的. 待续...

  7. EffectiveJava(23)为什么不能在新生代码中使用原生态类型

    泛型类和泛型接口 声明一个或者多个类型参数的类或者接口. 为什么不要在新代码中使用原生态类型 原生态类型,即泛型不带参数的类型 如List的list,list就是其原生态类型 1.使用原生态类型,插入 ...

  8. Activemq消息确认机制 --转载

      转自:http://blog.csdn.net/czp11210/article/details/47022639 ActiveMQ消息传送机制以及ACK机制详解 AcitveMQ是作为一种消息存 ...

  9. Java 多线程之 synchronized 和 volatile 的比較

    概述 在做多线程并发处理时,常常须要对资源进行可见性訪问和相互排斥同步操作.有时候,我们可能从前辈那里得知我们须要对资源进行 volatile 或是 synchronized 关键字修饰处理.但是,我 ...

  10. Linux——下常用程序的代理服务器(proxy)配置

    Linux下有很多程序都只有命令行接口,对于这类程序,它们通过代理服务器(proxy)访问网络的方式也不尽相同.在本文中Easwy总结了一些常用Linux程序配置代理服务器的方法. [ 通用代理服务器 ...