I.MX6 Ethernet MAC (ENET) MAC Address hacking
/*********************************************************************
* 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的更多相关文章
- I.MX6 MAC Address hacking
/************************************************************************** * I.MX6 MAC Address hack ...
- OK335xS mac address hacking
/*********************************************************************** * OK335xS mac address hacki ...
- k64 datasheet学习笔记45---10/100-Mbps Ethernet MAC(ENET)之功能描述
1.前言 本文是对K64 datasheet 之ENET部分的功能描述,将对每个部分进行详细说明 2.Ethernet MAC frame formats MAC帧组成格式 (1)7字节前导码:如按最 ...
- I.MX6 Ethernet UI patch failed
/*********************************************************************** * I.MX6 Ethernet UI patch f ...
- 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 ...
- windows远程连接Mac、Mac远程连接Mac、Mac连接Windows
最近因为要进行学习交流,需要用到远程连接,所以找了三种不同的方式,记录如下 1.Windows远程连接Mac 1.mac os x电脑设置 系统偏好设置-共享-勾选“远端管理”,然后在电脑设置—VNC ...
- 第一篇 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 ...
- I.MX6 天嵌 E9 U-boot menu hacking
/************************************************************************************ * I.MX6 天嵌 E9 ...
- 开源一个Mac漂亮的小工具 PPRows for Mac, 在Mac上优雅的计算你写了多少行代码
开源一个Mac漂亮的小工具 PPRows for Mac, 在Mac上优雅的计算你写了多少行代码. 开源地址: https://github.com/jkpang/PPRows
随机推荐
- ftrace
下面是一些关于ftrace的博文: ftrace 简介(IBM) 使用 ftrace 调试 Linux 内核 第 1 部分 第 2 部分 第 3 部分 Android系统性能调优工具介绍
- 如何订阅Linux相关的邮件列表
转:http://blog.163.com/sunshine_linting/blog/static/44893323201282114012845/ 1.google"linux kern ...
- Could not instantiate bean class [org.springframework.data.domain.Pageable]: Specified class is an interface解决方案
原文:http://pimin.net/archives/432 环境:Eclipse LUNA.Spring 4.1.1.或Spring 4.3.3.Spring Data Elasticsearc ...
- IIS 7 网站权限问题
IIS7 应用程序池[标识]为[ApplicationPoolIdentity] 给程序目录赋权限: IUSER IIS AppPool\[应用程序池名]
- iOS开发学习 阶段过程简述
下面就简单介绍一下我iOS开发的感受,也是学习iOS开发的一个体系架构. 1 iOS开发环境 1.1 开发环境 标准的配置是Mac OS X + Xcode. MacOSX的话首选用苹果电脑,macm ...
- javascript前端三层,字面量,变量,语句(if,switch,三元运算符,for,do while等)
1:前端三层: 结构层 HTML 样式层 CSS 行为层 JavaScript 2:JavaScript语句和语句之间的换行.空格.缩进都不敏感.alert("你");alert ...
- 自建Saltstack的repo软件源仓库
因为Saltstack自己的repo源是在国外,在国内服务器yum安装Saltstack的时候下载软件包就非常慢,很多情况下还经常下载失败,其实软件包总大小只有10M左右,如果这样安装多台minion ...
- oracle 10g函数大全--聚合函数
AVG([distinct|all]x) [功能]统计数据表选中行x列的平均值. [参数]all表示对所有的值求平均值,distinct只对不同的值求平均值,默认为all 如果有参数distinct或 ...
- Invalidate、RedrawWindow与UpdateWindow的差别
一:什么时候才会发生重绘窗体的消息? 当须要更新或又一次绘制窗体的外观时,应用程序就会发送WM_PAINT消息. 对窗体进行又一次绘制. 二:Invalidate() -- RedrawW ...
- Docker核心技术
Docker核心技术 1.cgroup 即controller group,其重要概念是子系统,首先挂载子系统,然后才有control group.例如cpu子系统,挂载至系统之后,创建一个cgrou ...