博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
I.MX6 Ethernet MAC (ENET) MAC Address hacking
阅读量:6271 次
发布时间:2019-06-22

本文共 31368 字,大约阅读时间需要 104 分钟。

/********************************************************************* *        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 (0);                                    |                |           }                                                  |                |                                                              |                |           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) < 0)                                                        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[6];                                                                                                                                       for (i = 0; i < sizeof(fec_info) / sizeof(fec_info[0]); 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, 0, 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) == 0) {            ------*-----+                   printf("got MAC address from IIM: %pM\n", ethaddr);   |     |                   memcpy(dev->enetaddr, ethaddr, 6);                    |     |                   fec_set_hwaddr(dev);                            ------*-----*-+             }                                                         |     | |         }                                                             |     | |                                                                       |     | |         return 1;                                                     |     | |     }                                                                 |     | |                                                                       |     | |     struct fec_info_s fec_info[] = {                       <----------+     | |         {                                                             |     | |          0,            /* index */                                    |     | |          CONFIG_FEC0_IOBASE,    /* io base */               --------+-*-----*-*-+        CONFIG_FEC0_PHY_ADDR,    /* phy_addr */                    | |     | | |        0,            /* duplex and speed */                       | |     | | |        0,            /* phy name */                               | |     | | |        0,            /* phyname init */                           | |     | | |        0,            /* RX BD */                                  | |     | | |        0,            /* TX BD */                                  | |     | | |        0,            /* rx Index */                               | |     | | |        0,            /* tx Index */                               | |     | | |        0,            /* tx buffer */                              | |     | | |   #ifdef CONFIG_ARCH_MMU                                          | |     | | |        { 0 },            /* rx buffer */                          | |     | | |   #endif                                                          | |     | | |        0,            /* 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 0;                                                 |           | |   #else                                                         |           | |       return -1;                                                |           | |   #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(0));                    | |       mac[5] = value & 0xff;                                                | |       mac[4] = (value >> 8) & 0xff;                                         | |       mac[3] = (value >> 16) & 0xff;                                        | |       mac[2] = (value >> 24) & 0xff;                                        | |       value = readl(OCOTP_BASE_ADDR + HW_OCOTP_MACn(1));                    | |       mac[1] = value & 0xff;                                                | |       mac[0] = (value >> 8) & 0xff;                                         | |   #else                                                                     | |       eth_getenv_enetaddr("ethaddr", mac);            ----------+           | |   #endif                                                        |           | |       return 0;                                                 |           | |   }                                                             |           | |   #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(0, &fecp->iaur);                                   |             |       writel(0, &fecp->ialr);                                   |             |       writel(0, &fecp->gaur);                                   |             |       writel(0, &fecp->galr);                                   |             |                                                                 |             |       /*                                                        |             |        * Set physical address                                   |             |        */                                                       V             |       writel((mac[0] << 24) + (mac[1] << 16) + (mac[2] << 8) + mac[3],  ------*-+             &fecp->palr);                                                   | |     writel((mac[4] << 24) + (mac[5] << 16) + 0x8808, &fecp->paur);          | |                                                                             | |     return 0;                                                               | | }                                                                           | |                                                                             | |                                                                             | | 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 - 1,                         |      | |             .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, 0,           |      | |             res, ARRAY_SIZE(res),                                    |      | |             pdata, sizeof(*pdata), DMA_BIT_MASK(32));                |      | | }                                                                    |      | |                                                                      |      | | #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[0]) =                              |     |             be32_to_cpu(readl(fep->hwp + FEC_ADDR_LOW));     <----------+-----+         *((unsigned short *) &tmpaddr[4]) =                                                 be16_to_cpu(readl(fep->hwp + FEC_ADDR_HIGH) >> 16);                         iap = &tmpaddr[0];                                                          }                                                                                                                                                               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->pdev->id;      }

 

转载地址:http://sslpa.baihongyu.com/

你可能感兴趣的文章
ASP.NET MVC性能优化(实际项目中)
查看>>
ES6里关于类的拓展(一)
查看>>
零元学Expression Blend 4 - Chapter 46 三分钟快速充电-设定Margin的小撇步
查看>>
Format Conditions按条件显示表格记录
查看>>
RichTextBox指定全部文字显示不同颜色及部分文字高亮颜色显示
查看>>
mysql优化----explain的列分析
查看>>
Python正则表达式
查看>>
Java中CAS详解
查看>>
Spring Boot Unregistering JMX-exposed beans on shutdown
查看>>
命令行man的帮助手册
查看>>
Ubuntu 16.04下为Android编译OpenCV 3.2.0 Manager
查看>>
poi 导入导出的api说明(大全)
查看>>
Fix-Mapped Addresses
查看>>
fmt标签如何计算两个日期之间相隔的天数
查看>>
Spark核心技术原理透视一(Spark运行原理)
查看>>
《Gradle权威指南》--Gradle任务
查看>>
IntelliJ IDEA创建文件时自动填入作者时间 定制格式
查看>>
Android app启动activity并调用onCreate()方法时都默默地干了什么?
查看>>
远程监视jboss应用java内存的配置
查看>>
前端如何接收 websocket 发送过来的实时数据
查看>>