版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/WXXGoodJob/article/details/82865682
启动imx6dl,发现每次启动之后eth0 的mach地址都都是自动获取,导致每次启动都不一样,这个对于IP型(路由器,ip型影音设备,网络打印机,传真机等)设备来说,这是个致命的BUG,打印信息如下。
CAN device driver interface
2188000.ethernet supply phy not found, using dummy regulator
pps pps0: new PPS source ptp0
fec 2188000.ethernet (unregistered net_device): Invalid MAC address: 00:00:00:00:00:00
fec 2188000.ethernet (unregistered net_device): Using random MAC address: c6:60:85:f1:12:33
libphy: fec_enet_mii_bus: probed
fec 2188000.ethernet eth0: registered PHC device 0
PPP generic driver version 2.4.2
drivers/net/ethernet/freescale/fec_main.c:
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];
/*
* 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;
}
memcpy(ndev->dev_addr, iap, ETH_ALEN);
/* Adjust MAC if using macaddr */
if (iap == macaddr)
ndev->dev_addr[ETH_ALEN-1] = macaddr[ETH_ALEN-1] + fep->dev_id;
}
从上面意思的源码可以看出,系统通过四种方式去获取MAC地址,如果都不能获取成功,则会通过第五种方式random生成一个随机的MAC地址,再写hw_addr。
所以,我们不去随机生成MAC,而是直接从phy芯片里面获取,
drivers/net/ethernet/freescale/fec_main.c:
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;
unsigned char i;
/*
* 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];
}
mem_mac_addr = ioremap(0x021BC410,0x100);
printk("the value is %x\r\n",*(unsigned int *)mem_mac_addr);
#if 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;
}
#endif
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 ;
// memcpy(ndev->dev_addr, iap, ETH_ALEN);
/* Adjust MAC if using macaddr */
if (iap == macaddr)
ndev->dev_addr[ETH_ALEN-1] = macaddr[ETH_ALEN-1] + fep->dev_id;
}
搞定!!!
拓展:
1. 怎么烧写imx6的mac
2. MAC地址查询