aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-05-05 16:30:03 -0400
committerDavid S. Miller <davem@davemloft.net>2014-05-05 16:30:03 -0400
commit780ce3a225c4d6e85b5436d9beb95727b2c4e69f (patch)
tree84950724cfea30d789f4bdebf17eab5694c406df
parenteaff82929c1daf900e40763936a14f9cb2ba4d7b (diff)
parent2c9826243bebeb90a57a7946d4144a2a9a43dc39 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net
Jeff Kirsher says: ==================== Intel Wired LAN Driver Updates This series contains updates to e1000e only. David provides four fixes for e1000e, first is a workaround for a hardware erratum on 82579 devices which experienced packet loss in gigabit and 100 speeds when interconnect between the PHY and MAC is exiting K1 power saving state. Second expands the scope of a workaround to include i217 and i218 parts as well to address over aggressive transmit behavior when connecting at 10Mbs half-duplex. Next is to resolve a reported link flap issue on 82579 parts which was root caused as an interoperability problem between 82579 and at least some Broadcom PHYs in the Energy Efficient Ethernet wake mechanism. Lastly, restricts the workaround of putting the PHY into MDIO slow mode to access the PHY id to relevant parts since this issue has been fixed on the newer hardware. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/intel/e1000e/ich8lan.c71
-rw-r--r--drivers/net/ethernet/intel/e1000e/ich8lan.h3
-rw-r--r--drivers/net/ethernet/intel/e1000e/phy.h1
3 files changed, 46 insertions, 29 deletions
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c
index 9866f264f55e..f0bbd4246d71 100644
--- a/drivers/net/ethernet/intel/e1000e/ich8lan.c
+++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c
@@ -186,7 +186,7 @@ static bool e1000_phy_is_accessible_pchlan(struct e1000_hw *hw)
186{ 186{
187 u16 phy_reg = 0; 187 u16 phy_reg = 0;
188 u32 phy_id = 0; 188 u32 phy_id = 0;
189 s32 ret_val; 189 s32 ret_val = 0;
190 u16 retry_count; 190 u16 retry_count;
191 u32 mac_reg = 0; 191 u32 mac_reg = 0;
192 192
@@ -217,11 +217,13 @@ static bool e1000_phy_is_accessible_pchlan(struct e1000_hw *hw)
217 /* In case the PHY needs to be in mdio slow mode, 217 /* In case the PHY needs to be in mdio slow mode,
218 * set slow mode and try to get the PHY id again. 218 * set slow mode and try to get the PHY id again.
219 */ 219 */
220 hw->phy.ops.release(hw); 220 if (hw->mac.type < e1000_pch_lpt) {
221 ret_val = e1000_set_mdio_slow_mode_hv(hw); 221 hw->phy.ops.release(hw);
222 if (!ret_val) 222 ret_val = e1000_set_mdio_slow_mode_hv(hw);
223 ret_val = e1000e_get_phy_id(hw); 223 if (!ret_val)
224 hw->phy.ops.acquire(hw); 224 ret_val = e1000e_get_phy_id(hw);
225 hw->phy.ops.acquire(hw);
226 }
225 227
226 if (ret_val) 228 if (ret_val)
227 return false; 229 return false;
@@ -842,6 +844,17 @@ s32 e1000_set_eee_pchlan(struct e1000_hw *hw)
842 } 844 }
843 } 845 }
844 846
847 if (hw->phy.type == e1000_phy_82579) {
848 ret_val = e1000_read_emi_reg_locked(hw, I82579_LPI_PLL_SHUT,
849 &data);
850 if (ret_val)
851 goto release;
852
853 data &= ~I82579_LPI_100_PLL_SHUT;
854 ret_val = e1000_write_emi_reg_locked(hw, I82579_LPI_PLL_SHUT,
855 data);
856 }
857
845 /* R/Clr IEEE MMD 3.1 bits 11:10 - Tx/Rx LPI Received */ 858 /* R/Clr IEEE MMD 3.1 bits 11:10 - Tx/Rx LPI Received */
846 ret_val = e1000_read_emi_reg_locked(hw, pcs_status, &data); 859 ret_val = e1000_read_emi_reg_locked(hw, pcs_status, &data);
847 if (ret_val) 860 if (ret_val)
@@ -1314,14 +1327,17 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
1314 return ret_val; 1327 return ret_val;
1315 } 1328 }
1316 1329
1317 /* When connected at 10Mbps half-duplex, 82579 parts are excessively 1330 /* When connected at 10Mbps half-duplex, some parts are excessively
1318 * aggressive resulting in many collisions. To avoid this, increase 1331 * aggressive resulting in many collisions. To avoid this, increase
1319 * the IPG and reduce Rx latency in the PHY. 1332 * the IPG and reduce Rx latency in the PHY.
1320 */ 1333 */
1321 if ((hw->mac.type == e1000_pch2lan) && link) { 1334 if (((hw->mac.type == e1000_pch2lan) ||
1335 (hw->mac.type == e1000_pch_lpt)) && link) {
1322 u32 reg; 1336 u32 reg;
1323 reg = er32(STATUS); 1337 reg = er32(STATUS);
1324 if (!(reg & (E1000_STATUS_FD | E1000_STATUS_SPEED_MASK))) { 1338 if (!(reg & (E1000_STATUS_FD | E1000_STATUS_SPEED_MASK))) {
1339 u16 emi_addr;
1340
1325 reg = er32(TIPG); 1341 reg = er32(TIPG);
1326 reg &= ~E1000_TIPG_IPGT_MASK; 1342 reg &= ~E1000_TIPG_IPGT_MASK;
1327 reg |= 0xFF; 1343 reg |= 0xFF;
@@ -1332,8 +1348,12 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
1332 if (ret_val) 1348 if (ret_val)
1333 return ret_val; 1349 return ret_val;
1334 1350
1335 ret_val = 1351 if (hw->mac.type == e1000_pch2lan)
1336 e1000_write_emi_reg_locked(hw, I82579_RX_CONFIG, 0); 1352 emi_addr = I82579_RX_CONFIG;
1353 else
1354 emi_addr = I217_RX_CONFIG;
1355
1356 ret_val = e1000_write_emi_reg_locked(hw, emi_addr, 0);
1337 1357
1338 hw->phy.ops.release(hw); 1358 hw->phy.ops.release(hw);
1339 1359
@@ -2493,51 +2513,44 @@ release:
2493 * e1000_k1_gig_workaround_lv - K1 Si workaround 2513 * e1000_k1_gig_workaround_lv - K1 Si workaround
2494 * @hw: pointer to the HW structure 2514 * @hw: pointer to the HW structure
2495 * 2515 *
2496 * Workaround to set the K1 beacon duration for 82579 parts 2516 * Workaround to set the K1 beacon duration for 82579 parts in 10Mbps
2517 * Disable K1 in 1000Mbps and 100Mbps
2497 **/ 2518 **/
2498static s32 e1000_k1_workaround_lv(struct e1000_hw *hw) 2519static s32 e1000_k1_workaround_lv(struct e1000_hw *hw)
2499{ 2520{
2500 s32 ret_val = 0; 2521 s32 ret_val = 0;
2501 u16 status_reg = 0; 2522 u16 status_reg = 0;
2502 u32 mac_reg;
2503 u16 phy_reg;
2504 2523
2505 if (hw->mac.type != e1000_pch2lan) 2524 if (hw->mac.type != e1000_pch2lan)
2506 return 0; 2525 return 0;
2507 2526
2508 /* Set K1 beacon duration based on 1Gbps speed or otherwise */ 2527 /* Set K1 beacon duration based on 10Mbs speed */
2509 ret_val = e1e_rphy(hw, HV_M_STATUS, &status_reg); 2528 ret_val = e1e_rphy(hw, HV_M_STATUS, &status_reg);
2510 if (ret_val) 2529 if (ret_val)
2511 return ret_val; 2530 return ret_val;
2512 2531
2513 if ((status_reg & (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE)) 2532 if ((status_reg & (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE))
2514 == (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE)) { 2533 == (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE)) {
2515 mac_reg = er32(FEXTNVM4); 2534 if (status_reg &
2516 mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK; 2535 (HV_M_STATUS_SPEED_1000 | HV_M_STATUS_SPEED_100)) {
2517
2518 ret_val = e1e_rphy(hw, I82579_LPI_CTRL, &phy_reg);
2519 if (ret_val)
2520 return ret_val;
2521
2522 if (status_reg & HV_M_STATUS_SPEED_1000) {
2523 u16 pm_phy_reg; 2536 u16 pm_phy_reg;
2524 2537
2525 mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_8USEC; 2538 /* LV 1G/100 Packet drop issue wa */
2526 phy_reg &= ~I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT;
2527 /* LV 1G Packet drop issue wa */
2528 ret_val = e1e_rphy(hw, HV_PM_CTRL, &pm_phy_reg); 2539 ret_val = e1e_rphy(hw, HV_PM_CTRL, &pm_phy_reg);
2529 if (ret_val) 2540 if (ret_val)
2530 return ret_val; 2541 return ret_val;
2531 pm_phy_reg &= ~HV_PM_CTRL_PLL_STOP_IN_K1_GIGA; 2542 pm_phy_reg &= ~HV_PM_CTRL_K1_ENABLE;
2532 ret_val = e1e_wphy(hw, HV_PM_CTRL, pm_phy_reg); 2543 ret_val = e1e_wphy(hw, HV_PM_CTRL, pm_phy_reg);
2533 if (ret_val) 2544 if (ret_val)
2534 return ret_val; 2545 return ret_val;
2535 } else { 2546 } else {
2547 u32 mac_reg;
2548
2549 mac_reg = er32(FEXTNVM4);
2550 mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK;
2536 mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_16USEC; 2551 mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_16USEC;
2537 phy_reg |= I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT; 2552 ew32(FEXTNVM4, mac_reg);
2538 } 2553 }
2539 ew32(FEXTNVM4, mac_reg);
2540 ret_val = e1e_wphy(hw, I82579_LPI_CTRL, phy_reg);
2541 } 2554 }
2542 2555
2543 return ret_val; 2556 return ret_val;
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.h b/drivers/net/ethernet/intel/e1000e/ich8lan.h
index bead50f9187b..5515126c81c1 100644
--- a/drivers/net/ethernet/intel/e1000e/ich8lan.h
+++ b/drivers/net/ethernet/intel/e1000e/ich8lan.h
@@ -232,16 +232,19 @@
232#define I82577_MSE_THRESHOLD 0x0887 /* 82577 Mean Square Error Threshold */ 232#define I82577_MSE_THRESHOLD 0x0887 /* 82577 Mean Square Error Threshold */
233#define I82579_MSE_LINK_DOWN 0x2411 /* MSE count before dropping link */ 233#define I82579_MSE_LINK_DOWN 0x2411 /* MSE count before dropping link */
234#define I82579_RX_CONFIG 0x3412 /* Receive configuration */ 234#define I82579_RX_CONFIG 0x3412 /* Receive configuration */
235#define I82579_LPI_PLL_SHUT 0x4412 /* LPI PLL Shut Enable */
235#define I82579_EEE_PCS_STATUS 0x182E /* IEEE MMD Register 3.1 >> 8 */ 236#define I82579_EEE_PCS_STATUS 0x182E /* IEEE MMD Register 3.1 >> 8 */
236#define I82579_EEE_CAPABILITY 0x0410 /* IEEE MMD Register 3.20 */ 237#define I82579_EEE_CAPABILITY 0x0410 /* IEEE MMD Register 3.20 */
237#define I82579_EEE_ADVERTISEMENT 0x040E /* IEEE MMD Register 7.60 */ 238#define I82579_EEE_ADVERTISEMENT 0x040E /* IEEE MMD Register 7.60 */
238#define I82579_EEE_LP_ABILITY 0x040F /* IEEE MMD Register 7.61 */ 239#define I82579_EEE_LP_ABILITY 0x040F /* IEEE MMD Register 7.61 */
239#define I82579_EEE_100_SUPPORTED (1 << 1) /* 100BaseTx EEE */ 240#define I82579_EEE_100_SUPPORTED (1 << 1) /* 100BaseTx EEE */
240#define I82579_EEE_1000_SUPPORTED (1 << 2) /* 1000BaseTx EEE */ 241#define I82579_EEE_1000_SUPPORTED (1 << 2) /* 1000BaseTx EEE */
242#define I82579_LPI_100_PLL_SHUT (1 << 2) /* 100M LPI PLL Shut Enabled */
241#define I217_EEE_PCS_STATUS 0x9401 /* IEEE MMD Register 3.1 */ 243#define I217_EEE_PCS_STATUS 0x9401 /* IEEE MMD Register 3.1 */
242#define I217_EEE_CAPABILITY 0x8000 /* IEEE MMD Register 3.20 */ 244#define I217_EEE_CAPABILITY 0x8000 /* IEEE MMD Register 3.20 */
243#define I217_EEE_ADVERTISEMENT 0x8001 /* IEEE MMD Register 7.60 */ 245#define I217_EEE_ADVERTISEMENT 0x8001 /* IEEE MMD Register 7.60 */
244#define I217_EEE_LP_ABILITY 0x8002 /* IEEE MMD Register 7.61 */ 246#define I217_EEE_LP_ABILITY 0x8002 /* IEEE MMD Register 7.61 */
247#define I217_RX_CONFIG 0xB20C /* Receive configuration */
245 248
246#define E1000_EEE_RX_LPI_RCVD 0x0400 /* Tx LP idle received */ 249#define E1000_EEE_RX_LPI_RCVD 0x0400 /* Tx LP idle received */
247#define E1000_EEE_TX_LPI_RCVD 0x0800 /* Rx LP idle received */ 250#define E1000_EEE_TX_LPI_RCVD 0x0800 /* Rx LP idle received */
diff --git a/drivers/net/ethernet/intel/e1000e/phy.h b/drivers/net/ethernet/intel/e1000e/phy.h
index 3841bccf058c..537d2780b408 100644
--- a/drivers/net/ethernet/intel/e1000e/phy.h
+++ b/drivers/net/ethernet/intel/e1000e/phy.h
@@ -164,6 +164,7 @@ s32 e1000_get_cable_length_82577(struct e1000_hw *hw);
164#define HV_M_STATUS_AUTONEG_COMPLETE 0x1000 164#define HV_M_STATUS_AUTONEG_COMPLETE 0x1000
165#define HV_M_STATUS_SPEED_MASK 0x0300 165#define HV_M_STATUS_SPEED_MASK 0x0300
166#define HV_M_STATUS_SPEED_1000 0x0200 166#define HV_M_STATUS_SPEED_1000 0x0200
167#define HV_M_STATUS_SPEED_100 0x0100
167#define HV_M_STATUS_LINK_UP 0x0040 168#define HV_M_STATUS_LINK_UP 0x0040
168 169
169#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4 170#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4