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

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
...@@ -46,6 +46,9 @@ ...@@ -46,6 +46,9 @@
#define E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT 0x0000 #define E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT 0x0000
#define E1000_KMRNCTRLSTA_OPMODE_E_IDLE 0x2000 #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 E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gigabit Carry Extend Padding */
#define DEFAULT_TCTL_EXT_GCEX_80003ES2LAN 0x00010000 #define DEFAULT_TCTL_EXT_GCEX_80003ES2LAN 0x00010000
...@@ -462,28 +465,36 @@ static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, ...@@ -462,28 +465,36 @@ static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
return ret_val; 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 * The "ready" bit in the MDIC register may be incorrectly set
* transaction. So we wait 200us after each MDI command... * before the device has completed the "Page Select" MDI
*/ * transaction. So we wait 200us after each MDI command...
udelay(200); */
udelay(200);
/* ...and verify the command was successful. */ /* ...and verify the command was successful. */
ret_val = e1000e_read_phy_reg_mdic(hw, page_select, &temp); ret_val = e1000e_read_phy_reg_mdic(hw, page_select, &temp);
if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) { if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) {
ret_val = -E1000_ERR_PHY; ret_val = -E1000_ERR_PHY;
e1000_release_phy_80003es2lan(hw); e1000_release_phy_80003es2lan(hw);
return ret_val; return ret_val;
} }
udelay(200); udelay(200);
ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, ret_val = e1000e_read_phy_reg_mdic(hw,
data); MAX_PHY_REG_ADDRESS & offset,
data);
udelay(200);
} else {
ret_val = e1000e_read_phy_reg_mdic(hw,
MAX_PHY_REG_ADDRESS & offset,
data);
}
udelay(200);
e1000_release_phy_80003es2lan(hw); e1000_release_phy_80003es2lan(hw);
return ret_val; return ret_val;
...@@ -526,28 +537,35 @@ static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, ...@@ -526,28 +537,35 @@ static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
return ret_val; 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
* transaction. So we wait 200us after each MDI command...
*/
udelay(200);
/* /* ...and verify the command was successful. */
* The "ready" bit in the MDIC register may be incorrectly set ret_val = e1000e_read_phy_reg_mdic(hw, page_select, &temp);
* before the device has completed the "Page Select" MDI
* transaction. So we wait 200us after each MDI command...
*/
udelay(200);
/* ...and verify the command was successful. */ if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) {
ret_val = e1000e_read_phy_reg_mdic(hw, page_select, &temp); e1000_release_phy_80003es2lan(hw);
return -E1000_ERR_PHY;
}
if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) { udelay(200);
e1000_release_phy_80003es2lan(hw);
return -E1000_ERR_PHY;
}
udelay(200); ret_val = e1000e_write_phy_reg_mdic(hw,
MAX_PHY_REG_ADDRESS & offset,
data);
ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, udelay(200);
data); } else {
ret_val = e1000e_write_phy_reg_mdic(hw,
MAX_PHY_REG_ADDRESS & offset,
data);
}
udelay(200);
e1000_release_phy_80003es2lan(hw); e1000_release_phy_80003es2lan(hw);
return ret_val; return ret_val;
...@@ -866,6 +884,19 @@ static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw) ...@@ -866,6 +884,19 @@ static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw)
reg_data &= ~0x00100000; reg_data &= ~0x00100000;
E1000_WRITE_REG_ARRAY(hw, E1000_FFLT, 0x0001, reg_data); 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 * Clear all of the statistics registers (clear on read). It is
* important that we do this after we have tried to establish link * important that we do this after we have tried to establish link
......
...@@ -900,6 +900,10 @@ struct e1000_dev_spec_82571 { ...@@ -900,6 +900,10 @@ struct e1000_dev_spec_82571 {
u32 smb_counter; u32 smb_counter;
}; };
struct e1000_dev_spec_80003es2lan {
bool mdic_wa_enable;
};
struct e1000_shadow_ram { struct e1000_shadow_ram {
u16 value; u16 value;
bool modified; bool modified;
...@@ -928,6 +932,7 @@ struct e1000_hw { ...@@ -928,6 +932,7 @@ struct e1000_hw {
union { union {
struct e1000_dev_spec_82571 e82571; struct e1000_dev_spec_82571 e82571;
struct e1000_dev_spec_80003es2lan e80003es2lan;
struct e1000_dev_spec_ich8lan ich8lan; struct e1000_dev_spec_ich8lan ich8lan;
} dev_spec; } dev_spec;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment