Commit 780ce3a2 authored by David S. Miller's avatar David S. Miller

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net

Jeff Kirsher says:

====================
Intel Wired LAN Driver Updates

This series contains updates to e1000e only.

David provides four fixes for e1000e, first is a workaround for a hardware
erratum on 82579 devices which experienced packet loss in gigabit and 100
speeds when interconnect between the PHY and MAC is exiting K1 power saving
state.  Second expands the scope of a workaround to include i217 and i218
parts as well to address over aggressive transmit behavior when connecting
at 10Mbs half-duplex.  Next is to resolve a reported link flap issue on
82579 parts which was root caused as an interoperability problem between
82579 and at least some Broadcom PHYs in the Energy Efficient Ethernet wake
mechanism.  Lastly, restricts the workaround of putting the PHY into MDIO
slow mode to access the PHY id to relevant parts since this issue has been
fixed on the newer hardware.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents eaff8292 2c982624
...@@ -186,7 +186,7 @@ static bool e1000_phy_is_accessible_pchlan(struct e1000_hw *hw) ...@@ -186,7 +186,7 @@ static bool e1000_phy_is_accessible_pchlan(struct e1000_hw *hw)
{ {
u16 phy_reg = 0; u16 phy_reg = 0;
u32 phy_id = 0; u32 phy_id = 0;
s32 ret_val; s32 ret_val = 0;
u16 retry_count; u16 retry_count;
u32 mac_reg = 0; u32 mac_reg = 0;
...@@ -217,11 +217,13 @@ static bool e1000_phy_is_accessible_pchlan(struct e1000_hw *hw) ...@@ -217,11 +217,13 @@ static bool e1000_phy_is_accessible_pchlan(struct e1000_hw *hw)
/* In case the PHY needs to be in mdio slow mode, /* In case the PHY needs to be in mdio slow mode,
* set slow mode and try to get the PHY id again. * set slow mode and try to get the PHY id again.
*/ */
hw->phy.ops.release(hw); if (hw->mac.type < e1000_pch_lpt) {
ret_val = e1000_set_mdio_slow_mode_hv(hw); hw->phy.ops.release(hw);
if (!ret_val) ret_val = e1000_set_mdio_slow_mode_hv(hw);
ret_val = e1000e_get_phy_id(hw); if (!ret_val)
hw->phy.ops.acquire(hw); ret_val = e1000e_get_phy_id(hw);
hw->phy.ops.acquire(hw);
}
if (ret_val) if (ret_val)
return false; return false;
...@@ -842,6 +844,17 @@ s32 e1000_set_eee_pchlan(struct e1000_hw *hw) ...@@ -842,6 +844,17 @@ s32 e1000_set_eee_pchlan(struct e1000_hw *hw)
} }
} }
if (hw->phy.type == e1000_phy_82579) {
ret_val = e1000_read_emi_reg_locked(hw, I82579_LPI_PLL_SHUT,
&data);
if (ret_val)
goto release;
data &= ~I82579_LPI_100_PLL_SHUT;
ret_val = e1000_write_emi_reg_locked(hw, I82579_LPI_PLL_SHUT,
data);
}
/* R/Clr IEEE MMD 3.1 bits 11:10 - Tx/Rx LPI Received */ /* R/Clr IEEE MMD 3.1 bits 11:10 - Tx/Rx LPI Received */
ret_val = e1000_read_emi_reg_locked(hw, pcs_status, &data); ret_val = e1000_read_emi_reg_locked(hw, pcs_status, &data);
if (ret_val) if (ret_val)
...@@ -1314,14 +1327,17 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) ...@@ -1314,14 +1327,17 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
return ret_val; return ret_val;
} }
/* When connected at 10Mbps half-duplex, 82579 parts are excessively /* When connected at 10Mbps half-duplex, some parts are excessively
* aggressive resulting in many collisions. To avoid this, increase * aggressive resulting in many collisions. To avoid this, increase
* the IPG and reduce Rx latency in the PHY. * the IPG and reduce Rx latency in the PHY.
*/ */
if ((hw->mac.type == e1000_pch2lan) && link) { if (((hw->mac.type == e1000_pch2lan) ||
(hw->mac.type == e1000_pch_lpt)) && link) {
u32 reg; u32 reg;
reg = er32(STATUS); reg = er32(STATUS);
if (!(reg & (E1000_STATUS_FD | E1000_STATUS_SPEED_MASK))) { if (!(reg & (E1000_STATUS_FD | E1000_STATUS_SPEED_MASK))) {
u16 emi_addr;
reg = er32(TIPG); reg = er32(TIPG);
reg &= ~E1000_TIPG_IPGT_MASK; reg &= ~E1000_TIPG_IPGT_MASK;
reg |= 0xFF; reg |= 0xFF;
...@@ -1332,8 +1348,12 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) ...@@ -1332,8 +1348,12 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
if (ret_val) if (ret_val)
return ret_val; return ret_val;
ret_val = if (hw->mac.type == e1000_pch2lan)
e1000_write_emi_reg_locked(hw, I82579_RX_CONFIG, 0); emi_addr = I82579_RX_CONFIG;
else
emi_addr = I217_RX_CONFIG;
ret_val = e1000_write_emi_reg_locked(hw, emi_addr, 0);
hw->phy.ops.release(hw); hw->phy.ops.release(hw);
...@@ -2493,51 +2513,44 @@ static s32 e1000_lv_phy_workarounds_ich8lan(struct e1000_hw *hw) ...@@ -2493,51 +2513,44 @@ static s32 e1000_lv_phy_workarounds_ich8lan(struct e1000_hw *hw)
* e1000_k1_gig_workaround_lv - K1 Si workaround * e1000_k1_gig_workaround_lv - K1 Si workaround
* @hw: pointer to the HW structure * @hw: pointer to the HW structure
* *
* Workaround to set the K1 beacon duration for 82579 parts * Workaround to set the K1 beacon duration for 82579 parts in 10Mbps
* Disable K1 in 1000Mbps and 100Mbps
**/ **/
static s32 e1000_k1_workaround_lv(struct e1000_hw *hw) static s32 e1000_k1_workaround_lv(struct e1000_hw *hw)
{ {
s32 ret_val = 0; s32 ret_val = 0;
u16 status_reg = 0; u16 status_reg = 0;
u32 mac_reg;
u16 phy_reg;
if (hw->mac.type != e1000_pch2lan) if (hw->mac.type != e1000_pch2lan)
return 0; return 0;
/* Set K1 beacon duration based on 1Gbps speed or otherwise */ /* Set K1 beacon duration based on 10Mbs speed */
ret_val = e1e_rphy(hw, HV_M_STATUS, &status_reg); ret_val = e1e_rphy(hw, HV_M_STATUS, &status_reg);
if (ret_val) if (ret_val)
return ret_val; return ret_val;
if ((status_reg & (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE)) if ((status_reg & (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE))
== (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE)) { == (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE)) {
mac_reg = er32(FEXTNVM4); if (status_reg &
mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK; (HV_M_STATUS_SPEED_1000 | HV_M_STATUS_SPEED_100)) {
ret_val = e1e_rphy(hw, I82579_LPI_CTRL, &phy_reg);
if (ret_val)
return ret_val;
if (status_reg & HV_M_STATUS_SPEED_1000) {
u16 pm_phy_reg; u16 pm_phy_reg;
mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_8USEC; /* LV 1G/100 Packet drop issue wa */
phy_reg &= ~I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT;
/* LV 1G Packet drop issue wa */
ret_val = e1e_rphy(hw, HV_PM_CTRL, &pm_phy_reg); ret_val = e1e_rphy(hw, HV_PM_CTRL, &pm_phy_reg);
if (ret_val) if (ret_val)
return ret_val; return ret_val;
pm_phy_reg &= ~HV_PM_CTRL_PLL_STOP_IN_K1_GIGA; pm_phy_reg &= ~HV_PM_CTRL_K1_ENABLE;
ret_val = e1e_wphy(hw, HV_PM_CTRL, pm_phy_reg); ret_val = e1e_wphy(hw, HV_PM_CTRL, pm_phy_reg);
if (ret_val) if (ret_val)
return ret_val; return ret_val;
} else { } else {
u32 mac_reg;
mac_reg = er32(FEXTNVM4);
mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK;
mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_16USEC; mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_16USEC;
phy_reg |= I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT; ew32(FEXTNVM4, mac_reg);
} }
ew32(FEXTNVM4, mac_reg);
ret_val = e1e_wphy(hw, I82579_LPI_CTRL, phy_reg);
} }
return ret_val; return ret_val;
......
...@@ -232,16 +232,19 @@ ...@@ -232,16 +232,19 @@
#define I82577_MSE_THRESHOLD 0x0887 /* 82577 Mean Square Error Threshold */ #define I82577_MSE_THRESHOLD 0x0887 /* 82577 Mean Square Error Threshold */
#define I82579_MSE_LINK_DOWN 0x2411 /* MSE count before dropping link */ #define I82579_MSE_LINK_DOWN 0x2411 /* MSE count before dropping link */
#define I82579_RX_CONFIG 0x3412 /* Receive configuration */ #define I82579_RX_CONFIG 0x3412 /* Receive configuration */
#define I82579_LPI_PLL_SHUT 0x4412 /* LPI PLL Shut Enable */
#define I82579_EEE_PCS_STATUS 0x182E /* IEEE MMD Register 3.1 >> 8 */ #define I82579_EEE_PCS_STATUS 0x182E /* IEEE MMD Register 3.1 >> 8 */
#define I82579_EEE_CAPABILITY 0x0410 /* IEEE MMD Register 3.20 */ #define I82579_EEE_CAPABILITY 0x0410 /* IEEE MMD Register 3.20 */
#define I82579_EEE_ADVERTISEMENT 0x040E /* IEEE MMD Register 7.60 */ #define I82579_EEE_ADVERTISEMENT 0x040E /* IEEE MMD Register 7.60 */
#define I82579_EEE_LP_ABILITY 0x040F /* IEEE MMD Register 7.61 */ #define I82579_EEE_LP_ABILITY 0x040F /* IEEE MMD Register 7.61 */
#define I82579_EEE_100_SUPPORTED (1 << 1) /* 100BaseTx EEE */ #define I82579_EEE_100_SUPPORTED (1 << 1) /* 100BaseTx EEE */
#define I82579_EEE_1000_SUPPORTED (1 << 2) /* 1000BaseTx EEE */ #define I82579_EEE_1000_SUPPORTED (1 << 2) /* 1000BaseTx EEE */
#define I82579_LPI_100_PLL_SHUT (1 << 2) /* 100M LPI PLL Shut Enabled */
#define I217_EEE_PCS_STATUS 0x9401 /* IEEE MMD Register 3.1 */ #define I217_EEE_PCS_STATUS 0x9401 /* IEEE MMD Register 3.1 */
#define I217_EEE_CAPABILITY 0x8000 /* IEEE MMD Register 3.20 */ #define I217_EEE_CAPABILITY 0x8000 /* IEEE MMD Register 3.20 */
#define I217_EEE_ADVERTISEMENT 0x8001 /* IEEE MMD Register 7.60 */ #define I217_EEE_ADVERTISEMENT 0x8001 /* IEEE MMD Register 7.60 */
#define I217_EEE_LP_ABILITY 0x8002 /* IEEE MMD Register 7.61 */ #define I217_EEE_LP_ABILITY 0x8002 /* IEEE MMD Register 7.61 */
#define I217_RX_CONFIG 0xB20C /* Receive configuration */
#define E1000_EEE_RX_LPI_RCVD 0x0400 /* Tx LP idle received */ #define E1000_EEE_RX_LPI_RCVD 0x0400 /* Tx LP idle received */
#define E1000_EEE_TX_LPI_RCVD 0x0800 /* Rx LP idle received */ #define E1000_EEE_TX_LPI_RCVD 0x0800 /* Rx LP idle received */
......
...@@ -164,6 +164,7 @@ s32 e1000_get_cable_length_82577(struct e1000_hw *hw); ...@@ -164,6 +164,7 @@ s32 e1000_get_cable_length_82577(struct e1000_hw *hw);
#define HV_M_STATUS_AUTONEG_COMPLETE 0x1000 #define HV_M_STATUS_AUTONEG_COMPLETE 0x1000
#define HV_M_STATUS_SPEED_MASK 0x0300 #define HV_M_STATUS_SPEED_MASK 0x0300
#define HV_M_STATUS_SPEED_1000 0x0200 #define HV_M_STATUS_SPEED_1000 0x0200
#define HV_M_STATUS_SPEED_100 0x0100
#define HV_M_STATUS_LINK_UP 0x0040 #define HV_M_STATUS_LINK_UP 0x0040
#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4 #define IGP01E1000_PHY_PCS_INIT_REG 0x00B4
......
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