imx6dl系統每次啟動MAC地址都不一樣
阿新 • • 發佈:2018-11-02
啟動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地址查詢