e1000e: workaround for packet drop on 82579 at 100Mbps
authorBruce Allan <bruce.w.allan@intel.com>
Fri, 29 Jul 2011 05:52:56 +0000 (05:52 +0000)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Sat, 13 Aug 2011 09:12:31 +0000 (02:12 -0700)
The MAC can drop short packets when the PHY detects noise on the line at
100Mbps due to a timing issue.  Workaround the issue by increasing the PLL
counter so the PHY properly recognizes the synchronization pattern from the
MAC.

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>
drivers/net/e1000e/ich8lan.c

index 7525e37..46a5277 100644 (file)
 #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
@@ -1670,6 +1671,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;
@@ -1684,12 +1686,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: