#define DP83TG720S_LPS_CFG3 0x18c /* Power modes are documented as bit fields but used as values */ /* Power Mode 0 is Normal mode */ #define DP83TG720S_LPS_CFG3_PWR_MODE_0 BIT(0)
/* Open Aliance 1000BaseT1 compatible HDD.TDR Fault Status Register */ #define DP83TG720S_TDR_FAULT_STATUS 0x30f
/* Register 0x0576: TDR Master Link Down Control */ #define DP83TG720S_TDR_MASTER_LINK_DOWN 0x576
#define DP83TG720S_RGMII_DELAY_CTRL 0x602 /* In RGMII mode, Enable or disable the internal delay for RXD */ #define DP83TG720S_RGMII_RX_CLK_SEL BIT(1) /* In RGMII mode, Enable or disable the internal delay for TXD */ #define DP83TG720S_RGMII_TX_CLK_SEL BIT(0)
/* Initialize the PHY to run the TDR test as described in the *"DP83TG720S-Q1:ConfiguringforOpenAllianceSpecification *Compliance(Rev.B)"applicationnote. *Mostoftheregistersarenotdocumented.Someofregisternames *areguessedbycomparingtheregisteroffsetswiththeDP83TD510E.
*/
/* Force master link down */
ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND2,
DP83TG720S_TDR_MASTER_LINK_DOWN, 0x0400); if (ret) return ret;
ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_TDR_CFG2, 0xa008); if (ret) return ret;
ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_TDR_CFG3, 0x0928); if (ret) return ret;
ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_TDR_CFG4, 0x0004); if (ret) return ret;
ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_UNKNOWN_0405, 0x6400); if (ret) return ret;
ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_UNKNOWN_083F, 0x3003); if (ret) return ret;
/* Start the TDR */
ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_TDR_CFG,
DP83TG720S_TDR_START); if (ret) return ret;
/* Read the TDR status */
ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_TDR_CFG); if (ret < 0) return ret;
/* Check if the TDR test is done */ if (!(ret & DP83TG720S_TDR_DONE)) return0;
/* Check for TDR test failure */ if (!(ret & DP83TG720S_TDR_FAIL)) { int location;
/* Read fault status */
ret = phy_read_mmd(phydev, MDIO_MMD_VEND2,
DP83TG720S_TDR_FAULT_STATUS); if (ret < 0) return ret;
/* Get fault type */
stat = oa_1000bt1_get_ethtool_cable_result_code(ret);
/* Determine fault location */
location = oa_1000bt1_get_tdr_distance(ret); if (location > 0)
ethnl_cable_test_fault_length(phydev,
ETHTOOL_A_CABLE_PAIR_A,
location);
} else { /* Active link partner or other issues */
stat = ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
}
/* save the current stats before resetting the PHY */
ret = dp83tg720_update_stats(phydev); if (ret) return ret;
return phy_init_hw(phydev);
}
staticint dp83tg720_config_aneg(struct phy_device *phydev)
{ int ret;
/* Autoneg is not supported and this PHY supports only one speed. *Weneedtocareonlyaboutmaster/slaveconfigurationifitwas *changedbyuser.
*/
ret = genphy_c45_pma_baset1_setup_master_slave(phydev); if (ret) return ret;
/* Re-read role configuration to make changes visible even if *thelinkisinadministrativedownstate.
*/ return genphy_c45_pma_baset1_read_master_slave(phydev);
}
staticint dp83tg720_read_status(struct phy_device *phydev)
{
u16 phy_sts; int ret;
phydev->pause = 0;
phydev->asym_pause = 0;
/* Most of Clause 45 registers are not present, so we can't use *genphy_c45_read_status()here.
*/
phy_sts = phy_read(phydev, DP83TG720S_MII_REG_10);
phydev->link = !!(phy_sts & DP83TG720S_LINK_STATUS); if (!phydev->link) { /* save the current stats before resetting the PHY */
ret = dp83tg720_update_stats(phydev); if (ret) return ret;
/* According to the "DP83TC81x, DP83TG72x Software *ImplementationGuide",thePHYneedstoberesetaftera *linklossorifnolinkiscreatedafteratleast100ms.
*/
ret = phy_init_hw(phydev); if (ret) return ret;
/* After HW reset we need to restore master/slave configuration. *genphy_c45_pma_baset1_read_master_slave()callwillbedone *bythedp83tg720_config_aneg()function.
*/
ret = dp83tg720_config_aneg(phydev); if (ret) return ret;
phydev->speed = SPEED_UNKNOWN;
phydev->duplex = DUPLEX_UNKNOWN;
} else { /* PMA/PMD control 1 register (Register 1.0) is present, but it *doesn'tcontainthelinkspeedinformation. *Sogenphy_c45_read_pma()can'tbeusedhere.
*/
ret = genphy_c45_pma_baset1_read_master_slave(phydev); if (ret) return ret;
staticint dp83tg720_config_init(struct phy_device *phydev)
{ int ret;
/* Reset the PHY to recover from a link failure */
ret = dp83tg720_soft_reset(phydev); if (ret) return ret;
if (phy_interface_is_rgmii(phydev)) {
ret = dp83tg720_config_rgmii_delay(phydev); if (ret) return ret;
}
/* In case the PHY is bootstrapped in managed mode, we need to *wakeit.
*/
ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_LPS_CFG3,
DP83TG720S_LPS_CFG3_PWR_MODE_0); if (ret) return ret;
/* Make role configuration visible for ethtool on init and after *rest.
*/ return genphy_c45_pma_baset1_read_master_slave(phydev);
}
if (phydev->link) {
priv->last_link_down_jiffies = 0;
/* When the link is up, use a slower interval (in jiffies) */
next_time_jiffies =
msecs_to_jiffies(DP83TG720S_POLL_ACTIVE_LINK);
} else { unsignedlong now = jiffies;
if (!priv->last_link_down_jiffies)
priv->last_link_down_jiffies = now;
if (time_before(now, priv->last_link_down_jiffies +
msecs_to_jiffies(DP83TG720S_FAST_POLL_DURATION_MS))) { /* Link recently went down: fast polling */
next_time_jiffies =
msecs_to_jiffies(DP83TG720S_POLL_NO_LINK);
} else { /* Link has been down for a while: slow polling */
next_time_jiffies =
msecs_to_jiffies(DP83TG720S_POLL_SLOW);
}
}
/* Ensure the polling time is at least one jiffy */ return max(next_time_jiffies, 1U);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.