Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3421eecd authored by Bruce Allan's avatar Bruce Allan Committed by David S. Miller
Browse files

e1000e: only perform ESB2 MDIC workaround on certain configurations



A workaround added for all ESB2 devices (adds a delay for all MDIC accesses
which resolves an issue with the MDIC ready bit being set prematurely) is
applicable only to devices in which the MAC-PHY interconnect is not
operating in a certain mode with in-band MDIO.  Check the control register
for the operating mode and enable the workaround accordingly.

Signed-off-by: default avatarBruce Allan <bruce.w.allan@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 07818950
Loading
Loading
Loading
Loading
+64 −33
Original line number Diff line number Diff line
@@ -46,6 +46,9 @@
#define E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT	 0x0000
#define E1000_KMRNCTRLSTA_OPMODE_E_IDLE		 0x2000

#define E1000_KMRNCTRLSTA_OPMODE_MASK		 0x000C
#define E1000_KMRNCTRLSTA_OPMODE_INBAND_MDIO	 0x0004

#define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gigabit Carry Extend Padding */
#define DEFAULT_TCTL_EXT_GCEX_80003ES2LAN	 0x00010000

@@ -462,6 +465,7 @@ static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
		return ret_val;
	}

	if (hw->dev_spec.e80003es2lan.mdic_wa_enable == true) {
		/*
		 * The "ready" bit in the MDIC register may be incorrectly set
		 * before the device has completed the "Page Select" MDI
@@ -480,10 +484,17 @@ static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,

		udelay(200);

	ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
		ret_val = e1000e_read_phy_reg_mdic(hw,
		                                  MAX_PHY_REG_ADDRESS & offset,
		                                  data);

		udelay(200);
	} else {
		ret_val = e1000e_read_phy_reg_mdic(hw,
		                                  MAX_PHY_REG_ADDRESS & offset,
		                                  data);
	}

	e1000_release_phy_80003es2lan(hw);

	return ret_val;
@@ -526,7 +537,7 @@ static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
		return ret_val;
	}


	if (hw->dev_spec.e80003es2lan.mdic_wa_enable == true) {
		/*
		 * The "ready" bit in the MDIC register may be incorrectly set
		 * before the device has completed the "Page Select" MDI
@@ -544,10 +555,17 @@ static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,

		udelay(200);

	ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
		ret_val = e1000e_write_phy_reg_mdic(hw,
		                                  MAX_PHY_REG_ADDRESS & offset,
		                                  data);

		udelay(200);
	} else {
		ret_val = e1000e_write_phy_reg_mdic(hw,
		                                  MAX_PHY_REG_ADDRESS & offset,
		                                  data);
	}

	e1000_release_phy_80003es2lan(hw);

	return ret_val;
@@ -866,6 +884,19 @@ static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw)
	reg_data &= ~0x00100000;
	E1000_WRITE_REG_ARRAY(hw, E1000_FFLT, 0x0001, reg_data);

	/* default to true to enable the MDIC W/A */
	hw->dev_spec.e80003es2lan.mdic_wa_enable = true;

	ret_val = e1000_read_kmrn_reg_80003es2lan(hw,
	                              E1000_KMRNCTRLSTA_OFFSET >>
	                              E1000_KMRNCTRLSTA_OFFSET_SHIFT,
	                              &i);
	if (!ret_val) {
		if ((i & E1000_KMRNCTRLSTA_OPMODE_MASK) ==
		     E1000_KMRNCTRLSTA_OPMODE_INBAND_MDIO)
			hw->dev_spec.e80003es2lan.mdic_wa_enable = false;
	}

	/*
	 * Clear all of the statistics registers (clear on read).  It is
	 * important that we do this after we have tried to establish link
+5 −0
Original line number Diff line number Diff line
@@ -900,6 +900,10 @@ struct e1000_dev_spec_82571 {
	u32 smb_counter;
};

struct e1000_dev_spec_80003es2lan {
	bool  mdic_wa_enable;
};

struct e1000_shadow_ram {
	u16  value;
	bool modified;
@@ -928,6 +932,7 @@ struct e1000_hw {

	union {
		struct e1000_dev_spec_82571	e82571;
		struct e1000_dev_spec_80003es2lan e80003es2lan;
		struct e1000_dev_spec_ich8lan	ich8lan;
	} dev_spec;
};