/****************************************************************************** * * sysMpc85xxMsDelay - delay for the specified amount of time (MS) * * This routine will delay for the specified amount of time by counting * decrementer ticks. * * This routine is not dependent on a particular rollover value for * the decrementer, it should work no matter what the rollover * value is. * * A small amount of count may be lost at the rollover point resulting in * the sysMpc85xxMsDelay() causing a slightly longer delay than requested. * * This routine will produce incorrect results if the delay time requested * requires a count larger than 0xffffffff to hold the decrementer * elapsed tick count. For a System Bus Speed of 67 MHz this amounts to * about 258 seconds. * * RETURNS: N/A * * ERRNO: N/A */ void sysMpc85xxMsDelay ( UINT delay /* length of time in MS to delay */ ) { sysMsDelay(delay); }
/****************************************************************************** * ae531x_reset -- Cold reset ethernet interface */ void ae531x_reset(ae531x_MAC_t *MACInfo) { UINT32 mask = 0; UINT32 regtmp; if (MACInfo->unit == 0) { mask = RESET_ENET0 | RESET_EPHY0; } else { mask = RESET_ENET1 | RESET_EPHY1; #ifdef TWISTED_ENET_MACS mask |= RESET_ENET0 | RESET_EPHY0; #endif } /* Put into reset */ regtmp = sysRegRead(AR531X_RESET); sysRegWrite(AR531X_RESET, regtmp | mask); sysMsDelay(15); /* Pull out of reset */ regtmp = sysRegRead(AR531X_RESET); sysRegWrite(AR531X_RESET, regtmp & ~mask); sysUDelay(25); /* Enable */ if (MACInfo->unit == 0) { mask = ENABLE_ENET0; } else { mask = ENABLE_ENET1; #ifdef TWISTED_ENET_MACS mask |= ENABLE_ENET0; #endif } regtmp = sysRegRead(AR531X_ENABLE); sysRegWrite(AR531X_ENABLE, regtmp | mask); }
/****************************************************************************** * * mv_phySetup - reset and setup the PHY switch. * * Resets each PHY port. * * RETURNS: * TRUE --> at least 1 PHY with LINK * FALSE --> no LINKs on this ethernet unit */ BOOL mv_phySetup(int ethUnit, UINT32 phyBase) { int phyUnit; int liveLinks = 0; BOOL foundPhy = FALSE; UINT32 phyAddr; UINT16 atuControl; /* * See if there's any configuration data for this enet, * and set up phyBase in table. */ for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) { if (MV_ETHUNIT(phyUnit) != ethUnit) { continue; } MV_PHYBASE(phyUnit) = phyBase; foundPhy = TRUE; } if (!foundPhy) { return FALSE; /* No PHY's configured for this ethUnit */ } /* Verify that the switch is what we think it is, and that it's ready */ mv_verifyReady(ethUnit); /* Initialize global switch settings */ atuControl = MV_ATUCTRL_AGE_TIME_DEFAULT << MV_ATUCTRL_AGE_TIME_SHIFT; atuControl |= MV_ATUCTRL_ATU_SIZE_DEFAULT << MV_ATUCTRL_ATU_SIZE_SHIFT; phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_CONTROL, atuControl); /* Reset PHYs and start autonegoation on each. */ for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) { if (MV_ETHUNIT(phyUnit) != ethUnit) { continue; } phyBase = MV_PHYBASE(phyUnit); phyAddr = MV_PHYADDR(phyUnit); phyRegWrite(phyBase, phyAddr, MV_PHY_CONTROL, MV_CTRL_SOFTWARE_RESET | MV_CTRL_AUTONEGOTIATION_ENABLE); } #if 0 /* Don't wait -- we'll detect shortly after the link comes up */ { int timeout; UINT16 phyHwStatus; /* * Wait 5 seconds for ALL associated PHYs to finish autonegotiation. */ timeout=50; for (phyUnit=0; (phyUnit < MV_PHY_MAX) && (timeout > 0); phyUnit++) { if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) { continue; } for (;;) { phyBase = MV_PHYBASE(phyUnit); phyAddr = MV_PHYADDR(phyUnit); phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS); if (MV_AUTONEG_DONE(phyHwStatus)) { break; } if (--timeout == 0) { break; } sysMsDelay(100); } } } #endif /* * All PHYs have had adequate time to autonegotiate. * Now initialize software status. * * It's possible that some ports may take a bit longer * to autonegotiate; but we can't wait forever. They'll * get noticed by mv_phyCheckStatusChange during regular * polling activities. */ for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) { if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) { continue; } if (mv_phyIsLinkAlive(phyUnit)) { liveLinks++; MV_IS_PHY_ALIVE(phyUnit) = TRUE; } else { MV_IS_PHY_ALIVE(phyUnit) = FALSE; } MV_PRINT(MV_DEBUG_PHYSETUP, ("eth%d: Phy Status=%4.4x\n", ethUnit, phyRegRead(MV_PHYBASE(phyUnit), MV_PHYADDR(phyUnit), MV_PHY_SPECIFIC_STATUS))); } mv_VLANInit(ethUnit); mv_enableConfiguredPorts(ethUnit); return (liveLinks > 0); }
BOOL adm_phySetup(int ethUnit) { int phyUnit, global; uint16_t phyHwStatus; uint16_t timeout; int liveLinks = 0; uint32_t phyBase = 0; BOOL foundPhy = FALSE; uint32_t phyAddr; static int inited = 0; /* Reset PHYs*/ for (phyUnit=0; phyUnit < ADM_PHY_MAX; phyUnit++) { if (!ADM_IS_ETHUNIT(phyUnit, ethUnit)) { continue; } phyBase = ADM_PHYBASE(phyUnit); phyAddr = ADM_PHYADDR(phyUnit); phy_reg_write(phyBase, phyAddr, ADM_PHY_CONTROL, ADM_CTRL_SOFTWARE_RESET); } /* * After the phy is reset, it takes a little while before * it can respond properly. */ sysMsDelay(300); /* See if there's any configuration data for this enet */ for (phyUnit=0; phyUnit < ADM_PHY_MAX; phyUnit++) { if (!ADM_IS_ETHUNIT(phyUnit, ethUnit)) { continue; } phyBase = ADM_PHYBASE(phyUnit); foundPhy = TRUE; break; } if (!foundPhy) { return FALSE; /* No PHY's configured for this ethUnit */ } /* start auto negogiation on each phy */ for (phyUnit=0; phyUnit < ADM_PHY_MAX; phyUnit++) { if (!ADM_IS_ETHUNIT(phyUnit, ethUnit)) { continue; } phyBase = ADM_PHYBASE(phyUnit); phyAddr = ADM_PHYADDR(phyUnit); phy_reg_write(phyBase, phyAddr, ADM_AUTONEG_ADVERT, ADM_ADVERTISE_ALL); phy_reg_write(phyBase, phyAddr, ADM_PHY_CONTROL, ADM_CTRL_AUTONEGOTIATION_ENABLE | ADM_CTRL_START_AUTONEGOTIATION); } /* * Wait up to .75 seconds for ALL associated PHYs to finish * autonegotiation. The only way we get out of here sooner is * if ALL PHYs are connected AND finish autonegotiation. */ timeout=5; for (phyUnit=0; (phyUnit < ADM_PHY_MAX) /*&& (timeout > 0) */; phyUnit++) { if (!ADM_IS_ETHUNIT(phyUnit, ethUnit)) { continue; } for (;;) { phyBase = ADM_PHYBASE(phyUnit); phyAddr = ADM_PHYADDR(phyUnit); phyHwStatus = phy_reg_read(phyBase, phyAddr, ADM_PHY_STATUS); if (ADM_AUTONEG_DONE(phyHwStatus)) { DRV_PRINT(DRV_DEBUG_PHYSETUP, ("Port %d, Neg Success\n", phyUnit)); break; } if (timeout == 0) { DRV_PRINT(DRV_DEBUG_PHYSETUP, ("Port %d, Negogiation timeout\n", phyUnit)); break; } if (--timeout == 0) { DRV_PRINT(DRV_DEBUG_PHYSETUP, ("Port %d, Negogiation timeout\n", phyUnit)); break; } sysMsDelay(150); } } /* * All PHYs have had adequate time to autonegotiate. * Now initialize software status. * * It's possible that some ports may take a bit longer * to autonegotiate; but we can't wait forever. They'll * get noticed by mv_phyCheckStatusChange during regular * polling activities. */ for (phyUnit=0; phyUnit < ADM_PHY_MAX; phyUnit++) { if (!ADM_IS_ETHUNIT(phyUnit, ethUnit)) { continue; } if (adm_phyIsLinkAlive(phyUnit)) { liveLinks++; ADM_IS_PHY_ALIVE(phyUnit) = TRUE; } else { ADM_IS_PHY_ALIVE(phyUnit) = FALSE; } DRV_PRINT(DRV_DEBUG_PHYSETUP, ("eth%d: Phy Status=%4.4x\n", ethUnit, phy_reg_read(ADM_PHYBASE(phyUnit), ADM_PHYADDR(phyUnit), ADM_PHY_STATUS))); } /* * XXX */ phy_reg_write(0, 0, 0x10, 0x50); return (liveLinks > 0); }
/****************************************************************************** * * ip_phySetup - reset and setup the PHY switch. * * Resets each PHY port. * * RETURNS: * TRUE --> at least 1 PHY with LINK * FALSE --> no LINKs on this ethernet unit */ BOOL ip_phySetup(int ethUnit) { int phyUnit; UINT16 phyHwStatus; UINT16 timeout; int liveLinks = 0; UINT32 phyBase = 0; BOOL foundPhy = FALSE; UINT32 phyAddr; /* Reset PHYs*/ for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) { if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) { continue; } phyBase = IP_PHYBASE(phyUnit); phyAddr = IP_PHYADDR(phyUnit); phyRegWrite(phyBase, phyAddr, IP_PHY_CONTROL, IP_CTRL_SOFTWARE_RESET); } /* * After the phy is reset, it takes a little while before * it can respond properly. */ sysMsDelay(300); /* Verify that the switch is what we think it is, and that it's ready */ ip_verifyReady(ethUnit); /* See if there's any configuration data for this enet */ for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) { if (IP_ETHUNIT(phyUnit) != ethUnit) { continue; } phyBase = IP_PHYBASE(phyUnit); foundPhy = TRUE; break; } if (!foundPhy) { return FALSE; /* No PHY's configured for this ethUnit */ } #ifdef COBRA_TODO /* Initialize global switch settings */ /* Initialize the aging time */ /* Set the learning properties */ #endif /* start auto negogiation on each phy */ for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) { if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) { continue; } phyBase = IP_PHYBASE(phyUnit); phyAddr = IP_PHYADDR(phyUnit); phyRegWrite(phyBase, phyAddr, IP_AUTONEG_ADVERT, IP_ADVERTISE_ALL); phyRegWrite(phyBase, phyAddr, IP_PHY_CONTROL, IP_CTRL_AUTONEGOTIATION_ENABLE | IP_CTRL_START_AUTONEGOTIATION); } /* * Wait up to .75 seconds for ALL associated PHYs to finish * autonegotiation. The only way we get out of here sooner is * if ALL PHYs are connected AND finish autonegotiation. */ timeout=5; for (phyUnit=0; (phyUnit < IP_PHY_MAX) /*&& (timeout > 0) */; phyUnit++) { if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) { continue; } for (;;) { phyBase = IP_PHYBASE(phyUnit); phyAddr = IP_PHYADDR(phyUnit); phyHwStatus = phyRegRead(phyBase, phyAddr, IP_PHY_STATUS); if (IP_AUTONEG_DONE(phyHwStatus)) { DRV_PRINT(DRV_DEBUG_PHYSETUP, ("Port %d, Neg Success\n", phyUnit)); break; } if (timeout == 0) { DRV_PRINT(DRV_DEBUG_PHYSETUP, ("Port %d, Negogiation timeout\n", phyUnit)); break; } if (--timeout == 0) { DRV_PRINT(DRV_DEBUG_PHYSETUP, ("Port %d, Negogiation timeout\n", phyUnit)); break; } sysMsDelay(150); } } /* * All PHYs have had adequate time to autonegotiate. * Now initialize software status. * * It's possible that some ports may take a bit longer * to autonegotiate; but we can't wait forever. They'll * get noticed by mv_phyCheckStatusChange during regular * polling activities. */ for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) { if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) { continue; } if (ip_phyIsLinkAlive(phyUnit)) { liveLinks++; IP_IS_PHY_ALIVE(phyUnit) = TRUE; } else { IP_IS_PHY_ALIVE(phyUnit) = FALSE; } DRV_PRINT(DRV_DEBUG_PHYSETUP, ("eth%d: Phy Status=%4.4x\n", ethUnit, phyRegRead(IP_PHYBASE(phyUnit), IP_PHYADDR(phyUnit), IP_PHY_STATUS))); } ip_VLANInit(ethUnit); return (liveLinks > 0); }