aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBruce Allan <bruce.w.allan@intel.com>2010-09-22 13:16:18 -0400
committerDavid S. Miller <davem@davemloft.net>2010-09-22 23:41:20 -0400
commit831bd2e6a6c09588fdde453ecb858f050ac1b942 (patch)
treed574443e20c1e4e8ae9a7a13c525f151c3365ccb
parent5f3eed6fe0e36e4b56c8dd9160241a868ee0de2a (diff)
e1000e: 82579 unaccounted missed packets
On 82579, there is a hardware bug that can cause received packets to not get transferred from the PHY to the MAC due to K1 (a power saving feature of the PHY-MAC interconnect similar to ASPM L1). Since the MAC controls the accounting of missed packets, these will go unnoticed. Workaround the issue by setting the K1 beacon duration according to the link speed. Signed-off-by: Bruce Allan <bruce.w.allan@intel.com> Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/e1000e/hw.h1
-rw-r--r--drivers/net/e1000e/ich8lan.c48
2 files changed, 49 insertions, 0 deletions
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index 66ed08f726fb..ba302a5c2c30 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -57,6 +57,7 @@ enum e1e_registers {
57 E1000_SCTL = 0x00024, /* SerDes Control - RW */ 57 E1000_SCTL = 0x00024, /* SerDes Control - RW */
58 E1000_FCAL = 0x00028, /* Flow Control Address Low - RW */ 58 E1000_FCAL = 0x00028, /* Flow Control Address Low - RW */
59 E1000_FCAH = 0x0002C, /* Flow Control Address High -RW */ 59 E1000_FCAH = 0x0002C, /* Flow Control Address High -RW */
60 E1000_FEXTNVM4 = 0x00024, /* Future Extended NVM 4 - RW */
60 E1000_FEXTNVM = 0x00028, /* Future Extended NVM - RW */ 61 E1000_FEXTNVM = 0x00028, /* Future Extended NVM - RW */
61 E1000_FCT = 0x00030, /* Flow Control Type - RW */ 62 E1000_FCT = 0x00030, /* Flow Control Type - RW */
62 E1000_VET = 0x00038, /* VLAN Ether Type - RW */ 63 E1000_VET = 0x00038, /* VLAN Ether Type - RW */
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index 6f9cb0d44d3a..89b1e1aea526 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -105,6 +105,10 @@
105#define E1000_FEXTNVM_SW_CONFIG 1 105#define E1000_FEXTNVM_SW_CONFIG 1
106#define E1000_FEXTNVM_SW_CONFIG_ICH8M (1 << 27) /* Bit redefined for ICH8M :/ */ 106#define E1000_FEXTNVM_SW_CONFIG_ICH8M (1 << 27) /* Bit redefined for ICH8M :/ */
107 107
108#define E1000_FEXTNVM4_BEACON_DURATION_MASK 0x7
109#define E1000_FEXTNVM4_BEACON_DURATION_8USEC 0x7
110#define E1000_FEXTNVM4_BEACON_DURATION_16USEC 0x3
111
108#define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL 112#define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL
109 113
110#define E1000_ICH_RAR_ENTRIES 7 114#define E1000_ICH_RAR_ENTRIES 7
@@ -238,6 +242,7 @@ static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link);
238static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw); 242static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw);
239static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw); 243static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw);
240static bool e1000_check_mng_mode_pchlan(struct e1000_hw *hw); 244static bool e1000_check_mng_mode_pchlan(struct e1000_hw *hw);
245static s32 e1000_k1_workaround_lv(struct e1000_hw *hw);
241 246
242static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg) 247static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg)
243{ 248{
@@ -653,6 +658,12 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
653 goto out; 658 goto out;
654 } 659 }
655 660
661 if (hw->mac.type == e1000_pch2lan) {
662 ret_val = e1000_k1_workaround_lv(hw);
663 if (ret_val)
664 goto out;
665 }
666
656 /* 667 /*
657 * Check if there was DownShift, must be checked 668 * Check if there was DownShift, must be checked
658 * immediately after link-up 669 * immediately after link-up
@@ -1583,6 +1594,43 @@ out:
1583} 1594}
1584 1595
1585/** 1596/**
1597 * e1000_k1_gig_workaround_lv - K1 Si workaround
1598 * @hw: pointer to the HW structure
1599 *
1600 * Workaround to set the K1 beacon duration for 82579 parts
1601 **/
1602static s32 e1000_k1_workaround_lv(struct e1000_hw *hw)
1603{
1604 s32 ret_val = 0;
1605 u16 status_reg = 0;
1606 u32 mac_reg;
1607
1608 if (hw->mac.type != e1000_pch2lan)
1609 goto out;
1610
1611 /* Set K1 beacon duration based on 1Gbps speed or otherwise */
1612 ret_val = e1e_rphy(hw, HV_M_STATUS, &status_reg);
1613 if (ret_val)
1614 goto out;
1615
1616 if ((status_reg & (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE))
1617 == (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE)) {
1618 mac_reg = er32(FEXTNVM4);
1619 mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK;
1620
1621 if (status_reg & HV_M_STATUS_SPEED_1000)
1622 mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_8USEC;
1623 else
1624 mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_16USEC;
1625
1626 ew32(FEXTNVM4, mac_reg);
1627 }
1628
1629out:
1630 return ret_val;
1631}
1632
1633/**
1586 * e1000_lan_init_done_ich8lan - Check for PHY config completion 1634 * e1000_lan_init_done_ich8lan - Check for PHY config completion
1587 * @hw: pointer to the HW structure 1635 * @hw: pointer to the HW structure
1588 * 1636 *