/*********************************************************************** * 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. * ...... */