OK335xS mac address hacking

weixin_33896726發表於2016-02-01
/***********************************************************************
 *                       OK335xS mac address hacking
 * 宣告:
 *     在一般的嵌入式產品中,一般mac地址都是存在於CPU晶片中,不過有時候
 * 我們也許會表示懷疑,因為我們可能更希望知道那些東西到底存在哪裡,以一
 * 種什麼樣的形式存在。
 *
 *                                      2016-2-1 深圳 南山平山村 曾劍鋒
 **********************************************************************/

MACHINE_START(AM335XEVM, "am335xevm")
    /* Maintainer: Texas Instruments */
    .atag_offset    = 0x100,
    .map_io        = am335x_evm_map_io,
    .init_early    = am33xx_init_early,
    .init_irq    = ti81xx_init_irq,
    .handle_irq     = omap3_intc_handle_irq,
    .timer        = &omap3_am33xx_timer,
    .init_machine    = am335x_evm_init,    -----------+
MACHINE_END                                           |
                                                      |
MACHINE_START(AM335XIAEVM, "am335xiaevm")             |
    /* Maintainer: Texas Instruments */               |
    .atag_offset    = 0x100,                          |
    .map_io        = am335x_evm_map_io,               |
    .init_irq    = ti81xx_init_irq,                   |
    .init_early    = am33xx_init_early,               |
    .timer        = &omap3_am33xx_timer,              |
    .init_machine    = am335x_evm_init,               |
MACHINE_END                                           |
                                                      |
                                                      |
static void __init am335x_evm_init(void)   <----------+
{
    am33xx_cpuidle_init();
    am33xx_mux_init(board_mux);
    omap_serial_init();
    am335x_evm_i2c_init();
    omap_sdrc_init(NULL, NULL);
    usb_musb_init(&musb_board_data);

    omap_board_config = am335x_evm_config;
    omap_board_config_size = ARRAY_SIZE(am335x_evm_config);

    _configure_device(EVM_SK, mfd_dev_cfg, PROFILE_NONE);

    daughter_brd_detected = false;
    setup_zengjf();                              ------------------------------+
                                                                               |
    /*create  /proc/boardname to export info to userspace*/                    |
    proc_init();                                                               |
                                                                               |
    /* Create an alias for icss clock */                                       |
    if (clk_add_alias("pruss", NULL, "pruss_uart_gclk", NULL))                 |
        pr_warn("failed to create an alias: icss_uart_gclk --> pruss\n");      |
    /* Create an alias for gfx/sgx clock */                                    |
    if (clk_add_alias("sgx_ck", NULL, "gfx_fclk", NULL))                       |
        pr_warn("failed to create an alias: gfx_fclk --> sgx_ck\n");           |
}                                                                              |
                                                                               |
/* sbc-zengjf */                                                               |
#define TLK110_PHY_ID       0x2000a211                                         |
#define LAN8710A_PHY_ID       0x7c0f1                                          |
char sbc_zengjf_phy1[10] = {"0:00"};                                           |
char sbc_zengjf_phy2[10] = {"0:01"};                                           |
                                                                               |
static void setup_zengjf(void)                <--------------------------------+
{
    pr_info("The board is a sbc-zengjf.\n");

    /*which doesn't have Write Protect pin LAN8710A_PHY_ID */
    am335x_mmc[0].gpio_wp = -EINVAL;

    int ret;


    _configure_device(EVM_SK, sbc_zengjf_dev_cfg, PROFILE_NONE);

    am33xx_cpsw_init(AM33XX_CPSW_MODE_MII, sbc_zengjf_phy1, sbc_zengjf_phy2);   ---+
    phy_register_fixup_for_uid(LAN8710A_PHY_ID , AM335X_EVM_PHY_MASK,              |
                                 am33xx_evm_tx_clk_dly_phy_fixup);                 |
}                                                                                  |
                                                                                   |
                                                                                   |
int am33xx_cpsw_init(enum am33xx_cpsw_mac_mode mode, unsigned char *phy_id0,     <-+
             unsigned char *phy_id1)
{
    struct omap_hwmod *oh;
    struct platform_device *pdev;
    u32 mac_lo, mac_hi, gmii_sel;
    u32 i;

    mac_lo = omap_ctrl_readl(TI81XX_CONTROL_MAC_ID0_LO);
    mac_hi = omap_ctrl_readl(TI81XX_CONTROL_MAC_ID0_HI);         ------------+
    am33xx_cpsw_slaves[0].mac_addr[0] = mac_hi & 0xFF;                       |
    am33xx_cpsw_slaves[0].mac_addr[1] = (mac_hi & 0xFF00) >> 8;              |
    am33xx_cpsw_slaves[0].mac_addr[2] = (mac_hi & 0xFF0000) >> 16;           |
    am33xx_cpsw_slaves[0].mac_addr[3] = (mac_hi & 0xFF000000) >> 24;         |
    am33xx_cpsw_slaves[0].mac_addr[4] = mac_lo & 0xFF;                       |
    am33xx_cpsw_slaves[0].mac_addr[5] = (mac_lo & 0xFF00) >> 8;              |
                                                                             |
    /* Read MACID0 from eeprom if eFuse MACID is invalid */                  |
    if (!is_valid_ether_addr(am33xx_cpsw_slaves[0].mac_addr)) {              |
        for (i = 0; i < ETH_ALEN; i++)                                       |
            am33xx_cpsw_slaves[0].mac_addr[i] = am33xx_macid0[i];            |
    }                                                                        |
                                                                             |
    mac_lo = omap_ctrl_readl(TI81XX_CONTROL_MAC_ID1_LO);                     |
    mac_hi = omap_ctrl_readl(TI81XX_CONTROL_MAC_ID1_HI);                     |
    am33xx_cpsw_slaves[1].mac_addr[0] = mac_hi & 0xFF;                       |
    am33xx_cpsw_slaves[1].mac_addr[1] = (mac_hi & 0xFF00) >> 8;              |
    am33xx_cpsw_slaves[1].mac_addr[2] = (mac_hi & 0xFF0000) >> 16;           |
    am33xx_cpsw_slaves[1].mac_addr[3] = (mac_hi & 0xFF000000) >> 24;         |
    am33xx_cpsw_slaves[1].mac_addr[4] = mac_lo & 0xFF;                       |
    am33xx_cpsw_slaves[1].mac_addr[5] = (mac_lo & 0xFF00) >> 8;              |
    // Read MACID1 from eeprom if eFuse MACID is invalid                     |
    if (!is_valid_ether_addr(am33xx_cpsw_slaves[1].mac_addr)) {              |
        for (i = 0; i < ETH_ALEN; i++)                                       |
            am33xx_cpsw_slaves[1].mac_addr[i] = am33xx_macid1[i];            |
    }                                                                        |
                                                                             |
                                                                             |
    switch (mode) {                                                          |
    case AM33XX_CPSW_MODE_MII:                                               |
        gmii_sel = AM33XX_MII_MODE_EN;                                       |
        break;                                                               |
    case AM33XX_CPSW_MODE_RMII:                                              |
        gmii_sel = AM33XX_RMII_MODE_EN;                                      |
        break;                                                               |
    case AM33XX_CPSW_MODE_RGMII:                                             |
        gmii_sel = AM33XX_RGMII_MODE_EN;                                     |
        am33xx_cpsw_slaves[0].phy_if = PHY_INTERFACE_MODE_RGMII;             |
        am33xx_cpsw_slaves[1].phy_if = PHY_INTERFACE_MODE_RGMII;             |
        break;                                                               |
    default:                                                                 |
        return -EINVAL;                                                      |
    }                                                                        |
                                                                             |
    writel(gmii_sel, AM33XX_CTRL_REGADDR(AM33XX_CONTROL_GMII_SEL_OFFSET));   |
                                                                             |
    if (phy_id0 != NULL)                                                     |
        am33xx_cpsw_slaves[0].phy_id = phy_id0;                              |
                                                                             |
    if (phy_id1 != NULL)                                                     |
        am33xx_cpsw_slaves[1].phy_id = phy_id1;                              |
                                                                             |
    memcpy(am33xx_cpsw_pdata.mac_addr,                                       |
            am33xx_cpsw_slaves[0].mac_addr, ETH_ALEN);                       |
                                                                             |
    oh = omap_hwmod_lookup("mdio");                                          |
    if (!oh) {                                                               |
        pr_err("could not find cpgmac0 hwmod data\n");                       |
        return -ENODEV;                                                      |
    }                                                                        |
                                                                             |
    pdev = omap_device_build("davinci_mdio", 0, oh, &am33xx_cpsw_mdiopdata,  |
            sizeof(am33xx_cpsw_mdiopdata), NULL, 0, 0);                      |
    if (IS_ERR(pdev))                                                        |
        pr_err("could not build omap_device for cpsw\n");                    |
                                                                             |
    oh = omap_hwmod_lookup("cpgmac0");                                       |
    if (!oh) {                                                               |
        pr_err("could not find cpgmac0 hwmod data\n");                       |
        return -ENODEV;                                                      |
    }                                                                        |
                                                                             |
    pdev = omap_device_build("cpsw", -1, oh, &am33xx_cpsw_pdata,             |
            sizeof(am33xx_cpsw_pdata), NULL, 0, 0);                          |
    if (IS_ERR(pdev))                                                        |
        pr_err("could not build omap_device for cpsw\n");                    |
                                                                             |
    return 0;                                                                |
}                                                                            |
                                                                             |
/* TI81XX spefic control submodules */                                       |
#define TI81XX_CONTROL_DEVCONF        0x600             <--------------------*---+
                                                                             |   |
/* TI81XX CONTROL_DEVCONF register offsets */                                |   |
#define TI81XX_CONTROL_MAC_ID0_LO       (TI81XX_CONTROL_DEVCONF + 0x030)     |   |
// TI81XX_CONTROL_MAC_ID0_HI = 0x634              ---------------------------*---*-+
#define TI81XX_CONTROL_MAC_ID0_HI       (TI81XX_CONTROL_DEVCONF + 0x034) <---+ --+ |
                                                                                   |
/*                                                                                 |
 * 1. 參考文件:                                                                   |
 *     AM335x ARM® Cortex™-A8 Microprocessors (MPUs) Technical Reference Manual    |
 *                                                                                 |
 * 2. 確認暫存器:                                                                 |
 *               Table 9-10. CONTROL_MODULE REGISTERS                              |
 *     +--------+------------------+-------------+----------------+                |
 *     | Offset | Acronym Register | Description | Section        |                |
 *     +--------+------------------+-------------+----------------+                |
 *     | 634h   | mac_id0_hi       |             | Section 9.3.26 |   <------------+
 *     +--------+------------------+-------------+----------------+
 *
 * 3. 暫存器說明:
 *     26.1.8.4.1 Device Initialization
 *         ......
 *         • Device uses EFUSE registers mac_id0_lo and mac_id0_hi in the control module for Ethernet MAC address of the device.
 *         ......
 */

 

相關文章