/***************************************************************************** * * mv_phyCheckStatusChange -- checks for significant changes in PHY state. * * A "significant change" is: * dropped link (e.g. ethernet cable unplugged) OR * autonegotiation completed + link (e.g. ethernet cable plugged in) */ void mv_phyCheckStatusChange(int ethUnit) { int phyUnit; UINT16 phyHwStatus; mvPhyInfo_t *lastStatus; int linkCount = 0; int lostLinks = 0; int gainedLinks = 0; UINT32 phyBase; UINT32 phyAddr; for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) { if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) { continue; } phyBase = MV_PHYBASE(phyUnit); phyAddr = MV_PHYADDR(phyUnit); lastStatus = &mvPhyInfo[phyUnit]; phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS); if (lastStatus->isPhyAlive) { /* last known link status was ALIVE */ /* See if we've lost link */ if (phyHwStatus & MV_STATUS_REAL_TIME_LINK_UP) { linkCount++; } else { lostLinks++; mv_flushATUDB(phyUnit); MV_PRINT(MV_DEBUG_PHYCHANGE,("\neth%d port%d down\n", ethUnit, phyUnit)); lastStatus->isPhyAlive = FALSE; } } else { /* last known link status was DEAD */ /* Check for AutoNegotiation complete */ if (MV_AUTONEG_DONE(phyHwStatus)) { gainedLinks++; linkCount++; MV_PRINT(MV_DEBUG_PHYCHANGE,("\neth%d port%d up\n", ethUnit, phyUnit)); lastStatus->isPhyAlive = TRUE; } } } if (linkCount == 0) { if (lostLinks) { /* We just lost the last link for this MAC */ phyLinkLost(ethUnit); } } else { if (gainedLinks == linkCount) { /* We just gained our first link(s) for this MAC */ phyLinkGained(ethUnit); } } }
int adm_phyIsUp(int ethUnit) { int phyUnit; uint16_t phyHwStatus; admPhyInfo_t *lastStatus; int linkCount = 0; int lostLinks = 0; int gainedLinks = 0; uint32_t phyBase; uint32_t phyAddr; for (phyUnit=0; phyUnit < ADM_PHY_MAX; phyUnit++) { if (!ADM_IS_ETHUNIT(phyUnit, ethUnit)) { continue; } phyBase = ADM_PHYBASE(phyUnit); phyAddr = ADM_PHYADDR(phyUnit); lastStatus = &admPhyInfo[phyUnit]; phyHwStatus = phy_reg_read(phyBase, phyAddr, ADM_PHY_STATUS); if (lastStatus->isPhyAlive) { /* last known link status was ALIVE */ /* See if we've lost link */ if (phyHwStatus & ADM_STATUS_LINK_PASS) { linkCount++; } else { lostLinks++; #ifdef COBRA_TODO mv_flushATUDB(phyUnit); #endif DRV_PRINT(DRV_DEBUG_PHYCHANGE,("\nenet%d port%d down\n", ethUnit, phyUnit)); lastStatus->isPhyAlive = FALSE; } } else { /* last known link status was DEAD */ /* Check for AutoNegotiation complete */ if (ADM_AUTONEG_DONE(phyHwStatus)) { //printk("autoneg done\n"); gainedLinks++; linkCount++; DRV_PRINT(DRV_DEBUG_PHYCHANGE,("\nenet%d port%d up\n", ethUnit, phyUnit)); lastStatus->isPhyAlive = TRUE; } } } return (linkCount); #if 0 if (linkCount == 0) { if (lostLinks) { /* We just lost the last link for this MAC */ phyLinkLost(ethUnit); } } else { if (gainedLinks == linkCount) { /* We just gained our first link(s) for this MAC */ phyLinkGained(ethUnit); } } #endif }