diff -ruNb u-boot-original/README u-boot-work/README --- u-boot-original/README 2004-04-16 02:14:49.000000000 +0300 +++ u-boot-work/README 2004-04-16 19:28:29.278549688 +0300 @@ -1943,6 +1943,28 @@ CFG_POCMR2_MASK_ATTRIB: (MPC826x only) Overrides the default PCI memory map in cpu/mpc8260/pci.c if set. +- CONFIG_ETHER_ON_FEC[12] + Define to enable FEC[12] on a 8xx series processor. + +- CONFIG_FEC[12]_PHY + Define to the hardcoded phy address which corresponds + to the given FEC. + + i.e. + #define CONFIG_FEC1_PHY 4 + means that the phy with address 4 is connected to FEC1 + + When set to -1, means to probe for first available. + +- CONFIG_FEC[12]_PHY_NORXERR + The PHY does not have a RXERR line (RMII only). + (so program the FEC to ignore it). + +- CONFIG_RMII + Enable RMII mode for all FECs. + Note that this is a global option, we can't + have one FEC in standard MII mode and another in RMII mode. + Building the Software: ====================== diff -ruNb u-boot-original/cpu/mpc8xx/fec.c u-boot-work/cpu/mpc8xx/fec.c --- u-boot-original/cpu/mpc8xx/fec.c 2004-04-16 00:31:56.000000000 +0300 +++ u-boot-work/cpu/mpc8xx/fec.c 2004-04-16 19:18:56.396640976 +0300 @@ -60,22 +60,22 @@ { int ether_index; int fecp_offset; - int bd_offset; int phy_addr; int actual_phy_addr; + int initialized; } ether_fcc_info[] = { #if defined(CONFIG_ETHER_ON_FEC1) { 0, offsetof(immap_t, im_cpm.cp_fec1), - CPM_FEC_BASE, #if defined(CONFIG_FEC1_PHY) CONFIG_FEC1_PHY, #else -1, /* discover */ #endif -1, + 0, }, #endif @@ -83,13 +83,13 @@ { 1, offsetof(immap_t, im_cpm.cp_fec2), - CPM_FEC_BASE + 0x50, #if defined(CONFIG_FEC2_PHY) CONFIG_FEC2_PHY, #else -1, #endif -1, + 0, }, #endif }; @@ -383,6 +383,11 @@ */ fecp->fec_mii_speed = ((bd->bi_intfreq + 4999999) / 5000000) << 1; +#if defined(CONFIG_NETTA) || defined(CONFIG_NETPHONE) + /* our PHYs are the limit at 2.5 MHz */ + fecp->fec_mii_speed <<= 1; +#endif + #if defined(CONFIG_DUET) && defined(WANT_MII) /* use MDC for MII */ immr->im_ioport.iop_pdpar |= 0x0080; @@ -695,6 +700,14 @@ efis->actual_phy_addr = efis->phy_addr; } #if defined(CONFIG_MII) && defined(CONFIG_RMII) + + /* the MII interface is connected to FEC1 + so for the miiphy_xxx function to work we must + call mii_init since fec_halt messes the thing up */ + + if (efis->ether_index != 0) + mii_init(); + /* * adapt the RMII speed to the speed of the phy */ @@ -719,25 +732,43 @@ /* And last, try to fill Rx Buffer Descriptors */ fecp->fec_r_des_active = 0x01000000; /* Descriptor polling active */ + efis->initialized = 1; + return 1; } static void fec_halt(struct eth_device* dev) { -#if 0 - volatile immap_t *immr = (immap_t *)CFG_IMMR; - immr->im_cpm.cp_scc[SCC_ENET].scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); -#endif -} + struct ether_fcc_info_s *efis = dev->priv; + volatile fec_t *fecp = (volatile fec_t *)(CFG_IMMR + efis->fecp_offset); + int i; -#if 0 -void restart(void) -{ - volatile immap_t *immr = (immap_t *)CFG_IMMR; - immr->im_cpm.cp_scc[SCC_ENET].scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); + /* avoid halt if initialized; mii gets stuck otherwise */ + if (!efis->initialized) + return; + + /* Whack a reset. + * A delay is required between a reset of the FEC block and + * initialization of other FEC registers because the reset takes + * some time to complete. If you don't delay, subsequent writes + * to FEC registers might get killed by the reset routine which is + * still in progress. + */ + + fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET; + for (i = 0; + (fecp->fec_ecntrl & FEC_ECNTRL_RESET) && (i < FEC_RESET_DELAY); + ++i) { + udelay (1); + } + if (i == FEC_RESET_DELAY) { + printf ("FEC_RESET_DELAY timeout\n"); + return; + } + + efis->initialized = 0; } -#endif #if defined(CFG_DISCOVER_PHY) || defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII) @@ -781,14 +812,20 @@ { uint mii_reply; volatile fec_t *ep; + int cnt; ep = &(((immap_t *)CFG_IMMR)->im_cpm.cp_fec); ep->fec_mii_data = mii_cmd; /* command to phy */ /* wait for mii complete */ - while (!(ep->fec_ievent & FEC_ENET_MII)) - ; /* spin until done */ + cnt = 0; + while (!(ep->fec_ievent & FEC_ENET_MII)) { + if (++cnt > 1000) { + printf("mii_send STUCK!\n"); + break; + } + } mii_reply = ep->fec_mii_data; /* result from phy */ ep->fec_ievent = FEC_ENET_MII; /* clear MII complete */ #if 0 @@ -870,8 +907,6 @@ #if (defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)) && !defined(CONFIG_BITBANGMII) -static int mii_init_done = 0; - /**************************************************************************** * mii_init -- Initialize the MII for MII command without ethernet * This function is a subset of eth_init @@ -883,10 +918,6 @@ volatile fec_t *fecp = &(immr->im_cpm.cp_fec); int i, j; - if (mii_init_done != 0) { - return; - } - for (j = 0; j < sizeof(ether_fcc_info) / sizeof(ether_fcc_info[0]); j++) { /* Whack a reset. @@ -924,8 +955,6 @@ */ fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN; } - - mii_init_done = 1; } /*****************************************************************************