最近生产了一批板卡,但是只焊接了EMAC1的网卡芯片,没有焊接EMAC0。这就无法直接使用了TI给的UBoot源码了。所以必须修改Uboot源码支持EMAC1.
首先先要弄明白EMAC工作原理。
管理EMAC的MII接口在初始化话的时候会读取网卡芯片的PHY地址,并保存在一个32位的寄存器中。比如我的PHY地址是3,那么这个寄存器的读取的值会成为0x00000008,即第三位置为1. 我们在源码中arch/arm/include/asm/arch-ti81xx/emac_defs.h 需要修改 EMAC_MDIO_PHY_NUM 为 3 . 源码中有这么一行:
#define EMAC_MDIO_PHY_MASK (1 << EMAC_MDIO_PHY_NUM)
所以MDIO的掩码是0x08。
我们需要使用EMAC1,就必须修改EMAC对应的基地址,所以相应的我们也在这个文件中添加:
//#define EMAC0
#ifdef EMAC0
    #define EMAC_MDIO_PHY_NUM               (1)
    
    #define EMAC_BASE_ADDR                  (0x4A100000)
    
    #define EMAC_WRAPPER_BASE_ADDR          (0x4A100900)
    
    #define EMAC_WRAPPER_RAM_ADDR           (0x4A102000)
#else
    #define EMAC_MDIO_PHY_NUM               (3)
    
    #define EMAC_WRAPPER_RAM_ADDR           (0x4A122000)
    
    #define EMAC_WRAPPER_BASE_ADDR          (0x4A120900)
    
    #define EMAC_BASE_ADDR                  (0x4A120000)
#endif
    #define EMAC_MDIO_BASE_ADDR             (0x4A100800)
    
    #define DAVINCI_EMAC_VERSION2
    
    #define DAVINCI_EMAC_GIG_ENABLE
    #define EMAC_MDIO_BUS_FREQ              (250000000UL)
    
    #define EMAC_MDIO_CLOCK_FREQ            (2000000UL)
    
   
之前我以为执行到这里,我的源码就修改完成了。结果我发现我从MDIO通信中的确识别了网卡,但是之后使用ping操作的时候,都不好使。找了好久终于发现了问题。
原来处理器默认使用EMAC0,所以初始化了EMAC0的相关IO。
但是EMAC1的IO没有初始化。打开drivers/net/davinci_emac.c
在函数davinci_emac_initialize() 的开始位置添加:
    #ifndef EMAC0
    
    #define EMAC1_PINCTRL_BASE       *( volatile unsigned int* )( 0x481408C8 )
    
    /*Initialize EMAC1 pins */
    
    pReg = &EMAC1_PINCTRL_BASE;
    
    for ( i = 0 ; i < 24 ; i++ )
    
    {
    
    
    debug_emac(“Before : 0x%08x\t”,readl(pReg));
    
    writel(readl(pReg)|0x01,pReg);
    
    debug_emac(“After : 0x%08x\n”,readl(pReg));
    
    pReg++;
    
    }
    
    #endif
   
直到现在,已经完成了99%,也许好用,也许不好用。原因很特别:
    
    看函数davinci_emac_initialize() 中的
   
    for (i = 0; i < 256; i++) {
    
    
    alive = readl(&adap_mdio->ALIVE);
    
    //      printf(“times:%03d,alive:0x%08x\n”,i,alive);
    
    if (alive)
    
    break;
    
    udelay(10);
    
    }
    
   
为什么要读这么多次?
可能是因为网卡没有初始完毕,CPU读得太快,所以需要重复读取。
当我使用双网卡的时候,我发现我的网卡地址分别是1和3. 所以我读取这个寄存器的时候,总会先返回了0x02然后再过一段时候之后再返回0x0a。所以这里需要自己做一些处理,需要一些延时或者重复读取的处理。
 
