aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/e1000e/ich8lan.c
diff options
context:
space:
mode:
authorBruce Allan <bruce.w.allan@intel.com>2013-06-21 05:07:13 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2013-07-28 06:24:14 -0400
commite0236ad9cd29f3e08dc0baa60ea3a8b219ff2610 (patch)
treefe5d5179723f9b74d618329659bd95a2de574a38 /drivers/net/ethernet/intel/e1000e/ich8lan.c
parentce345e082ee305fc7f2435630a7497ab85d30af6 (diff)
e1000e: Tx hang on I218 when linked at 100Half and slow response at 10Mbps
Tx hang is an unintended consequence of another workaround that is in the EEPROM for an issue with the firmware at 10Mbps when K1 (a power mode of the MAC-PHY interconnect) is enabled. The issue is resolved by setting appropriate Tx re-transmission timeouts in the PHY and associated K1 entry times in the MAC to allow enough transmissions to occur without triggering a Tx hang. A similar change is needed when linked at 10Mbps to improve latency. 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>
Diffstat (limited to 'drivers/net/ethernet/intel/e1000e/ich8lan.c')
-rw-r--r--drivers/net/ethernet/intel/e1000e/ich8lan.c49
1 files changed, 42 insertions, 7 deletions
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c
index 9dde390f7e71..b56c61acbac1 100644
--- a/drivers/net/ethernet/intel/e1000e/ich8lan.c
+++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c
@@ -793,29 +793,31 @@ release:
793 * When K1 is enabled for 1Gbps, the MAC can miss 2 DMA completion indications 793 * When K1 is enabled for 1Gbps, the MAC can miss 2 DMA completion indications
794 * preventing further DMA write requests. Workaround the issue by disabling 794 * preventing further DMA write requests. Workaround the issue by disabling
795 * the de-assertion of the clock request when in 1Gpbs mode. 795 * the de-assertion of the clock request when in 1Gpbs mode.
796 * Also, set appropriate Tx re-transmission timeouts for 10 and 100Half link
797 * speeds in order to avoid Tx hangs.
796 **/ 798 **/
797static s32 e1000_k1_workaround_lpt_lp(struct e1000_hw *hw, bool link) 799static s32 e1000_k1_workaround_lpt_lp(struct e1000_hw *hw, bool link)
798{ 800{
799 u32 fextnvm6 = er32(FEXTNVM6); 801 u32 fextnvm6 = er32(FEXTNVM6);
802 u32 status = er32(STATUS);
800 s32 ret_val = 0; 803 s32 ret_val = 0;
804 u16 reg;
801 805
802 if (link && (er32(STATUS) & E1000_STATUS_SPEED_1000)) { 806 if (link && (status & E1000_STATUS_SPEED_1000)) {
803 u16 kmrn_reg;
804
805 ret_val = hw->phy.ops.acquire(hw); 807 ret_val = hw->phy.ops.acquire(hw);
806 if (ret_val) 808 if (ret_val)
807 return ret_val; 809 return ret_val;
808 810
809 ret_val = 811 ret_val =
810 e1000e_read_kmrn_reg_locked(hw, E1000_KMRNCTRLSTA_K1_CONFIG, 812 e1000e_read_kmrn_reg_locked(hw, E1000_KMRNCTRLSTA_K1_CONFIG,
811 &kmrn_reg); 813 &reg);
812 if (ret_val) 814 if (ret_val)
813 goto release; 815 goto release;
814 816
815 ret_val = 817 ret_val =
816 e1000e_write_kmrn_reg_locked(hw, 818 e1000e_write_kmrn_reg_locked(hw,
817 E1000_KMRNCTRLSTA_K1_CONFIG, 819 E1000_KMRNCTRLSTA_K1_CONFIG,
818 kmrn_reg & 820 reg &
819 ~E1000_KMRNCTRLSTA_K1_ENABLE); 821 ~E1000_KMRNCTRLSTA_K1_ENABLE);
820 if (ret_val) 822 if (ret_val)
821 goto release; 823 goto release;
@@ -827,12 +829,45 @@ static s32 e1000_k1_workaround_lpt_lp(struct e1000_hw *hw, bool link)
827 ret_val = 829 ret_val =
828 e1000e_write_kmrn_reg_locked(hw, 830 e1000e_write_kmrn_reg_locked(hw,
829 E1000_KMRNCTRLSTA_K1_CONFIG, 831 E1000_KMRNCTRLSTA_K1_CONFIG,
830 kmrn_reg); 832 reg);
831release: 833release:
832 hw->phy.ops.release(hw); 834 hw->phy.ops.release(hw);
833 } else { 835 } else {
834 /* clear FEXTNVM6 bit 8 on link down or 10/100 */ 836 /* clear FEXTNVM6 bit 8 on link down or 10/100 */
835 ew32(FEXTNVM6, fextnvm6 & ~E1000_FEXTNVM6_REQ_PLL_CLK); 837 fextnvm6 &= ~E1000_FEXTNVM6_REQ_PLL_CLK;
838
839 if (!link || ((status & E1000_STATUS_SPEED_100) &&
840 (status & E1000_STATUS_FD)))
841 goto update_fextnvm6;
842
843 ret_val = e1e_rphy(hw, I217_INBAND_CTRL, &reg);
844 if (ret_val)
845 return ret_val;
846
847 /* Clear link status transmit timeout */
848 reg &= ~I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_MASK;
849
850 if (status & E1000_STATUS_SPEED_100) {
851 /* Set inband Tx timeout to 5x10us for 100Half */
852 reg |= 5 << I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_SHIFT;
853
854 /* Do not extend the K1 entry latency for 100Half */
855 fextnvm6 &= ~E1000_FEXTNVM6_ENABLE_K1_ENTRY_CONDITION;
856 } else {
857 /* Set inband Tx timeout to 50x10us for 10Full/Half */
858 reg |= 50 <<
859 I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_SHIFT;
860
861 /* Extend the K1 entry latency for 10 Mbps */
862 fextnvm6 |= E1000_FEXTNVM6_ENABLE_K1_ENTRY_CONDITION;
863 }
864
865 ret_val = e1e_wphy(hw, I217_INBAND_CTRL, reg);
866 if (ret_val)
867 return ret_val;
868
869update_fextnvm6:
870 ew32(FEXTNVM6, fextnvm6);
836 } 871 }
837 872
838 return ret_val; 873 return ret_val;