Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

e1000e: access multiple PHY registers on same page at the same time

Doing a PHY page select can take a long time, relatively speaking. This
can cause a significant delay when updating a number of PHY registers on
the same page by unnecessarily setting the page for each PHY access. For
example when going to Sx, all the PHY wakeup registers (WUC, RAR[], MTA[],
SHRAR[], IP4AT[], IP6AT[], etc.) on 82577/8/9 need to be updated which
takes a long time which can cause issues when suspending.

This patch introduces new PHY ops function pointers to allow callers to
set the page directly and do any number of PHY accesses on that page.
This feature is currently only implemented for 82577, 82578 and 82579
PHYs for both the normally addressed registers as well as the special-
case addressing of the PHY wakeup registers on page 800. For the latter
registers, the existing function for accessing the wakeup registers has
been divided up into three- 1) enable access to the wakeup register page,
2) perform the register access and 3) disable access to the wakeup register
page. The two functions that enable/disable access to the wakeup register
page are necessarily available to the caller so that the caller can restore
the value of the Port Control (a.k.a. Wakeup Enable) register after the
wakeup register accesses are done.

All instances of writing to multiple PHY registers on the same page are
updated to use this new method and to acquire any PHY locking mechanism
before setting the page and performing the register accesses, and release
the locking mechanism afterward.

Some affiliated magic number cleanup is done as well.

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>

authored by

Bruce Allan and committed by
Jeff Kirsher
2b6b168d 400484fa

+368 -227
+24 -14
drivers/net/e1000e/e1000.h
··· 122 122 #define BM_RCTL_PMCF 0x0040 /* Pass MAC Control Frames */ 123 123 #define BM_RCTL_RFCE 0x0080 /* Rx Flow Control Enable */ 124 124 125 - #define HV_SCC_UPPER PHY_REG(778, 16) /* Single Collision Count */ 126 - #define HV_SCC_LOWER PHY_REG(778, 17) 127 - #define HV_ECOL_UPPER PHY_REG(778, 18) /* Excessive Collision Count */ 128 - #define HV_ECOL_LOWER PHY_REG(778, 19) 129 - #define HV_MCC_UPPER PHY_REG(778, 20) /* Multiple Collision Count */ 130 - #define HV_MCC_LOWER PHY_REG(778, 21) 131 - #define HV_LATECOL_UPPER PHY_REG(778, 23) /* Late Collision Count */ 132 - #define HV_LATECOL_LOWER PHY_REG(778, 24) 133 - #define HV_COLC_UPPER PHY_REG(778, 25) /* Collision Count */ 134 - #define HV_COLC_LOWER PHY_REG(778, 26) 135 - #define HV_DC_UPPER PHY_REG(778, 27) /* Defer Count */ 136 - #define HV_DC_LOWER PHY_REG(778, 28) 137 - #define HV_TNCRS_UPPER PHY_REG(778, 29) /* Transmit with no CRS */ 138 - #define HV_TNCRS_LOWER PHY_REG(778, 30) 125 + #define HV_STATS_PAGE 778 126 + #define HV_SCC_UPPER PHY_REG(HV_STATS_PAGE, 16) /* Single Collision Count */ 127 + #define HV_SCC_LOWER PHY_REG(HV_STATS_PAGE, 17) 128 + #define HV_ECOL_UPPER PHY_REG(HV_STATS_PAGE, 18) /* Excessive Coll. Count */ 129 + #define HV_ECOL_LOWER PHY_REG(HV_STATS_PAGE, 19) 130 + #define HV_MCC_UPPER PHY_REG(HV_STATS_PAGE, 20) /* Multiple Coll. Count */ 131 + #define HV_MCC_LOWER PHY_REG(HV_STATS_PAGE, 21) 132 + #define HV_LATECOL_UPPER PHY_REG(HV_STATS_PAGE, 23) /* Late Collision Count */ 133 + #define HV_LATECOL_LOWER PHY_REG(HV_STATS_PAGE, 24) 134 + #define HV_COLC_UPPER PHY_REG(HV_STATS_PAGE, 25) /* Collision Count */ 135 + #define HV_COLC_LOWER PHY_REG(HV_STATS_PAGE, 26) 136 + #define HV_DC_UPPER PHY_REG(HV_STATS_PAGE, 27) /* Defer Count */ 137 + #define HV_DC_LOWER PHY_REG(HV_STATS_PAGE, 28) 138 + #define HV_TNCRS_UPPER PHY_REG(HV_STATS_PAGE, 29) /* Transmit with no CRS */ 139 + #define HV_TNCRS_LOWER PHY_REG(HV_STATS_PAGE, 30) 139 140 140 141 #define E1000_FCRTV_PCH 0x05F40 /* PCH Flow Control Refresh Timer Value */ 141 142 ··· 586 585 extern s32 e1000e_phy_force_speed_duplex_igp(struct e1000_hw *hw); 587 586 extern s32 e1000e_get_cable_length_igp_2(struct e1000_hw *hw); 588 587 extern s32 e1000e_get_phy_info_igp(struct e1000_hw *hw); 588 + extern s32 e1000_set_page_igp(struct e1000_hw *hw, u16 page); 589 589 extern s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data); 590 590 extern s32 e1000e_read_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, 591 591 u16 *data); ··· 607 605 extern s32 e1000e_determine_phy_address(struct e1000_hw *hw); 608 606 extern s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data); 609 607 extern s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data); 608 + extern s32 e1000_enable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, 609 + u16 *phy_reg); 610 + extern s32 e1000_disable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, 611 + u16 *phy_reg); 610 612 extern s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data); 611 613 extern s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data); 612 614 extern void e1000e_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl); ··· 631 625 extern s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data); 632 626 extern s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, 633 627 u16 *data); 628 + extern s32 e1000_read_phy_reg_page_hv(struct e1000_hw *hw, u32 offset, 629 + u16 *data); 634 630 extern s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data); 635 631 extern s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, 636 632 u16 data); 633 + extern s32 e1000_write_phy_reg_page_hv(struct e1000_hw *hw, u32 offset, 634 + u16 data); 637 635 extern s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw); 638 636 extern s32 e1000_copper_link_setup_82577(struct e1000_hw *hw); 639 637 extern s32 e1000_check_polarity_82577(struct e1000_hw *hw);
+19 -1
drivers/net/e1000e/hw.h
··· 246 246 #define BM_WUC_ENABLE_REG 17 247 247 #define BM_WUC_ENABLE_BIT (1 << 2) 248 248 #define BM_WUC_HOST_WU_BIT (1 << 4) 249 + #define BM_WUC_ME_WU_BIT (1 << 5) 249 250 250 251 #define BM_WUC PHY_REG(BM_WUC_PAGE, 1) 251 252 #define BM_WUFC PHY_REG(BM_WUC_PAGE, 2) ··· 779 778 s32 (*read_mac_addr)(struct e1000_hw *); 780 779 }; 781 780 782 - /* Function pointers for the PHY. */ 781 + /* 782 + * When to use various PHY register access functions: 783 + * 784 + * Func Caller 785 + * Function Does Does When to use 786 + * ~~~~~~~~~~~~ ~~~~~ ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 787 + * X_reg L,P,A n/a for simple PHY reg accesses 788 + * X_reg_locked P,A L for multiple accesses of different regs 789 + * on different pages 790 + * X_reg_page A L,P for multiple accesses of different regs 791 + * on the same page 792 + * 793 + * Where X=[read|write], L=locking, P=sets page, A=register access 794 + * 795 + */ 783 796 struct e1000_phy_operations { 784 797 s32 (*acquire)(struct e1000_hw *); 785 798 s32 (*cfg_on_link_up)(struct e1000_hw *); ··· 804 789 s32 (*get_cfg_done)(struct e1000_hw *hw); 805 790 s32 (*get_cable_length)(struct e1000_hw *); 806 791 s32 (*get_info)(struct e1000_hw *); 792 + s32 (*set_page)(struct e1000_hw *, u16); 807 793 s32 (*read_reg)(struct e1000_hw *, u32, u16 *); 808 794 s32 (*read_reg_locked)(struct e1000_hw *, u32, u16 *); 795 + s32 (*read_reg_page)(struct e1000_hw *, u32, u16 *); 809 796 void (*release)(struct e1000_hw *); 810 797 s32 (*reset)(struct e1000_hw *); 811 798 s32 (*set_d0_lplu_state)(struct e1000_hw *, bool); 812 799 s32 (*set_d3_lplu_state)(struct e1000_hw *, bool); 813 800 s32 (*write_reg)(struct e1000_hw *, u32, u16); 814 801 s32 (*write_reg_locked)(struct e1000_hw *, u32, u16); 802 + s32 (*write_reg_page)(struct e1000_hw *, u32, u16); 815 803 void (*power_up)(struct e1000_hw *); 816 804 void (*power_down)(struct e1000_hw *); 817 805 };
+51 -19
drivers/net/e1000e/ich8lan.c
··· 303 303 phy->addr = 1; 304 304 phy->reset_delay_us = 100; 305 305 306 + phy->ops.set_page = e1000_set_page_igp; 306 307 phy->ops.read_reg = e1000_read_phy_reg_hv; 307 308 phy->ops.read_reg_locked = e1000_read_phy_reg_hv_locked; 309 + phy->ops.read_reg_page = e1000_read_phy_reg_page_hv; 308 310 phy->ops.set_d0_lplu_state = e1000_set_lplu_state_pchlan; 309 311 phy->ops.set_d3_lplu_state = e1000_set_lplu_state_pchlan; 310 312 phy->ops.write_reg = e1000_write_phy_reg_hv; 311 313 phy->ops.write_reg_locked = e1000_write_phy_reg_hv_locked; 314 + phy->ops.write_reg_page = e1000_write_phy_reg_page_hv; 312 315 phy->ops.power_up = e1000_power_up_phy_copper; 313 316 phy->ops.power_down = e1000_power_down_phy_copper_ich8lan; 314 317 phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; ··· 1412 1409 void e1000_copy_rx_addrs_to_phy_ich8lan(struct e1000_hw *hw) 1413 1410 { 1414 1411 u32 mac_reg; 1415 - u16 i; 1412 + u16 i, phy_reg = 0; 1413 + s32 ret_val; 1414 + 1415 + ret_val = hw->phy.ops.acquire(hw); 1416 + if (ret_val) 1417 + return; 1418 + ret_val = e1000_enable_phy_wakeup_reg_access_bm(hw, &phy_reg); 1419 + if (ret_val) 1420 + goto release; 1416 1421 1417 1422 /* Copy both RAL/H (rar_entry_count) and SHRAL/H (+4) to PHY */ 1418 1423 for (i = 0; i < (hw->mac.rar_entry_count + 4); i++) { 1419 1424 mac_reg = er32(RAL(i)); 1420 - e1e_wphy(hw, BM_RAR_L(i), (u16)(mac_reg & 0xFFFF)); 1421 - e1e_wphy(hw, BM_RAR_M(i), (u16)((mac_reg >> 16) & 0xFFFF)); 1425 + hw->phy.ops.write_reg_page(hw, BM_RAR_L(i), 1426 + (u16)(mac_reg & 0xFFFF)); 1427 + hw->phy.ops.write_reg_page(hw, BM_RAR_M(i), 1428 + (u16)((mac_reg >> 16) & 0xFFFF)); 1429 + 1422 1430 mac_reg = er32(RAH(i)); 1423 - e1e_wphy(hw, BM_RAR_H(i), (u16)(mac_reg & 0xFFFF)); 1424 - e1e_wphy(hw, BM_RAR_CTRL(i), (u16)((mac_reg >> 16) & 0x8000)); 1431 + hw->phy.ops.write_reg_page(hw, BM_RAR_H(i), 1432 + (u16)(mac_reg & 0xFFFF)); 1433 + hw->phy.ops.write_reg_page(hw, BM_RAR_CTRL(i), 1434 + (u16)((mac_reg & E1000_RAH_AV) 1435 + >> 16)); 1425 1436 } 1437 + 1438 + e1000_disable_phy_wakeup_reg_access_bm(hw, &phy_reg); 1439 + 1440 + release: 1441 + hw->phy.ops.release(hw); 1426 1442 } 1427 1443 1428 1444 /** ··· 3919 3897 static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw) 3920 3898 { 3921 3899 u16 phy_data; 3900 + s32 ret_val; 3922 3901 3923 3902 e1000e_clear_hw_cntrs_base(hw); 3924 3903 ··· 3941 3918 if ((hw->phy.type == e1000_phy_82578) || 3942 3919 (hw->phy.type == e1000_phy_82579) || 3943 3920 (hw->phy.type == e1000_phy_82577)) { 3944 - e1e_rphy(hw, HV_SCC_UPPER, &phy_data); 3945 - e1e_rphy(hw, HV_SCC_LOWER, &phy_data); 3946 - e1e_rphy(hw, HV_ECOL_UPPER, &phy_data); 3947 - e1e_rphy(hw, HV_ECOL_LOWER, &phy_data); 3948 - e1e_rphy(hw, HV_MCC_UPPER, &phy_data); 3949 - e1e_rphy(hw, HV_MCC_LOWER, &phy_data); 3950 - e1e_rphy(hw, HV_LATECOL_UPPER, &phy_data); 3951 - e1e_rphy(hw, HV_LATECOL_LOWER, &phy_data); 3952 - e1e_rphy(hw, HV_COLC_UPPER, &phy_data); 3953 - e1e_rphy(hw, HV_COLC_LOWER, &phy_data); 3954 - e1e_rphy(hw, HV_DC_UPPER, &phy_data); 3955 - e1e_rphy(hw, HV_DC_LOWER, &phy_data); 3956 - e1e_rphy(hw, HV_TNCRS_UPPER, &phy_data); 3957 - e1e_rphy(hw, HV_TNCRS_LOWER, &phy_data); 3921 + ret_val = hw->phy.ops.acquire(hw); 3922 + if (ret_val) 3923 + return; 3924 + ret_val = hw->phy.ops.set_page(hw, 3925 + HV_STATS_PAGE << IGP_PAGE_SHIFT); 3926 + if (ret_val) 3927 + goto release; 3928 + hw->phy.ops.read_reg_page(hw, HV_SCC_UPPER, &phy_data); 3929 + hw->phy.ops.read_reg_page(hw, HV_SCC_LOWER, &phy_data); 3930 + hw->phy.ops.read_reg_page(hw, HV_ECOL_UPPER, &phy_data); 3931 + hw->phy.ops.read_reg_page(hw, HV_ECOL_LOWER, &phy_data); 3932 + hw->phy.ops.read_reg_page(hw, HV_MCC_UPPER, &phy_data); 3933 + hw->phy.ops.read_reg_page(hw, HV_MCC_LOWER, &phy_data); 3934 + hw->phy.ops.read_reg_page(hw, HV_LATECOL_UPPER, &phy_data); 3935 + hw->phy.ops.read_reg_page(hw, HV_LATECOL_LOWER, &phy_data); 3936 + hw->phy.ops.read_reg_page(hw, HV_COLC_UPPER, &phy_data); 3937 + hw->phy.ops.read_reg_page(hw, HV_COLC_LOWER, &phy_data); 3938 + hw->phy.ops.read_reg_page(hw, HV_DC_UPPER, &phy_data); 3939 + hw->phy.ops.read_reg_page(hw, HV_DC_LOWER, &phy_data); 3940 + hw->phy.ops.read_reg_page(hw, HV_TNCRS_UPPER, &phy_data); 3941 + hw->phy.ops.read_reg_page(hw, HV_TNCRS_LOWER, &phy_data); 3942 + release: 3943 + hw->phy.ops.release(hw); 3958 3944 } 3959 3945 } 3960 3946
+43 -68
drivers/net/e1000e/netdev.c
··· 3833 3833 /** 3834 3834 * e1000e_update_phy_stats - Update the PHY statistics counters 3835 3835 * @adapter: board private structure 3836 + * 3837 + * Read/clear the upper 16-bit PHY registers and read/accumulate lower 3836 3838 **/ 3837 3839 static void e1000e_update_phy_stats(struct e1000_adapter *adapter) 3838 3840 { ··· 3846 3844 if (ret_val) 3847 3845 return; 3848 3846 3849 - hw->phy.addr = 1; 3850 - 3851 - #define HV_PHY_STATS_PAGE 778 3852 3847 /* 3853 3848 * A page set is expensive so check if already on desired page. 3854 3849 * If not, set to the page with the PHY status registers. 3855 3850 */ 3851 + hw->phy.addr = 1; 3856 3852 ret_val = e1000e_read_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 3857 3853 &phy_data); 3858 3854 if (ret_val) 3859 3855 goto release; 3860 - if (phy_data != (HV_PHY_STATS_PAGE << IGP_PAGE_SHIFT)) { 3861 - ret_val = e1000e_write_phy_reg_mdic(hw, 3862 - IGP01E1000_PHY_PAGE_SELECT, 3863 - (HV_PHY_STATS_PAGE << 3864 - IGP_PAGE_SHIFT)); 3856 + if (phy_data != (HV_STATS_PAGE << IGP_PAGE_SHIFT)) { 3857 + ret_val = hw->phy.ops.set_page(hw, 3858 + HV_STATS_PAGE << IGP_PAGE_SHIFT); 3865 3859 if (ret_val) 3866 3860 goto release; 3867 3861 } 3868 3862 3869 - /* Read/clear the upper 16-bit registers and read/accumulate lower */ 3870 - 3871 3863 /* Single Collision Count */ 3872 - e1000e_read_phy_reg_mdic(hw, HV_SCC_UPPER & MAX_PHY_REG_ADDRESS, 3873 - &phy_data); 3874 - ret_val = e1000e_read_phy_reg_mdic(hw, 3875 - HV_SCC_LOWER & MAX_PHY_REG_ADDRESS, 3876 - &phy_data); 3864 + hw->phy.ops.read_reg_page(hw, HV_SCC_UPPER, &phy_data); 3865 + ret_val = hw->phy.ops.read_reg_page(hw, HV_SCC_LOWER, &phy_data); 3877 3866 if (!ret_val) 3878 3867 adapter->stats.scc += phy_data; 3879 3868 3880 3869 /* Excessive Collision Count */ 3881 - e1000e_read_phy_reg_mdic(hw, HV_ECOL_UPPER & MAX_PHY_REG_ADDRESS, 3882 - &phy_data); 3883 - ret_val = e1000e_read_phy_reg_mdic(hw, 3884 - HV_ECOL_LOWER & MAX_PHY_REG_ADDRESS, 3885 - &phy_data); 3870 + hw->phy.ops.read_reg_page(hw, HV_ECOL_UPPER, &phy_data); 3871 + ret_val = hw->phy.ops.read_reg_page(hw, HV_ECOL_LOWER, &phy_data); 3886 3872 if (!ret_val) 3887 3873 adapter->stats.ecol += phy_data; 3888 3874 3889 3875 /* Multiple Collision Count */ 3890 - e1000e_read_phy_reg_mdic(hw, HV_MCC_UPPER & MAX_PHY_REG_ADDRESS, 3891 - &phy_data); 3892 - ret_val = e1000e_read_phy_reg_mdic(hw, 3893 - HV_MCC_LOWER & MAX_PHY_REG_ADDRESS, 3894 - &phy_data); 3876 + hw->phy.ops.read_reg_page(hw, HV_MCC_UPPER, &phy_data); 3877 + ret_val = hw->phy.ops.read_reg_page(hw, HV_MCC_LOWER, &phy_data); 3895 3878 if (!ret_val) 3896 3879 adapter->stats.mcc += phy_data; 3897 3880 3898 3881 /* Late Collision Count */ 3899 - e1000e_read_phy_reg_mdic(hw, HV_LATECOL_UPPER & MAX_PHY_REG_ADDRESS, 3900 - &phy_data); 3901 - ret_val = e1000e_read_phy_reg_mdic(hw, 3902 - HV_LATECOL_LOWER & 3903 - MAX_PHY_REG_ADDRESS, 3904 - &phy_data); 3882 + hw->phy.ops.read_reg_page(hw, HV_LATECOL_UPPER, &phy_data); 3883 + ret_val = hw->phy.ops.read_reg_page(hw, HV_LATECOL_LOWER, &phy_data); 3905 3884 if (!ret_val) 3906 3885 adapter->stats.latecol += phy_data; 3907 3886 3908 3887 /* Collision Count - also used for adaptive IFS */ 3909 - e1000e_read_phy_reg_mdic(hw, HV_COLC_UPPER & MAX_PHY_REG_ADDRESS, 3910 - &phy_data); 3911 - ret_val = e1000e_read_phy_reg_mdic(hw, 3912 - HV_COLC_LOWER & MAX_PHY_REG_ADDRESS, 3913 - &phy_data); 3888 + hw->phy.ops.read_reg_page(hw, HV_COLC_UPPER, &phy_data); 3889 + ret_val = hw->phy.ops.read_reg_page(hw, HV_COLC_LOWER, &phy_data); 3914 3890 if (!ret_val) 3915 3891 hw->mac.collision_delta = phy_data; 3916 3892 3917 3893 /* Defer Count */ 3918 - e1000e_read_phy_reg_mdic(hw, HV_DC_UPPER & MAX_PHY_REG_ADDRESS, 3919 - &phy_data); 3920 - ret_val = e1000e_read_phy_reg_mdic(hw, 3921 - HV_DC_LOWER & MAX_PHY_REG_ADDRESS, 3922 - &phy_data); 3894 + hw->phy.ops.read_reg_page(hw, HV_DC_UPPER, &phy_data); 3895 + ret_val = hw->phy.ops.read_reg_page(hw, HV_DC_LOWER, &phy_data); 3923 3896 if (!ret_val) 3924 3897 adapter->stats.dc += phy_data; 3925 3898 3926 3899 /* Transmit with no CRS */ 3927 - e1000e_read_phy_reg_mdic(hw, HV_TNCRS_UPPER & MAX_PHY_REG_ADDRESS, 3928 - &phy_data); 3929 - ret_val = e1000e_read_phy_reg_mdic(hw, 3930 - HV_TNCRS_LOWER & MAX_PHY_REG_ADDRESS, 3931 - &phy_data); 3900 + hw->phy.ops.read_reg_page(hw, HV_TNCRS_UPPER, &phy_data); 3901 + ret_val = hw->phy.ops.read_reg_page(hw, HV_TNCRS_LOWER, &phy_data); 3932 3902 if (!ret_val) 3933 3903 adapter->stats.tncrs += phy_data; 3934 3904 ··· 5128 5154 { 5129 5155 struct e1000_hw *hw = &adapter->hw; 5130 5156 u32 i, mac_reg; 5131 - u16 phy_reg; 5157 + u16 phy_reg, wuc_enable; 5132 5158 int retval = 0; 5133 5159 5134 5160 /* copy MAC RARs to PHY RARs */ 5135 5161 e1000_copy_rx_addrs_to_phy_ich8lan(hw); 5136 5162 5137 - /* copy MAC MTA to PHY MTA */ 5163 + retval = hw->phy.ops.acquire(hw); 5164 + if (retval) { 5165 + e_err("Could not acquire PHY\n"); 5166 + return retval; 5167 + } 5168 + 5169 + /* Enable access to wakeup registers on and set page to BM_WUC_PAGE */ 5170 + retval = e1000_enable_phy_wakeup_reg_access_bm(hw, &wuc_enable); 5171 + if (retval) 5172 + goto out; 5173 + 5174 + /* copy MAC MTA to PHY MTA - only needed for pchlan */ 5138 5175 for (i = 0; i < adapter->hw.mac.mta_reg_count; i++) { 5139 5176 mac_reg = E1000_READ_REG_ARRAY(hw, E1000_MTA, i); 5140 - e1e_wphy(hw, BM_MTA(i), (u16)(mac_reg & 0xFFFF)); 5141 - e1e_wphy(hw, BM_MTA(i) + 1, (u16)((mac_reg >> 16) & 0xFFFF)); 5177 + hw->phy.ops.write_reg_page(hw, BM_MTA(i), 5178 + (u16)(mac_reg & 0xFFFF)); 5179 + hw->phy.ops.write_reg_page(hw, BM_MTA(i) + 1, 5180 + (u16)((mac_reg >> 16) & 0xFFFF)); 5142 5181 } 5143 5182 5144 5183 /* configure PHY Rx Control register */ 5145 - e1e_rphy(&adapter->hw, BM_RCTL, &phy_reg); 5184 + hw->phy.ops.read_reg_page(&adapter->hw, BM_RCTL, &phy_reg); 5146 5185 mac_reg = er32(RCTL); 5147 5186 if (mac_reg & E1000_RCTL_UPE) 5148 5187 phy_reg |= BM_RCTL_UPE; ··· 5172 5185 mac_reg = er32(CTRL); 5173 5186 if (mac_reg & E1000_CTRL_RFCE) 5174 5187 phy_reg |= BM_RCTL_RFCE; 5175 - e1e_wphy(&adapter->hw, BM_RCTL, phy_reg); 5188 + hw->phy.ops.write_reg_page(&adapter->hw, BM_RCTL, phy_reg); 5176 5189 5177 5190 /* enable PHY wakeup in MAC register */ 5178 5191 ew32(WUFC, wufc); 5179 5192 ew32(WUC, E1000_WUC_PHY_WAKE | E1000_WUC_PME_EN); 5180 5193 5181 5194 /* configure and enable PHY wakeup in PHY registers */ 5182 - e1e_wphy(&adapter->hw, BM_WUFC, wufc); 5183 - e1e_wphy(&adapter->hw, BM_WUC, E1000_WUC_PME_EN); 5195 + hw->phy.ops.write_reg_page(&adapter->hw, BM_WUFC, wufc); 5196 + hw->phy.ops.write_reg_page(&adapter->hw, BM_WUC, E1000_WUC_PME_EN); 5184 5197 5185 5198 /* activate PHY wakeup */ 5186 - retval = hw->phy.ops.acquire(hw); 5187 - if (retval) { 5188 - e_err("Could not acquire PHY\n"); 5189 - return retval; 5190 - } 5191 - e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 5192 - (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT)); 5193 - retval = e1000e_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &phy_reg); 5194 - if (retval) { 5195 - e_err("Could not read PHY page 769\n"); 5196 - goto out; 5197 - } 5198 - phy_reg |= BM_WUC_ENABLE_BIT | BM_WUC_HOST_WU_BIT; 5199 - retval = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg); 5199 + wuc_enable |= BM_WUC_ENABLE_BIT | BM_WUC_HOST_WU_BIT; 5200 + retval = e1000_disable_phy_wakeup_reg_access_bm(hw, &wuc_enable); 5200 5201 if (retval) 5201 5202 e_err("Could not set PHY Host Wakeup bit\n"); 5202 5203 out:
+231 -125
drivers/net/e1000e/phy.c
··· 36 36 static s32 e1000_wait_autoneg(struct e1000_hw *hw); 37 37 static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg); 38 38 static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, 39 - u16 *data, bool read); 39 + u16 *data, bool read, bool page_set); 40 40 static u32 e1000_get_phy_addr_for_hv_page(u32 page); 41 41 static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, 42 42 u16 *data, bool read); ··· 345 345 hw->phy.ops.release(hw); 346 346 347 347 return ret_val; 348 + } 349 + 350 + /** 351 + * e1000_set_page_igp - Set page as on IGP-like PHY(s) 352 + * @hw: pointer to the HW structure 353 + * @page: page to set (shifted left when necessary) 354 + * 355 + * Sets PHY page required for PHY register access. Assumes semaphore is 356 + * already acquired. Note, this function sets phy.addr to 1 so the caller 357 + * must set it appropriately (if necessary) after this function returns. 358 + **/ 359 + s32 e1000_set_page_igp(struct e1000_hw *hw, u16 page) 360 + { 361 + e_dbg("Setting page 0x%x\n", page); 362 + 363 + hw->phy.addr = 1; 364 + 365 + return e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, page); 348 366 } 349 367 350 368 /** ··· 2436 2418 /* Page 800 works differently than the rest so it has its own func */ 2437 2419 if (page == BM_WUC_PAGE) { 2438 2420 ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data, 2439 - false); 2421 + false, false); 2440 2422 goto out; 2441 2423 } 2442 2424 ··· 2495 2477 /* Page 800 works differently than the rest so it has its own func */ 2496 2478 if (page == BM_WUC_PAGE) { 2497 2479 ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data, 2498 - true); 2480 + true, false); 2499 2481 goto out; 2500 2482 } 2501 2483 ··· 2553 2535 /* Page 800 works differently than the rest so it has its own func */ 2554 2536 if (page == BM_WUC_PAGE) { 2555 2537 ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data, 2556 - true); 2538 + true, false); 2557 2539 goto out; 2558 2540 } 2559 2541 ··· 2597 2579 /* Page 800 works differently than the rest so it has its own func */ 2598 2580 if (page == BM_WUC_PAGE) { 2599 2581 ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data, 2600 - false); 2582 + false, false); 2601 2583 goto out; 2602 2584 } 2603 2585 ··· 2621 2603 } 2622 2604 2623 2605 /** 2624 - * e1000_access_phy_wakeup_reg_bm - Read BM PHY wakeup register 2606 + * e1000_enable_phy_wakeup_reg_access_bm - enable access to BM wakeup registers 2607 + * @hw: pointer to the HW structure 2608 + * @phy_reg: pointer to store original contents of BM_WUC_ENABLE_REG 2609 + * 2610 + * Assumes semaphore already acquired and phy_reg points to a valid memory 2611 + * address to store contents of the BM_WUC_ENABLE_REG register. 2612 + **/ 2613 + s32 e1000_enable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg) 2614 + { 2615 + s32 ret_val; 2616 + u16 temp; 2617 + 2618 + /* All page select, port ctrl and wakeup registers use phy address 1 */ 2619 + hw->phy.addr = 1; 2620 + 2621 + /* Select Port Control Registers page */ 2622 + ret_val = e1000_set_page_igp(hw, (BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT)); 2623 + if (ret_val) { 2624 + e_dbg("Could not set Port Control page\n"); 2625 + goto out; 2626 + } 2627 + 2628 + ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg); 2629 + if (ret_val) { 2630 + e_dbg("Could not read PHY register %d.%d\n", 2631 + BM_PORT_CTRL_PAGE, BM_WUC_ENABLE_REG); 2632 + goto out; 2633 + } 2634 + 2635 + /* 2636 + * Enable both PHY wakeup mode and Wakeup register page writes. 2637 + * Prevent a power state change by disabling ME and Host PHY wakeup. 2638 + */ 2639 + temp = *phy_reg; 2640 + temp |= BM_WUC_ENABLE_BIT; 2641 + temp &= ~(BM_WUC_ME_WU_BIT | BM_WUC_HOST_WU_BIT); 2642 + 2643 + ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, temp); 2644 + if (ret_val) { 2645 + e_dbg("Could not write PHY register %d.%d\n", 2646 + BM_PORT_CTRL_PAGE, BM_WUC_ENABLE_REG); 2647 + goto out; 2648 + } 2649 + 2650 + /* Select Host Wakeup Registers page */ 2651 + ret_val = e1000_set_page_igp(hw, (BM_WUC_PAGE << IGP_PAGE_SHIFT)); 2652 + 2653 + /* caller now able to write registers on the Wakeup registers page */ 2654 + out: 2655 + return ret_val; 2656 + } 2657 + 2658 + /** 2659 + * e1000_disable_phy_wakeup_reg_access_bm - disable access to BM wakeup regs 2660 + * @hw: pointer to the HW structure 2661 + * @phy_reg: pointer to original contents of BM_WUC_ENABLE_REG 2662 + * 2663 + * Restore BM_WUC_ENABLE_REG to its original value. 2664 + * 2665 + * Assumes semaphore already acquired and *phy_reg is the contents of the 2666 + * BM_WUC_ENABLE_REG before register(s) on BM_WUC_PAGE were accessed by 2667 + * caller. 2668 + **/ 2669 + s32 e1000_disable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg) 2670 + { 2671 + s32 ret_val = 0; 2672 + 2673 + /* Select Port Control Registers page */ 2674 + ret_val = e1000_set_page_igp(hw, (BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT)); 2675 + if (ret_val) { 2676 + e_dbg("Could not set Port Control page\n"); 2677 + goto out; 2678 + } 2679 + 2680 + /* Restore 769.17 to its original value */ 2681 + ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, *phy_reg); 2682 + if (ret_val) 2683 + e_dbg("Could not restore PHY register %d.%d\n", 2684 + BM_PORT_CTRL_PAGE, BM_WUC_ENABLE_REG); 2685 + out: 2686 + return ret_val; 2687 + } 2688 + 2689 + /** 2690 + * e1000_access_phy_wakeup_reg_bm - Read/write BM PHY wakeup register 2625 2691 * @hw: pointer to the HW structure 2626 2692 * @offset: register offset to be read or written 2627 2693 * @data: pointer to the data to read or write 2628 2694 * @read: determines if operation is read or write 2695 + * @page_set: BM_WUC_PAGE already set and access enabled 2629 2696 * 2630 - * Acquires semaphore, if necessary, then reads the PHY register at offset 2631 - * and storing the retrieved information in data. Release any acquired 2632 - * semaphores before exiting. Note that procedure to read the wakeup 2633 - * registers are different. It works as such: 2634 - * 1) Set page 769, register 17, bit 2 = 1 2697 + * Read the PHY register at offset and store the retrieved information in 2698 + * data, or write data to PHY register at offset. Note the procedure to 2699 + * access the PHY wakeup registers is different than reading the other PHY 2700 + * registers. It works as such: 2701 + * 1) Set 769.17.2 (page 769, register 17, bit 2) = 1 2635 2702 * 2) Set page to 800 for host (801 if we were manageability) 2636 2703 * 3) Write the address using the address opcode (0x11) 2637 2704 * 4) Read or write the data using the data opcode (0x12) 2638 - * 5) Restore 769_17.2 to its original value 2705 + * 5) Restore 769.17.2 to its original value 2639 2706 * 2640 - * Assumes semaphore already acquired. 2707 + * Steps 1 and 2 are done by e1000_enable_phy_wakeup_reg_access_bm() and 2708 + * step 5 is done by e1000_disable_phy_wakeup_reg_access_bm(). 2709 + * 2710 + * Assumes semaphore is already acquired. When page_set==true, assumes 2711 + * the PHY page is set to BM_WUC_PAGE (i.e. a function in the call stack 2712 + * is responsible for calls to e1000_[enable|disable]_phy_wakeup_reg_bm()). 2641 2713 **/ 2642 2714 static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, 2643 - u16 *data, bool read) 2715 + u16 *data, bool read, bool page_set) 2644 2716 { 2645 2717 s32 ret_val; 2646 2718 u16 reg = BM_PHY_REG_NUM(offset); 2719 + u16 page = BM_PHY_REG_PAGE(offset); 2647 2720 u16 phy_reg = 0; 2648 2721 2649 - /* Gig must be disabled for MDIO accesses to page 800 */ 2722 + /* Gig must be disabled for MDIO accesses to Host Wakeup reg page */ 2650 2723 if ((hw->mac.type == e1000_pchlan) && 2651 - (!(er32(PHY_CTRL) & E1000_PHY_CTRL_GBE_DISABLE))) 2652 - e_dbg("Attempting to access page 800 while gig enabled.\n"); 2724 + (!(er32(PHY_CTRL) & E1000_PHY_CTRL_GBE_DISABLE))) 2725 + e_dbg("Attempting to access page %d while gig enabled.\n", 2726 + page); 2653 2727 2654 - /* All operations in this function are phy address 1 */ 2655 - hw->phy.addr = 1; 2656 - 2657 - /* Set page 769 */ 2658 - e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 2659 - (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT)); 2660 - 2661 - ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &phy_reg); 2662 - if (ret_val) { 2663 - e_dbg("Could not read PHY page 769\n"); 2664 - goto out; 2728 + if (!page_set) { 2729 + /* Enable access to PHY wakeup registers */ 2730 + ret_val = e1000_enable_phy_wakeup_reg_access_bm(hw, &phy_reg); 2731 + if (ret_val) { 2732 + e_dbg("Could not enable PHY wakeup reg access\n"); 2733 + goto out; 2734 + } 2665 2735 } 2666 2736 2667 - /* First clear bit 4 to avoid a power state change */ 2668 - phy_reg &= ~(BM_WUC_HOST_WU_BIT); 2669 - ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg); 2670 - if (ret_val) { 2671 - e_dbg("Could not clear PHY page 769 bit 4\n"); 2672 - goto out; 2673 - } 2737 + e_dbg("Accessing PHY page %d reg 0x%x\n", page, reg); 2674 2738 2675 - /* Write bit 2 = 1, and clear bit 4 to 769_17 */ 2676 - ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, 2677 - phy_reg | BM_WUC_ENABLE_BIT); 2678 - if (ret_val) { 2679 - e_dbg("Could not write PHY page 769 bit 2\n"); 2680 - goto out; 2681 - } 2682 - 2683 - /* Select page 800 */ 2684 - ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 2685 - (BM_WUC_PAGE << IGP_PAGE_SHIFT)); 2686 - 2687 - /* Write the page 800 offset value using opcode 0x11 */ 2739 + /* Write the Wakeup register page offset value using opcode 0x11 */ 2688 2740 ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ADDRESS_OPCODE, reg); 2689 2741 if (ret_val) { 2690 - e_dbg("Could not write address opcode to page 800\n"); 2742 + e_dbg("Could not write address opcode to page %d\n", page); 2691 2743 goto out; 2692 2744 } 2693 2745 2694 2746 if (read) { 2695 - /* Read the page 800 value using opcode 0x12 */ 2747 + /* Read the Wakeup register page value using opcode 0x12 */ 2696 2748 ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE, 2697 2749 data); 2698 2750 } else { 2699 - /* Write the page 800 value using opcode 0x12 */ 2751 + /* Write the Wakeup register page value using opcode 0x12 */ 2700 2752 ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE, 2701 2753 *data); 2702 2754 } 2703 2755 2704 2756 if (ret_val) { 2705 - e_dbg("Could not access data value from page 800\n"); 2757 + e_dbg("Could not access PHY reg %d.%d\n", page, reg); 2706 2758 goto out; 2707 2759 } 2708 2760 2709 - /* 2710 - * Restore 769_17.2 to its original value 2711 - * Set page 769 2712 - */ 2713 - e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 2714 - (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT)); 2715 - 2716 - /* Clear 769_17.2 */ 2717 - ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg); 2718 - if (ret_val) { 2719 - e_dbg("Could not clear PHY page 769 bit 2\n"); 2720 - goto out; 2721 - } 2761 + if (!page_set) 2762 + ret_val = e1000_disable_phy_wakeup_reg_access_bm(hw, &phy_reg); 2722 2763 2723 2764 out: 2724 2765 return ret_val; ··· 2869 2792 * semaphore before exiting. 2870 2793 **/ 2871 2794 static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data, 2872 - bool locked) 2795 + bool locked, bool page_set) 2873 2796 { 2874 2797 s32 ret_val; 2875 2798 u16 page = BM_PHY_REG_PAGE(offset); 2876 2799 u16 reg = BM_PHY_REG_NUM(offset); 2800 + u32 phy_addr = hw->phy.addr = e1000_get_phy_addr_for_hv_page(page); 2877 2801 2878 2802 if (!locked) { 2879 2803 ret_val = hw->phy.ops.acquire(hw); ··· 2884 2806 2885 2807 /* Page 800 works differently than the rest so it has its own func */ 2886 2808 if (page == BM_WUC_PAGE) { 2887 - ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, 2888 - data, true); 2809 + ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data, 2810 + true, page_set); 2889 2811 goto out; 2890 2812 } 2891 2813 ··· 2895 2817 goto out; 2896 2818 } 2897 2819 2898 - hw->phy.addr = e1000_get_phy_addr_for_hv_page(page); 2820 + if (!page_set) { 2821 + if (page == HV_INTC_FC_PAGE_START) 2822 + page = 0; 2899 2823 2900 - if (page == HV_INTC_FC_PAGE_START) 2901 - page = 0; 2824 + if (reg > MAX_PHY_MULTI_PAGE_REG) { 2825 + /* Page is shifted left, PHY expects (page x 32) */ 2826 + ret_val = e1000_set_page_igp(hw, 2827 + (page << IGP_PAGE_SHIFT)); 2902 2828 2903 - if (reg > MAX_PHY_MULTI_PAGE_REG) { 2904 - u32 phy_addr = hw->phy.addr; 2829 + hw->phy.addr = phy_addr; 2905 2830 2906 - hw->phy.addr = 1; 2907 - 2908 - /* Page is shifted left, PHY expects (page x 32) */ 2909 - ret_val = e1000e_write_phy_reg_mdic(hw, 2910 - IGP01E1000_PHY_PAGE_SELECT, 2911 - (page << IGP_PAGE_SHIFT)); 2912 - hw->phy.addr = phy_addr; 2913 - 2914 - if (ret_val) 2915 - goto out; 2831 + if (ret_val) 2832 + goto out; 2833 + } 2916 2834 } 2835 + 2836 + e_dbg("reading PHY page %d (or 0x%x shifted) reg 0x%x\n", page, 2837 + page << IGP_PAGE_SHIFT, reg); 2917 2838 2918 2839 ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, 2919 2840 data); ··· 2935 2858 **/ 2936 2859 s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data) 2937 2860 { 2938 - return __e1000_read_phy_reg_hv(hw, offset, data, false); 2861 + return __e1000_read_phy_reg_hv(hw, offset, data, false, false); 2939 2862 } 2940 2863 2941 2864 /** ··· 2949 2872 **/ 2950 2873 s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 *data) 2951 2874 { 2952 - return __e1000_read_phy_reg_hv(hw, offset, data, true); 2875 + return __e1000_read_phy_reg_hv(hw, offset, data, true, false); 2876 + } 2877 + 2878 + /** 2879 + * e1000_read_phy_reg_page_hv - Read HV PHY register 2880 + * @hw: pointer to the HW structure 2881 + * @offset: register offset to write to 2882 + * @data: data to write at register offset 2883 + * 2884 + * Reads the PHY register at offset and stores the retrieved information 2885 + * in data. Assumes semaphore already acquired and page already set. 2886 + **/ 2887 + s32 e1000_read_phy_reg_page_hv(struct e1000_hw *hw, u32 offset, u16 *data) 2888 + { 2889 + return __e1000_read_phy_reg_hv(hw, offset, data, true, true); 2953 2890 } 2954 2891 2955 2892 /** ··· 2977 2886 * at the offset. Release any acquired semaphores before exiting. 2978 2887 **/ 2979 2888 static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data, 2980 - bool locked) 2889 + bool locked, bool page_set) 2981 2890 { 2982 2891 s32 ret_val; 2983 2892 u16 page = BM_PHY_REG_PAGE(offset); 2984 2893 u16 reg = BM_PHY_REG_NUM(offset); 2894 + u32 phy_addr = hw->phy.addr = e1000_get_phy_addr_for_hv_page(page); 2985 2895 2986 2896 if (!locked) { 2987 2897 ret_val = hw->phy.ops.acquire(hw); ··· 2992 2900 2993 2901 /* Page 800 works differently than the rest so it has its own func */ 2994 2902 if (page == BM_WUC_PAGE) { 2995 - ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, 2996 - &data, false); 2903 + ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data, 2904 + false, page_set); 2997 2905 goto out; 2998 2906 } 2999 2907 ··· 3003 2911 goto out; 3004 2912 } 3005 2913 3006 - hw->phy.addr = e1000_get_phy_addr_for_hv_page(page); 2914 + if (!page_set) { 2915 + if (page == HV_INTC_FC_PAGE_START) 2916 + page = 0; 3007 2917 3008 - if (page == HV_INTC_FC_PAGE_START) 3009 - page = 0; 2918 + /* 2919 + * Workaround MDIO accesses being disabled after entering IEEE 2920 + * Power Down (when bit 11 of the PHY Control register is set) 2921 + */ 2922 + if ((hw->phy.type == e1000_phy_82578) && 2923 + (hw->phy.revision >= 1) && 2924 + (hw->phy.addr == 2) && 2925 + ((MAX_PHY_REG_ADDRESS & reg) == 0) && (data & (1 << 11))) { 2926 + u16 data2 = 0x7EFF; 2927 + ret_val = e1000_access_phy_debug_regs_hv(hw, 2928 + (1 << 6) | 0x3, 2929 + &data2, false); 2930 + if (ret_val) 2931 + goto out; 2932 + } 3010 2933 3011 - /* 3012 - * Workaround MDIO accesses being disabled after entering IEEE Power 3013 - * Down (whenever bit 11 of the PHY Control register is set) 3014 - */ 3015 - if ((hw->phy.type == e1000_phy_82578) && 3016 - (hw->phy.revision >= 1) && 3017 - (hw->phy.addr == 2) && 3018 - ((MAX_PHY_REG_ADDRESS & reg) == 0) && 3019 - (data & (1 << 11))) { 3020 - u16 data2 = 0x7EFF; 3021 - ret_val = e1000_access_phy_debug_regs_hv(hw, (1 << 6) | 0x3, 3022 - &data2, false); 3023 - if (ret_val) 3024 - goto out; 2934 + if (reg > MAX_PHY_MULTI_PAGE_REG) { 2935 + /* Page is shifted left, PHY expects (page x 32) */ 2936 + ret_val = e1000_set_page_igp(hw, 2937 + (page << IGP_PAGE_SHIFT)); 2938 + 2939 + hw->phy.addr = phy_addr; 2940 + 2941 + if (ret_val) 2942 + goto out; 2943 + } 3025 2944 } 3026 2945 3027 - if (reg > MAX_PHY_MULTI_PAGE_REG) { 3028 - u32 phy_addr = hw->phy.addr; 3029 - 3030 - hw->phy.addr = 1; 3031 - 3032 - /* Page is shifted left, PHY expects (page x 32) */ 3033 - ret_val = e1000e_write_phy_reg_mdic(hw, 3034 - IGP01E1000_PHY_PAGE_SELECT, 3035 - (page << IGP_PAGE_SHIFT)); 3036 - hw->phy.addr = phy_addr; 3037 - 3038 - if (ret_val) 3039 - goto out; 3040 - } 2946 + e_dbg("writing PHY page %d (or 0x%x shifted) reg 0x%x\n", page, 2947 + page << IGP_PAGE_SHIFT, reg); 3041 2948 3042 2949 ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, 3043 2950 data); ··· 3059 2968 **/ 3060 2969 s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data) 3061 2970 { 3062 - return __e1000_write_phy_reg_hv(hw, offset, data, false); 2971 + return __e1000_write_phy_reg_hv(hw, offset, data, false, false); 3063 2972 } 3064 2973 3065 2974 /** ··· 3073 2982 **/ 3074 2983 s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 data) 3075 2984 { 3076 - return __e1000_write_phy_reg_hv(hw, offset, data, true); 2985 + return __e1000_write_phy_reg_hv(hw, offset, data, true, false); 2986 + } 2987 + 2988 + /** 2989 + * e1000_write_phy_reg_page_hv - Write HV PHY register 2990 + * @hw: pointer to the HW structure 2991 + * @offset: register offset to write to 2992 + * @data: data to write at register offset 2993 + * 2994 + * Writes the data to PHY register at the offset. Assumes semaphore 2995 + * already acquired and page already set. 2996 + **/ 2997 + s32 e1000_write_phy_reg_page_hv(struct e1000_hw *hw, u32 offset, u16 data) 2998 + { 2999 + return __e1000_write_phy_reg_hv(hw, offset, data, true, true); 3077 3000 } 3078 3001 3079 3002 /** ··· 3109 3004 * @hw: pointer to the HW structure 3110 3005 * @offset: register offset to be read or written 3111 3006 * @data: pointer to the data to be read or written 3112 - * @read: determines if operation is read or written 3007 + * @read: determines if operation is read or write 3113 3008 * 3114 3009 * Reads the PHY register at offset and stores the retreived information 3115 3010 * in data. Assumes semaphore already acquired. Note that the procedure 3116 - * to read these regs uses the address port and data port to read/write. 3011 + * to access these regs uses the address port and data port to read/write. 3012 + * These accesses done with PHY address 2 and without using pages. 3117 3013 **/ 3118 3014 static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, 3119 3015 u16 *data, bool read) ··· 3134 3028 /* masking with 0x3F to remove the page from offset */ 3135 3029 ret_val = e1000e_write_phy_reg_mdic(hw, addr_reg, (u16)offset & 0x3F); 3136 3030 if (ret_val) { 3137 - e_dbg("Could not write PHY the HV address register\n"); 3031 + e_dbg("Could not write the Address Offset port register\n"); 3138 3032 goto out; 3139 3033 } 3140 3034 ··· 3145 3039 ret_val = e1000e_write_phy_reg_mdic(hw, data_reg, *data); 3146 3040 3147 3041 if (ret_val) { 3148 - e_dbg("Could not read data value from HV data register\n"); 3042 + e_dbg("Could not access the Data port register\n"); 3149 3043 goto out; 3150 3044 } 3151 3045