|
@@ -137,8 +137,9 @@
|
|
|
#define HV_PM_CTRL PHY_REG(770, 17)
|
|
|
|
|
|
/* PHY Low Power Idle Control */
|
|
|
-#define I82579_LPI_CTRL PHY_REG(772, 20)
|
|
|
-#define I82579_LPI_CTRL_ENABLE_MASK 0x6000
|
|
|
+#define I82579_LPI_CTRL PHY_REG(772, 20)
|
|
|
+#define I82579_LPI_CTRL_ENABLE_MASK 0x6000
|
|
|
+#define I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT 0x80
|
|
|
|
|
|
/* EMI Registers */
|
|
|
#define I82579_EMI_ADDR 0x10
|
|
@@ -163,6 +164,11 @@
|
|
|
#define HV_KMRN_MODE_CTRL PHY_REG(769, 16)
|
|
|
#define HV_KMRN_MDIO_SLOW 0x0400
|
|
|
|
|
|
+/* KMRN FIFO Control and Status */
|
|
|
+#define HV_KMRN_FIFO_CTRLSTA PHY_REG(770, 16)
|
|
|
+#define HV_KMRN_FIFO_CTRLSTA_PREAMBLE_MASK 0x7000
|
|
|
+#define HV_KMRN_FIFO_CTRLSTA_PREAMBLE_SHIFT 12
|
|
|
+
|
|
|
/* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */
|
|
|
/* Offset 04h HSFSTS */
|
|
|
union ich8_hws_flash_status {
|
|
@@ -657,6 +663,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
|
|
|
struct e1000_mac_info *mac = &hw->mac;
|
|
|
s32 ret_val;
|
|
|
bool link;
|
|
|
+ u16 phy_reg;
|
|
|
|
|
|
/*
|
|
|
* We only want to go out to the PHY registers to see if Auto-Neg
|
|
@@ -689,16 +696,35 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
|
|
|
|
|
|
mac->get_link_status = false;
|
|
|
|
|
|
- if (hw->phy.type == e1000_phy_82578) {
|
|
|
- ret_val = e1000_link_stall_workaround_hv(hw);
|
|
|
- if (ret_val)
|
|
|
- goto out;
|
|
|
- }
|
|
|
-
|
|
|
- if (hw->mac.type == e1000_pch2lan) {
|
|
|
+ switch (hw->mac.type) {
|
|
|
+ case e1000_pch2lan:
|
|
|
ret_val = e1000_k1_workaround_lv(hw);
|
|
|
if (ret_val)
|
|
|
goto out;
|
|
|
+ /* fall-thru */
|
|
|
+ case e1000_pchlan:
|
|
|
+ if (hw->phy.type == e1000_phy_82578) {
|
|
|
+ ret_val = e1000_link_stall_workaround_hv(hw);
|
|
|
+ if (ret_val)
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Workaround for PCHx parts in half-duplex:
|
|
|
+ * Set the number of preambles removed from the packet
|
|
|
+ * when it is passed from the PHY to the MAC to prevent
|
|
|
+ * the MAC from misinterpreting the packet type.
|
|
|
+ */
|
|
|
+ e1e_rphy(hw, HV_KMRN_FIFO_CTRLSTA, &phy_reg);
|
|
|
+ phy_reg &= ~HV_KMRN_FIFO_CTRLSTA_PREAMBLE_MASK;
|
|
|
+
|
|
|
+ if ((er32(STATUS) & E1000_STATUS_FD) != E1000_STATUS_FD)
|
|
|
+ phy_reg |= (1 << HV_KMRN_FIFO_CTRLSTA_PREAMBLE_SHIFT);
|
|
|
+
|
|
|
+ e1e_wphy(hw, HV_KMRN_FIFO_CTRLSTA, phy_reg);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -788,6 +814,11 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter)
|
|
|
(adapter->hw.phy.type == e1000_phy_igp_3))
|
|
|
adapter->flags |= FLAG_LSC_GIG_SPEED_DROP;
|
|
|
|
|
|
+ /* Enable workaround for 82579 w/ ME enabled */
|
|
|
+ if ((adapter->hw.mac.type == e1000_pch2lan) &&
|
|
|
+ (er32(FWSM) & E1000_ICH_FWSM_FW_VALID))
|
|
|
+ adapter->flags2 |= FLAG2_PCIM2PCI_ARBITER_WA;
|
|
|
+
|
|
|
/* Disable EEE by default until IEEE802.3az spec is finalized */
|
|
|
if (adapter->flags2 & FLAG2_HAS_EEE)
|
|
|
adapter->hw.dev_spec.ich8lan.eee_disable = true;
|
|
@@ -1355,7 +1386,7 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw)
|
|
|
return ret_val;
|
|
|
|
|
|
/* Preamble tuning for SSC */
|
|
|
- ret_val = e1e_wphy(hw, PHY_REG(770, 16), 0xA204);
|
|
|
+ ret_val = e1e_wphy(hw, HV_KMRN_FIFO_CTRLSTA, 0xA204);
|
|
|
if (ret_val)
|
|
|
return ret_val;
|
|
|
}
|
|
@@ -1645,6 +1676,7 @@ static s32 e1000_k1_workaround_lv(struct e1000_hw *hw)
|
|
|
s32 ret_val = 0;
|
|
|
u16 status_reg = 0;
|
|
|
u32 mac_reg;
|
|
|
+ u16 phy_reg;
|
|
|
|
|
|
if (hw->mac.type != e1000_pch2lan)
|
|
|
goto out;
|
|
@@ -1659,12 +1691,19 @@ static s32 e1000_k1_workaround_lv(struct e1000_hw *hw)
|
|
|
mac_reg = er32(FEXTNVM4);
|
|
|
mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK;
|
|
|
|
|
|
- if (status_reg & HV_M_STATUS_SPEED_1000)
|
|
|
+ ret_val = e1e_rphy(hw, I82579_LPI_CTRL, &phy_reg);
|
|
|
+ if (ret_val)
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ if (status_reg & HV_M_STATUS_SPEED_1000) {
|
|
|
mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_8USEC;
|
|
|
- else
|
|
|
+ phy_reg &= ~I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT;
|
|
|
+ } else {
|
|
|
mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_16USEC;
|
|
|
-
|
|
|
+ phy_reg |= I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT;
|
|
|
+ }
|
|
|
ew32(FEXTNVM4, mac_reg);
|
|
|
+ ret_val = e1e_wphy(hw, I82579_LPI_CTRL, phy_reg);
|
|
|
}
|
|
|
|
|
|
out:
|