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