示例#1
0
/**
 *  e1000_mng_enable_host_if_generic - Checks host interface is enabled
 *  @hw: pointer to the HW structure
 *
 *  Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND
 *
 *  This function checks whether the HOST IF is enabled for command operation
 *  and also checks whether the previous command is completed.  It busy waits
 *  in case of previous command is not completed.
 **/
s32 e1000_mng_enable_host_if_generic(struct e1000_hw * hw)
{
	u32 hicr;
	s32 ret_val = E1000_SUCCESS;
	u8  i;

	DEBUGFUNC("e1000_mng_enable_host_if_generic");

	/* Check that the host interface is enabled. */
	hicr = E1000_READ_REG(hw, E1000_HICR);
	if ((hicr & E1000_HICR_EN) == 0) {
		DEBUGOUT("E1000_HOST_EN bit disabled.\n");
		ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
		goto out;
	}
	/* check the previous command is completed */
	for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) {
		hicr = E1000_READ_REG(hw, E1000_HICR);
		if (!(hicr & E1000_HICR_C))
			break;
		msec_delay_irq(1);
	}

	if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) {
		DEBUGOUT("Previous command timeout failed .\n");
		ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
		goto out;
	}

out:
	return ret_val;
}
示例#2
0
/**
 *  e1000_acquire_swfw_sync_i210 - Acquire SW/FW semaphore
 *  @hw: pointer to the HW structure
 *  @mask: specifies which semaphore to acquire
 *
 *  Acquire the SW/FW semaphore to access the PHY or NVM.  The mask
 *  will also specify which port we're acquiring the lock for.
 **/
s32 e1000_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
{
	u32 swfw_sync;
	u32 swmask = mask;
	u32 fwmask = mask << 16;
	s32 ret_val = E1000_SUCCESS;
	s32 i = 0, timeout = 200; /* FIXME: find real value to use here */

	DEBUGFUNC("e1000_acquire_swfw_sync_i210");

	while (i < timeout) {
		if (e1000_get_hw_semaphore_i210(hw)) {
			ret_val = -E1000_ERR_SWFW_SYNC;
			goto out;
		}

		swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
		if (!(swfw_sync & (fwmask | swmask)))
			break;

		/*
		 * Firmware currently using resource (fwmask)
		 * or other software thread using resource (swmask)
		 */
		e1000_put_hw_semaphore_generic(hw);
		msec_delay_irq(5);
		i++;
	}

	if (i == timeout) {
		DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
		ret_val = -E1000_ERR_SWFW_SYNC;
		goto out;
	}

	swfw_sync |= swmask;
	E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);

	e1000_put_hw_semaphore_generic(hw);

out:
	return ret_val;
}
示例#3
0
/**
 *  e1000_polarity_reversal_workaround_82543 - Workaround polarity reversal
 *  @hw: pointer to the HW structure
 *
 *  When forcing link to 10 Full or 10 Half, the PHY can reverse the polarity
 *  inadvertently.  To workaround the issue, we disable the transmitter on
 *  the PHY until we have established the link partner's link parameters.
 **/
static s32 e1000_polarity_reversal_workaround_82543(struct e1000_hw *hw)
{
	s32 ret_val = E1000_SUCCESS;
	u16 mii_status_reg;
	u16 i;
	bool link;

	if (!(hw->phy.ops.write_reg))
		goto out;

	/* Polarity reversal workaround for forced 10F/10H links. */

	/* Disable the transmitter on the PHY */

	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
	if (ret_val)
		goto out;
	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFFF);
	if (ret_val)
		goto out;

	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);
	if (ret_val)
		goto out;

	/*
	 * This loop will early-out if the NO link condition has been met.
	 * In other words, DO NOT use e1000_phy_has_link_generic() here.
	 */
	for (i = PHY_FORCE_TIME; i > 0; i--) {
		/*
		 * Read the MII Status Register and wait for Link Status bit
		 * to be clear.
		 */

		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &mii_status_reg);
		if (ret_val)
			goto out;

		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &mii_status_reg);
		if (ret_val)
			goto out;

		if ((mii_status_reg & ~MII_SR_LINK_STATUS) == 0)
			break;
		msec_delay_irq(100);
	}

	/* Recommended delay time after link has been lost */
	msec_delay_irq(1000);

	/* Now we will re-enable the transmitter on the PHY */

	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
	if (ret_val)
		goto out;
	msec_delay_irq(50);
	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFF0);
	if (ret_val)
		goto out;
	msec_delay_irq(50);
	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFF00);
	if (ret_val)
		goto out;
	msec_delay_irq(50);
	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0x0000);
	if (ret_val)
		goto out;

	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);
	if (ret_val)
		goto out;

	/*
	 * Read the MII Status Register and wait for Link Status bit
	 * to be set.
	 */
	ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_TIME, 100000, &link);
	if (ret_val)
		goto out;

out:
	return ret_val;
}