Commit 1d5846b9216665d0ae743bf351d0b8fa90c40523

Authored by Bruce Allan
Committed by David S. Miller
1 parent f523d2114e

e1000e: rework disable K1 at 1000Mbps for 82577/82578

This patch reworks a previous workaround (commit 7d3cabbcc) for an issue
in hardware where noise on the interconnect between the MAC and PHY could
be generated by a lower power mode (K1) at 1000Mbps resulting in bad
packets.  Disable K1 while at 1000 Mbps but keep it enabled for 10/100Mbps
and when the cable is disconnected.  The original version of this
workaround was found to be incomplete.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 5 changed files with 190 additions and 28 deletions Side-by-side Diff

drivers/net/e1000e/defines.h
... ... @@ -76,6 +76,7 @@
76 76 /* Extended Device Control */
77 77 #define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Definable Pin 7 */
78 78 #define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */
  79 +#define E1000_CTRL_EXT_SPD_BYPS 0x00008000 /* Speed Select Bypass */
79 80 #define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */
80 81 #define E1000_CTRL_EXT_DMA_DYN_CLK_EN 0x00080000 /* DMA Dynamic Clock Gating */
81 82 #define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
drivers/net/e1000e/e1000.h
... ... @@ -141,6 +141,20 @@
141 141 #define HV_TNCRS_UPPER PHY_REG(778, 29) /* Transmit with no CRS */
142 142 #define HV_TNCRS_LOWER PHY_REG(778, 30)
143 143  
  144 +/* BM PHY Copper Specific Status */
  145 +#define BM_CS_STATUS 17
  146 +#define BM_CS_STATUS_LINK_UP 0x0400
  147 +#define BM_CS_STATUS_RESOLVED 0x0800
  148 +#define BM_CS_STATUS_SPEED_MASK 0xC000
  149 +#define BM_CS_STATUS_SPEED_1000 0x8000
  150 +
  151 +/* 82577 Mobile Phy Status Register */
  152 +#define HV_M_STATUS 26
  153 +#define HV_M_STATUS_AUTONEG_COMPLETE 0x1000
  154 +#define HV_M_STATUS_SPEED_MASK 0x0300
  155 +#define HV_M_STATUS_SPEED_1000 0x0200
  156 +#define HV_M_STATUS_LINK_UP 0x0040
  157 +
144 158 enum e1000_boards {
145 159 board_82571,
146 160 board_82572,
drivers/net/e1000e/hw.h
... ... @@ -903,6 +903,7 @@
903 903 struct e1000_dev_spec_ich8lan {
904 904 bool kmrn_lock_loss_workaround_enabled;
905 905 struct e1000_shadow_ram shadow_ram[E1000_ICH8_SHADOW_RAM_WORDS];
  906 + bool nvm_k1_enabled;
906 907 };
907 908  
908 909 struct e1000_hw {
drivers/net/e1000e/ich8lan.c
... ... @@ -140,6 +140,9 @@
140 140 #define HV_OEM_BITS_GBE_DIS 0x0040 /* Gigabit Disable */
141 141 #define HV_OEM_BITS_RESTART_AN 0x0400 /* Restart Auto-negotiation */
142 142  
  143 +#define E1000_NVM_K1_CONFIG 0x1B /* NVM K1 Config Word */
  144 +#define E1000_NVM_K1_ENABLE 0x1 /* NVM Enable K1 bit */
  145 +
143 146 /* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */
144 147 /* Offset 04h HSFSTS */
145 148 union ich8_hws_flash_status {
... ... @@ -220,6 +223,8 @@
220 223 static s32 e1000_led_off_pchlan(struct e1000_hw *hw);
221 224 static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active);
222 225 static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw);
  226 +static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link);
  227 +static s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable);
223 228  
224 229 static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg)
225 230 {
... ... @@ -495,14 +500,6 @@
495 500 goto out;
496 501 }
497 502  
498   - if (hw->mac.type == e1000_pchlan) {
499   - ret_val = e1000e_write_kmrn_reg(hw,
500   - E1000_KMRNCTRLSTA_K1_CONFIG,
501   - E1000_KMRNCTRLSTA_K1_ENABLE);
502   - if (ret_val)
503   - goto out;
504   - }
505   -
506 503 /*
507 504 * First we want to see if the MII Status Register reports
508 505 * link. If so, then we want to get the current speed/duplex
... ... @@ -512,6 +509,12 @@
512 509 if (ret_val)
513 510 goto out;
514 511  
  512 + if (hw->mac.type == e1000_pchlan) {
  513 + ret_val = e1000_k1_gig_workaround_hv(hw, link);
  514 + if (ret_val)
  515 + goto out;
  516 + }
  517 +
515 518 if (!link)
516 519 goto out; /* No link detected */
517 520  
... ... @@ -929,6 +932,141 @@
929 932 }
930 933  
931 934 /**
  935 + * e1000_k1_gig_workaround_hv - K1 Si workaround
  936 + * @hw: pointer to the HW structure
  937 + * @link: link up bool flag
  938 + *
  939 + * If K1 is enabled for 1Gbps, the MAC might stall when transitioning
  940 + * from a lower speed. This workaround disables K1 whenever link is at 1Gig
  941 + * If link is down, the function will restore the default K1 setting located
  942 + * in the NVM.
  943 + **/
  944 +static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link)
  945 +{
  946 + s32 ret_val = 0;
  947 + u16 status_reg = 0;
  948 + bool k1_enable = hw->dev_spec.ich8lan.nvm_k1_enabled;
  949 +
  950 + if (hw->mac.type != e1000_pchlan)
  951 + goto out;
  952 +
  953 + /* Wrap the whole flow with the sw flag */
  954 + ret_val = hw->phy.ops.acquire_phy(hw);
  955 + if (ret_val)
  956 + goto out;
  957 +
  958 + /* Disable K1 when link is 1Gbps, otherwise use the NVM setting */
  959 + if (link) {
  960 + if (hw->phy.type == e1000_phy_82578) {
  961 + ret_val = hw->phy.ops.read_phy_reg_locked(hw,
  962 + BM_CS_STATUS,
  963 + &status_reg);
  964 + if (ret_val)
  965 + goto release;
  966 +
  967 + status_reg &= BM_CS_STATUS_LINK_UP |
  968 + BM_CS_STATUS_RESOLVED |
  969 + BM_CS_STATUS_SPEED_MASK;
  970 +
  971 + if (status_reg == (BM_CS_STATUS_LINK_UP |
  972 + BM_CS_STATUS_RESOLVED |
  973 + BM_CS_STATUS_SPEED_1000))
  974 + k1_enable = false;
  975 + }
  976 +
  977 + if (hw->phy.type == e1000_phy_82577) {
  978 + ret_val = hw->phy.ops.read_phy_reg_locked(hw,
  979 + HV_M_STATUS,
  980 + &status_reg);
  981 + if (ret_val)
  982 + goto release;
  983 +
  984 + status_reg &= HV_M_STATUS_LINK_UP |
  985 + HV_M_STATUS_AUTONEG_COMPLETE |
  986 + HV_M_STATUS_SPEED_MASK;
  987 +
  988 + if (status_reg == (HV_M_STATUS_LINK_UP |
  989 + HV_M_STATUS_AUTONEG_COMPLETE |
  990 + HV_M_STATUS_SPEED_1000))
  991 + k1_enable = false;
  992 + }
  993 +
  994 + /* Link stall fix for link up */
  995 + ret_val = hw->phy.ops.write_phy_reg_locked(hw, PHY_REG(770, 19),
  996 + 0x0100);
  997 + if (ret_val)
  998 + goto release;
  999 +
  1000 + } else {
  1001 + /* Link stall fix for link down */
  1002 + ret_val = hw->phy.ops.write_phy_reg_locked(hw, PHY_REG(770, 19),
  1003 + 0x4100);
  1004 + if (ret_val)
  1005 + goto release;
  1006 + }
  1007 +
  1008 + ret_val = e1000_configure_k1_ich8lan(hw, k1_enable);
  1009 +
  1010 +release:
  1011 + hw->phy.ops.release_phy(hw);
  1012 +out:
  1013 + return ret_val;
  1014 +}
  1015 +
  1016 +/**
  1017 + * e1000_configure_k1_ich8lan - Configure K1 power state
  1018 + * @hw: pointer to the HW structure
  1019 + * @enable: K1 state to configure
  1020 + *
  1021 + * Configure the K1 power state based on the provided parameter.
  1022 + * Assumes semaphore already acquired.
  1023 + *
  1024 + * Success returns 0, Failure returns -E1000_ERR_PHY (-2)
  1025 + **/
  1026 +static s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable)
  1027 +{
  1028 + s32 ret_val = 0;
  1029 + u32 ctrl_reg = 0;
  1030 + u32 ctrl_ext = 0;
  1031 + u32 reg = 0;
  1032 + u16 kmrn_reg = 0;
  1033 +
  1034 + ret_val = e1000e_read_kmrn_reg_locked(hw,
  1035 + E1000_KMRNCTRLSTA_K1_CONFIG,
  1036 + &kmrn_reg);
  1037 + if (ret_val)
  1038 + goto out;
  1039 +
  1040 + if (k1_enable)
  1041 + kmrn_reg |= E1000_KMRNCTRLSTA_K1_ENABLE;
  1042 + else
  1043 + kmrn_reg &= ~E1000_KMRNCTRLSTA_K1_ENABLE;
  1044 +
  1045 + ret_val = e1000e_write_kmrn_reg_locked(hw,
  1046 + E1000_KMRNCTRLSTA_K1_CONFIG,
  1047 + kmrn_reg);
  1048 + if (ret_val)
  1049 + goto out;
  1050 +
  1051 + udelay(20);
  1052 + ctrl_ext = er32(CTRL_EXT);
  1053 + ctrl_reg = er32(CTRL);
  1054 +
  1055 + reg = ctrl_reg & ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100);
  1056 + reg |= E1000_CTRL_FRCSPD;
  1057 + ew32(CTRL, reg);
  1058 +
  1059 + ew32(CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_SPD_BYPS);
  1060 + udelay(20);
  1061 + ew32(CTRL, ctrl_reg);
  1062 + ew32(CTRL_EXT, ctrl_ext);
  1063 + udelay(20);
  1064 +
  1065 +out:
  1066 + return ret_val;
  1067 +}
  1068 +
  1069 +/**
932 1070 * e1000_oem_bits_config_ich8lan - SW-based LCD Configuration
933 1071 * @hw: pointer to the HW structure
934 1072 * @d0_state: boolean if entering d0 or d3 device state
935 1073  
936 1074  
... ... @@ -1030,10 +1168,20 @@
1030 1168 ret_val = hw->phy.ops.acquire_phy(hw);
1031 1169 if (ret_val)
1032 1170 return ret_val;
  1171 +
1033 1172 hw->phy.addr = 1;
1034   - e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0);
  1173 + ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0);
  1174 + if (ret_val)
  1175 + goto out;
1035 1176 hw->phy.ops.release_phy(hw);
1036 1177  
  1178 + /*
  1179 + * Configure the K1 Si workaround during phy reset assuming there is
  1180 + * link so that it disables K1 if link is in 1Gbps.
  1181 + */
  1182 + ret_val = e1000_k1_gig_workaround_hv(hw, true);
  1183 +
  1184 +out:
1037 1185 return ret_val;
1038 1186 }
1039 1187  
... ... @@ -2435,6 +2583,7 @@
2435 2583 **/
2436 2584 static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
2437 2585 {
  2586 + struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
2438 2587 u16 reg;
2439 2588 u32 ctrl, icr, kab;
2440 2589 s32 ret_val;
... ... @@ -2470,6 +2619,18 @@
2470 2619 ew32(PBS, E1000_PBS_16K);
2471 2620 }
2472 2621  
  2622 + if (hw->mac.type == e1000_pchlan) {
  2623 + /* Save the NVM K1 bit setting*/
  2624 + ret_val = e1000_read_nvm(hw, E1000_NVM_K1_CONFIG, 1, &reg);
  2625 + if (ret_val)
  2626 + return ret_val;
  2627 +
  2628 + if (reg & E1000_NVM_K1_ENABLE)
  2629 + dev_spec->nvm_k1_enabled = true;
  2630 + else
  2631 + dev_spec->nvm_k1_enabled = false;
  2632 + }
  2633 +
2473 2634 ctrl = er32(CTRL);
2474 2635  
2475 2636 if (!e1000_check_reset_block(hw)) {
... ... @@ -2846,14 +3007,6 @@
2846 3007 ret_val = e1000e_get_speed_and_duplex_copper(hw, speed, duplex);
2847 3008 if (ret_val)
2848 3009 return ret_val;
2849   -
2850   - if ((hw->mac.type == e1000_pchlan) && (*speed == SPEED_1000)) {
2851   - ret_val = e1000e_write_kmrn_reg(hw,
2852   - E1000_KMRNCTRLSTA_K1_CONFIG,
2853   - E1000_KMRNCTRLSTA_K1_DISABLE);
2854   - if (ret_val)
2855   - return ret_val;
2856   - }
2857 3010  
2858 3011 if ((hw->mac.type == e1000_ich8lan) &&
2859 3012 (hw->phy.type == e1000_phy_igp_3) &&
drivers/net/e1000e/phy.c
... ... @@ -95,13 +95,6 @@
95 95 /* BM PHY Copper Specific Control 1 */
96 96 #define BM_CS_CTRL1 16
97 97  
98   -/* BM PHY Copper Specific Status */
99   -#define BM_CS_STATUS 17
100   -#define BM_CS_STATUS_LINK_UP 0x0400
101   -#define BM_CS_STATUS_RESOLVED 0x0800
102   -#define BM_CS_STATUS_SPEED_MASK 0xC000
103   -#define BM_CS_STATUS_SPEED_1000 0x8000
104   -
105 98 #define HV_MUX_DATA_CTRL PHY_REG(776, 16)
106 99 #define HV_MUX_DATA_CTRL_GEN_TO_MAC 0x0400
107 100 #define HV_MUX_DATA_CTRL_FORCE_SPEED 0x0004
... ... @@ -563,7 +556,7 @@
563 556 }
564 557  
565 558 /**
566   - * e1000_read_kmrn_reg_locked - Read kumeran register
  559 + * e1000e_read_kmrn_reg_locked - Read kumeran register
567 560 * @hw: pointer to the HW structure
568 561 * @offset: register offset to be read
569 562 * @data: pointer to the read data
... ... @@ -572,7 +565,7 @@
572 565 * information retrieved is stored in data.
573 566 * Assumes semaphore already acquired.
574 567 **/
575   -s32 e1000_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 *data)
  568 +s32 e1000e_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 *data)
576 569 {
577 570 return __e1000_read_kmrn_reg(hw, offset, data, true);
578 571 }
... ... @@ -631,7 +624,7 @@
631 624 }
632 625  
633 626 /**
634   - * e1000_write_kmrn_reg_locked - Write kumeran register
  627 + * e1000e_write_kmrn_reg_locked - Write kumeran register
635 628 * @hw: pointer to the HW structure
636 629 * @offset: register offset to write to
637 630 * @data: data to write at register offset
... ... @@ -639,7 +632,7 @@
639 632 * Write the data to PHY register at the offset using the kumeran interface.
640 633 * Assumes semaphore already acquired.
641 634 **/
642   -s32 e1000_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 data)
  635 +s32 e1000e_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 data)
643 636 {
644 637 return __e1000_write_kmrn_reg(hw, offset, data, true);
645 638 }