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,6 +465,7 @@ static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, ...@@ -462,6 +465,7 @@ 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 * The "ready" bit in the MDIC register may be incorrectly set
* before the device has completed the "Page Select" MDI * 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, ...@@ -480,10 +484,17 @@ static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
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,
MAX_PHY_REG_ADDRESS & offset,
data); data);
udelay(200); udelay(200);
} else {
ret_val = e1000e_read_phy_reg_mdic(hw,
MAX_PHY_REG_ADDRESS & offset,
data);
}
e1000_release_phy_80003es2lan(hw); e1000_release_phy_80003es2lan(hw);
return ret_val; return ret_val;
...@@ -526,7 +537,7 @@ static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, ...@@ -526,7 +537,7 @@ 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 * The "ready" bit in the MDIC register may be incorrectly set
* before the device has completed the "Page Select" MDI * 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, ...@@ -544,10 +555,17 @@ static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
udelay(200); 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); data);
udelay(200); udelay(200);
} else {
ret_val = e1000e_write_phy_reg_mdic(hw,
MAX_PHY_REG_ADDRESS & offset,
data);
}
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