e1000e: fix unit hang during loopback test
authorYanir Lubetkin <yanirx.lubetkin@intel.com>
Tue, 2 Jun 2015 14:05:47 +0000 (17:05 +0300)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Wed, 3 Jun 2015 11:11:21 +0000 (04:11 -0700)
System would hang during execution of "ethtool -t <NIC>" for the same
reason that required flushing the descriptor rings. This fix disables
MULR for the loopback test to avoid the hang state.

Signed-off-by: Yanir Lubetkin <yanirx.lubetkin@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/e1000e/ethtool.c

index 11f486e..c62f0db 100644 (file)
@@ -1516,8 +1516,19 @@ static int e1000_set_es2lan_mac_loopback(struct e1000_adapter *adapter)
 static int e1000_setup_loopback_test(struct e1000_adapter *adapter)
 {
        struct e1000_hw *hw = &adapter->hw;
-       u32 rctl;
-
+       u32 rctl, fext_nvm11, tarc0;
+
+       if (hw->mac.type == e1000_pch_spt) {
+               fext_nvm11 = er32(FEXTNVM11);
+               fext_nvm11 |= E1000_FEXTNVM11_DISABLE_MULR_FIX;
+               ew32(FEXTNVM11, fext_nvm11);
+               tarc0 = er32(TARC(0));
+               /* clear bits 28 & 29 (control of MULR concurrent requests) */
+               tarc0 &= 0xcfffffff;
+               /* set bit 29 (value of MULR requests is now 2) */
+               tarc0 |= 0x20000000;
+               ew32(TARC(0), tarc0);
+       }
        if (hw->phy.media_type == e1000_media_type_fiber ||
            hw->phy.media_type == e1000_media_type_internal_serdes) {
                switch (hw->mac.type) {
@@ -1542,7 +1553,7 @@ static int e1000_setup_loopback_test(struct e1000_adapter *adapter)
 static void e1000_loopback_cleanup(struct e1000_adapter *adapter)
 {
        struct e1000_hw *hw = &adapter->hw;
-       u32 rctl;
+       u32 rctl, fext_nvm11, tarc0;
        u16 phy_reg;
 
        rctl = er32(RCTL);
@@ -1550,6 +1561,16 @@ static void e1000_loopback_cleanup(struct e1000_adapter *adapter)
        ew32(RCTL, rctl);
 
        switch (hw->mac.type) {
+       case e1000_pch_spt:
+               fext_nvm11 = er32(FEXTNVM11);
+               fext_nvm11 &= ~E1000_FEXTNVM11_DISABLE_MULR_FIX;
+               ew32(FEXTNVM11, fext_nvm11);
+               tarc0 = er32(TARC(0));
+               /* clear bits 28 & 29 (control of MULR concurrent requests) */
+               /* set bit 29 (value of MULR requests is now 0) */
+               tarc0 &= 0xcfffffff;
+               ew32(TARC(0), tarc0);
+               /* fall through */
        case e1000_80003es2lan:
                if (hw->phy.media_type == e1000_media_type_fiber ||
                    hw->phy.media_type == e1000_media_type_internal_serdes) {