AnsweredAssumed Answered

imx6dl每次启动MAC地址都不一样。

Question asked by Wuxiuxin Xiuxin on Sep 28, 2018
Latest reply on Oct 10, 2018 by Wuxiuxin Xiuxin

大家好,最新调试发现,每次启动板子,MAC都不一样,追踪代码发现。内核获取MAC地址通过五种方式(后附上源码)获取mac地址,前面四种获取失败之后,则会通过第五种方式随机生成一个mac地址。我所遇到的情况恰好就是每次启动都是随机生成一个mac地址。

static void fec_get_mac(struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
struct fec_platform_data *pdata = dev_get_platdata(&fep->pdev->dev);
unsigned char *iap, tmpaddr[ETH_ALEN];

unsigned char *mem_mac_addr;

/*
* 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 device tree data
*/
if (!is_valid_ether_addr(iap)) {
struct device_node *np = fep->pdev->dev.of_node;
if (np) {
const char *mac = of_get_mac_address(np);
if (mac)
iap = (unsigned char *) mac;
}
}

/*
* 3) 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)
iap = (unsigned char *)&pdata->mac;
#endif
}

/*
* 4) FEC mac registers set by bootloader
*/
if (!is_valid_ether_addr(iap)) {
*((__be32 *) &tmpaddr[0]) =
cpu_to_be32(readl(fep->hwp + FEC_ADDR_LOW));
*((__be16 *) &tmpaddr[4]) =
cpu_to_be16(readl(fep->hwp + FEC_ADDR_HIGH) >> 16);
iap = &tmpaddr[0];
}

/*
* 5) random mac address
*/
if (!is_valid_ether_addr(iap)) {
/* Report it and use a random ethernet address instead */
netdev_err(ndev, "Invalid MAC address: %pM\n", iap);
eth_hw_addr_random(ndev);
netdev_info(ndev, "Using random MAC address: %pM\n",
ndev->dev_addr);
return;
}

 

通过查看IMX6SDLRM.pdf数据手册的“47.5 OCOTP Memory Map/Register Definition”章节,发现MAC地址是已经固化在CPU的MAC里面了,所以我通过操作寄存器的方式获取MAC地址,方法如下:

mem_mac_addr = ioremap(0x021BC620,0x100);
printk("the value is %x\r\n",*(unsigned int *)mem_mac_addr);

ndev->addr_assign_type = NET_ADDR_RANDOM;

*mem_mac_addr &=0xfe;
*mem_mac_addr |= 0x02;

ndev->dev_addr[0] = *mem_mac_addr;
ndev->dev_addr[1] = *(mem_mac_addr+1);
ndev->dev_addr[2] = *(mem_mac_addr+2);
ndev->dev_addr[3] = *(mem_mac_addr+3);
ndev->dev_addr[4] = *(mem_mac_addr+0x12);

*(mem_mac_addr+0x13) &=0xfe;
*(mem_mac_addr+0x13) |= 0x02;
ndev->dev_addr[5] = *(mem_mac_addr+0x13);

return;

 

修改之后生成的zImage放到不同的板子上跑,结果获取到的MAC都一样:

root@imx6ull14x14evk:~# ifconfig
eth0 Link encap:Ethernet HWaddr 02:00:00:00:00:02

UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0

 

我换了一组寄存器地址,分别是: 0x021BC410, 0x021BC420, 0x021BC430,重新编译,放到不同的板子上去跑,结果是每个板子的MAC地址都不一样。

从手册的描述来看, 0x021BC410, 0x021BC420, 0x021BC430  这几个寄存器放的应该是制造商的信息,应该是每个CPU都一样才对。这是什么原因。

疑惑:

1. imx6dl内核的网络驱动有从CPU读取MAC地址的机制吗?(我追踪代码没有找到)

2. 为什么0x021BC620, 0x021BC630 这两个寄存器不能获取到正确的MAC地址?

3. 最终想要解决的问题是:能正确读取CPU的MAC地址,而不是通过软件随机生成一个。

 

Outcomes