Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
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);
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
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);
}