]> git.karo-electronics.de Git - karo-tx-redboot.git/blobdiff - packages/devs/eth/arm/tx27karo/v1_0/include/devs_eth_arm_tx27.inl
STK5 Release 1.10
[karo-tx-redboot.git] / packages / devs / eth / arm / tx27karo / v1_0 / include / devs_eth_arm_tx27.inl
index 436f4bf10ad8a9d14fbf4b2664af91722e9f6b88..c14e2b2046e3c6dca614325c97829388e62170e7 100644 (file)
@@ -50,7 +50,6 @@
 #endif
 #endif
 
-extern unsigned int sys_ver;
 
 #ifdef __WANT_DEVS
 
@@ -67,6 +66,21 @@ static char  mxc_fec_name[] = "mxc_fec";
 #define GPR_MASK(bit)          (1 << (GPR_SHIFT(bit)))
 #define GPR_VAL(bit,val)       (((val) << (GPR_SHIFT(bit))) & (GPR_MASK(bit)))
 
+#ifdef CYGSEM_REDBOOT_PLF_ESA_VALIDATE
+//
+// Verify that the given ESA is valid for this platform
+//
+static char oui[3] = CYGDAT_DEVS_ETH_ARM_TX27KARO_OUI;
+
+bool
+cyg_plf_redboot_esa_validate(unsigned char *val)
+{
+       return (val[0] == oui[0]) && (val[1] == oui[1]) && (val[2] == oui[2]);
+}
+#endif
+
+extern int tx27_mac_addr_program(unsigned char mac_addr[ETHER_ADDR_LEN]);
+
 static inline void tx27_set_reg(unsigned long addr, CYG_WORD32 set, CYG_WORD32 clr)
 {
        CYG_WORD32 val;
@@ -108,8 +122,8 @@ static bool tx27_fec_init(struct cyg_netdevtab_entry *tab)
        int ok;
 
        /* Check, whether MAC address is enabled */
-       ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
-                                        "fec_esa", &esa_set, CONFIG_BOOL);
+       ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
+                                                                        "fec_esa", &esa_set, CONFIG_BOOL);
        if (!(ok && esa_set)) {
                diag_printf("FEC disabled; set fec_esa=true to enable networking\n");
                return false;
@@ -158,8 +172,8 @@ static void tx27_fec_phy_init(void)
                tx27_set_reg(SOC_GPIOB_BASE + GPIO_DR, 0, GPR_MASK(30));
        }
 
-       const unsigned int phy_mode_mask = 0x1060;
-       // deassert PD0-15 (except 5,6,12 => PHY MODE[0..2])
+       const unsigned int phy_mode_mask = 0x10e0;
+       // deassert PD0-15 (except 5,6,7,12 => PHY MODE[0..2], INTSEL)
        tx27_set_reg(SOC_GPIOD_BASE + GPIO_OCR1, 0xffffffff, 0);
        tx27_set_reg(SOC_GPIOD_BASE + GPIO_DR, phy_mode_mask, ~phy_mode_mask);
        tx27_set_reg(SOC_GPIOD_BASE + GPIO_DDIR, 0xffff, 0);
@@ -203,12 +217,83 @@ ETH_PHY_REG_LEVEL_ACCESS_FUNS(eth0_phy,
                               mxc_fec_phy_write,
                               mxc_fec_phy_read);
 
+cyg_bool _tx27_provide_fec_esa(unsigned char *addr)
+{
+       cyg_bool enabled;
+       int ok;
+
+       ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
+                                        "fec_esa", &enabled, CONFIG_BOOL);
+       if (ok && enabled) {
+#ifdef CYGSEM_REDBOOT_PLF_ESA_VALIDATE
+               cyg_uint8 addr2[ETHER_ADDR_LEN];
+
+               addr[0] = readl(SOC_FEC_MAC_BASE2 + 0x0);
+               addr[1] = readl(SOC_FEC_MAC_BASE2 + 0x4);
+               addr[2] = readl(SOC_FEC_MAC_BASE2 + 0x8);
+               addr[3] = readl(SOC_FEC_MAC_BASE2 + 0xC);
+               addr[4] = readl(SOC_FEC_MAC_BASE2 + 0x10);
+               addr[5] = readl(SOC_FEC_MAC_BASE2 + 0x14);
+
+               if (cyg_plf_redboot_esa_validate(addr)) {
+                       diag_printf("Ethernet FEC MAC address from fuse bank: ");
+                       diag_printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
+                                   addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
+                       CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
+                                                                               "fec_esa_data", addr2, CONFIG_ESA);
+                       if (memcmp(addr, addr2, sizeof(addr)) != 0) {
+                               CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_SET,
+                                                                                       "fec_esa_data", addr, CONFIG_ESA);
+                       }
+#ifdef SOC_MAC_ADDR_LOCK
+                       if ((readl(SOC_FEC_MAC_BASE2 - 0x14) & SOC_MAC_ADDR_LOCK) == 0) {
+                               tx27_mac_addr_program(addr);
+                       }
+#endif // SOC_MAC_ADDR_LOCK
+                       return true;
+               }
+#endif // CYGSEM_REDBOOT_PLF_ESA_VALIDATE
+
+               CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
+                                                                       "fec_esa_data", addr, CONFIG_ESA);
+
+               diag_printf("Ethernet FEC MAC address from fconfig: ");
+               diag_printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
+                           addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
+
+#ifdef CYGSEM_REDBOOT_PLF_ESA_VALIDATE
+               if (cyg_plf_redboot_esa_validate(addr)) {
+                       tx27_mac_addr_program(addr);
+                       return true;
+               }
+
+               diag_printf("** Error: Invalid MAC address: ");
+               diag_printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
+                           addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
+
+#ifdef SOC_MAC_ADDR_LOCK
+               if ((readl(SOC_FEC_MAC_BASE2 - 0x14) & SOC_MAC_ADDR_LOCK) == 0) {
+                       diag_printf("Use 'fconfig fec_esa_data' to set the MAC address\n");
+                       return false;
+               } else {
+                       diag_printf("Using MAC address from fconfig\n");
+               }
+#else
+               diag_printf("Using MAC address from fconfig\n");
+#endif // SOC_MAC_ADDR_LOCK
+#endif // CYGSEM_REDBOOT_PLF_ESA_VALIDATE
+               return true;
+       }
+       return false;
+}
+
 static mxc_fec_priv_t mxc_fec_private = {
        .phy = &eth0_phy,                             // PHY access routines
+       .provide_esa = _tx27_provide_fec_esa,
 };
 
 ETH_DRV_SC(mxc_fec_sc,
-          &mxc_fec_private, // Driver specific data
+                  &mxc_fec_private, // Driver specific data
            mxc_fec_name,
            mxc_fec_start,
            mxc_fec_stop,
@@ -243,44 +328,6 @@ RedBoot_config_option("FEC network hardware address [MAC]",
 // Note that this section *is* active in an application, outside RedBoot,
 // where the above section is not included.
 
-#include <cyg/hal/hal_if.h>
-
-#ifndef CONFIG_ESA
-#define CONFIG_ESA (6)
-#endif
-#ifndef CONFIG_BOOL
-#define CONFIG_BOOL (1)
-#endif
-
-#ifndef CYGSEM_REDBOOT_FLASH_CONFIG
-void _tx27_provide_fec_esa(void)
-{
-       cyg_bool set_esa;
-       cyg_uint8 addr[6];
-       int ok;
-
-       ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
-                                        "fec_esa", &set_esa, CONFIG_BOOL);
-       diag_printf("%s: Ethernet FEC MAC address from %p: ", __FUNCTION__, SOC_FEC_MAC_BASE2);
-       if (ok && set_esa) {
-               CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
-                                           "fec_esa_data", addr, CONFIG_ESA);
-               addr[0] = readl(SOC_FEC_MAC_BASE2 + 0x0);
-               addr[1] = readl(SOC_FEC_MAC_BASE2 + 0x4);
-               addr[2] = readl(SOC_FEC_MAC_BASE2 + 0x8);
-               addr[3] = readl(SOC_FEC_MAC_BASE2 + 0xC);
-               addr[4] = readl(SOC_FEC_MAC_BASE2 + 0x10);
-               addr[5] = readl(SOC_FEC_MAC_BASE2 + 0x14);
-
-               diag_printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
-                           addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
-       } else {
-               diag_printf("is not set\n");
-       }
-}
-
-RedBoot_init(_tx27_provide_fec_esa, RedBoot_INIT_LAST);
-#endif // CYGSEM_REDBOOT_FLASH_CONFIG
 #endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
 #endif // CYGPKG_DEVS_ETH_ARM_MXCBOARD_ETH0