diff options
Diffstat (limited to 'cpu/ppc4xx/4xx_enet.c')
-rw-r--r-- | cpu/ppc4xx/4xx_enet.c | 139 |
1 files changed, 76 insertions, 63 deletions
diff --git a/cpu/ppc4xx/4xx_enet.c b/cpu/ppc4xx/4xx_enet.c index 427ea94..4f55583 100644 --- a/cpu/ppc4xx/4xx_enet.c +++ b/cpu/ppc4xx/4xx_enet.c @@ -166,6 +166,11 @@ struct eth_device *emac0_dev = NULL; #define LAST_EMAC_NUM 1 #endif +/* normal boards start with EMAC0 */ +#if !defined(CONFIG_EMAC_NR_START) +#define CONFIG_EMAC_NR_START 0 +#endif + /*-----------------------------------------------------------------------------+ * Prototypes and externals. *-----------------------------------------------------------------------------*/ @@ -601,6 +606,26 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis) /* end Vitesse/Cicada errata */ } #endif + +#if defined(CONFIG_ET1011C_PHY) + /* + * Agere ET1011c PHY needs to have an extended register whacked + * for RGMII mode. + */ + if (((devnum == 2) || (devnum ==3)) && (4 == ethgroup)) { + miiphy_read (dev->name, reg, 0x16, ®_short); + reg_short &= ~(0x7); + reg_short |= 0x6; /* RGMII DLL Delay*/ + miiphy_write (dev->name, reg, 0x16, reg_short); + + miiphy_read (dev->name, reg, 0x17, ®_short); + reg_short &= ~(0x40); + miiphy_write (dev->name, reg, 0x17, reg_short); + + miiphy_write(dev->name, reg, 0x1c, 0x74f0); + } +#endif + #endif /* Start/Restart autonegotiation */ phy_setup_aneg (dev->name, reg); @@ -643,8 +668,9 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis) if (hw_p->print_speed) { hw_p->print_speed = 0; - printf ("ENET Speed is %d Mbps - %s duplex connection\n", - (int) speed, (duplex == HALF) ? "HALF" : "FULL"); + printf ("ENET Speed is %d Mbps - %s duplex connection (EMAC%d)\n", + (int) speed, (duplex == HALF) ? "HALF" : "FULL", + hw_p->devnum); } #if defined(CONFIG_440) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) && \ @@ -1493,6 +1519,8 @@ int ppc_4xx_eth_initialize (bd_t * bis) struct eth_device *dev; int eth_num = 0; EMAC_4XX_HW_PST hw = NULL; + u8 ethaddr[4 + CONFIG_EMAC_NR_START][6]; + u32 hw_addr[4]; #if defined(CONFIG_440GX) unsigned long pfc1; @@ -1502,59 +1530,69 @@ int ppc_4xx_eth_initialize (bd_t * bis) pfc1 |= 0x01200000; mtsdr (sdr_pfc1, pfc1); #endif - /* set phy num and mode */ - bis->bi_phynum[0] = CONFIG_PHY_ADDR; - bis->bi_phymode[0] = 0; -#if defined(CONFIG_PHY1_ADDR) - bis->bi_phynum[1] = CONFIG_PHY1_ADDR; - bis->bi_phymode[1] = 0; -#endif -#if defined(CONFIG_440GX) - bis->bi_phynum[2] = CONFIG_PHY2_ADDR; - bis->bi_phynum[3] = CONFIG_PHY3_ADDR; - bis->bi_phymode[2] = 2; - bis->bi_phymode[3] = 2; - - ppc_4xx_eth_setup_bridge(0, bis); -#endif + /* first clear all mac-addresses */ + for (eth_num = 0; eth_num < LAST_EMAC_NUM; eth_num++) + memcpy(ethaddr[eth_num], "\0\0\0\0\0\0", 6); for (eth_num = 0; eth_num < LAST_EMAC_NUM; eth_num++) { - - /* See if we can actually bring up the interface, otherwise, skip it */ switch (eth_num) { default: /* fall through */ case 0: - if (memcmp (bis->bi_enetaddr, "\0\0\0\0\0\0", 6) == 0) { - bis->bi_phymode[eth_num] = BI_PHYMODE_NONE; - continue; - } + memcpy(ethaddr[eth_num + CONFIG_EMAC_NR_START], + bis->bi_enetaddr, 6); + hw_addr[eth_num] = 0x0; break; #ifdef CONFIG_HAS_ETH1 case 1: - if (memcmp (bis->bi_enet1addr, "\0\0\0\0\0\0", 6) == 0) { - bis->bi_phymode[eth_num] = BI_PHYMODE_NONE; - continue; - } + memcpy(ethaddr[eth_num + CONFIG_EMAC_NR_START], + bis->bi_enet1addr, 6); + hw_addr[eth_num] = 0x100; break; #endif #ifdef CONFIG_HAS_ETH2 case 2: - if (memcmp (bis->bi_enet2addr, "\0\0\0\0\0\0", 6) == 0) { - bis->bi_phymode[eth_num] = BI_PHYMODE_NONE; - continue; - } + memcpy(ethaddr[eth_num + CONFIG_EMAC_NR_START], + bis->bi_enet2addr, 6); + hw_addr[eth_num] = 0x400; break; #endif #ifdef CONFIG_HAS_ETH3 case 3: - if (memcmp (bis->bi_enet3addr, "\0\0\0\0\0\0", 6) == 0) { - bis->bi_phymode[eth_num] = BI_PHYMODE_NONE; - continue; - } + memcpy(ethaddr[eth_num + CONFIG_EMAC_NR_START], + bis->bi_enet3addr, 6); + hw_addr[eth_num] = 0x600; break; #endif } + } + + /* set phy num and mode */ + bis->bi_phynum[0] = CONFIG_PHY_ADDR; + bis->bi_phymode[0] = 0; + +#if defined(CONFIG_PHY1_ADDR) + bis->bi_phynum[1] = CONFIG_PHY1_ADDR; + bis->bi_phymode[1] = 0; +#endif +#if defined(CONFIG_440GX) + bis->bi_phynum[2] = CONFIG_PHY2_ADDR; + bis->bi_phynum[3] = CONFIG_PHY3_ADDR; + bis->bi_phymode[2] = 2; + bis->bi_phymode[3] = 2; + + ppc_4xx_eth_setup_bridge(0, bis); +#endif + + for (eth_num = 0; eth_num < LAST_EMAC_NUM; eth_num++) { + /* + * See if we can actually bring up the interface, + * otherwise, skip it + */ + if (memcmp (ethaddr[eth_num], "\0\0\0\0\0\0", 6) == 0) { + bis->bi_phymode[eth_num] = BI_PHYMODE_NONE; + continue; + } /* Allocate device structure */ dev = (struct eth_device *) malloc (sizeof (*dev)); @@ -1576,36 +1614,12 @@ int ppc_4xx_eth_initialize (bd_t * bis) } memset(hw, 0, sizeof(*hw)); - switch (eth_num) { - default: /* fall through */ - case 0: - hw->hw_addr = 0; - memcpy (dev->enetaddr, bis->bi_enetaddr, 6); - break; -#ifdef CONFIG_HAS_ETH1 - case 1: - hw->hw_addr = 0x100; - memcpy (dev->enetaddr, bis->bi_enet1addr, 6); - break; -#endif -#ifdef CONFIG_HAS_ETH2 - case 2: - hw->hw_addr = 0x400; - memcpy (dev->enetaddr, bis->bi_enet2addr, 6); - break; -#endif -#ifdef CONFIG_HAS_ETH3 - case 3: - hw->hw_addr = 0x600; - memcpy (dev->enetaddr, bis->bi_enet3addr, 6); - break; -#endif - } - + hw->hw_addr = hw_addr[eth_num]; + memcpy (dev->enetaddr, ethaddr[eth_num], 6); hw->devnum = eth_num; hw->print_speed = 1; - sprintf (dev->name, "ppc_4xx_eth%d", eth_num); + sprintf (dev->name, "ppc_4xx_eth%d", eth_num - CONFIG_EMAC_NR_START); dev->priv = (void *) hw; dev->init = ppc_4xx_eth_init; dev->halt = ppc_4xx_eth_halt; @@ -1663,7 +1677,6 @@ int ppc_4xx_eth_initialize (bd_t * bis) return (1); } - #if !defined(CONFIG_NET_MULTI) void eth_halt (void) { if (emac0_dev) { |