aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000e/phy.c
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/net/e1000e/phy.c
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/net/e1000e/phy.c')
-rw-r--r--drivers/net/e1000e/phy.c352
1 files changed, 229 insertions, 123 deletions
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