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); }
static void xgbe_phy_stop(struct xgbe_prv_data *pdata) { netif_dbg(pdata, link, pdata->netdev, "stopping PHY\n"); /* Disable auto-negotiation */ xgbe_disable_an(pdata); /* Disable auto-negotiation interrupts */ XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0); devm_free_irq(pdata->dev, pdata->an_irq, pdata); pdata->phy.link = 0; netif_carrier_off(pdata->netdev); xgbe_phy_adjust_link(pdata); }
static void xgbe_phy_stop(struct xgbe_prv_data *pdata) { netif_dbg(pdata, link, pdata->netdev, "stopping PHY\n"); if (!pdata->phy_started) return; /* Indicate the PHY is down */ pdata->phy_started = 0; /* Disable auto-negotiation */ xgbe_an_disable_all(pdata); if (pdata->dev_irq != pdata->an_irq) devm_free_irq(pdata->dev, pdata->an_irq, pdata); pdata->phy_if.phy_impl.stop(pdata); pdata->phy.link = 0; netif_carrier_off(pdata->netdev); xgbe_phy_adjust_link(pdata); }