diff options
Diffstat (limited to 'drivers/net')
| -rw-r--r-- | drivers/net/e1000e/e1000.h | 38 | ||||
| -rw-r--r-- | drivers/net/e1000e/hw.h | 20 | ||||
| -rw-r--r-- | drivers/net/e1000e/ich8lan.c | 70 | ||||
| -rw-r--r-- | drivers/net/e1000e/netdev.c | 111 | ||||
| -rw-r--r-- | drivers/net/e1000e/phy.c | 352 |
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); | |||
| 585 | extern s32 e1000e_phy_force_speed_duplex_igp(struct e1000_hw *hw); | 586 | extern s32 e1000e_phy_force_speed_duplex_igp(struct e1000_hw *hw); |
| 586 | extern s32 e1000e_get_cable_length_igp_2(struct e1000_hw *hw); | 587 | extern s32 e1000e_get_cable_length_igp_2(struct e1000_hw *hw); |
| 587 | extern s32 e1000e_get_phy_info_igp(struct e1000_hw *hw); | 588 | extern s32 e1000e_get_phy_info_igp(struct e1000_hw *hw); |
| 589 | extern s32 e1000_set_page_igp(struct e1000_hw *hw, u16 page); | ||
| 588 | extern s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data); | 590 | extern s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data); |
| 589 | extern s32 e1000e_read_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, | 591 | extern 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); | |||
| 605 | extern s32 e1000e_determine_phy_address(struct e1000_hw *hw); | 607 | extern s32 e1000e_determine_phy_address(struct e1000_hw *hw); |
| 606 | extern s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data); | 608 | extern s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data); |
| 607 | extern s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data); | 609 | extern s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data); |
| 610 | extern s32 e1000_enable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, | ||
| 611 | u16 *phy_reg); | ||
| 612 | extern s32 e1000_disable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, | ||
| 613 | u16 *phy_reg); | ||
| 608 | extern s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data); | 614 | extern s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data); |
| 609 | extern s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data); | 615 | extern s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data); |
| 610 | extern void e1000e_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl); | 616 | extern 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); | |||
| 625 | extern s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data); | 631 | extern s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data); |
| 626 | extern s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, | 632 | extern s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, |
| 627 | u16 *data); | 633 | u16 *data); |
| 634 | extern s32 e1000_read_phy_reg_page_hv(struct e1000_hw *hw, u32 offset, | ||
| 635 | u16 *data); | ||
| 628 | extern s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data); | 636 | extern s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data); |
| 629 | extern s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, | 637 | extern s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, |
| 630 | u16 data); | 638 | u16 data); |
| 639 | extern s32 e1000_write_phy_reg_page_hv(struct e1000_hw *hw, u32 offset, | ||
| 640 | u16 data); | ||
| 631 | extern s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw); | 641 | extern s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw); |
| 632 | extern s32 e1000_copper_link_setup_82577(struct e1000_hw *hw); | 642 | extern s32 e1000_copper_link_setup_82577(struct e1000_hw *hw); |
| 633 | extern s32 e1000_check_polarity_82577(struct e1000_hw *hw); | 643 | extern 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 | */ | ||
| 782 | struct e1000_phy_operations { | 797 | struct 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: | |||
| 1409 | void e1000_copy_rx_addrs_to_phy_ich8lan(struct e1000_hw *hw) | 1412 | void 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 | |||
| 1443 | release: | ||
| 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) | |||
| 3897 | static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw) | 3919 | static 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); | ||
| 3965 | release: | ||
| 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 | **/ |
| 3837 | static void e1000e_update_phy_stats(struct e1000_adapter *adapter) | 3839 | static 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"); |
| 5215 | out: | 5190 | out: |
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); | |||
| 36 | static s32 e1000_wait_autoneg(struct e1000_hw *hw); | 36 | static s32 e1000_wait_autoneg(struct e1000_hw *hw); |
| 37 | static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg); | 37 | static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg); |
| 38 | static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, | 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 | static u32 e1000_get_phy_addr_for_hv_page(u32 page); | 40 | static u32 e1000_get_phy_addr_for_hv_page(u32 page); |
| 41 | static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, | 41 | static 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 | **/ | ||
| 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); | ||
| 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 | **/ |
| 2624 | static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, | 2631 | s32 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 */ | ||
| 2672 | out: | ||
| 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 | **/ | ||
| 2687 | s32 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); | ||
| 2703 | out: | ||
| 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 | **/ | ||
| 2732 | static 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 | ||
| 2705 | out: | 2782 | out: |
| 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 | **/ |
| 2794 | static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data, | 2871 | static 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); |
| 2842 | out: | 2919 | out: |
| @@ -2858,7 +2935,7 @@ out: | |||
| 2858 | **/ | 2935 | **/ |
| 2859 | s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data) | 2936 | s32 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 | **/ |
| 2873 | s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 *data) | 2950 | s32 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 | **/ | ||
| 2964 | s32 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 | **/ |
| 2888 | static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data, | 2979 | static 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 | **/ |
| 2969 | s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data) | 3060 | s32 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 | **/ |
| 2983 | s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 data) | 3074 | s32 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 | **/ | ||
| 3088 | s32 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 | **/ |
| 3013 | static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, | 3119 | static 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 | ||
