devices/e1000e/phy-3.6-orig.c
author Florian Pose <fp@igh-essen.com>
Tue, 16 Feb 2016 15:18:34 +0100
branchstable-1.5
changeset 2639 3bedfc5ecd74
parent 2546 2fa43746d972
permissions -rw-r--r--
Merged CCAT driver v0.14.
2546
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2012 Intel Corporation.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
*******************************************************************************/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
#include "e1000.h"
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
static s32 e1000_wait_autoneg(struct e1000_hw *hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
					  u16 *data, bool read, bool page_set);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
static u32 e1000_get_phy_addr_for_hv_page(u32 page);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
                                          u16 *data, bool read);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
/* Cable length tables */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
static const u16 e1000_m88_cable_length_table[] = {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
	0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED };
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
#define M88E1000_CABLE_LENGTH_TABLE_SIZE \
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
		ARRAY_SIZE(e1000_m88_cable_length_table)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
static const u16 e1000_igp_2_cable_length_table[] = {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
	0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21, 0, 0, 0, 3,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
	6, 10, 13, 16, 19, 23, 26, 29, 32, 35, 38, 41, 6, 10, 14, 18, 22,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
	26, 30, 33, 37, 41, 44, 48, 51, 54, 58, 61, 21, 26, 31, 35, 40,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
	44, 49, 53, 57, 61, 65, 68, 72, 75, 79, 82, 40, 45, 51, 56, 61,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
	66, 70, 75, 79, 83, 87, 91, 94, 98, 101, 104, 60, 66, 72, 77, 82,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
	87, 92, 96, 100, 104, 108, 111, 114, 117, 119, 121, 83, 89, 95,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
	100, 105, 109, 113, 116, 119, 122, 124, 104, 109, 114, 118, 121,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
	124};
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
#define IGP02E1000_CABLE_LENGTH_TABLE_SIZE \
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
		ARRAY_SIZE(e1000_igp_2_cable_length_table)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
#define BM_PHY_REG_PAGE(offset) \
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
	((u16)(((offset) >> PHY_PAGE_SHIFT) & 0xFFFF))
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
#define BM_PHY_REG_NUM(offset) \
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
	((u16)(((offset) & MAX_PHY_REG_ADDRESS) |\
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
	 (((offset) >> (PHY_UPPER_SHIFT - PHY_PAGE_SHIFT)) &\
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
		~MAX_PHY_REG_ADDRESS)))
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
#define HV_INTC_FC_PAGE_START             768
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
#define I82578_ADDR_REG                   29
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
#define I82577_ADDR_REG                   16
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
#define I82577_CFG_REG                    22
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
#define I82577_CFG_ASSERT_CRS_ON_TX       (1 << 15)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
#define I82577_CFG_ENABLE_DOWNSHIFT       (3 << 10) /* auto downshift 100/10 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
#define I82577_CTRL_REG                   23
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
/* 82577 specific PHY registers */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
#define I82577_PHY_CTRL_2            18
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
#define I82577_PHY_STATUS_2          26
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
#define I82577_PHY_DIAG_STATUS       31
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
/* I82577 PHY Status 2 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
#define I82577_PHY_STATUS2_REV_POLARITY   0x0400
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
#define I82577_PHY_STATUS2_MDIX           0x0800
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
#define I82577_PHY_STATUS2_SPEED_MASK     0x0300
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
#define I82577_PHY_STATUS2_SPEED_1000MBPS 0x0200
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
/* I82577 PHY Control 2 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
#define I82577_PHY_CTRL2_AUTO_MDIX        0x0400
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
#define I82577_PHY_CTRL2_FORCE_MDI_MDIX   0x0200
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
/* I82577 PHY Diagnostics Status */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
#define I82577_DSTATUS_CABLE_LENGTH       0x03FC
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
#define I82577_DSTATUS_CABLE_LENGTH_SHIFT 2
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
/* BM PHY Copper Specific Control 1 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
#define BM_CS_CTRL1                       16
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
#define HV_MUX_DATA_CTRL               PHY_REG(776, 16)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
#define HV_MUX_DATA_CTRL_GEN_TO_MAC    0x0400
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
#define HV_MUX_DATA_CTRL_FORCE_SPEED   0x0004
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
 *  e1000e_check_reset_block_generic - Check if PHY reset is blocked
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
 *  Read the PHY management control register and check whether a PHY reset
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
 *  is blocked.  If a reset is not blocked return 0, otherwise
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
 *  return E1000_BLK_PHY_RESET (12).
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
s32 e1000e_check_reset_block_generic(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
	u32 manc;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
	manc = er32(MANC);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
	return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ?
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
	       E1000_BLK_PHY_RESET : 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
 *  e1000e_get_phy_id - Retrieve the PHY ID and revision
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
 *  Reads the PHY registers and stores the PHY ID and possibly the PHY
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
 *  revision in the hardware structure.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
s32 e1000e_get_phy_id(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
	struct e1000_phy_info *phy = &hw->phy;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
	s32 ret_val = 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
	u16 phy_id;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
	u16 retry_count = 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
	if (!phy->ops.read_reg)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
		return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
	while (retry_count < 2) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
		ret_val = e1e_rphy(hw, PHY_ID1, &phy_id);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
		phy->id = (u32)(phy_id << 16);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
		udelay(20);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
		ret_val = e1e_rphy(hw, PHY_ID2, &phy_id);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
		phy->id |= (u32)(phy_id & PHY_REVISION_MASK);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
		phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
		if (phy->id != 0 && phy->id != PHY_REVISION_MASK)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
			return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
		retry_count++;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
	return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
 *  e1000e_phy_reset_dsp - Reset PHY DSP
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
 *  Reset the digital signal processor.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
s32 e1000e_phy_reset_dsp(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
	ret_val = e1e_wphy(hw, M88E1000_PHY_GEN_CONTROL, 0xC1);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
	return e1e_wphy(hw, M88E1000_PHY_GEN_CONTROL, 0);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
 *  e1000e_read_phy_reg_mdic - Read MDI control register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
 *  @offset: register offset to be read
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
 *  @data: pointer to the read data
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
 *  Reads the MDI control register in the PHY at offset and stores the
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
 *  information read to data.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
	struct e1000_phy_info *phy = &hw->phy;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
	u32 i, mdic = 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
	if (offset > MAX_PHY_REG_ADDRESS) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
		e_dbg("PHY Address %d is out of range\n", offset);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
		return -E1000_ERR_PARAM;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
	/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
	 * Set up Op-code, Phy Address, and register offset in the MDI
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
	 * Control register.  The MAC will take care of interfacing with the
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
	 * PHY to retrieve the desired data.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
	 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
	mdic = ((offset << E1000_MDIC_REG_SHIFT) |
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
		(phy->addr << E1000_MDIC_PHY_SHIFT) |
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
		(E1000_MDIC_OP_READ));
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
	ew32(MDIC, mdic);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
	/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
	 * Poll the ready bit to see if the MDI read completed
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
	 * Increasing the time out as testing showed failures with
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
	 * the lower time out
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
	 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
	for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
		udelay(50);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
		mdic = er32(MDIC);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
		if (mdic & E1000_MDIC_READY)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
			break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
	if (!(mdic & E1000_MDIC_READY)) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
		e_dbg("MDI Read did not complete\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
		return -E1000_ERR_PHY;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
	if (mdic & E1000_MDIC_ERROR) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
		e_dbg("MDI Error\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
		return -E1000_ERR_PHY;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
	*data = (u16) mdic;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
	/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
	 * Allow some time after each MDIC transaction to avoid
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
	 * reading duplicate data in the next MDIC transaction.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
	 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
	if (hw->mac.type == e1000_pch2lan)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
		udelay(100);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
	return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
 *  e1000e_write_phy_reg_mdic - Write MDI control register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
 *  @offset: register offset to write to
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
 *  @data: data to write to register at offset
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
 *  Writes data to MDI control register in the PHY at offset.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
	struct e1000_phy_info *phy = &hw->phy;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
	u32 i, mdic = 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
	if (offset > MAX_PHY_REG_ADDRESS) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
		e_dbg("PHY Address %d is out of range\n", offset);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
		return -E1000_ERR_PARAM;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
	/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
	 * Set up Op-code, Phy Address, and register offset in the MDI
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
	 * Control register.  The MAC will take care of interfacing with the
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
	 * PHY to retrieve the desired data.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
	 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
	mdic = (((u32)data) |
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
		(offset << E1000_MDIC_REG_SHIFT) |
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
		(phy->addr << E1000_MDIC_PHY_SHIFT) |
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
		(E1000_MDIC_OP_WRITE));
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
	ew32(MDIC, mdic);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
	/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
	 * Poll the ready bit to see if the MDI read completed
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
	 * Increasing the time out as testing showed failures with
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
	 * the lower time out
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
	 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
	for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
		udelay(50);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
		mdic = er32(MDIC);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
		if (mdic & E1000_MDIC_READY)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
			break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
	if (!(mdic & E1000_MDIC_READY)) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
		e_dbg("MDI Write did not complete\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
		return -E1000_ERR_PHY;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
	if (mdic & E1000_MDIC_ERROR) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
		e_dbg("MDI Error\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
		return -E1000_ERR_PHY;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
	/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
	 * Allow some time after each MDIC transaction to avoid
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
	 * reading duplicate data in the next MDIC transaction.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
	 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
	if (hw->mac.type == e1000_pch2lan)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
		udelay(100);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
	return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
 *  e1000e_read_phy_reg_m88 - Read m88 PHY register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
 *  @offset: register offset to be read
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
 *  @data: pointer to the read data
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
 *  Acquires semaphore, if necessary, then reads the PHY register at offset
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
 *  and storing the retrieved information in data.  Release any acquired
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
 *  semaphores before exiting.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
s32 e1000e_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
	ret_val = hw->phy.ops.acquire(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
	ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
					   data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
	hw->phy.ops.release(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
 *  e1000e_write_phy_reg_m88 - Write m88 PHY register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
 *  @offset: register offset to write to
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
 *  @data: data to write at register offset
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
 *  Acquires semaphore, if necessary, then writes the data to PHY register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
 *  at the offset.  Release any acquired semaphores before exiting.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
s32 e1000e_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
	ret_val = hw->phy.ops.acquire(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
	ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
					    data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
	hw->phy.ops.release(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
 *  e1000_set_page_igp - Set page as on IGP-like PHY(s)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
 *  @page: page to set (shifted left when necessary)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
 *  Sets PHY page required for PHY register access.  Assumes semaphore is
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
 *  already acquired.  Note, this function sets phy.addr to 1 so the caller
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
 *  must set it appropriately (if necessary) after this function returns.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
s32 e1000_set_page_igp(struct e1000_hw *hw, u16 page)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
	e_dbg("Setting page 0x%x\n", page);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
	hw->phy.addr = 1;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
	return e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, page);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
 *  __e1000e_read_phy_reg_igp - Read igp PHY register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
 *  @offset: register offset to be read
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
 *  @data: pointer to the read data
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
 *  @locked: semaphore has already been acquired or not
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
 *  Acquires semaphore, if necessary, then reads the PHY register at offset
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
 *  and stores the retrieved information in data.  Release any acquired
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
 *  semaphores before exiting.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
static s32 __e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
                                    bool locked)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
	s32 ret_val = 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
	if (!locked) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
		if (!hw->phy.ops.acquire)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
			return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
		ret_val = hw->phy.ops.acquire(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
	if (offset > MAX_PHY_MULTI_PAGE_REG)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
		ret_val = e1000e_write_phy_reg_mdic(hw,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
						    IGP01E1000_PHY_PAGE_SELECT,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
						    (u16)offset);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
	if (!ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
		ret_val = e1000e_read_phy_reg_mdic(hw,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
						   MAX_PHY_REG_ADDRESS & offset,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
						   data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
	if (!locked)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
		hw->phy.ops.release(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
 *  e1000e_read_phy_reg_igp - Read igp PHY register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
 *  @offset: register offset to be read
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
 *  @data: pointer to the read data
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
 *  Acquires semaphore then reads the PHY register at offset and stores the
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
 *  retrieved information in data.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
 *  Release the acquired semaphore before exiting.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
	return __e1000e_read_phy_reg_igp(hw, offset, data, false);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
 *  e1000e_read_phy_reg_igp_locked - Read igp PHY register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
 *  @offset: register offset to be read
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
 *  @data: pointer to the read data
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
 *  Reads the PHY register at offset and stores the retrieved information
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
 *  in data.  Assumes semaphore already acquired.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
s32 e1000e_read_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 *data)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
	return __e1000e_read_phy_reg_igp(hw, offset, data, true);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
 *  e1000e_write_phy_reg_igp - Write igp PHY register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
 *  @offset: register offset to write to
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
 *  @data: data to write at register offset
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
 *  @locked: semaphore has already been acquired or not
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
 *  Acquires semaphore, if necessary, then writes the data to PHY register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
 *  at the offset.  Release any acquired semaphores before exiting.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
static s32 __e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
                                     bool locked)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
	s32 ret_val = 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
	if (!locked) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
		if (!hw->phy.ops.acquire)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
			return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
		ret_val = hw->phy.ops.acquire(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
	if (offset > MAX_PHY_MULTI_PAGE_REG)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
		ret_val = e1000e_write_phy_reg_mdic(hw,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
						    IGP01E1000_PHY_PAGE_SELECT,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
						    (u16)offset);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
	if (!ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
		ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS &
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
							offset,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
						    data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
	if (!locked)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
		hw->phy.ops.release(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
 *  e1000e_write_phy_reg_igp - Write igp PHY register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
 *  @offset: register offset to write to
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
 *  @data: data to write at register offset
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
 *  Acquires semaphore then writes the data to PHY register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
 *  at the offset.  Release any acquired semaphores before exiting.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
s32 e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
	return __e1000e_write_phy_reg_igp(hw, offset, data, false);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
 *  e1000e_write_phy_reg_igp_locked - Write igp PHY register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
 *  @offset: register offset to write to
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
 *  @data: data to write at register offset
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
 *  Writes the data to PHY register at the offset.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
 *  Assumes semaphore already acquired.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
s32 e1000e_write_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 data)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
	return __e1000e_write_phy_reg_igp(hw, offset, data, true);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
 *  __e1000_read_kmrn_reg - Read kumeran register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
 *  @offset: register offset to be read
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
 *  @data: pointer to the read data
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
 *  @locked: semaphore has already been acquired or not
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
 *  Acquires semaphore, if necessary.  Then reads the PHY register at offset
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
 *  using the kumeran interface.  The information retrieved is stored in data.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
 *  Release any acquired semaphores before exiting.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
static s32 __e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
                                 bool locked)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
	u32 kmrnctrlsta;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
	if (!locked) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
		s32 ret_val = 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
		if (!hw->phy.ops.acquire)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
			return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
		ret_val = hw->phy.ops.acquire(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
	kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
		       E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
	ew32(KMRNCTRLSTA, kmrnctrlsta);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
	e1e_flush();
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
	udelay(2);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
	kmrnctrlsta = er32(KMRNCTRLSTA);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
	*data = (u16)kmrnctrlsta;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
	if (!locked)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
		hw->phy.ops.release(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
	return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
 *  e1000e_read_kmrn_reg -  Read kumeran register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
 *  @offset: register offset to be read
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
 *  @data: pointer to the read data
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
 *  Acquires semaphore then reads the PHY register at offset using the
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
 *  kumeran interface.  The information retrieved is stored in data.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
 *  Release the acquired semaphore before exiting.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
	return __e1000_read_kmrn_reg(hw, offset, data, false);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
 *  e1000e_read_kmrn_reg_locked -  Read kumeran register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
 *  @offset: register offset to be read
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
 *  @data: pointer to the read data
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
 *  Reads the PHY register at offset using the kumeran interface.  The
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
 *  information retrieved is stored in data.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
 *  Assumes semaphore already acquired.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
s32 e1000e_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 *data)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
	return __e1000_read_kmrn_reg(hw, offset, data, true);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
 *  __e1000_write_kmrn_reg - Write kumeran register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
 *  @offset: register offset to write to
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
 *  @data: data to write at register offset
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
 *  @locked: semaphore has already been acquired or not
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
 *  Acquires semaphore, if necessary.  Then write the data to PHY register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
 *  at the offset using the kumeran interface.  Release any acquired semaphores
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
 *  before exiting.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
static s32 __e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
                                  bool locked)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
	u32 kmrnctrlsta;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
	if (!locked) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
		s32 ret_val = 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
		if (!hw->phy.ops.acquire)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
			return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
		ret_val = hw->phy.ops.acquire(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
	kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
		       E1000_KMRNCTRLSTA_OFFSET) | data;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
	ew32(KMRNCTRLSTA, kmrnctrlsta);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
	e1e_flush();
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
	udelay(2);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
	if (!locked)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
		hw->phy.ops.release(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
	return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
 *  e1000e_write_kmrn_reg -  Write kumeran register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
 *  @offset: register offset to write to
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
 *  @data: data to write at register offset
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
 *  Acquires semaphore then writes the data to the PHY register at the offset
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
 *  using the kumeran interface.  Release the acquired semaphore before exiting.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
	return __e1000_write_kmrn_reg(hw, offset, data, false);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
 *  e1000e_write_kmrn_reg_locked -  Write kumeran register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
 *  @offset: register offset to write to
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
 *  @data: data to write at register offset
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
 *  Write the data to PHY register at the offset using the kumeran interface.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
 *  Assumes semaphore already acquired.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
s32 e1000e_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 data)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
	return __e1000_write_kmrn_reg(hw, offset, data, true);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
 *  e1000_set_master_slave_mode - Setup PHY for Master/slave mode
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
 *  Sets up Master/slave mode
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
static s32 e1000_set_master_slave_mode(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
	u16 phy_data;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
	/* Resolve Master/Slave mode */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
	ret_val = e1e_rphy(hw, PHY_1000T_CTRL, &phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
	/* load defaults for future use */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
	hw->phy.original_ms_type = (phy_data & CR_1000T_MS_ENABLE) ?
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
	    ((phy_data & CR_1000T_MS_VALUE) ?
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
	     e1000_ms_force_master : e1000_ms_force_slave) : e1000_ms_auto;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
	switch (hw->phy.ms_type) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
	case e1000_ms_force_master:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
		phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
		break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
	case e1000_ms_force_slave:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
		phy_data |= CR_1000T_MS_ENABLE;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
		phy_data &= ~(CR_1000T_MS_VALUE);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
		break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
	case e1000_ms_auto:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
		phy_data &= ~CR_1000T_MS_ENABLE;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
		/* fall-through */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
	default:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
		break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
	return e1e_wphy(hw, PHY_1000T_CTRL, phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
 *  e1000_copper_link_setup_82577 - Setup 82577 PHY for copper link
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
 *  Sets up Carrier-sense on Transmit and downshift values.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
s32 e1000_copper_link_setup_82577(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
	u16 phy_data;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
	/* Enable CRS on Tx. This must be set for half-duplex operation. */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
	ret_val = e1e_rphy(hw, I82577_CFG_REG, &phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
	phy_data |= I82577_CFG_ASSERT_CRS_ON_TX;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
	/* Enable downshift */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
	phy_data |= I82577_CFG_ENABLE_DOWNSHIFT;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
	ret_val = e1e_wphy(hw, I82577_CFG_REG, phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
	return e1000_set_master_slave_mode(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
 *  e1000e_copper_link_setup_m88 - Setup m88 PHY's for copper link
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
 *  Sets up MDI/MDI-X and polarity for m88 PHY's.  If necessary, transmit clock
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
 *  and downshift values are set also.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
	struct e1000_phy_info *phy = &hw->phy;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
	u16 phy_data;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
	/* Enable CRS on Tx. This must be set for half-duplex operation. */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
	/* For BM PHY this bit is downshift enable */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
	if (phy->type != e1000_phy_bm)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
		phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
	/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
	 * Options:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
	 *   MDI/MDI-X = 0 (default)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
	 *   0 - Auto for all speeds
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
	 *   1 - MDI mode
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
	 *   2 - MDI-X mode
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
	 *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
	 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
	phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
	switch (phy->mdix) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
	case 1:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
		phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
		break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
	case 2:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
		phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
		break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
	case 3:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
		phy_data |= M88E1000_PSCR_AUTO_X_1000T;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
		break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
	case 0:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
	default:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
		phy_data |= M88E1000_PSCR_AUTO_X_MODE;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
		break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
	/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
	 * Options:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
	 *   disable_polarity_correction = 0 (default)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
	 *       Automatic Correction for Reversed Cable Polarity
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
	 *   0 - Disabled
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
	 *   1 - Enabled
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
	 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
	phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
	if (phy->disable_polarity_correction)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
		phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
	/* Enable downshift on BM (disabled by default) */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
	if (phy->type == e1000_phy_bm) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
		/* For 82574/82583, first disable then enable downshift */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
		if (phy->id == BME1000_E_PHY_ID_R2) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
			phy_data &= ~BME1000_PSCR_ENABLE_DOWNSHIFT;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
			ret_val = e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
					   phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
			if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
				return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
			/* Commit the changes. */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
			ret_val = e1000e_commit_phy(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
			if (ret_val) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
				e_dbg("Error committing the PHY changes\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
				return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
			}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
		}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
		phy_data |= BME1000_PSCR_ENABLE_DOWNSHIFT;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
	ret_val = e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
	if ((phy->type == e1000_phy_m88) &&
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
	    (phy->revision < E1000_REVISION_4) &&
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
	    (phy->id != BME1000_E_PHY_ID_R2)) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
		/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
		 * Force TX_CLK in the Extended PHY Specific Control Register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
		 * to 25MHz clock.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
		 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
		ret_val = e1e_rphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
		phy_data |= M88E1000_EPSCR_TX_CLK_25;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
		if ((phy->revision == 2) &&
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
		    (phy->id == M88E1111_I_PHY_ID)) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
			/* 82573L PHY - set the downshift counter to 5x. */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
			phy_data &= ~M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
			phy_data |= M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
		} else {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
			/* Configure Master and Slave downshift values */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
			phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
				      M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
			phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
				     M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
		}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
		ret_val = e1e_wphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
	if ((phy->type == e1000_phy_bm) && (phy->id == BME1000_E_PHY_ID_R2)) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
		/* Set PHY page 0, register 29 to 0x0003 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
		ret_val = e1e_wphy(hw, 29, 0x0003);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
		/* Set PHY page 0, register 30 to 0x0000 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
		ret_val = e1e_wphy(hw, 30, 0x0000);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
	/* Commit the changes. */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
	ret_val = e1000e_commit_phy(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
	if (ret_val) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
		e_dbg("Error committing the PHY changes\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
	if (phy->type == e1000_phy_82578) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
		ret_val = e1e_rphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
		/* 82578 PHY - set the downshift count to 1x. */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
		phy_data |= I82578_EPSCR_DOWNSHIFT_ENABLE;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
		phy_data &= ~I82578_EPSCR_DOWNSHIFT_COUNTER_MASK;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
		ret_val = e1e_wphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
	return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
 *  e1000e_copper_link_setup_igp - Setup igp PHY's for copper link
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
 *  Sets up LPLU, MDI/MDI-X, polarity, Smartspeed and Master/Slave config for
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
 *  igp PHY's.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
s32 e1000e_copper_link_setup_igp(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
	struct e1000_phy_info *phy = &hw->phy;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
	u16 data;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
	ret_val = e1000_phy_hw_reset(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
	if (ret_val) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
		e_dbg("Error resetting the PHY.\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
	/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
	 * Wait 100ms for MAC to configure PHY from NVM settings, to avoid
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
	 * timeout issues when LFS is enabled.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
	 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
	msleep(100);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
	/* disable lplu d0 during driver init */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
	ret_val = e1000_set_d0_lplu_state(hw, false);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
	if (ret_val) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
		e_dbg("Error Disabling LPLU D0\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
	/* Configure mdi-mdix settings */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
	ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CTRL, &data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
	data &= ~IGP01E1000_PSCR_AUTO_MDIX;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
	switch (phy->mdix) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
	case 1:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
		data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
		break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
	case 2:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
		data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
		break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
	case 0:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
	default:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
		data |= IGP01E1000_PSCR_AUTO_MDIX;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
		break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
	ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CTRL, data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
	/* set auto-master slave resolution settings */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
	if (hw->mac.autoneg) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
		/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
		 * when autonegotiation advertisement is only 1000Mbps then we
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
		 * should disable SmartSpeed and enable Auto MasterSlave
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
		 * resolution as hardware default.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
		 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
		if (phy->autoneg_advertised == ADVERTISE_1000_FULL) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
			/* Disable SmartSpeed */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
			ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
					   &data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
			if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
				return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
			data &= ~IGP01E1000_PSCFR_SMART_SPEED;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
			ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
					   data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
			if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
				return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
			/* Set auto Master/Slave resolution process */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
			ret_val = e1e_rphy(hw, PHY_1000T_CTRL, &data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
			if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
				return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
			data &= ~CR_1000T_MS_ENABLE;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
			ret_val = e1e_wphy(hw, PHY_1000T_CTRL, data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
			if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
				return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
		}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
		ret_val = e1000_set_master_slave_mode(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
 *  e1000_phy_setup_autoneg - Configure PHY for auto-negotiation
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
 *  Reads the MII auto-neg advertisement register and/or the 1000T control
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
 *  register and if the PHY is already setup for auto-negotiation, then
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
 *  return successful.  Otherwise, setup advertisement and flow control to
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
 *  the appropriate values for the wanted auto-negotiation.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
static s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
	struct e1000_phy_info *phy = &hw->phy;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
	u16 mii_autoneg_adv_reg;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
	u16 mii_1000t_ctrl_reg = 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
	phy->autoneg_advertised &= phy->autoneg_mask;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
	/* Read the MII Auto-Neg Advertisement Register (Address 4). */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
	ret_val = e1e_rphy(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
	if (phy->autoneg_mask & ADVERTISE_1000_FULL) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
		/* Read the MII 1000Base-T Control Register (Address 9). */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
		ret_val = e1e_rphy(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
	/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
	 * Need to parse both autoneg_advertised and fc and set up
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
	 * the appropriate PHY registers.  First we will parse for
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
	 * autoneg_advertised software override.  Since we can advertise
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
	 * a plethora of combinations, we need to check each bit
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
	 * individually.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
	 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
	/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
	 * First we clear all the 10/100 mb speed bits in the Auto-Neg
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
	 * Advertisement Register (Address 4) and the 1000 mb speed bits in
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
	 * the  1000Base-T Control Register (Address 9).
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
	 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
	mii_autoneg_adv_reg &= ~(NWAY_AR_100TX_FD_CAPS |
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
				 NWAY_AR_100TX_HD_CAPS |
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
				 NWAY_AR_10T_FD_CAPS   |
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
				 NWAY_AR_10T_HD_CAPS);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
	mii_1000t_ctrl_reg &= ~(CR_1000T_HD_CAPS | CR_1000T_FD_CAPS);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
	e_dbg("autoneg_advertised %x\n", phy->autoneg_advertised);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
	/* Do we want to advertise 10 Mb Half Duplex? */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
	if (phy->autoneg_advertised & ADVERTISE_10_HALF) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
		e_dbg("Advertise 10mb Half duplex\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
		mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
	/* Do we want to advertise 10 Mb Full Duplex? */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
	if (phy->autoneg_advertised & ADVERTISE_10_FULL) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
		e_dbg("Advertise 10mb Full duplex\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
		mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
	/* Do we want to advertise 100 Mb Half Duplex? */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
	if (phy->autoneg_advertised & ADVERTISE_100_HALF) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
		e_dbg("Advertise 100mb Half duplex\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
		mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
	/* Do we want to advertise 100 Mb Full Duplex? */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
	if (phy->autoneg_advertised & ADVERTISE_100_FULL) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
		e_dbg("Advertise 100mb Full duplex\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
		mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
	/* We do not allow the Phy to advertise 1000 Mb Half Duplex */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
	if (phy->autoneg_advertised & ADVERTISE_1000_HALF)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
		e_dbg("Advertise 1000mb Half duplex request denied!\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
	/* Do we want to advertise 1000 Mb Full Duplex? */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
	if (phy->autoneg_advertised & ADVERTISE_1000_FULL) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
		e_dbg("Advertise 1000mb Full duplex\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
		mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
	/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
	 * Check for a software override of the flow control settings, and
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
	 * setup the PHY advertisement registers accordingly.  If
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
	 * auto-negotiation is enabled, then software will have to set the
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
	 * "PAUSE" bits to the correct value in the Auto-Negotiation
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
	 * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto-
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
	 * negotiation.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
	 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
	 * The possible values of the "fc" parameter are:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
	 *      0:  Flow control is completely disabled
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
	 *      1:  Rx flow control is enabled (we can receive pause frames
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
	 *          but not send pause frames).
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
	 *      2:  Tx flow control is enabled (we can send pause frames
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
	 *          but we do not support receiving pause frames).
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
	 *      3:  Both Rx and Tx flow control (symmetric) are enabled.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
	 *  other:  No software override.  The flow control configuration
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
	 *          in the EEPROM is used.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
	 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
	switch (hw->fc.current_mode) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
	case e1000_fc_none:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
		/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
		 * Flow control (Rx & Tx) is completely disabled by a
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
		 * software over-ride.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
		 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
		mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
		break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
	case e1000_fc_rx_pause:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
		/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
		 * Rx Flow control is enabled, and Tx Flow control is
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
		 * disabled, by a software over-ride.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
		 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
		 * Since there really isn't a way to advertise that we are
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
		 * capable of Rx Pause ONLY, we will advertise that we
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
		 * support both symmetric and asymmetric Rx PAUSE.  Later
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
		 * (in e1000e_config_fc_after_link_up) we will disable the
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
		 * hw's ability to send PAUSE frames.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
		 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
		break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
	case e1000_fc_tx_pause:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
		/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
		 * Tx Flow control is enabled, and Rx Flow control is
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
		 * disabled, by a software over-ride.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
		 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
		mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
		mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
		break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
	case e1000_fc_full:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
		/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
		 * Flow control (both Rx and Tx) is enabled by a software
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
		 * over-ride.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
		 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
		break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
	default:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
		e_dbg("Flow control param set incorrectly\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
		return -E1000_ERR_CONFIG;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
	ret_val = e1e_wphy(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
	e_dbg("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
	if (phy->autoneg_mask & ADVERTISE_1000_FULL)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
		ret_val = e1e_wphy(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
 *  e1000_copper_link_autoneg - Setup/Enable autoneg for copper link
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
 *  Performs initial bounds checking on autoneg advertisement parameter, then
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
 *  configure to advertise the full capability.  Setup the PHY to autoneg
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
 *  and restart the negotiation process between the link partner.  If
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
 *  autoneg_wait_to_complete, then wait for autoneg to complete before exiting.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
static s32 e1000_copper_link_autoneg(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
	struct e1000_phy_info *phy = &hw->phy;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
	u16 phy_ctrl;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
	/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
	 * Perform some bounds checking on the autoneg advertisement
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
	 * parameter.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
	 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
	phy->autoneg_advertised &= phy->autoneg_mask;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
	/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
	 * If autoneg_advertised is zero, we assume it was not defaulted
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
	 * by the calling code so we set to advertise full capability.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
	 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
	if (!phy->autoneg_advertised)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
		phy->autoneg_advertised = phy->autoneg_mask;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
	e_dbg("Reconfiguring auto-neg advertisement params\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
	ret_val = e1000_phy_setup_autoneg(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
	if (ret_val) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
		e_dbg("Error Setting up Auto-Negotiation\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
	e_dbg("Restarting Auto-Neg\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
	/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
	 * Restart auto-negotiation by setting the Auto Neg Enable bit and
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
	 * the Auto Neg Restart bit in the PHY control register.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
	 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
	ret_val = e1e_rphy(hw, PHY_CONTROL, &phy_ctrl);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
	phy_ctrl |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
	ret_val = e1e_wphy(hw, PHY_CONTROL, phy_ctrl);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
	/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
	 * Does the user want to wait for Auto-Neg to complete here, or
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
	 * check at a later time (for example, callback routine).
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
	 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
	if (phy->autoneg_wait_to_complete) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
		ret_val = e1000_wait_autoneg(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
		if (ret_val) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
			e_dbg("Error while waiting for autoneg to complete\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
		}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
	hw->mac.get_link_status = true;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
 *  e1000e_setup_copper_link - Configure copper link settings
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
 *  Calls the appropriate function to configure the link for auto-neg or forced
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
 *  speed and duplex.  Then we check for link, once link is established calls
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
 *  to configure collision distance and flow control are called.  If link is
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
 *  not established, we return -E1000_ERR_PHY (-2).
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
s32 e1000e_setup_copper_link(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
	bool link;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
	if (hw->mac.autoneg) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
		/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
		 * Setup autoneg and flow control advertisement and perform
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
		 * autonegotiation.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
		 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
		ret_val = e1000_copper_link_autoneg(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
	} else {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
		/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
		 * PHY will be set to 10H, 10F, 100H or 100F
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
		 * depending on user settings.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
		 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
		e_dbg("Forcing Speed and Duplex\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
		ret_val = e1000_phy_force_speed_duplex(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
		if (ret_val) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
			e_dbg("Error Forcing Speed and Duplex\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
		}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
	/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
	 * Check link status. Wait up to 100 microseconds for link to become
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
	 * valid.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
	 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
	ret_val = e1000e_phy_has_link_generic(hw, COPPER_LINK_UP_LIMIT, 10,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
					      &link);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
	if (link) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
		e_dbg("Valid link established!!!\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
		hw->mac.ops.config_collision_dist(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
		ret_val = e1000e_config_fc_after_link_up(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
	} else {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
		e_dbg("Unable to establish link!!!\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
 *  e1000e_phy_force_speed_duplex_igp - Force speed/duplex for igp PHY
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
 *  Calls the PHY setup function to force speed and duplex.  Clears the
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
 *  auto-crossover to force MDI manually.  Waits for link and returns
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
 *  successful if link up is successful, else -E1000_ERR_PHY (-2).
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
s32 e1000e_phy_force_speed_duplex_igp(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
	struct e1000_phy_info *phy = &hw->phy;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
	u16 phy_data;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
	bool link;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
	ret_val = e1e_rphy(hw, PHY_CONTROL, &phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
	e1000e_phy_force_speed_duplex_setup(hw, &phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
	ret_val = e1e_wphy(hw, PHY_CONTROL, phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
	/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
	 * Clear Auto-Crossover to force MDI manually.  IGP requires MDI
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
	 * forced whenever speed and duplex are forced.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
	 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
	ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
	phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
	phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
	ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
	e_dbg("IGP PSCR: %X\n", phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
	udelay(1);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
	if (phy->autoneg_wait_to_complete) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
		e_dbg("Waiting for forced speed/duplex link on IGP phy.\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
		ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
						      100000, &link);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
		if (!link)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
			e_dbg("Link taking longer than expected.\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
		/* Try once more */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
		ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
						      100000, &link);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
 *  e1000e_phy_force_speed_duplex_m88 - Force speed/duplex for m88 PHY
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
 *  Calls the PHY setup function to force speed and duplex.  Clears the
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
 *  auto-crossover to force MDI manually.  Resets the PHY to commit the
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
 *  changes.  If time expires while waiting for link up, we reset the DSP.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
 *  After reset, TX_CLK and CRS on Tx must be set.  Return successful upon
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
 *  successful completion, else return corresponding error code.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
	struct e1000_phy_info *phy = &hw->phy;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
	u16 phy_data;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
	bool link;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
	/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
	 * Clear Auto-Crossover to force MDI manually.  M88E1000 requires MDI
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
	 * forced whenever speed and duplex are forced.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
	 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
	phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
	ret_val = e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
	e_dbg("M88E1000 PSCR: %X\n", phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
	ret_val = e1e_rphy(hw, PHY_CONTROL, &phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
	e1000e_phy_force_speed_duplex_setup(hw, &phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
	ret_val = e1e_wphy(hw, PHY_CONTROL, phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
	/* Reset the phy to commit changes. */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
	ret_val = e1000e_commit_phy(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
	if (phy->autoneg_wait_to_complete) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
		e_dbg("Waiting for forced speed/duplex link on M88 phy.\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
		ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
						     100000, &link);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
		if (!link) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
			if (hw->phy.type != e1000_phy_m88) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
				e_dbg("Link taking longer than expected.\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
			} else {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
				/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
				 * We didn't get link.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
				 * Reset the DSP and cross our fingers.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
				 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
				ret_val = e1e_wphy(hw, M88E1000_PHY_PAGE_SELECT,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
						   0x001d);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
				if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
					return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
				ret_val = e1000e_phy_reset_dsp(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
				if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
					return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
			}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
		}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
		/* Try once more */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
		ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
						     100000, &link);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
	if (hw->phy.type != e1000_phy_m88)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
		return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
	ret_val = e1e_rphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
	/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
	 * Resetting the phy means we need to re-force TX_CLK in the
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
	 * Extended PHY Specific Control Register to 25MHz clock from
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
	 * the reset value of 2.5MHz.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
	 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
	phy_data |= M88E1000_EPSCR_TX_CLK_25;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
	ret_val = e1e_wphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
	/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
	 * In addition, we must re-enable CRS on Tx for both half and full
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
	 * duplex.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
	 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
	phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
	ret_val = e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
 *  e1000_phy_force_speed_duplex_ife - Force PHY speed & duplex
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
 *  Forces the speed and duplex settings of the PHY.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
 *  This is a function pointer entry point only called by
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
 *  PHY setup routines.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
s32 e1000_phy_force_speed_duplex_ife(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
	struct e1000_phy_info *phy = &hw->phy;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
	u16 data;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
	bool link;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
	ret_val = e1e_rphy(hw, PHY_CONTROL, &data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
	e1000e_phy_force_speed_duplex_setup(hw, &data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
	ret_val = e1e_wphy(hw, PHY_CONTROL, data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
	/* Disable MDI-X support for 10/100 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
	ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, &data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
	data &= ~IFE_PMC_AUTO_MDIX;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
	data &= ~IFE_PMC_FORCE_MDIX;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
	ret_val = e1e_wphy(hw, IFE_PHY_MDIX_CONTROL, data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
	e_dbg("IFE PMC: %X\n", data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
	udelay(1);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
	if (phy->autoneg_wait_to_complete) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
		e_dbg("Waiting for forced speed/duplex link on IFE phy.\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
		ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
						      100000, &link);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
		if (!link)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
			e_dbg("Link taking longer than expected.\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
		/* Try once more */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
		ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
						      100000, &link);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
	return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
 *  e1000e_phy_force_speed_duplex_setup - Configure forced PHY speed/duplex
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
 *  @phy_ctrl: pointer to current value of PHY_CONTROL
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
 *  Forces speed and duplex on the PHY by doing the following: disable flow
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
 *  control, force speed/duplex on the MAC, disable auto speed detection,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
 *  disable auto-negotiation, configure duplex, configure speed, configure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
 *  the collision distance, write configuration to CTRL register.  The
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
 *  caller must write to the PHY_CONTROL register for these settings to
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
 *  take affect.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
void e1000e_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
	struct e1000_mac_info *mac = &hw->mac;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
	u32 ctrl;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
	/* Turn off flow control when forcing speed/duplex */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
	hw->fc.current_mode = e1000_fc_none;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
	/* Force speed/duplex on the mac */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
	ctrl = er32(CTRL);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
	ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
	ctrl &= ~E1000_CTRL_SPD_SEL;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
	/* Disable Auto Speed Detection */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
	ctrl &= ~E1000_CTRL_ASDE;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
	/* Disable autoneg on the phy */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
	*phy_ctrl &= ~MII_CR_AUTO_NEG_EN;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
	/* Forcing Full or Half Duplex? */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
	if (mac->forced_speed_duplex & E1000_ALL_HALF_DUPLEX) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
		ctrl &= ~E1000_CTRL_FD;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
		*phy_ctrl &= ~MII_CR_FULL_DUPLEX;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
		e_dbg("Half Duplex\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
	} else {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
		ctrl |= E1000_CTRL_FD;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
		*phy_ctrl |= MII_CR_FULL_DUPLEX;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
		e_dbg("Full Duplex\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
	/* Forcing 10mb or 100mb? */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
	if (mac->forced_speed_duplex & E1000_ALL_100_SPEED) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
		ctrl |= E1000_CTRL_SPD_100;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
		*phy_ctrl |= MII_CR_SPEED_100;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
		*phy_ctrl &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_10);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
		e_dbg("Forcing 100mb\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
	} else {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
		ctrl &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
		*phy_ctrl |= MII_CR_SPEED_10;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
		*phy_ctrl &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_100);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
		e_dbg("Forcing 10mb\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
	hw->mac.ops.config_collision_dist(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
	ew32(CTRL, ctrl);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
 *  e1000e_set_d3_lplu_state - Sets low power link up state for D3
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
 *  @active: boolean used to enable/disable lplu
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
 *  Success returns 0, Failure returns 1
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
 *  The low power link up (lplu) state is set to the power management level D3
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
 *  and SmartSpeed is disabled when active is true, else clear lplu for D3
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
 *  and enable Smartspeed.  LPLU and Smartspeed are mutually exclusive.  LPLU
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
 *  is used during Dx states where the power conservation is most important.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
 *  During driver activity, SmartSpeed should be enabled so performance is
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
 *  maintained.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
s32 e1000e_set_d3_lplu_state(struct e1000_hw *hw, bool active)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
	struct e1000_phy_info *phy = &hw->phy;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
	u16 data;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
	ret_val = e1e_rphy(hw, IGP02E1000_PHY_POWER_MGMT, &data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
	if (!active) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
		data &= ~IGP02E1000_PM_D3_LPLU;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
		ret_val = e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
		/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
		 * LPLU and SmartSpeed are mutually exclusive.  LPLU is used
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
		 * during Dx states where the power conservation is most
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
		 * important.  During driver activity we should enable
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
		 * SmartSpeed, so performance is maintained.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
		 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
		if (phy->smart_speed == e1000_smart_speed_on) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
			ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
					   &data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
			if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
				return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
			data |= IGP01E1000_PSCFR_SMART_SPEED;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
			ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
					   data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
			if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
				return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
		} else if (phy->smart_speed == e1000_smart_speed_off) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
			ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
					   &data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
			if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
				return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
			data &= ~IGP01E1000_PSCFR_SMART_SPEED;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
			ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
					   data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
			if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
				return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
		}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
	} else if ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) ||
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
		   (phy->autoneg_advertised == E1000_ALL_NOT_GIG) ||
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
		   (phy->autoneg_advertised == E1000_ALL_10_SPEED)) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
		data |= IGP02E1000_PM_D3_LPLU;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
		ret_val = e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
		/* When LPLU is enabled, we should disable SmartSpeed */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
		ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG, &data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
		data &= ~IGP01E1000_PSCFR_SMART_SPEED;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
		ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG, data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
 *  e1000e_check_downshift - Checks whether a downshift in speed occurred
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
 *  Success returns 0, Failure returns 1
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
 *  A downshift is detected by querying the PHY link health.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
s32 e1000e_check_downshift(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
	struct e1000_phy_info *phy = &hw->phy;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
	u16 phy_data, offset, mask;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
	switch (phy->type) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
	case e1000_phy_m88:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
	case e1000_phy_gg82563:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
	case e1000_phy_bm:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
	case e1000_phy_82578:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
		offset	= M88E1000_PHY_SPEC_STATUS;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
		mask	= M88E1000_PSSR_DOWNSHIFT;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
		break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
	case e1000_phy_igp_2:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
	case e1000_phy_igp_3:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
		offset	= IGP01E1000_PHY_LINK_HEALTH;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
		mask	= IGP01E1000_PLHR_SS_DOWNGRADE;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
		break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
	default:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
		/* speed downshift not supported */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
		phy->speed_downgraded = false;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
		return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
	ret_val = e1e_rphy(hw, offset, &phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
	if (!ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
		phy->speed_downgraded = !!(phy_data & mask);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
 *  e1000_check_polarity_m88 - Checks the polarity.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
 *  Success returns 0, Failure returns -E1000_ERR_PHY (-2)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
 *  Polarity is determined based on the PHY specific status register.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
s32 e1000_check_polarity_m88(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
	struct e1000_phy_info *phy = &hw->phy;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
	u16 data;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_STATUS, &data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
	if (!ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
		phy->cable_polarity = (data & M88E1000_PSSR_REV_POLARITY)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
				      ? e1000_rev_polarity_reversed
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
				      : e1000_rev_polarity_normal;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
 *  e1000_check_polarity_igp - Checks the polarity.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
 *  Success returns 0, Failure returns -E1000_ERR_PHY (-2)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
 *  Polarity is determined based on the PHY port status register, and the
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
 *  current speed (since there is no polarity at 100Mbps).
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
s32 e1000_check_polarity_igp(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
	struct e1000_phy_info *phy = &hw->phy;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
	u16 data, offset, mask;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
	/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
	 * Polarity is determined based on the speed of
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
	 * our connection.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
	 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
	ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_STATUS, &data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
	if ((data & IGP01E1000_PSSR_SPEED_MASK) ==
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
	    IGP01E1000_PSSR_SPEED_1000MBPS) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
		offset	= IGP01E1000_PHY_PCS_INIT_REG;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
		mask	= IGP01E1000_PHY_POLARITY_MASK;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
	} else {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
		/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
		 * This really only applies to 10Mbps since
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
		 * there is no polarity for 100Mbps (always 0).
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
		 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
		offset	= IGP01E1000_PHY_PORT_STATUS;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
		mask	= IGP01E1000_PSSR_POLARITY_REVERSED;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
	ret_val = e1e_rphy(hw, offset, &data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
	if (!ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
		phy->cable_polarity = (data & mask)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
				      ? e1000_rev_polarity_reversed
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
				      : e1000_rev_polarity_normal;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
 *  e1000_check_polarity_ife - Check cable polarity for IFE PHY
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
 *  Polarity is determined on the polarity reversal feature being enabled.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
s32 e1000_check_polarity_ife(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
	struct e1000_phy_info *phy = &hw->phy;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
	u16 phy_data, offset, mask;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
	/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
	 * Polarity is determined based on the reversal feature being enabled.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
	 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
	if (phy->polarity_correction) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
		offset = IFE_PHY_EXTENDED_STATUS_CONTROL;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
		mask = IFE_PESC_POLARITY_REVERSED;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
	} else {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
		offset = IFE_PHY_SPECIAL_CONTROL;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
		mask = IFE_PSC_FORCE_POLARITY;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
	ret_val = e1e_rphy(hw, offset, &phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
	if (!ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
		phy->cable_polarity = (phy_data & mask)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
		                       ? e1000_rev_polarity_reversed
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
		                       : e1000_rev_polarity_normal;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
 *  e1000_wait_autoneg - Wait for auto-neg completion
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
 *  Waits for auto-negotiation to complete or for the auto-negotiation time
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
 *  limit to expire, which ever happens first.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
static s32 e1000_wait_autoneg(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
	s32 ret_val = 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
	u16 i, phy_status;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
	/* Break after autoneg completes or PHY_AUTO_NEG_LIMIT expires. */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
	for (i = PHY_AUTO_NEG_LIMIT; i > 0; i--) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
		ret_val = e1e_rphy(hw, PHY_STATUS, &phy_status);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
			break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
		ret_val = e1e_rphy(hw, PHY_STATUS, &phy_status);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
			break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
		if (phy_status & MII_SR_AUTONEG_COMPLETE)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
			break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
		msleep(100);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
	/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
	 * PHY_AUTO_NEG_TIME expiration doesn't guarantee auto-negotiation
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
	 * has completed.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
	 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
 *  e1000e_phy_has_link_generic - Polls PHY for link
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
 *  @iterations: number of times to poll for link
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
 *  @usec_interval: delay between polling attempts
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
 *  @success: pointer to whether polling was successful or not
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
 *  Polls the PHY status register for link, 'iterations' number of times.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
			       u32 usec_interval, bool *success)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
	s32 ret_val = 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
	u16 i, phy_status;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
	for (i = 0; i < iterations; i++) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
		/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
		 * Some PHYs require the PHY_STATUS register to be read
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
		 * twice due to the link bit being sticky.  No harm doing
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
		 * it across the board.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
		 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
		ret_val = e1e_rphy(hw, PHY_STATUS, &phy_status);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
			/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
			 * If the first read fails, another entity may have
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
			 * ownership of the resources, wait and try again to
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
			 * see if they have relinquished the resources yet.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
			 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
			udelay(usec_interval);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
		ret_val = e1e_rphy(hw, PHY_STATUS, &phy_status);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
			break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
		if (phy_status & MII_SR_LINK_STATUS)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
			break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
		if (usec_interval >= 1000)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
			mdelay(usec_interval/1000);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
		else
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
			udelay(usec_interval);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
	*success = (i < iterations);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
 *  e1000e_get_cable_length_m88 - Determine cable length for m88 PHY
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
 *  Reads the PHY specific status register to retrieve the cable length
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
 *  information.  The cable length is determined by averaging the minimum and
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
 *  maximum values to get the "average" cable length.  The m88 PHY has four
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
 *  possible cable length values, which are:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
 *	Register Value		Cable Length
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
 *	0			< 50 meters
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
 *	1			50 - 80 meters
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
 *	2			80 - 110 meters
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
 *	3			110 - 140 meters
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
 *	4			> 140 meters
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
s32 e1000e_get_cable_length_m88(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
	struct e1000_phy_info *phy = &hw->phy;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
	u16 phy_data, index;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
	index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
	        M88E1000_PSSR_CABLE_LENGTH_SHIFT;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
	if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
		return -E1000_ERR_PHY;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
	phy->min_cable_length = e1000_m88_cable_length_table[index];
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
	phy->max_cable_length = e1000_m88_cable_length_table[index + 1];
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
	phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
	return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
 *  e1000e_get_cable_length_igp_2 - Determine cable length for igp2 PHY
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
 *  The automatic gain control (agc) normalizes the amplitude of the
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
 *  received signal, adjusting for the attenuation produced by the
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
 *  cable.  By reading the AGC registers, which represent the
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
 *  combination of coarse and fine gain value, the value can be put
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
 *  into a lookup table to obtain the approximate cable length
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
 *  for each channel.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
s32 e1000e_get_cable_length_igp_2(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
	struct e1000_phy_info *phy = &hw->phy;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
	u16 phy_data, i, agc_value = 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
	u16 cur_agc_index, max_agc_index = 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
	u16 min_agc_index = IGP02E1000_CABLE_LENGTH_TABLE_SIZE - 1;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
	static const u16 agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] = {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
	       IGP02E1000_PHY_AGC_A,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
	       IGP02E1000_PHY_AGC_B,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
	       IGP02E1000_PHY_AGC_C,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
	       IGP02E1000_PHY_AGC_D
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
	};
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
	/* Read the AGC registers for all channels */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
	for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
		ret_val = e1e_rphy(hw, agc_reg_array[i], &phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
		/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
		 * Getting bits 15:9, which represent the combination of
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
		 * coarse and fine gain values.  The result is a number
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
		 * that can be put into the lookup table to obtain the
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
		 * approximate cable length.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
		 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
		cur_agc_index = (phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) &
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
				IGP02E1000_AGC_LENGTH_MASK;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
		/* Array index bound check. */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
		if ((cur_agc_index >= IGP02E1000_CABLE_LENGTH_TABLE_SIZE) ||
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
		    (cur_agc_index == 0))
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
			return -E1000_ERR_PHY;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
		/* Remove min & max AGC values from calculation. */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
		if (e1000_igp_2_cable_length_table[min_agc_index] >
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
		    e1000_igp_2_cable_length_table[cur_agc_index])
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
			min_agc_index = cur_agc_index;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
		if (e1000_igp_2_cable_length_table[max_agc_index] <
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
		    e1000_igp_2_cable_length_table[cur_agc_index])
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
			max_agc_index = cur_agc_index;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
		agc_value += e1000_igp_2_cable_length_table[cur_agc_index];
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
	agc_value -= (e1000_igp_2_cable_length_table[min_agc_index] +
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
		      e1000_igp_2_cable_length_table[max_agc_index]);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
	agc_value /= (IGP02E1000_PHY_CHANNEL_NUM - 2);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
	/* Calculate cable length with the error range of +/- 10 meters. */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
	phy->min_cable_length = ((agc_value - IGP02E1000_AGC_RANGE) > 0) ?
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
				 (agc_value - IGP02E1000_AGC_RANGE) : 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
	phy->max_cable_length = agc_value + IGP02E1000_AGC_RANGE;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
	phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
	return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
 *  e1000e_get_phy_info_m88 - Retrieve PHY information
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
 *  Valid for only copper links.  Read the PHY status register (sticky read)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
 *  to verify that link is up.  Read the PHY special control register to
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
 *  determine the polarity and 10base-T extended distance.  Read the PHY
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
 *  special status register to determine MDI/MDIx and current speed.  If
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
 *  speed is 1000, then determine cable length, local and remote receiver.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
s32 e1000e_get_phy_info_m88(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
	struct e1000_phy_info *phy = &hw->phy;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
	s32  ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
	u16 phy_data;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
	bool link;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
	if (phy->media_type != e1000_media_type_copper) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
		e_dbg("Phy info is only valid for copper media\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
		return -E1000_ERR_CONFIG;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
	ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
	if (!link) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
		e_dbg("Phy info is only valid if link is up\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
		return -E1000_ERR_CONFIG;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
	phy->polarity_correction = !!(phy_data &
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
				      M88E1000_PSCR_POLARITY_REVERSAL);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
	ret_val = e1000_check_polarity_m88(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
	phy->is_mdix = !!(phy_data & M88E1000_PSSR_MDIX);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
	if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
		ret_val = e1000_get_cable_length(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
		ret_val = e1e_rphy(hw, PHY_1000T_STATUS, &phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
		phy->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
				? e1000_1000t_rx_status_ok
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
				: e1000_1000t_rx_status_not_ok;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
		phy->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
				 ? e1000_1000t_rx_status_ok
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
				 : e1000_1000t_rx_status_not_ok;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
	} else {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
		/* Set values to "undefined" */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
		phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
		phy->local_rx = e1000_1000t_rx_status_undefined;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
		phy->remote_rx = e1000_1000t_rx_status_undefined;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
 *  e1000e_get_phy_info_igp - Retrieve igp PHY information
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
 *  Read PHY status to determine if link is up.  If link is up, then
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
 *  set/determine 10base-T extended distance and polarity correction.  Read
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
 *  PHY port status to determine MDI/MDIx and speed.  Based on the speed,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
 *  determine on the cable length, local and remote receiver.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
s32 e1000e_get_phy_info_igp(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
	struct e1000_phy_info *phy = &hw->phy;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
	u16 data;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
	bool link;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
	ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
	if (!link) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
		e_dbg("Phy info is only valid if link is up\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
		return -E1000_ERR_CONFIG;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
	phy->polarity_correction = true;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
	ret_val = e1000_check_polarity_igp(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
	ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_STATUS, &data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
	phy->is_mdix = !!(data & IGP01E1000_PSSR_MDIX);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
	if ((data & IGP01E1000_PSSR_SPEED_MASK) ==
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
	    IGP01E1000_PSSR_SPEED_1000MBPS) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
		ret_val = e1000_get_cable_length(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
		ret_val = e1e_rphy(hw, PHY_1000T_STATUS, &data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
		phy->local_rx = (data & SR_1000T_LOCAL_RX_STATUS)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
				? e1000_1000t_rx_status_ok
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
				: e1000_1000t_rx_status_not_ok;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
		phy->remote_rx = (data & SR_1000T_REMOTE_RX_STATUS)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
				 ? e1000_1000t_rx_status_ok
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
				 : e1000_1000t_rx_status_not_ok;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
	} else {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
		phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
		phy->local_rx = e1000_1000t_rx_status_undefined;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
		phy->remote_rx = e1000_1000t_rx_status_undefined;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
 *  e1000_get_phy_info_ife - Retrieves various IFE PHY states
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
 *  Populates "phy" structure with various feature states.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
s32 e1000_get_phy_info_ife(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
	struct e1000_phy_info *phy = &hw->phy;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
	u16 data;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
	bool link;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
	ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
	if (!link) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
		e_dbg("Phy info is only valid if link is up\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
		return -E1000_ERR_CONFIG;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
	ret_val = e1e_rphy(hw, IFE_PHY_SPECIAL_CONTROL, &data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
	phy->polarity_correction = !(data & IFE_PSC_AUTO_POLARITY_DISABLE);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
	if (phy->polarity_correction) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
		ret_val = e1000_check_polarity_ife(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
	} else {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
		/* Polarity is forced */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
		phy->cable_polarity = (data & IFE_PSC_FORCE_POLARITY)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
		                      ? e1000_rev_polarity_reversed
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
		                      : e1000_rev_polarity_normal;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
	ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, &data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
	phy->is_mdix = !!(data & IFE_PMC_MDIX_STATUS);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
	/* The following parameters are undefined for 10/100 operation. */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
	phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
	phy->local_rx = e1000_1000t_rx_status_undefined;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
	phy->remote_rx = e1000_1000t_rx_status_undefined;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
	return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
 *  e1000e_phy_sw_reset - PHY software reset
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
 *  Does a software reset of the PHY by reading the PHY control register and
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
 *  setting/write the control register reset bit to the PHY.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
s32 e1000e_phy_sw_reset(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
	u16 phy_ctrl;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
	ret_val = e1e_rphy(hw, PHY_CONTROL, &phy_ctrl);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
	phy_ctrl |= MII_CR_RESET;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
	ret_val = e1e_wphy(hw, PHY_CONTROL, phy_ctrl);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
	udelay(1);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
 *  e1000e_phy_hw_reset_generic - PHY hardware reset
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
 *  Verify the reset block is not blocking us from resetting.  Acquire
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
 *  semaphore (if necessary) and read/set/write the device control reset
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
 *  bit in the PHY.  Wait the appropriate delay time for the device to
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
 *  reset and release the semaphore (if necessary).
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
s32 e1000e_phy_hw_reset_generic(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
	struct e1000_phy_info *phy = &hw->phy;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
	u32 ctrl;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
	if (phy->ops.check_reset_block) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
		ret_val = phy->ops.check_reset_block(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
			return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
	ret_val = phy->ops.acquire(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
	ctrl = er32(CTRL);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
	ew32(CTRL, ctrl | E1000_CTRL_PHY_RST);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
	e1e_flush();
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
	udelay(phy->reset_delay_us);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
	ew32(CTRL, ctrl);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
	e1e_flush();
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
	udelay(150);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
	phy->ops.release(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
	return e1000_get_phy_cfg_done(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
 *  e1000e_get_cfg_done - Generic configuration done
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
 *  Generic function to wait 10 milli-seconds for configuration to complete
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
 *  and return success.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
s32 e1000e_get_cfg_done(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
	mdelay(10);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
	return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
 *  e1000e_phy_init_script_igp3 - Inits the IGP3 PHY
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
 *  Initializes a Intel Gigabit PHY3 when an EEPROM is not present.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
s32 e1000e_phy_init_script_igp3(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
	e_dbg("Running IGP 3 PHY init script\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
	/* PHY init IGP 3 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
	/* Enable rise/fall, 10-mode work in class-A */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
	e1e_wphy(hw, 0x2F5B, 0x9018);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
	/* Remove all caps from Replica path filter */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
	e1e_wphy(hw, 0x2F52, 0x0000);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
	/* Bias trimming for ADC, AFE and Driver (Default) */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
	e1e_wphy(hw, 0x2FB1, 0x8B24);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
	/* Increase Hybrid poly bias */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
	e1e_wphy(hw, 0x2FB2, 0xF8F0);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
	/* Add 4% to Tx amplitude in Gig mode */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
	e1e_wphy(hw, 0x2010, 0x10B0);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
	/* Disable trimming (TTT) */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
	e1e_wphy(hw, 0x2011, 0x0000);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
	/* Poly DC correction to 94.6% + 2% for all channels */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
	e1e_wphy(hw, 0x20DD, 0x249A);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
	/* ABS DC correction to 95.9% */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
	e1e_wphy(hw, 0x20DE, 0x00D3);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
	/* BG temp curve trim */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
	e1e_wphy(hw, 0x28B4, 0x04CE);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
	/* Increasing ADC OPAMP stage 1 currents to max */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
	e1e_wphy(hw, 0x2F70, 0x29E4);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
	/* Force 1000 ( required for enabling PHY regs configuration) */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
	e1e_wphy(hw, 0x0000, 0x0140);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
	/* Set upd_freq to 6 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
	e1e_wphy(hw, 0x1F30, 0x1606);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
	/* Disable NPDFE */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
	e1e_wphy(hw, 0x1F31, 0xB814);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
	/* Disable adaptive fixed FFE (Default) */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
	e1e_wphy(hw, 0x1F35, 0x002A);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
	/* Enable FFE hysteresis */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
	e1e_wphy(hw, 0x1F3E, 0x0067);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
	/* Fixed FFE for short cable lengths */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
	e1e_wphy(hw, 0x1F54, 0x0065);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
	/* Fixed FFE for medium cable lengths */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
	e1e_wphy(hw, 0x1F55, 0x002A);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
	/* Fixed FFE for long cable lengths */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
	e1e_wphy(hw, 0x1F56, 0x002A);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
	/* Enable Adaptive Clip Threshold */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
	e1e_wphy(hw, 0x1F72, 0x3FB0);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
	/* AHT reset limit to 1 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
	e1e_wphy(hw, 0x1F76, 0xC0FF);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
	/* Set AHT master delay to 127 msec */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
	e1e_wphy(hw, 0x1F77, 0x1DEC);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
	/* Set scan bits for AHT */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
	e1e_wphy(hw, 0x1F78, 0xF9EF);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
	/* Set AHT Preset bits */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
	e1e_wphy(hw, 0x1F79, 0x0210);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
	/* Change integ_factor of channel A to 3 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
	e1e_wphy(hw, 0x1895, 0x0003);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
	/* Change prop_factor of channels BCD to 8 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
	e1e_wphy(hw, 0x1796, 0x0008);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
	/* Change cg_icount + enable integbp for channels BCD */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
	e1e_wphy(hw, 0x1798, 0xD008);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
	/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
	 * Change cg_icount + enable integbp + change prop_factor_master
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
	 * to 8 for channel A
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
	 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
	e1e_wphy(hw, 0x1898, 0xD918);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
	/* Disable AHT in Slave mode on channel A */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
	e1e_wphy(hw, 0x187A, 0x0800);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
	/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
	 * Enable LPLU and disable AN to 1000 in non-D0a states,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
	 * Enable SPD+B2B
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
	 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
	e1e_wphy(hw, 0x0019, 0x008D);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
	/* Enable restart AN on an1000_dis change */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
	e1e_wphy(hw, 0x001B, 0x2080);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
	/* Enable wh_fifo read clock in 10/100 modes */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
	e1e_wphy(hw, 0x0014, 0x0045);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
	/* Restart AN, Speed selection is 1000 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
	e1e_wphy(hw, 0x0000, 0x1340);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
	return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
/* Internal function pointers */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
 *  e1000_get_phy_cfg_done - Generic PHY configuration done
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
 *  Return success if silicon family did not implement a family specific
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
 *  get_cfg_done function.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
	if (hw->phy.ops.get_cfg_done)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
		return hw->phy.ops.get_cfg_done(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
	return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
 *  e1000_phy_force_speed_duplex - Generic force PHY speed/duplex
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
 *  When the silicon family has not implemented a forced speed/duplex
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
 *  function for the PHY, simply return 0.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
	if (hw->phy.ops.force_speed_duplex)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
		return hw->phy.ops.force_speed_duplex(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
	return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
 *  e1000e_get_phy_type_from_id - Get PHY type from id
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
 *  @phy_id: phy_id read from the phy
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
 *  Returns the phy type from the id.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
	enum e1000_phy_type phy_type = e1000_phy_unknown;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
	switch (phy_id) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
	case M88E1000_I_PHY_ID:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
	case M88E1000_E_PHY_ID:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
	case M88E1111_I_PHY_ID:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
	case M88E1011_I_PHY_ID:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
		phy_type = e1000_phy_m88;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
		break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
	case IGP01E1000_I_PHY_ID: /* IGP 1 & 2 share this */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
		phy_type = e1000_phy_igp_2;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
		break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
	case GG82563_E_PHY_ID:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
		phy_type = e1000_phy_gg82563;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
		break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
	case IGP03E1000_E_PHY_ID:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
		phy_type = e1000_phy_igp_3;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
		break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
	case IFE_E_PHY_ID:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
	case IFE_PLUS_E_PHY_ID:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
	case IFE_C_E_PHY_ID:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
		phy_type = e1000_phy_ife;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
		break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
	case BME1000_E_PHY_ID:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
	case BME1000_E_PHY_ID_R2:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
		phy_type = e1000_phy_bm;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
		break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
	case I82578_E_PHY_ID:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
		phy_type = e1000_phy_82578;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
		break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
	case I82577_E_PHY_ID:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
		phy_type = e1000_phy_82577;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
		break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
	case I82579_E_PHY_ID:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
		phy_type = e1000_phy_82579;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
		break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
	case I217_E_PHY_ID:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
		phy_type = e1000_phy_i217;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
		break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
	default:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
		phy_type = e1000_phy_unknown;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
		break;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
	return phy_type;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
 *  e1000e_determine_phy_address - Determines PHY address.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
 *  This uses a trial and error method to loop through possible PHY
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
 *  addresses. It tests each by reading the PHY ID registers and
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
 *  checking for a match.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
s32 e1000e_determine_phy_address(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
	u32 phy_addr = 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
	u32 i;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
	enum e1000_phy_type phy_type = e1000_phy_unknown;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
	hw->phy.id = phy_type;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
	for (phy_addr = 0; phy_addr < E1000_MAX_PHY_ADDR; phy_addr++) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
		hw->phy.addr = phy_addr;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
		i = 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
		do {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
			e1000e_get_phy_id(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
			phy_type = e1000e_get_phy_type_from_id(hw->phy.id);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
			/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
			 * If phy_type is valid, break - we found our
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
			 * PHY address
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
			 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
			if (phy_type  != e1000_phy_unknown)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
				return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
			usleep_range(1000, 2000);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
			i++;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
		} while (i < 10);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
	return -E1000_ERR_PHY_TYPE;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
 *  e1000_get_phy_addr_for_bm_page - Retrieve PHY page address
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
 *  @page: page to access
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
 *  Returns the phy address for the page requested.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
	u32 phy_addr = 2;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
	if ((page >= 768) || (page == 0 && reg == 25) || (reg == 31))
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
		phy_addr = 1;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
	return phy_addr;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
 *  e1000e_write_phy_reg_bm - Write BM PHY register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
 *  @offset: register offset to write to
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
 *  @data: data to write at register offset
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
 *  Acquires semaphore, if necessary, then writes the data to PHY register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
 *  at the offset.  Release any acquired semaphores before exiting.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
	u32 page = offset >> IGP_PAGE_SHIFT;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
	ret_val = hw->phy.ops.acquire(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
	/* Page 800 works differently than the rest so it has its own func */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
	if (page == BM_WUC_PAGE) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
							 false, false);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
		goto release;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
	hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
	if (offset > MAX_PHY_MULTI_PAGE_REG) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
		u32 page_shift, page_select;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
		/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
		 * Page select is register 31 for phy address 1 and 22 for
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
		 * phy address 2 and 3. Page select is shifted only for
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
		 * phy address 1.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
		 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
		if (hw->phy.addr == 1) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
			page_shift = IGP_PAGE_SHIFT;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
			page_select = IGP01E1000_PHY_PAGE_SELECT;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
		} else {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
			page_shift = 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
			page_select = BM_PHY_PAGE_SELECT;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
		}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
		/* Page is shifted left, PHY expects (page x 32) */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
		ret_val = e1000e_write_phy_reg_mdic(hw, page_select,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
		                                    (page << page_shift));
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
			goto release;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
	ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
	                                    data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
release:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
	hw->phy.ops.release(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
 *  e1000e_read_phy_reg_bm - Read BM PHY register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
 *  @offset: register offset to be read
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
 *  @data: pointer to the read data
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
 *  Acquires semaphore, if necessary, then reads the PHY register at offset
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
 *  and storing the retrieved information in data.  Release any acquired
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
 *  semaphores before exiting.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
	u32 page = offset >> IGP_PAGE_SHIFT;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
	ret_val = hw->phy.ops.acquire(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
	/* Page 800 works differently than the rest so it has its own func */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
	if (page == BM_WUC_PAGE) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
							 true, false);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
		goto release;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
	hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
	if (offset > MAX_PHY_MULTI_PAGE_REG) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
		u32 page_shift, page_select;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
		/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
		 * Page select is register 31 for phy address 1 and 22 for
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
		 * phy address 2 and 3. Page select is shifted only for
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
		 * phy address 1.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
		 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
		if (hw->phy.addr == 1) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
			page_shift = IGP_PAGE_SHIFT;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
			page_select = IGP01E1000_PHY_PAGE_SELECT;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
		} else {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
			page_shift = 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
			page_select = BM_PHY_PAGE_SELECT;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
		}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
		/* Page is shifted left, PHY expects (page x 32) */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
		ret_val = e1000e_write_phy_reg_mdic(hw, page_select,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
		                                    (page << page_shift));
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
			goto release;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
	ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
	                                   data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
release:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
	hw->phy.ops.release(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
 *  e1000e_read_phy_reg_bm2 - Read BM PHY register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
 *  @offset: register offset to be read
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
 *  @data: pointer to the read data
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
 *  Acquires semaphore, if necessary, then reads the PHY register at offset
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
 *  and storing the retrieved information in data.  Release any acquired
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
 *  semaphores before exiting.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
	u16 page = (u16)(offset >> IGP_PAGE_SHIFT);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
	ret_val = hw->phy.ops.acquire(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
	/* Page 800 works differently than the rest so it has its own func */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
	if (page == BM_WUC_PAGE) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
							 true, false);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
		goto release;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
	hw->phy.addr = 1;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
	if (offset > MAX_PHY_MULTI_PAGE_REG) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
		/* Page is shifted left, PHY expects (page x 32) */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
		ret_val = e1000e_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
						    page);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
			goto release;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
	ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
					   data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
release:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
	hw->phy.ops.release(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
 *  e1000e_write_phy_reg_bm2 - Write BM PHY register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
 *  @offset: register offset to write to
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
 *  @data: data to write at register offset
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
 *  Acquires semaphore, if necessary, then writes the data to PHY register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
 *  at the offset.  Release any acquired semaphores before exiting.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
	u16 page = (u16)(offset >> IGP_PAGE_SHIFT);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
	ret_val = hw->phy.ops.acquire(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
	/* Page 800 works differently than the rest so it has its own func */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
	if (page == BM_WUC_PAGE) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
							 false, false);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
		goto release;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
	hw->phy.addr = 1;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
	if (offset > MAX_PHY_MULTI_PAGE_REG) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
		/* Page is shifted left, PHY expects (page x 32) */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
		ret_val = e1000e_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
						    page);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
			goto release;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
	ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
					    data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
release:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
	hw->phy.ops.release(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
 *  e1000_enable_phy_wakeup_reg_access_bm - enable access to BM wakeup registers
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
 *  @phy_reg: pointer to store original contents of BM_WUC_ENABLE_REG
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
 *  Assumes semaphore already acquired and phy_reg points to a valid memory
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
 *  address to store contents of the BM_WUC_ENABLE_REG register.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
s32 e1000_enable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
	u16 temp;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
	/* All page select, port ctrl and wakeup registers use phy address 1 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
	hw->phy.addr = 1;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
	/* Select Port Control Registers page */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
	ret_val = e1000_set_page_igp(hw, (BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT));
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
	if (ret_val) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
		e_dbg("Could not set Port Control page\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
	ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
	if (ret_val) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
		e_dbg("Could not read PHY register %d.%d\n",
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
		      BM_PORT_CTRL_PAGE, BM_WUC_ENABLE_REG);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
	/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
	 * Enable both PHY wakeup mode and Wakeup register page writes.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
	 * Prevent a power state change by disabling ME and Host PHY wakeup.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
	 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
	temp = *phy_reg;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
	temp |= BM_WUC_ENABLE_BIT;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
	temp &= ~(BM_WUC_ME_WU_BIT | BM_WUC_HOST_WU_BIT);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
	ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, temp);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
	if (ret_val) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
		e_dbg("Could not write PHY register %d.%d\n",
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
		      BM_PORT_CTRL_PAGE, BM_WUC_ENABLE_REG);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
	/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
	 * Select Host Wakeup Registers page - caller now able to write
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
	 * registers on the Wakeup registers page
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
	 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
	return e1000_set_page_igp(hw, (BM_WUC_PAGE << IGP_PAGE_SHIFT));
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
 *  e1000_disable_phy_wakeup_reg_access_bm - disable access to BM wakeup regs
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
 *  @phy_reg: pointer to original contents of BM_WUC_ENABLE_REG
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
 *  Restore BM_WUC_ENABLE_REG to its original value.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
 *  Assumes semaphore already acquired and *phy_reg is the contents of the
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
 *  BM_WUC_ENABLE_REG before register(s) on BM_WUC_PAGE were accessed by
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
 *  caller.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
s32 e1000_disable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
	s32 ret_val = 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
	/* Select Port Control Registers page */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
	ret_val = e1000_set_page_igp(hw, (BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT));
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
	if (ret_val) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
		e_dbg("Could not set Port Control page\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
	/* Restore 769.17 to its original value */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
	ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, *phy_reg);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
		e_dbg("Could not restore PHY register %d.%d\n",
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
		      BM_PORT_CTRL_PAGE, BM_WUC_ENABLE_REG);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
 *  e1000_access_phy_wakeup_reg_bm - Read/write BM PHY wakeup register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
 *  @offset: register offset to be read or written
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
 *  @data: pointer to the data to read or write
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
 *  @read: determines if operation is read or write
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
 *  @page_set: BM_WUC_PAGE already set and access enabled
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
 *  Read the PHY register at offset and store the retrieved information in
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
 *  data, or write data to PHY register at offset.  Note the procedure to
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
 *  access the PHY wakeup registers is different than reading the other PHY
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
 *  registers. It works as such:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
 *  1) Set 769.17.2 (page 769, register 17, bit 2) = 1
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
 *  2) Set page to 800 for host (801 if we were manageability)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
 *  3) Write the address using the address opcode (0x11)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
 *  4) Read or write the data using the data opcode (0x12)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
 *  5) Restore 769.17.2 to its original value
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
 *  Steps 1 and 2 are done by e1000_enable_phy_wakeup_reg_access_bm() and
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
 *  step 5 is done by e1000_disable_phy_wakeup_reg_access_bm().
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
 *  Assumes semaphore is already acquired.  When page_set==true, assumes
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
 *  the PHY page is set to BM_WUC_PAGE (i.e. a function in the call stack
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
 *  is responsible for calls to e1000_[enable|disable]_phy_wakeup_reg_bm()).
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
					  u16 *data, bool read, bool page_set)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
	u16 reg = BM_PHY_REG_NUM(offset);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
	u16 page = BM_PHY_REG_PAGE(offset);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
	u16 phy_reg = 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
	/* Gig must be disabled for MDIO accesses to Host Wakeup reg page */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
	if ((hw->mac.type == e1000_pchlan) &&
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
	    (!(er32(PHY_CTRL) & E1000_PHY_CTRL_GBE_DISABLE)))
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
		e_dbg("Attempting to access page %d while gig enabled.\n",
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
		      page);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
	if (!page_set) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
		/* Enable access to PHY wakeup registers */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
		ret_val = e1000_enable_phy_wakeup_reg_access_bm(hw, &phy_reg);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
		if (ret_val) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
			e_dbg("Could not enable PHY wakeup reg access\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
		}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
	e_dbg("Accessing PHY page %d reg 0x%x\n", page, reg);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
	/* Write the Wakeup register page offset value using opcode 0x11 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
	ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ADDRESS_OPCODE, reg);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
	if (ret_val) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
		e_dbg("Could not write address opcode to page %d\n", page);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
	if (read) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
		/* Read the Wakeup register page value using opcode 0x12 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
		ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
		                                   data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
	} else {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
		/* Write the Wakeup register page value using opcode 0x12 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
		ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
						    *data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
	if (ret_val) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
		e_dbg("Could not access PHY reg %d.%d\n", page, reg);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
	if (!page_set)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
		ret_val = e1000_disable_phy_wakeup_reg_access_bm(hw, &phy_reg);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
 * e1000_power_up_phy_copper - Restore copper link in case of PHY power down
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
 * @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
 * In the case of a PHY power down to save power, or to turn off link during a
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
 * driver unload, or wake on lan is not enabled, restore the link to previous
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
 * settings.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
void e1000_power_up_phy_copper(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
	u16 mii_reg = 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
	/* The PHY will retain its settings across a power down/up cycle */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
	e1e_rphy(hw, PHY_CONTROL, &mii_reg);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
	mii_reg &= ~MII_CR_POWER_DOWN;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
	e1e_wphy(hw, PHY_CONTROL, mii_reg);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
 * e1000_power_down_phy_copper - Restore copper link in case of PHY power down
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
 * @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
 * In the case of a PHY power down to save power, or to turn off link during a
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
 * driver unload, or wake on lan is not enabled, restore the link to previous
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
 * settings.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
void e1000_power_down_phy_copper(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
	u16 mii_reg = 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
	/* The PHY will retain its settings across a power down/up cycle */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
	e1e_rphy(hw, PHY_CONTROL, &mii_reg);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
	mii_reg |= MII_CR_POWER_DOWN;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
	e1e_wphy(hw, PHY_CONTROL, mii_reg);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
	usleep_range(1000, 2000);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
 *  e1000e_commit_phy - Soft PHY reset
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
 *  Performs a soft PHY reset on those that apply. This is a function pointer
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
 *  entry point called by drivers.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
s32 e1000e_commit_phy(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
	if (hw->phy.ops.commit)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
		return hw->phy.ops.commit(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
	return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
 *  e1000_set_d0_lplu_state - Sets low power link up state for D0
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
 *  @active: boolean used to enable/disable lplu
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
 *  Success returns 0, Failure returns 1
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2849
 *  The low power link up (lplu) state is set to the power management level D0
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
 *  and SmartSpeed is disabled when active is true, else clear lplu for D0
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
 *  and enable Smartspeed.  LPLU and Smartspeed are mutually exclusive.  LPLU
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
 *  is used during Dx states where the power conservation is most important.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
 *  During driver activity, SmartSpeed should be enabled so performance is
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
 *  maintained.  This is a function pointer entry point called by drivers.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
	if (hw->phy.ops.set_d0_lplu_state)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
		return hw->phy.ops.set_d0_lplu_state(hw, active);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
	return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
 *  __e1000_read_phy_reg_hv -  Read HV PHY register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
 *  @offset: register offset to be read
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
 *  @data: pointer to the read data
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
 *  @locked: semaphore has already been acquired or not
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
 *  Acquires semaphore, if necessary, then reads the PHY register at offset
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
 *  and stores the retrieved information in data.  Release any acquired
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
 *  semaphore before exiting.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
				   bool locked, bool page_set)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
	u16 page = BM_PHY_REG_PAGE(offset);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
	u16 reg = BM_PHY_REG_NUM(offset);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
	u32 phy_addr = hw->phy.addr = e1000_get_phy_addr_for_hv_page(page);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
	if (!locked) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
		ret_val = hw->phy.ops.acquire(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2888
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
	/* Page 800 works differently than the rest so it has its own func */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2890
	if (page == BM_WUC_PAGE) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
							 true, page_set);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
		goto out;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
	if (page > 0 && page < HV_INTC_FC_PAGE_START) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
		ret_val = e1000_access_phy_debug_regs_hv(hw, offset,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
		                                         data, true);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
		goto out;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
	if (!page_set) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
		if (page == HV_INTC_FC_PAGE_START)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
			page = 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
		if (reg > MAX_PHY_MULTI_PAGE_REG) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
			/* Page is shifted left, PHY expects (page x 32) */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
			ret_val = e1000_set_page_igp(hw,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
						     (page << IGP_PAGE_SHIFT));
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
			hw->phy.addr = phy_addr;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
			if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
				goto out;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
		}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2918
	e_dbg("reading PHY page %d (or 0x%x shifted) reg 0x%x\n", page,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
	      page << IGP_PAGE_SHIFT, reg);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
	ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
	                                  data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
out:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
	if (!locked)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
		hw->phy.ops.release(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
 *  e1000_read_phy_reg_hv -  Read HV PHY register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2933
 *  @offset: register offset to be read
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2934
 *  @data: pointer to the read data
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
 *  Acquires semaphore then reads the PHY register at offset and stores
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
 *  the retrieved information in data.  Release the acquired semaphore
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
 *  before exiting.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
	return __e1000_read_phy_reg_hv(hw, offset, data, false, false);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
 *  e1000_read_phy_reg_hv_locked -  Read HV PHY register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
 *  @offset: register offset to be read
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
 *  @data: pointer to the read data
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2950
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
 *  Reads the PHY register at offset and stores the retrieved information
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
 *  in data.  Assumes semaphore already acquired.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 *data)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
	return __e1000_read_phy_reg_hv(hw, offset, data, true, false);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2957
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
 *  e1000_read_phy_reg_page_hv - Read HV PHY register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
 *  @offset: register offset to write to
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
 *  @data: data to write at register offset
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
 *  Reads the PHY register at offset and stores the retrieved information
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
 *  in data.  Assumes semaphore already acquired and page already set.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
s32 e1000_read_phy_reg_page_hv(struct e1000_hw *hw, u32 offset, u16 *data)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
	return __e1000_read_phy_reg_hv(hw, offset, data, true, true);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
 *  __e1000_write_phy_reg_hv - Write HV PHY register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
 *  @offset: register offset to write to
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
 *  @data: data to write at register offset
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
 *  @locked: semaphore has already been acquired or not
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
 *  Acquires semaphore, if necessary, then writes the data to PHY register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
 *  at the offset.  Release any acquired semaphores before exiting.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
				    bool locked, bool page_set)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
	u16 page = BM_PHY_REG_PAGE(offset);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
	u16 reg = BM_PHY_REG_NUM(offset);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
	u32 phy_addr = hw->phy.addr = e1000_get_phy_addr_for_hv_page(page);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2990
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
	if (!locked) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
		ret_val = hw->phy.ops.acquire(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
	/* Page 800 works differently than the rest so it has its own func */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
	if (page == BM_WUC_PAGE) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
							 false, page_set);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
		goto out;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
	if (page > 0 && page < HV_INTC_FC_PAGE_START) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
		ret_val = e1000_access_phy_debug_regs_hv(hw, offset,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3006
		                                         &data, false);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
		goto out;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
	if (!page_set) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
		if (page == HV_INTC_FC_PAGE_START)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
			page = 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
		/*
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
		 * Workaround MDIO accesses being disabled after entering IEEE
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
		 * Power Down (when bit 11 of the PHY Control register is set)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
		 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
		if ((hw->phy.type == e1000_phy_82578) &&
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
		    (hw->phy.revision >= 1) &&
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
		    (hw->phy.addr == 2) &&
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
		    !(MAX_PHY_REG_ADDRESS & reg) && (data & (1 << 11))) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
			u16 data2 = 0x7EFF;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
			ret_val = e1000_access_phy_debug_regs_hv(hw,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
								 (1 << 6) | 0x3,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
								 &data2, false);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
			if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
				goto out;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
		}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
		if (reg > MAX_PHY_MULTI_PAGE_REG) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
			/* Page is shifted left, PHY expects (page x 32) */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
			ret_val = e1000_set_page_igp(hw,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3033
						     (page << IGP_PAGE_SHIFT));
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
			hw->phy.addr = phy_addr;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
			if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
				goto out;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
		}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
	e_dbg("writing PHY page %d (or 0x%x shifted) reg 0x%x\n", page,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
	      page << IGP_PAGE_SHIFT, reg);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
	ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
	                                  data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
out:
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3049
	if (!locked)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
		hw->phy.ops.release(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3056
 *  e1000_write_phy_reg_hv - Write HV PHY register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
 *  @offset: register offset to write to
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
 *  @data: data to write at register offset
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3060
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
 *  Acquires semaphore then writes the data to PHY register at the offset.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
 *  Release the acquired semaphores before exiting.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3066
	return __e1000_write_phy_reg_hv(hw, offset, data, false, false);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
 *  e1000_write_phy_reg_hv_locked - Write HV PHY register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
 *  @offset: register offset to write to
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
 *  @data: data to write at register offset
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
 *  Writes the data to PHY register at the offset.  Assumes semaphore
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
 *  already acquired.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 data)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3079
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
	return __e1000_write_phy_reg_hv(hw, offset, data, true, false);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
 *  e1000_write_phy_reg_page_hv - Write HV PHY register
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
 *  @offset: register offset to write to
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
 *  @data: data to write at register offset
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
 *  Writes the data to PHY register at the offset.  Assumes semaphore
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
 *  already acquired and page already set.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
s32 e1000_write_phy_reg_page_hv(struct e1000_hw *hw, u32 offset, u16 data)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
	return __e1000_write_phy_reg_hv(hw, offset, data, true, true);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
 *  e1000_get_phy_addr_for_hv_page - Get PHY address based on page
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
 *  @page: page to be accessed
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
static u32 e1000_get_phy_addr_for_hv_page(u32 page)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
	u32 phy_addr = 2;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
	if (page >= HV_INTC_FC_PAGE_START)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
		phy_addr = 1;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
	return phy_addr;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3111
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
 *  e1000_access_phy_debug_regs_hv - Read HV PHY vendor specific high registers
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
 *  @offset: register offset to be read or written
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
 *  @data: pointer to the data to be read or written
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
 *  @read: determines if operation is read or write
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
 *  Reads the PHY register at offset and stores the retreived information
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
 *  in data.  Assumes semaphore already acquired.  Note that the procedure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
 *  to access these regs uses the address port and data port to read/write.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
 *  These accesses done with PHY address 2 and without using pages.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3124
                                          u16 *data, bool read)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
	u32 addr_reg = 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
	u32 data_reg = 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
	/* This takes care of the difference with desktop vs mobile phy */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
	addr_reg = (hw->phy.type == e1000_phy_82578) ?
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
	           I82578_ADDR_REG : I82577_ADDR_REG;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
	data_reg = addr_reg + 1;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
	/* All operations in this function are phy address 2 */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
	hw->phy.addr = 2;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3138
	/* masking with 0x3F to remove the page from offset */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
	ret_val = e1000e_write_phy_reg_mdic(hw, addr_reg, (u16)offset & 0x3F);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
	if (ret_val) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
		e_dbg("Could not write the Address Offset port register\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
	/* Read or write the data value next */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
	if (read)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
		ret_val = e1000e_read_phy_reg_mdic(hw, data_reg, data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
	else
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
		ret_val = e1000e_write_phy_reg_mdic(hw, data_reg, *data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3150
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
		e_dbg("Could not access the Data port register\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3153
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
 *  e1000_link_stall_workaround_hv - Si workaround
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
 *  This function works around a Si bug where the link partner can get
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
 *  a link up indication before the PHY does.  If small packets are sent
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
 *  by the link partner they can be placed in the packet buffer without
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
 *  being properly accounted for by the PHY and will stall preventing
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
 *  further packets from being received.  The workaround is to clear the
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
 *  packet buffer after the PHY detects link up.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3170
	s32 ret_val = 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
	u16 data;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3172
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
	if (hw->phy.type != e1000_phy_82578)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
		return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
	/* Do not apply workaround if in PHY loopback bit 14 set */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
	e1e_rphy(hw, PHY_CONTROL, &data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
	if (data & PHY_CONTROL_LB)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
		return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
	/* check if link is up and at 1Gbps */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
	ret_val = e1e_rphy(hw, BM_CS_STATUS, &data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
	data &= BM_CS_STATUS_LINK_UP | BM_CS_STATUS_RESOLVED |
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
		BM_CS_STATUS_SPEED_MASK;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
	if (data != (BM_CS_STATUS_LINK_UP | BM_CS_STATUS_RESOLVED |
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
		     BM_CS_STATUS_SPEED_1000))
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
		return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
	msleep(200);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3194
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3195
	/* flush the packets in the fifo buffer */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3196
	ret_val = e1e_wphy(hw, HV_MUX_DATA_CTRL, HV_MUX_DATA_CTRL_GEN_TO_MAC |
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
			   HV_MUX_DATA_CTRL_FORCE_SPEED);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3198
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
	return e1e_wphy(hw, HV_MUX_DATA_CTRL, HV_MUX_DATA_CTRL_GEN_TO_MAC);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
 *  e1000_check_polarity_82577 - Checks the polarity.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
 *  Success returns 0, Failure returns -E1000_ERR_PHY (-2)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
 *  Polarity is determined based on the PHY specific status register.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3211
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3212
s32 e1000_check_polarity_82577(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
	struct e1000_phy_info *phy = &hw->phy;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
	u16 data;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3217
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3218
	ret_val = e1e_rphy(hw, I82577_PHY_STATUS_2, &data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3219
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3220
	if (!ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3221
		phy->cable_polarity = (data & I82577_PHY_STATUS2_REV_POLARITY)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
		                      ? e1000_rev_polarity_reversed
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
		                      : e1000_rev_polarity_normal;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3224
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3227
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3228
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3229
 *  e1000_phy_force_speed_duplex_82577 - Force speed/duplex for I82577 PHY
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3230
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
 *  Calls the PHY setup function to force speed and duplex.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3233
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3234
s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3235
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3236
	struct e1000_phy_info *phy = &hw->phy;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3237
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3238
	u16 phy_data;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3239
	bool link;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3240
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3241
	ret_val = e1e_rphy(hw, PHY_CONTROL, &phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3242
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3243
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3244
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3245
	e1000e_phy_force_speed_duplex_setup(hw, &phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3246
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3247
	ret_val = e1e_wphy(hw, PHY_CONTROL, phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3248
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3249
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3250
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3251
	udelay(1);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3252
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3253
	if (phy->autoneg_wait_to_complete) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3254
		e_dbg("Waiting for forced speed/duplex link on 82577 phy\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3255
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3256
		ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3257
						      100000, &link);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3258
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3259
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3260
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3261
		if (!link)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3262
			e_dbg("Link taking longer than expected.\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3263
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3264
		/* Try once more */
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3265
		ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3266
						      100000, &link);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3267
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3268
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3269
	return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3270
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3271
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3272
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3273
 *  e1000_get_phy_info_82577 - Retrieve I82577 PHY information
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3274
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3275
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3276
 *  Read PHY status to determine if link is up.  If link is up, then
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3277
 *  set/determine 10base-T extended distance and polarity correction.  Read
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3278
 *  PHY port status to determine MDI/MDIx and speed.  Based on the speed,
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3279
 *  determine on the cable length, local and remote receiver.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3280
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3281
s32 e1000_get_phy_info_82577(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3282
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3283
	struct e1000_phy_info *phy = &hw->phy;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3284
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3285
	u16 data;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3286
	bool link;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3287
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3288
	ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3289
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3290
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3291
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3292
	if (!link) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3293
		e_dbg("Phy info is only valid if link is up\n");
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3294
		return -E1000_ERR_CONFIG;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3295
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3296
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3297
	phy->polarity_correction = true;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3298
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3299
	ret_val = e1000_check_polarity_82577(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3300
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3301
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3302
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3303
	ret_val = e1e_rphy(hw, I82577_PHY_STATUS_2, &data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3304
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3305
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3306
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3307
	phy->is_mdix = !!(data & I82577_PHY_STATUS2_MDIX);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3308
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3309
	if ((data & I82577_PHY_STATUS2_SPEED_MASK) ==
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3310
	    I82577_PHY_STATUS2_SPEED_1000MBPS) {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3311
		ret_val = hw->phy.ops.get_cable_length(hw);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3312
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3313
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3314
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3315
		ret_val = e1e_rphy(hw, PHY_1000T_STATUS, &data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3316
		if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3317
			return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3318
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3319
		phy->local_rx = (data & SR_1000T_LOCAL_RX_STATUS)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3320
		                ? e1000_1000t_rx_status_ok
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3321
		                : e1000_1000t_rx_status_not_ok;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3322
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3323
		phy->remote_rx = (data & SR_1000T_REMOTE_RX_STATUS)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3324
		                 ? e1000_1000t_rx_status_ok
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3325
		                 : e1000_1000t_rx_status_not_ok;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3326
	} else {
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3327
		phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3328
		phy->local_rx = e1000_1000t_rx_status_undefined;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3329
		phy->remote_rx = e1000_1000t_rx_status_undefined;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3330
	}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3331
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3332
	return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3333
}
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3334
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3335
/**
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3336
 *  e1000_get_cable_length_82577 - Determine cable length for 82577 PHY
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3337
 *  @hw: pointer to the HW structure
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3338
 *
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3339
 * Reads the diagnostic status register and verifies result is valid before
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3340
 * placing it in the phy_cable_length field.
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3341
 **/
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3342
s32 e1000_get_cable_length_82577(struct e1000_hw *hw)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3343
{
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3344
	struct e1000_phy_info *phy = &hw->phy;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3345
	s32 ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3346
	u16 phy_data, length;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3347
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3348
	ret_val = e1e_rphy(hw, I82577_PHY_DIAG_STATUS, &phy_data);
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3349
	if (ret_val)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3350
		return ret_val;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3351
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3352
	length = (phy_data & I82577_DSTATUS_CABLE_LENGTH) >>
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3353
	         I82577_DSTATUS_CABLE_LENGTH_SHIFT;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3354
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3355
	if (length == E1000_CABLE_LENGTH_UNDEFINED)
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3356
		ret_val = -E1000_ERR_PHY;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3357
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3358
	phy->cable_length = length;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3359
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3360
	return 0;
2fa43746d972 Added e1000e driver for kernel 3.6.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3361
}