Exemple #1
0
static int tenxpress_phy_reconfigure(struct efx_nic *efx)
{
	struct tenxpress_phy_data *phy_data = efx->phy_data;
	bool phy_mode_change, loop_reset;

	if (efx->phy_mode & (PHY_MODE_OFF | PHY_MODE_SPECIAL)) {
		phy_data->phy_mode = efx->phy_mode;
		return 0;
	}

	phy_mode_change = (efx->phy_mode == PHY_MODE_NORMAL &&
			   phy_data->phy_mode != PHY_MODE_NORMAL);
	loop_reset = (LOOPBACK_OUT_OF(phy_data, efx, LOOPBACKS_EXTERNAL(efx)) ||
		      LOOPBACK_CHANGED(phy_data, efx, 1 << LOOPBACK_GPHY));

	if (loop_reset || phy_mode_change) {
		tenxpress_special_reset(efx);
		falcon_reset_xaui(efx);
	}

	tenxpress_low_power(efx);
	efx_mdio_transmit_disable(efx);
	efx_mdio_phy_reconfigure(efx);
	tenxpress_ext_loopback(efx);
	efx_mdio_an_reconfigure(efx);

	phy_data->loopback_mode = efx->loopback_mode;
	phy_data->phy_mode = efx->phy_mode;

	return 0;
}
Exemple #2
0
static int tenxpress_phy_init(struct efx_nic *efx)
{
	int rc;

	falcon_board(efx)->type->init_phy(efx);

	if (!(efx->phy_mode & PHY_MODE_SPECIAL)) {
		rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS);
		if (rc < 0)
			return rc;

		rc = efx_mdio_check_mmds(efx, TENXPRESS_REQUIRED_DEVS);
		if (rc < 0)
			return rc;
	}

	rc = tenxpress_init(efx);
	if (rc < 0)
		return rc;

	/* Reinitialise flow control settings */
	efx_link_set_wanted_fc(efx, efx->wanted_fc);
	efx_mdio_an_reconfigure(efx);

	schedule_timeout_uninterruptible(HZ / 5); /* 200ms */

	/* Let XGXS and SerDes out of reset */
	falcon_reset_xaui(efx);

	return 0;
}
Exemple #3
0
static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags)
{
	int rc = 0, rc2, i, ctrl_reg, res_reg;

	/* Initialise cable diagnostic results to unknown failure */
	for (i = 1; i < 9; ++i)
		results[i] = -1;

	/* Run cable diagnostics; wait up to 5 seconds for them to complete.
	 * A cable fault is not a self-test failure, but a timeout is. */
	ctrl_reg = ((1 << CDIAG_CTRL_IMMED_LBN) |
		    (CDIAG_CTRL_LEN_METRES << CDIAG_CTRL_LEN_UNIT_LBN));
	if (flags & ETH_TEST_FL_OFFLINE) {
		/* Break the link in order to run full diagnostics.  We
		 * must reset the PHY to resume normal service. */
		ctrl_reg |= (1 << CDIAG_CTRL_BRK_LINK_LBN);
	}
	efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_CTRL_REG,
		       ctrl_reg);
	i = 0;
	while (efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_CTRL_REG) &
	       (1 << CDIAG_CTRL_IN_PROG_LBN)) {
		if (++i == 50) {
			rc = -ETIMEDOUT;
			goto out;
		}
		msleep(100);
	}
	res_reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_RES_REG);
	for (i = 0; i < 4; i++) {
		int pair_res =
			(res_reg >> (CDIAG_RES_A_LBN - i * CDIAG_RES_WIDTH))
			& ((1 << CDIAG_RES_WIDTH) - 1);
		int len_reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD,
					    PMA_PMD_CDIAG_LEN_REG + i);
		if (pair_res == CDIAG_RES_OK)
			results[1 + i] = 1;
		else if (pair_res == CDIAG_RES_INVALID)
			results[1 + i] = -1;
		else
			results[1 + i] = -pair_res;
		if (pair_res != CDIAG_RES_INVALID &&
		    pair_res != CDIAG_RES_OPEN &&
		    len_reg != 0xffff)
			results[5 + i] = len_reg;
	}

out:
	if (flags & ETH_TEST_FL_OFFLINE) {
		/* Reset, running the BIST and then resuming normal service. */
		rc2 = tenxpress_special_reset(efx);
		results[0] = rc2 ? -1 : 1;
		if (!rc)
			rc = rc2;

		efx_mdio_an_reconfigure(efx);
	}

	return rc;
}
Exemple #4
0
static int
sfx7101_run_tests(struct efx_nic *efx, int *results, unsigned flags)
{
	int rc;

	if (!(flags & ETH_TEST_FL_OFFLINE))
		return 0;

	/* BIST is automatically run after a special software reset */
	rc = tenxpress_special_reset(efx);
	results[0] = rc ? -1 : 1;

	efx_mdio_an_reconfigure(efx);

	return rc;
}
static int
sfx7101_run_tests(struct efx_nic *efx, int *results, unsigned flags)
{
	int rc;

	if (!(flags & ETH_TEST_FL_OFFLINE))
		return 0;

	
	rc = tenxpress_special_reset(efx);
	results[0] = rc ? -1 : 1;

	efx_mdio_an_reconfigure(efx);

	return rc;
}
Exemple #6
0
static int tenxpress_phy_init(struct efx_nic *efx)
{
	int rc;

	falcon_board(efx)->type->init_phy(efx);

	if (!(efx->phy_mode & PHY_MODE_SPECIAL)) {
		if (efx->phy_type == PHY_TYPE_SFT9001A) {
			int reg;
			reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD,
					    PMA_PMD_XCONTROL_REG);
			reg |= (1 << PMA_PMD_EXT_SSR_LBN);
			efx_mdio_write(efx, MDIO_MMD_PMAPMD,
				       PMA_PMD_XCONTROL_REG, reg);
			mdelay(200);
		}

		rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS);
		if (rc < 0)
			return rc;

		rc = efx_mdio_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0);
		if (rc < 0)
			return rc;
	}

	rc = tenxpress_init(efx);
	if (rc < 0)
		return rc;

	/* Reinitialise flow control settings */
	efx_link_set_wanted_fc(efx, efx->wanted_fc);
	efx_mdio_an_reconfigure(efx);

	schedule_timeout_uninterruptible(HZ / 5); /* 200ms */

	/* Let XGXS and SerDes out of reset */
	falcon_reset_xaui(efx);

	return 0;
}
Exemple #7
0
static int tenxpress_phy_reconfigure(struct efx_nic *efx)
{
	struct tenxpress_phy_data *phy_data = efx->phy_data;
	bool phy_mode_change, loop_reset;

	if (efx->phy_mode & (PHY_MODE_OFF | PHY_MODE_SPECIAL)) {
		phy_data->phy_mode = efx->phy_mode;
		return 0;
	}

	phy_mode_change = (efx->phy_mode == PHY_MODE_NORMAL &&
			   phy_data->phy_mode != PHY_MODE_NORMAL);
	loop_reset = (LOOPBACK_OUT_OF(phy_data, efx, LOOPBACKS_EXTERNAL(efx)) ||
		      LOOPBACK_CHANGED(phy_data, efx, 1 << LOOPBACK_GPHY));

	if (loop_reset || phy_mode_change) {
		tenxpress_special_reset(efx);

		/* Reset XAUI if we were in 10G, and are staying
		 * in 10G. If we're moving into and out of 10G
		 * then xaui will be reset anyway */
		if (EFX_IS10G(efx))
			falcon_reset_xaui(efx);
	}

	tenxpress_low_power(efx);
	efx_mdio_transmit_disable(efx);
	efx_mdio_phy_reconfigure(efx);
	tenxpress_ext_loopback(efx);
	efx_mdio_an_reconfigure(efx);

	phy_data->loopback_mode = efx->loopback_mode;
	phy_data->phy_mode = efx->phy_mode;

	return 0;
}