aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000e/phy.c
diff options
context:
space:
mode:
authorBruce Allan <bruce.w.allan@intel.com>2009-11-19 07:34:40 -0500
committerDavid S. Miller <davem@davemloft.net>2009-11-20 16:53:22 -0500
commit842ec8b64ac34e9b245da31b4a5a49c3e744a714 (patch)
tree75b346c36df75725179e4eedb7012f83901ebe01 /drivers/net/e1000e/phy.c
parent38eb394e33d65abb9d05411547d2058db53b4d23 (diff)
e1000e: read of PHY register may access wrong page on 82578
Remove unnecessary workaround that mistakenly does not perform a page select operation for PHY registers 29 and 30 (assuming these are the PHY debug port address and data registers) on 82578 which can cause reads of the Transmit with No Carrier Sense statistics register on page 778 to be read from an incorrect page. Also error out if the page select operation fails. 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>
Diffstat (limited to 'drivers/net/e1000e/phy.c')
-rw-r--r--drivers/net/e1000e/phy.c46
1 files changed, 22 insertions, 24 deletions
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c
index 03175b3a2c9e..8189d00bfefe 100644
--- a/drivers/net/e1000e/phy.c
+++ b/drivers/net/e1000e/phy.c
@@ -2658,19 +2658,18 @@ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data,
2658 page = 0; 2658 page = 0;
2659 2659
2660 if (reg > MAX_PHY_MULTI_PAGE_REG) { 2660 if (reg > MAX_PHY_MULTI_PAGE_REG) {
2661 if ((hw->phy.type != e1000_phy_82578) || 2661 u32 phy_addr = hw->phy.addr;
2662 ((reg != I82578_ADDR_REG) &&
2663 (reg != I82578_ADDR_REG + 1))) {
2664 u32 phy_addr = hw->phy.addr;
2665 2662
2666 hw->phy.addr = 1; 2663 hw->phy.addr = 1;
2667 2664
2668 /* Page is shifted left, PHY expects (page x 32) */ 2665 /* Page is shifted left, PHY expects (page x 32) */
2669 ret_val = e1000e_write_phy_reg_mdic(hw, 2666 ret_val = e1000e_write_phy_reg_mdic(hw,
2670 IGP01E1000_PHY_PAGE_SELECT, 2667 IGP01E1000_PHY_PAGE_SELECT,
2671 (page << IGP_PAGE_SHIFT)); 2668 (page << IGP_PAGE_SHIFT));
2672 hw->phy.addr = phy_addr; 2669 hw->phy.addr = phy_addr;
2673 } 2670
2671 if (ret_val)
2672 goto out;
2674 } 2673 }
2675 2674
2676 ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, 2675 ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg,
@@ -2678,7 +2677,7 @@ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data,
2678out: 2677out:
2679 /* Revert to MDIO fast mode, if applicable */ 2678 /* Revert to MDIO fast mode, if applicable */
2680 if ((hw->phy.type == e1000_phy_82577) && in_slow_mode) 2679 if ((hw->phy.type == e1000_phy_82577) && in_slow_mode)
2681 ret_val = e1000_set_mdio_slow_mode_hv(hw, false); 2680 ret_val |= e1000_set_mdio_slow_mode_hv(hw, false);
2682 2681
2683 if (!locked) 2682 if (!locked)
2684 hw->phy.ops.release_phy(hw); 2683 hw->phy.ops.release_phy(hw);
@@ -2784,19 +2783,18 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data,
2784 } 2783 }
2785 2784
2786 if (reg > MAX_PHY_MULTI_PAGE_REG) { 2785 if (reg > MAX_PHY_MULTI_PAGE_REG) {
2787 if ((hw->phy.type != e1000_phy_82578) || 2786 u32 phy_addr = hw->phy.addr;
2788 ((reg != I82578_ADDR_REG) &&
2789 (reg != I82578_ADDR_REG + 1))) {
2790 u32 phy_addr = hw->phy.addr;
2791 2787
2792 hw->phy.addr = 1; 2788 hw->phy.addr = 1;
2793 2789
2794 /* Page is shifted left, PHY expects (page x 32) */ 2790 /* Page is shifted left, PHY expects (page x 32) */
2795 ret_val = e1000e_write_phy_reg_mdic(hw, 2791 ret_val = e1000e_write_phy_reg_mdic(hw,
2796 IGP01E1000_PHY_PAGE_SELECT, 2792 IGP01E1000_PHY_PAGE_SELECT,
2797 (page << IGP_PAGE_SHIFT)); 2793 (page << IGP_PAGE_SHIFT));
2798 hw->phy.addr = phy_addr; 2794 hw->phy.addr = phy_addr;
2799 } 2795
2796 if (ret_val)
2797 goto out;
2800 } 2798 }
2801 2799
2802 ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, 2800 ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg,
@@ -2805,7 +2803,7 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data,
2805out: 2803out:
2806 /* Revert to MDIO fast mode, if applicable */ 2804 /* Revert to MDIO fast mode, if applicable */
2807 if ((hw->phy.type == e1000_phy_82577) && in_slow_mode) 2805 if ((hw->phy.type == e1000_phy_82577) && in_slow_mode)
2808 ret_val = e1000_set_mdio_slow_mode_hv(hw, false); 2806 ret_val |= e1000_set_mdio_slow_mode_hv(hw, false);
2809 2807
2810 if (!locked) 2808 if (!locked)
2811 hw->phy.ops.release_phy(hw); 2809 hw->phy.ops.release_phy(hw);