static void xgbe_phy_status(struct xgbe_prv_data *pdata) { unsigned int reg, link_aneg; if (test_bit(XGBE_LINK_ERR, &pdata->dev_state)) { if (test_and_clear_bit(XGBE_LINK, &pdata->dev_state)) netif_carrier_off(pdata->netdev); pdata->phy.link = 0; goto adjust_link; } link_aneg = (pdata->phy.autoneg == AUTONEG_ENABLE); /* Get the link status. Link status is latched low, so read * once to clear and then read again to get current state */ reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); pdata->phy.link = (reg & MDIO_STAT1_LSTATUS) ? 1 : 0; if (pdata->phy.link) { if (link_aneg && !xgbe_phy_aneg_done(pdata)) { xgbe_check_link_timeout(pdata); return; } xgbe_phy_status_aneg(pdata); if (test_bit(XGBE_LINK_INIT, &pdata->dev_state)) clear_bit(XGBE_LINK_INIT, &pdata->dev_state); if (!test_bit(XGBE_LINK, &pdata->dev_state)) { set_bit(XGBE_LINK, &pdata->dev_state); netif_carrier_on(pdata->netdev); } } else { if (test_bit(XGBE_LINK_INIT, &pdata->dev_state)) { xgbe_check_link_timeout(pdata); if (link_aneg) return; } xgbe_phy_status_aneg(pdata); if (test_bit(XGBE_LINK, &pdata->dev_state)) { clear_bit(XGBE_LINK, &pdata->dev_state); netif_carrier_off(pdata->netdev); } } adjust_link: xgbe_phy_adjust_link(pdata); }
static void xgbe_phy_status(struct xgbe_prv_data *pdata) { unsigned int link_aneg; int an_restart; if (test_bit(XGBE_LINK_ERR, &pdata->dev_state)) { netif_carrier_off(pdata->netdev); pdata->phy.link = 0; goto adjust_link; } link_aneg = (pdata->phy.autoneg == AUTONEG_ENABLE); pdata->phy.link = pdata->phy_if.phy_impl.link_status(pdata, &an_restart); if (an_restart) { xgbe_phy_config_aneg(pdata); return; } if (pdata->phy.link) { if (link_aneg && !xgbe_phy_aneg_done(pdata)) { xgbe_check_link_timeout(pdata); return; } xgbe_phy_status_result(pdata); if (test_bit(XGBE_LINK_INIT, &pdata->dev_state)) clear_bit(XGBE_LINK_INIT, &pdata->dev_state); netif_carrier_on(pdata->netdev); } else { if (test_bit(XGBE_LINK_INIT, &pdata->dev_state)) { xgbe_check_link_timeout(pdata); if (link_aneg) return; } xgbe_phy_status_result(pdata); netif_carrier_off(pdata->netdev); } adjust_link: xgbe_phy_adjust_link(pdata); }