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

版权声明:本文为博主原创文章,未经博主允许不得转载。 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地址查询

3.imx6 mac地址设置

4. IMX6读取唯一标识UID的方法

猜你喜欢

转载自blog.csdn.net/WXXGoodJob/article/details/82865682