static bool sft9001_link_ok(struct efx_nic *efx, struct ethtool_cmd *ecmd)
{
	int phy_id = efx->mii.phy_id;
	u32 reg;

	if (efx_phy_mode_disabled(efx->phy_mode))
		return false;
	else if (efx->loopback_mode == LOOPBACK_GPHY)
		return true;
	else if (efx->loopback_mode)
		return mdio_clause45_links_ok(efx,
					      MDIO_MMDREG_DEVS_PMAPMD |
					      MDIO_MMDREG_DEVS_PHYXS);

	/* We must use the same definition of link state as LASI,
	 * otherwise we can miss a link state transition
	 */
	if (ecmd->speed == 10000) {
		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS,
					 PCS_10GBASET_STAT1);
		return reg & (1 << PCS_10GBASET_BLKLK_LBN);
	} else {
		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
					 C22EXT_STATUS_REG);
		return reg & (1 << C22EXT_STATUS_LINK_LBN);
	}
}
Exemple #2
0
/* Try and bring the Falcon side of the Falcon-Phy XAUI link fails
 * to come back up. Bash it until it comes back up */
static bool falcon_check_xaui_link_up(struct efx_nic *efx)
{
	int max_tries, tries;
	tries = EFX_WORKAROUND_5147(efx) ? 5 : 1;
	max_tries = tries;

	if ((efx->loopback_mode == LOOPBACK_NETWORK) ||
	    (efx->phy_type == PHY_TYPE_NONE) ||
	    efx_phy_mode_disabled(efx->phy_mode))
		return false;

	while (tries) {
		if (falcon_xaui_link_ok(efx))
			return true;

		EFX_LOG(efx, "%s Clobbering XAUI (%d tries left).\n",
			__func__, tries);
		falcon_reset_xaui(efx);
		udelay(200);
		tries--;
	}

	EFX_LOG(efx, "Failed to bring XAUI link back up in %d tries!\n",
		max_tries);
	return false;
}
Exemple #3
0
static void falcon_check_xaui_link_up(struct efx_nic *efx, int tries)
{
	efx->mac_up = falcon_xaui_link_ok(efx);

	if ((efx->loopback_mode == LOOPBACK_NETWORK) ||
	    efx_phy_mode_disabled(efx->phy_mode))
		
		return;

	while (!efx->mac_up && tries) {
		EFX_LOG(efx, "bashing xaui\n");
		falcon_reset_xaui(efx);
		udelay(200);

		efx->mac_up = falcon_xaui_link_ok(efx);
		--tries;
	}
}
Exemple #4
0
int falcon_check_xmac(struct efx_nic *efx)
{
	bool xaui_link_ok;
	int rc;

	if ((efx->loopback_mode == LOOPBACK_NETWORK) ||
	    efx_phy_mode_disabled(efx->phy_mode))
		return 0;

	falcon_mask_status_intr(efx, false);
	xaui_link_ok = falcon_xaui_link_ok(efx);

	if (EFX_WORKAROUND_5147(efx) && !xaui_link_ok)
		falcon_reset_xaui(efx);

	/* Call the PHY check_hw routine */
	rc = efx->phy_op->check_hw(efx);

	/* Unmask interrupt if everything was (and still is) ok */
	if (xaui_link_ok && efx->link_up)
		falcon_mask_status_intr(efx, true);

	return rc;
}
/* Try to bring up the Falcon side of the Falcon-Phy XAUI link */
static bool falcon_xmac_link_ok_retry(struct efx_nic *efx, int tries)
{
	bool mac_up = falcon_xmac_link_ok(efx);

	if (LOOPBACK_MASK(efx) & LOOPBACKS_EXTERNAL(efx) & LOOPBACKS_WS ||
	    efx_phy_mode_disabled(efx->phy_mode))
		/* XAUI link is expected to be down */
		return mac_up;

	falcon_stop_nic_stats(efx);

	while (!mac_up && tries) {
		EFX_LOG(efx, "bashing xaui\n");
		falcon_reset_xaui(efx);
		udelay(200);

		mac_up = falcon_xmac_link_ok(efx);
		--tries;
	}

	falcon_start_nic_stats(efx);

	return mac_up;
}