devices/e1000e/phy-2.6.37-orig.c
author Patrick Bruenn <p.bruenn@beckhoff.com>
Tue, 12 Apr 2016 11:17:36 +0200
branchstable-1.5
changeset 2654 b3f6b3e5ef29
parent 2219 d52848f0be04
permissions -rw-r--r--
devices/ccat: revert "limit rx processing to one frame per poll"

revert "limit rx processing to one frame per poll", which caused etherlab
frame timeouts in setups with more than one frame per cycle.
2219
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2010 Intel Corporation.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
*******************************************************************************/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
#include <linux/delay.h>
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
#include "e1000.h"
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
static s32 e1000_wait_autoneg(struct e1000_hw *hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
					  u16 *data, bool read);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
static u32 e1000_get_phy_addr_for_hv_page(u32 page);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
                                          u16 *data, bool read);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
/* Cable length tables */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
static const u16 e1000_m88_cable_length_table[] =
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
	{ 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED };
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
#define M88E1000_CABLE_LENGTH_TABLE_SIZE \
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
		ARRAY_SIZE(e1000_m88_cable_length_table)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
static const u16 e1000_igp_2_cable_length_table[] =
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
	{ 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21, 0, 0, 0, 3,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
	  6, 10, 13, 16, 19, 23, 26, 29, 32, 35, 38, 41, 6, 10, 14, 18, 22,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
	  26, 30, 33, 37, 41, 44, 48, 51, 54, 58, 61, 21, 26, 31, 35, 40,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
	  44, 49, 53, 57, 61, 65, 68, 72, 75, 79, 82, 40, 45, 51, 56, 61,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
	  66, 70, 75, 79, 83, 87, 91, 94, 98, 101, 104, 60, 66, 72, 77, 82,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
	  87, 92, 96, 100, 104, 108, 111, 114, 117, 119, 121, 83, 89, 95,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
	  100, 105, 109, 113, 116, 119, 122, 124, 104, 109, 114, 118, 121,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
	  124};
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
#define IGP02E1000_CABLE_LENGTH_TABLE_SIZE \
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
		ARRAY_SIZE(e1000_igp_2_cable_length_table)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
#define BM_PHY_REG_PAGE(offset) \
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
	((u16)(((offset) >> PHY_PAGE_SHIFT) & 0xFFFF))
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
#define BM_PHY_REG_NUM(offset) \
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
	((u16)(((offset) & MAX_PHY_REG_ADDRESS) |\
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
	 (((offset) >> (PHY_UPPER_SHIFT - PHY_PAGE_SHIFT)) &\
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
		~MAX_PHY_REG_ADDRESS)))
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
#define HV_INTC_FC_PAGE_START             768
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
#define I82578_ADDR_REG                   29
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
#define I82577_ADDR_REG                   16
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
#define I82577_CFG_REG                    22
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
#define I82577_CFG_ASSERT_CRS_ON_TX       (1 << 15)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
#define I82577_CFG_ENABLE_DOWNSHIFT       (3 << 10) /* auto downshift 100/10 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
#define I82577_CTRL_REG                   23
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
/* 82577 specific PHY registers */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
#define I82577_PHY_CTRL_2            18
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
#define I82577_PHY_STATUS_2          26
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
#define I82577_PHY_DIAG_STATUS       31
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
/* I82577 PHY Status 2 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
#define I82577_PHY_STATUS2_REV_POLARITY   0x0400
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
#define I82577_PHY_STATUS2_MDIX           0x0800
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
#define I82577_PHY_STATUS2_SPEED_MASK     0x0300
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
#define I82577_PHY_STATUS2_SPEED_1000MBPS 0x0200
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
/* I82577 PHY Control 2 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
#define I82577_PHY_CTRL2_AUTO_MDIX        0x0400
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
#define I82577_PHY_CTRL2_FORCE_MDI_MDIX   0x0200
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
/* I82577 PHY Diagnostics Status */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
#define I82577_DSTATUS_CABLE_LENGTH       0x03FC
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
#define I82577_DSTATUS_CABLE_LENGTH_SHIFT 2
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
/* BM PHY Copper Specific Control 1 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
#define BM_CS_CTRL1                       16
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
#define HV_MUX_DATA_CTRL               PHY_REG(776, 16)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
#define HV_MUX_DATA_CTRL_GEN_TO_MAC    0x0400
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
#define HV_MUX_DATA_CTRL_FORCE_SPEED   0x0004
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
 *  e1000e_check_reset_block_generic - Check if PHY reset is blocked
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
 *  Read the PHY management control register and check whether a PHY reset
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
 *  is blocked.  If a reset is not blocked return 0, otherwise
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
 *  return E1000_BLK_PHY_RESET (12).
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
s32 e1000e_check_reset_block_generic(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
	u32 manc;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
	manc = er32(MANC);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
	return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ?
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
	       E1000_BLK_PHY_RESET : 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
 *  e1000e_get_phy_id - Retrieve the PHY ID and revision
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
 *  Reads the PHY registers and stores the PHY ID and possibly the PHY
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
 *  revision in the hardware structure.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
s32 e1000e_get_phy_id(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
	struct e1000_phy_info *phy = &hw->phy;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
	s32 ret_val = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
	u16 phy_id;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
	u16 retry_count = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
	if (!(phy->ops.read_reg))
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
	while (retry_count < 2) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
		ret_val = e1e_rphy(hw, PHY_ID1, &phy_id);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
			goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
		phy->id = (u32)(phy_id << 16);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
		udelay(20);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
		ret_val = e1e_rphy(hw, PHY_ID2, &phy_id);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
			goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
		phy->id |= (u32)(phy_id & PHY_REVISION_MASK);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
		phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
		if (phy->id != 0 && phy->id != PHY_REVISION_MASK)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
			goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
		retry_count++;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
out:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
 *  e1000e_phy_reset_dsp - Reset PHY DSP
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
 *  Reset the digital signal processor.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
s32 e1000e_phy_reset_dsp(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
	ret_val = e1e_wphy(hw, M88E1000_PHY_GEN_CONTROL, 0xC1);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
	return e1e_wphy(hw, M88E1000_PHY_GEN_CONTROL, 0);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
 *  e1000e_read_phy_reg_mdic - Read MDI control register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
 *  @offset: register offset to be read
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
 *  @data: pointer to the read data
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
 *  Reads the MDI control register in the PHY at offset and stores the
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
 *  information read to data.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
	struct e1000_phy_info *phy = &hw->phy;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
	u32 i, mdic = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
	if (offset > MAX_PHY_REG_ADDRESS) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
		e_dbg("PHY Address %d is out of range\n", offset);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
		return -E1000_ERR_PARAM;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
	/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
	 * Set up Op-code, Phy Address, and register offset in the MDI
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
	 * Control register.  The MAC will take care of interfacing with the
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
	 * PHY to retrieve the desired data.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
	 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
	mdic = ((offset << E1000_MDIC_REG_SHIFT) |
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
		(phy->addr << E1000_MDIC_PHY_SHIFT) |
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
		(E1000_MDIC_OP_READ));
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
	ew32(MDIC, mdic);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
	/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
	 * Poll the ready bit to see if the MDI read completed
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
	 * Increasing the time out as testing showed failures with
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
	 * the lower time out
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
	 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
	for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
		udelay(50);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
		mdic = er32(MDIC);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
		if (mdic & E1000_MDIC_READY)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
			break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
	if (!(mdic & E1000_MDIC_READY)) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
		e_dbg("MDI Read did not complete\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
		return -E1000_ERR_PHY;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
	if (mdic & E1000_MDIC_ERROR) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
		e_dbg("MDI Error\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
		return -E1000_ERR_PHY;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
	*data = (u16) mdic;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
	/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
	 * Allow some time after each MDIC transaction to avoid
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
	 * reading duplicate data in the next MDIC transaction.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
	 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
	if (hw->mac.type == e1000_pch2lan)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
		udelay(100);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
	return 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
 *  e1000e_write_phy_reg_mdic - Write MDI control register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
 *  @offset: register offset to write to
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
 *  @data: data to write to register at offset
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
 *  Writes data to MDI control register in the PHY at offset.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
	struct e1000_phy_info *phy = &hw->phy;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
	u32 i, mdic = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
	if (offset > MAX_PHY_REG_ADDRESS) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
		e_dbg("PHY Address %d is out of range\n", offset);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
		return -E1000_ERR_PARAM;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
	/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
	 * Set up Op-code, Phy Address, and register offset in the MDI
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
	 * Control register.  The MAC will take care of interfacing with the
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
	 * PHY to retrieve the desired data.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
	 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
	mdic = (((u32)data) |
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
		(offset << E1000_MDIC_REG_SHIFT) |
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
		(phy->addr << E1000_MDIC_PHY_SHIFT) |
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
		(E1000_MDIC_OP_WRITE));
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
	ew32(MDIC, mdic);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
	/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
	 * Poll the ready bit to see if the MDI read completed
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
	 * Increasing the time out as testing showed failures with
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
	 * the lower time out
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
	 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
	for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
		udelay(50);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
		mdic = er32(MDIC);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
		if (mdic & E1000_MDIC_READY)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
			break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
	if (!(mdic & E1000_MDIC_READY)) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
		e_dbg("MDI Write did not complete\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
		return -E1000_ERR_PHY;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
	if (mdic & E1000_MDIC_ERROR) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
		e_dbg("MDI Error\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
		return -E1000_ERR_PHY;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
	/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
	 * Allow some time after each MDIC transaction to avoid
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
	 * reading duplicate data in the next MDIC transaction.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
	 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
	if (hw->mac.type == e1000_pch2lan)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
		udelay(100);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
	return 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
 *  e1000e_read_phy_reg_m88 - Read m88 PHY register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
 *  @offset: register offset to be read
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
 *  @data: pointer to the read data
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
 *  Acquires semaphore, if necessary, then reads the PHY register at offset
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
 *  and storing the retrieved information in data.  Release any acquired
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
 *  semaphores before exiting.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
s32 e1000e_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
	ret_val = hw->phy.ops.acquire(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
	ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
					   data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
	hw->phy.ops.release(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
 *  e1000e_write_phy_reg_m88 - Write m88 PHY register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
 *  @offset: register offset to write to
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
 *  @data: data to write at register offset
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
 *  Acquires semaphore, if necessary, then writes the data to PHY register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
 *  at the offset.  Release any acquired semaphores before exiting.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
s32 e1000e_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
	ret_val = hw->phy.ops.acquire(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
	ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
					    data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
	hw->phy.ops.release(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
 *  __e1000e_read_phy_reg_igp - Read igp PHY register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
 *  @offset: register offset to be read
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
 *  @data: pointer to the read data
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
 *  @locked: semaphore has already been acquired or not
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
 *  Acquires semaphore, if necessary, then reads the PHY register at offset
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
 *  and stores the retrieved information in data.  Release any acquired
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
 *  semaphores before exiting.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
static s32 __e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
                                    bool locked)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
	s32 ret_val = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
	if (!locked) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
		if (!(hw->phy.ops.acquire))
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
			goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
		ret_val = hw->phy.ops.acquire(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
			goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
	if (offset > MAX_PHY_MULTI_PAGE_REG) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
		ret_val = e1000e_write_phy_reg_mdic(hw,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
						    IGP01E1000_PHY_PAGE_SELECT,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
						    (u16)offset);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
			goto release;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
	ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
	                                  data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
release:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
	if (!locked)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
		hw->phy.ops.release(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
out:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
 *  e1000e_read_phy_reg_igp - Read igp PHY register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
 *  @offset: register offset to be read
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
 *  @data: pointer to the read data
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
 *  Acquires semaphore then reads the PHY register at offset and stores the
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
 *  retrieved information in data.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
 *  Release the acquired semaphore before exiting.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
	return __e1000e_read_phy_reg_igp(hw, offset, data, false);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
 *  e1000e_read_phy_reg_igp_locked - Read igp PHY register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
 *  @offset: register offset to be read
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
 *  @data: pointer to the read data
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
 *  Reads the PHY register at offset and stores the retrieved information
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
 *  in data.  Assumes semaphore already acquired.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
s32 e1000e_read_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 *data)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
	return __e1000e_read_phy_reg_igp(hw, offset, data, true);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
 *  e1000e_write_phy_reg_igp - Write igp PHY register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
 *  @offset: register offset to write to
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
 *  @data: data to write at register offset
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
 *  @locked: semaphore has already been acquired or not
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
 *  Acquires semaphore, if necessary, then writes the data to PHY register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
 *  at the offset.  Release any acquired semaphores before exiting.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
static s32 __e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
                                     bool locked)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
	s32 ret_val = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
	if (!locked) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
		if (!(hw->phy.ops.acquire))
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
			goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
		ret_val = hw->phy.ops.acquire(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
			goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
	if (offset > MAX_PHY_MULTI_PAGE_REG) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
		ret_val = e1000e_write_phy_reg_mdic(hw,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
						    IGP01E1000_PHY_PAGE_SELECT,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
						    (u16)offset);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
			goto release;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
	ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
					    data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
release:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
	if (!locked)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
		hw->phy.ops.release(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
out:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
 *  e1000e_write_phy_reg_igp - Write igp PHY register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
 *  @offset: register offset to write to
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
 *  @data: data to write at register offset
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
 *  Acquires semaphore then writes the data to PHY register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
 *  at the offset.  Release any acquired semaphores before exiting.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
s32 e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
	return __e1000e_write_phy_reg_igp(hw, offset, data, false);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
 *  e1000e_write_phy_reg_igp_locked - Write igp PHY register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
 *  @offset: register offset to write to
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
 *  @data: data to write at register offset
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
 *  Writes the data to PHY register at the offset.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
 *  Assumes semaphore already acquired.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
s32 e1000e_write_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 data)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
	return __e1000e_write_phy_reg_igp(hw, offset, data, true);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
 *  __e1000_read_kmrn_reg - Read kumeran register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
 *  @offset: register offset to be read
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
 *  @data: pointer to the read data
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
 *  @locked: semaphore has already been acquired or not
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
 *  Acquires semaphore, if necessary.  Then reads the PHY register at offset
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
 *  using the kumeran interface.  The information retrieved is stored in data.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
 *  Release any acquired semaphores before exiting.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
static s32 __e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
                                 bool locked)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
	u32 kmrnctrlsta;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
	s32 ret_val = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
	if (!locked) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
		if (!(hw->phy.ops.acquire))
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
			goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
		ret_val = hw->phy.ops.acquire(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
			goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
	kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
		       E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
	ew32(KMRNCTRLSTA, kmrnctrlsta);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
	udelay(2);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
	kmrnctrlsta = er32(KMRNCTRLSTA);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
	*data = (u16)kmrnctrlsta;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
	if (!locked)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
		hw->phy.ops.release(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
out:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
 *  e1000e_read_kmrn_reg -  Read kumeran register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
 *  @offset: register offset to be read
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
 *  @data: pointer to the read data
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
 *  Acquires semaphore then reads the PHY register at offset using the
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
 *  kumeran interface.  The information retrieved is stored in data.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
 *  Release the acquired semaphore before exiting.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
	return __e1000_read_kmrn_reg(hw, offset, data, false);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
 *  e1000e_read_kmrn_reg_locked -  Read kumeran register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
 *  @offset: register offset to be read
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
 *  @data: pointer to the read data
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
 *  Reads the PHY register at offset using the kumeran interface.  The
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
 *  information retrieved is stored in data.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
 *  Assumes semaphore already acquired.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
s32 e1000e_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 *data)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
	return __e1000_read_kmrn_reg(hw, offset, data, true);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
 *  __e1000_write_kmrn_reg - Write kumeran register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
 *  @offset: register offset to write to
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
 *  @data: data to write at register offset
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
 *  @locked: semaphore has already been acquired or not
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
 *  Acquires semaphore, if necessary.  Then write the data to PHY register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
 *  at the offset using the kumeran interface.  Release any acquired semaphores
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
 *  before exiting.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
static s32 __e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
                                  bool locked)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
	u32 kmrnctrlsta;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
	s32 ret_val = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
	if (!locked) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
		if (!(hw->phy.ops.acquire))
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
			goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
		ret_val = hw->phy.ops.acquire(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
			goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
	kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
		       E1000_KMRNCTRLSTA_OFFSET) | data;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
	ew32(KMRNCTRLSTA, kmrnctrlsta);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
	udelay(2);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
	if (!locked)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
		hw->phy.ops.release(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
out:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
 *  e1000e_write_kmrn_reg -  Write kumeran register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
 *  @offset: register offset to write to
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
 *  @data: data to write at register offset
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
 *  Acquires semaphore then writes the data to the PHY register at the offset
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
 *  using the kumeran interface.  Release the acquired semaphore before exiting.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
	return __e1000_write_kmrn_reg(hw, offset, data, false);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
 *  e1000e_write_kmrn_reg_locked -  Write kumeran register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
 *  @offset: register offset to write to
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
 *  @data: data to write at register offset
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
 *  Write the data to PHY register at the offset using the kumeran interface.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
 *  Assumes semaphore already acquired.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
s32 e1000e_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 data)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
	return __e1000_write_kmrn_reg(hw, offset, data, true);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
 *  e1000_copper_link_setup_82577 - Setup 82577 PHY for copper link
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
 *  Sets up Carrier-sense on Transmit and downshift values.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
s32 e1000_copper_link_setup_82577(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
	struct e1000_phy_info *phy = &hw->phy;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
	u16 phy_data;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
	/* Enable CRS on TX. This must be set for half-duplex operation. */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
	ret_val = phy->ops.read_reg(hw, I82577_CFG_REG, &phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
	phy_data |= I82577_CFG_ASSERT_CRS_ON_TX;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
	/* Enable downshift */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
	phy_data |= I82577_CFG_ENABLE_DOWNSHIFT;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
	ret_val = phy->ops.write_reg(hw, I82577_CFG_REG, phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
out:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
 *  e1000e_copper_link_setup_m88 - Setup m88 PHY's for copper link
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
 *  Sets up MDI/MDI-X and polarity for m88 PHY's.  If necessary, transmit clock
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
 *  and downshift values are set also.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
	struct e1000_phy_info *phy = &hw->phy;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
	u16 phy_data;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
	/* Enable CRS on Tx. This must be set for half-duplex operation. */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
	/* For BM PHY this bit is downshift enable */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
	if (phy->type != e1000_phy_bm)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
		phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
	/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
	 * Options:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
	 *   MDI/MDI-X = 0 (default)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
	 *   0 - Auto for all speeds
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
	 *   1 - MDI mode
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
	 *   2 - MDI-X mode
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
	 *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
	 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
	phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
	switch (phy->mdix) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
	case 1:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
		phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
		break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
	case 2:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
		phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
		break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
	case 3:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
		phy_data |= M88E1000_PSCR_AUTO_X_1000T;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
		break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
	case 0:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
	default:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
		phy_data |= M88E1000_PSCR_AUTO_X_MODE;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
		break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
	/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
	 * Options:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
	 *   disable_polarity_correction = 0 (default)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
	 *       Automatic Correction for Reversed Cable Polarity
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
	 *   0 - Disabled
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
	 *   1 - Enabled
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
	 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
	phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
	if (phy->disable_polarity_correction == 1)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
		phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
	/* Enable downshift on BM (disabled by default) */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
	if (phy->type == e1000_phy_bm)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
		phy_data |= BME1000_PSCR_ENABLE_DOWNSHIFT;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
	ret_val = e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
	if ((phy->type == e1000_phy_m88) &&
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
	    (phy->revision < E1000_REVISION_4) &&
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
	    (phy->id != BME1000_E_PHY_ID_R2)) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
		/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
		 * Force TX_CLK in the Extended PHY Specific Control Register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
		 * to 25MHz clock.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
		 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
		ret_val = e1e_rphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
			return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
		phy_data |= M88E1000_EPSCR_TX_CLK_25;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
		if ((phy->revision == 2) &&
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
		    (phy->id == M88E1111_I_PHY_ID)) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
			/* 82573L PHY - set the downshift counter to 5x. */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
			phy_data &= ~M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
			phy_data |= M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
		} else {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
			/* Configure Master and Slave downshift values */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
			phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
				      M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
			phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
				     M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
		}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
		ret_val = e1e_wphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
			return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
	if ((phy->type == e1000_phy_bm) && (phy->id == BME1000_E_PHY_ID_R2)) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
		/* Set PHY page 0, register 29 to 0x0003 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
		ret_val = e1e_wphy(hw, 29, 0x0003);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
			return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
		/* Set PHY page 0, register 30 to 0x0000 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
		ret_val = e1e_wphy(hw, 30, 0x0000);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
			return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
	/* Commit the changes. */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
	ret_val = e1000e_commit_phy(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
	if (ret_val) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
		e_dbg("Error committing the PHY changes\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
	if (phy->type == e1000_phy_82578) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
		ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
		                            &phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
			return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
		/* 82578 PHY - set the downshift count to 1x. */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
		phy_data |= I82578_EPSCR_DOWNSHIFT_ENABLE;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
		phy_data &= ~I82578_EPSCR_DOWNSHIFT_COUNTER_MASK;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
		ret_val = phy->ops.write_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
		                             phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
			return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
	return 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
 *  e1000e_copper_link_setup_igp - Setup igp PHY's for copper link
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
 *  Sets up LPLU, MDI/MDI-X, polarity, Smartspeed and Master/Slave config for
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
 *  igp PHY's.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
s32 e1000e_copper_link_setup_igp(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
	struct e1000_phy_info *phy = &hw->phy;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
	u16 data;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
	ret_val = e1000_phy_hw_reset(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
	if (ret_val) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
		e_dbg("Error resetting the PHY.\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
	/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
	 * Wait 100ms for MAC to configure PHY from NVM settings, to avoid
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
	 * timeout issues when LFS is enabled.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
	 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
	msleep(100);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
	/* disable lplu d0 during driver init */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
	ret_val = e1000_set_d0_lplu_state(hw, false);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
	if (ret_val) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
		e_dbg("Error Disabling LPLU D0\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
	/* Configure mdi-mdix settings */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
	ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CTRL, &data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
	data &= ~IGP01E1000_PSCR_AUTO_MDIX;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
	switch (phy->mdix) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
	case 1:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
		data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
		break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
	case 2:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
		data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
		break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
	case 0:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
	default:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
		data |= IGP01E1000_PSCR_AUTO_MDIX;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
		break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
	ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CTRL, data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
	/* set auto-master slave resolution settings */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
	if (hw->mac.autoneg) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
		/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
		 * when autonegotiation advertisement is only 1000Mbps then we
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
		 * should disable SmartSpeed and enable Auto MasterSlave
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
		 * resolution as hardware default.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
		 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
		if (phy->autoneg_advertised == ADVERTISE_1000_FULL) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
			/* Disable SmartSpeed */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
			ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
					   &data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
			if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
				return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
			data &= ~IGP01E1000_PSCFR_SMART_SPEED;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
			ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
					   data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
			if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
				return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
			/* Set auto Master/Slave resolution process */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
			ret_val = e1e_rphy(hw, PHY_1000T_CTRL, &data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
			if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
				return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
			data &= ~CR_1000T_MS_ENABLE;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
			ret_val = e1e_wphy(hw, PHY_1000T_CTRL, data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
			if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
				return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
		}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
		ret_val = e1e_rphy(hw, PHY_1000T_CTRL, &data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
			return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
		/* load defaults for future use */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
		phy->original_ms_type = (data & CR_1000T_MS_ENABLE) ?
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
			((data & CR_1000T_MS_VALUE) ?
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
			e1000_ms_force_master :
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
			e1000_ms_force_slave) :
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
			e1000_ms_auto;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
		switch (phy->ms_type) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
		case e1000_ms_force_master:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
			data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
			break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
		case e1000_ms_force_slave:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
			data |= CR_1000T_MS_ENABLE;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
			data &= ~(CR_1000T_MS_VALUE);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
			break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
		case e1000_ms_auto:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
			data &= ~CR_1000T_MS_ENABLE;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
		default:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
			break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
		}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
		ret_val = e1e_wphy(hw, PHY_1000T_CTRL, data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
 *  e1000_phy_setup_autoneg - Configure PHY for auto-negotiation
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
 *  Reads the MII auto-neg advertisement register and/or the 1000T control
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
 *  register and if the PHY is already setup for auto-negotiation, then
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
 *  return successful.  Otherwise, setup advertisement and flow control to
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
 *  the appropriate values for the wanted auto-negotiation.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
static s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
	struct e1000_phy_info *phy = &hw->phy;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
	u16 mii_autoneg_adv_reg;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
	u16 mii_1000t_ctrl_reg = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
	phy->autoneg_advertised &= phy->autoneg_mask;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
	/* Read the MII Auto-Neg Advertisement Register (Address 4). */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
	ret_val = e1e_rphy(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
	if (phy->autoneg_mask & ADVERTISE_1000_FULL) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
		/* Read the MII 1000Base-T Control Register (Address 9). */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
		ret_val = e1e_rphy(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
			return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
	/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
	 * Need to parse both autoneg_advertised and fc and set up
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
	 * the appropriate PHY registers.  First we will parse for
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
	 * autoneg_advertised software override.  Since we can advertise
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
	 * a plethora of combinations, we need to check each bit
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
	 * individually.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
	 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
	/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
	 * First we clear all the 10/100 mb speed bits in the Auto-Neg
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
	 * Advertisement Register (Address 4) and the 1000 mb speed bits in
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
	 * the  1000Base-T Control Register (Address 9).
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
	 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
	mii_autoneg_adv_reg &= ~(NWAY_AR_100TX_FD_CAPS |
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
				 NWAY_AR_100TX_HD_CAPS |
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
				 NWAY_AR_10T_FD_CAPS   |
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
				 NWAY_AR_10T_HD_CAPS);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
	mii_1000t_ctrl_reg &= ~(CR_1000T_HD_CAPS | CR_1000T_FD_CAPS);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
	e_dbg("autoneg_advertised %x\n", phy->autoneg_advertised);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
	/* Do we want to advertise 10 Mb Half Duplex? */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
	if (phy->autoneg_advertised & ADVERTISE_10_HALF) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
		e_dbg("Advertise 10mb Half duplex\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
		mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
	/* Do we want to advertise 10 Mb Full Duplex? */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
	if (phy->autoneg_advertised & ADVERTISE_10_FULL) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
		e_dbg("Advertise 10mb Full duplex\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
		mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
	/* Do we want to advertise 100 Mb Half Duplex? */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
	if (phy->autoneg_advertised & ADVERTISE_100_HALF) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
		e_dbg("Advertise 100mb Half duplex\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
		mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
	/* Do we want to advertise 100 Mb Full Duplex? */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
	if (phy->autoneg_advertised & ADVERTISE_100_FULL) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
		e_dbg("Advertise 100mb Full duplex\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
		mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
	/* We do not allow the Phy to advertise 1000 Mb Half Duplex */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
	if (phy->autoneg_advertised & ADVERTISE_1000_HALF)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
		e_dbg("Advertise 1000mb Half duplex request denied!\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
	/* Do we want to advertise 1000 Mb Full Duplex? */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
	if (phy->autoneg_advertised & ADVERTISE_1000_FULL) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
		e_dbg("Advertise 1000mb Full duplex\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
		mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
	/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
	 * Check for a software override of the flow control settings, and
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
	 * setup the PHY advertisement registers accordingly.  If
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
	 * auto-negotiation is enabled, then software will have to set the
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
	 * "PAUSE" bits to the correct value in the Auto-Negotiation
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
	 * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto-
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
	 * negotiation.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
	 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
	 * The possible values of the "fc" parameter are:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
	 *      0:  Flow control is completely disabled
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
	 *      1:  Rx flow control is enabled (we can receive pause frames
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
	 *	  but not send pause frames).
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
	 *      2:  Tx flow control is enabled (we can send pause frames
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
	 *	  but we do not support receiving pause frames).
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
	 *      3:  Both Rx and Tx flow control (symmetric) are enabled.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
	 *  other:  No software override.  The flow control configuration
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
	 *	  in the EEPROM is used.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
	 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
	switch (hw->fc.current_mode) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
	case e1000_fc_none:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
		/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
		 * Flow control (Rx & Tx) is completely disabled by a
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
		 * software over-ride.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
		 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
		mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
		break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
	case e1000_fc_rx_pause:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
		/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
		 * Rx Flow control is enabled, and Tx Flow control is
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
		 * disabled, by a software over-ride.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
		 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
		 * Since there really isn't a way to advertise that we are
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
		 * capable of Rx Pause ONLY, we will advertise that we
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
		 * support both symmetric and asymmetric Rx PAUSE.  Later
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
		 * (in e1000e_config_fc_after_link_up) we will disable the
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
		 * hw's ability to send PAUSE frames.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
		 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
		break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
	case e1000_fc_tx_pause:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
		/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
		 * Tx Flow control is enabled, and Rx Flow control is
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
		 * disabled, by a software over-ride.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
		 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
		mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
		mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
		break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
	case e1000_fc_full:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
		/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
		 * Flow control (both Rx and Tx) is enabled by a software
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
		 * over-ride.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
		 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
		break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
	default:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
		e_dbg("Flow control param set incorrectly\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
		ret_val = -E1000_ERR_CONFIG;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
	ret_val = e1e_wphy(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
	e_dbg("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
	if (phy->autoneg_mask & ADVERTISE_1000_FULL) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
		ret_val = e1e_wphy(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
 *  e1000_copper_link_autoneg - Setup/Enable autoneg for copper link
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
 *  Performs initial bounds checking on autoneg advertisement parameter, then
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
 *  configure to advertise the full capability.  Setup the PHY to autoneg
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
 *  and restart the negotiation process between the link partner.  If
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
 *  autoneg_wait_to_complete, then wait for autoneg to complete before exiting.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
static s32 e1000_copper_link_autoneg(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
	struct e1000_phy_info *phy = &hw->phy;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
	u16 phy_ctrl;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
	/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
	 * Perform some bounds checking on the autoneg advertisement
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
	 * parameter.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
	 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
	phy->autoneg_advertised &= phy->autoneg_mask;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
	/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
	 * If autoneg_advertised is zero, we assume it was not defaulted
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
	 * by the calling code so we set to advertise full capability.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
	 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
	if (phy->autoneg_advertised == 0)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
		phy->autoneg_advertised = phy->autoneg_mask;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
	e_dbg("Reconfiguring auto-neg advertisement params\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
	ret_val = e1000_phy_setup_autoneg(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
	if (ret_val) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
		e_dbg("Error Setting up Auto-Negotiation\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
	e_dbg("Restarting Auto-Neg\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
	/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
	 * Restart auto-negotiation by setting the Auto Neg Enable bit and
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
	 * the Auto Neg Restart bit in the PHY control register.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
	 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
	ret_val = e1e_rphy(hw, PHY_CONTROL, &phy_ctrl);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
	phy_ctrl |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
	ret_val = e1e_wphy(hw, PHY_CONTROL, phy_ctrl);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
	/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
	 * Does the user want to wait for Auto-Neg to complete here, or
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
	 * check at a later time (for example, callback routine).
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
	 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
	if (phy->autoneg_wait_to_complete) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
		ret_val = e1000_wait_autoneg(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
		if (ret_val) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
			e_dbg("Error while waiting for "
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
				 "autoneg to complete\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
			return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
		}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
	hw->mac.get_link_status = 1;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
 *  e1000e_setup_copper_link - Configure copper link settings
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
 *  Calls the appropriate function to configure the link for auto-neg or forced
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
 *  speed and duplex.  Then we check for link, once link is established calls
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
 *  to configure collision distance and flow control are called.  If link is
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
 *  not established, we return -E1000_ERR_PHY (-2).
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
s32 e1000e_setup_copper_link(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
	bool link;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
	if (hw->mac.autoneg) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
		/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
		 * Setup autoneg and flow control advertisement and perform
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
		 * autonegotiation.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
		 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
		ret_val = e1000_copper_link_autoneg(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
			return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
	} else {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
		/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
		 * PHY will be set to 10H, 10F, 100H or 100F
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
		 * depending on user settings.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
		 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
		e_dbg("Forcing Speed and Duplex\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
		ret_val = e1000_phy_force_speed_duplex(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
		if (ret_val) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
			e_dbg("Error Forcing Speed and Duplex\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
			return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
		}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
	/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
	 * Check link status. Wait up to 100 microseconds for link to become
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
	 * valid.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
	 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
	ret_val = e1000e_phy_has_link_generic(hw,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
					     COPPER_LINK_UP_LIMIT,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
					     10,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
					     &link);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
	if (link) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
		e_dbg("Valid link established!!!\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
		e1000e_config_collision_dist(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
		ret_val = e1000e_config_fc_after_link_up(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
	} else {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
		e_dbg("Unable to establish link!!!\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
 *  e1000e_phy_force_speed_duplex_igp - Force speed/duplex for igp PHY
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
 *  Calls the PHY setup function to force speed and duplex.  Clears the
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
 *  auto-crossover to force MDI manually.  Waits for link and returns
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
 *  successful if link up is successful, else -E1000_ERR_PHY (-2).
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
s32 e1000e_phy_force_speed_duplex_igp(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
	struct e1000_phy_info *phy = &hw->phy;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
	u16 phy_data;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
	bool link;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
	ret_val = e1e_rphy(hw, PHY_CONTROL, &phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
	e1000e_phy_force_speed_duplex_setup(hw, &phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
	ret_val = e1e_wphy(hw, PHY_CONTROL, phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
	/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
	 * Clear Auto-Crossover to force MDI manually.  IGP requires MDI
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
	 * forced whenever speed and duplex are forced.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
	 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
	ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
	phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
	phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
	ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
	e_dbg("IGP PSCR: %X\n", phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
	udelay(1);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
	if (phy->autoneg_wait_to_complete) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
		e_dbg("Waiting for forced speed/duplex link on IGP phy.\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
		ret_val = e1000e_phy_has_link_generic(hw,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
						     PHY_FORCE_LIMIT,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
						     100000,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
						     &link);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
			return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
		if (!link)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
			e_dbg("Link taking longer than expected.\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
		/* Try once more */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
		ret_val = e1000e_phy_has_link_generic(hw,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
						     PHY_FORCE_LIMIT,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
						     100000,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
						     &link);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
			return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
 *  e1000e_phy_force_speed_duplex_m88 - Force speed/duplex for m88 PHY
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
 *  Calls the PHY setup function to force speed and duplex.  Clears the
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
 *  auto-crossover to force MDI manually.  Resets the PHY to commit the
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
 *  changes.  If time expires while waiting for link up, we reset the DSP.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
 *  After reset, TX_CLK and CRS on Tx must be set.  Return successful upon
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
 *  successful completion, else return corresponding error code.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
	struct e1000_phy_info *phy = &hw->phy;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
	u16 phy_data;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
	bool link;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
	/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
	 * Clear Auto-Crossover to force MDI manually.  M88E1000 requires MDI
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
	 * forced whenever speed and duplex are forced.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
	 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
	phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
	ret_val = e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
	e_dbg("M88E1000 PSCR: %X\n", phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
	ret_val = e1e_rphy(hw, PHY_CONTROL, &phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
	e1000e_phy_force_speed_duplex_setup(hw, &phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
	ret_val = e1e_wphy(hw, PHY_CONTROL, phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
	/* Reset the phy to commit changes. */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
	ret_val = e1000e_commit_phy(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
	if (phy->autoneg_wait_to_complete) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
		e_dbg("Waiting for forced speed/duplex link on M88 phy.\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
		ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
						     100000, &link);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
			return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
		if (!link) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
			if (hw->phy.type != e1000_phy_m88) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
				e_dbg("Link taking longer than expected.\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
			} else {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
				/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
				 * We didn't get link.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
				 * Reset the DSP and cross our fingers.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
				 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
				ret_val = e1e_wphy(hw,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
						M88E1000_PHY_PAGE_SELECT,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
						0x001d);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
				if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
					return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
				ret_val = e1000e_phy_reset_dsp(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
				if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
					return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
			}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
		}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
		/* Try once more */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
		ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
						     100000, &link);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
			return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
	if (hw->phy.type != e1000_phy_m88)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
		return 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
	ret_val = e1e_rphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
	/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
	 * Resetting the phy means we need to re-force TX_CLK in the
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
	 * Extended PHY Specific Control Register to 25MHz clock from
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
	 * the reset value of 2.5MHz.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
	 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
	phy_data |= M88E1000_EPSCR_TX_CLK_25;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
	ret_val = e1e_wphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
	/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
	 * In addition, we must re-enable CRS on Tx for both half and full
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
	 * duplex.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
	 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
	phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
	ret_val = e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
 *  e1000_phy_force_speed_duplex_ife - Force PHY speed & duplex
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
 *  Forces the speed and duplex settings of the PHY.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
 *  This is a function pointer entry point only called by
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
 *  PHY setup routines.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
s32 e1000_phy_force_speed_duplex_ife(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
	struct e1000_phy_info *phy = &hw->phy;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
	u16 data;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
	bool link;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
	ret_val = e1e_rphy(hw, PHY_CONTROL, &data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
	e1000e_phy_force_speed_duplex_setup(hw, &data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
	ret_val = e1e_wphy(hw, PHY_CONTROL, data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
	/* Disable MDI-X support for 10/100 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
	ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, &data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
	data &= ~IFE_PMC_AUTO_MDIX;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
	data &= ~IFE_PMC_FORCE_MDIX;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
	ret_val = e1e_wphy(hw, IFE_PHY_MDIX_CONTROL, data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
	e_dbg("IFE PMC: %X\n", data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
	udelay(1);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
	if (phy->autoneg_wait_to_complete) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
		e_dbg("Waiting for forced speed/duplex link on IFE phy.\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
		ret_val = e1000e_phy_has_link_generic(hw,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
		                                     PHY_FORCE_LIMIT,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
		                                     100000,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
		                                     &link);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
			goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
		if (!link)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
			e_dbg("Link taking longer than expected.\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
		/* Try once more */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
		ret_val = e1000e_phy_has_link_generic(hw,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
		                                     PHY_FORCE_LIMIT,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
		                                     100000,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
		                                     &link);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
			goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
out:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
 *  e1000e_phy_force_speed_duplex_setup - Configure forced PHY speed/duplex
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
 *  @phy_ctrl: pointer to current value of PHY_CONTROL
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
 *  Forces speed and duplex on the PHY by doing the following: disable flow
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
 *  control, force speed/duplex on the MAC, disable auto speed detection,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
 *  disable auto-negotiation, configure duplex, configure speed, configure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
 *  the collision distance, write configuration to CTRL register.  The
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
 *  caller must write to the PHY_CONTROL register for these settings to
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
 *  take affect.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
void e1000e_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
	struct e1000_mac_info *mac = &hw->mac;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
	u32 ctrl;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
	/* Turn off flow control when forcing speed/duplex */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
	hw->fc.current_mode = e1000_fc_none;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
	/* Force speed/duplex on the mac */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
	ctrl = er32(CTRL);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
	ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
	ctrl &= ~E1000_CTRL_SPD_SEL;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
	/* Disable Auto Speed Detection */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
	ctrl &= ~E1000_CTRL_ASDE;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
	/* Disable autoneg on the phy */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
	*phy_ctrl &= ~MII_CR_AUTO_NEG_EN;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
	/* Forcing Full or Half Duplex? */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
	if (mac->forced_speed_duplex & E1000_ALL_HALF_DUPLEX) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
		ctrl &= ~E1000_CTRL_FD;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
		*phy_ctrl &= ~MII_CR_FULL_DUPLEX;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
		e_dbg("Half Duplex\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
	} else {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
		ctrl |= E1000_CTRL_FD;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
		*phy_ctrl |= MII_CR_FULL_DUPLEX;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
		e_dbg("Full Duplex\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
	/* Forcing 10mb or 100mb? */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
	if (mac->forced_speed_duplex & E1000_ALL_100_SPEED) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
		ctrl |= E1000_CTRL_SPD_100;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
		*phy_ctrl |= MII_CR_SPEED_100;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
		*phy_ctrl &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_10);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
		e_dbg("Forcing 100mb\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
	} else {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
		ctrl &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
		*phy_ctrl |= MII_CR_SPEED_10;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
		*phy_ctrl &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_100);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
		e_dbg("Forcing 10mb\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
	e1000e_config_collision_dist(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
	ew32(CTRL, ctrl);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
 *  e1000e_set_d3_lplu_state - Sets low power link up state for D3
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
 *  @active: boolean used to enable/disable lplu
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
 *  Success returns 0, Failure returns 1
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
 *  The low power link up (lplu) state is set to the power management level D3
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
 *  and SmartSpeed is disabled when active is true, else clear lplu for D3
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
 *  and enable Smartspeed.  LPLU and Smartspeed are mutually exclusive.  LPLU
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
 *  is used during Dx states where the power conservation is most important.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
 *  During driver activity, SmartSpeed should be enabled so performance is
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
 *  maintained.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
s32 e1000e_set_d3_lplu_state(struct e1000_hw *hw, bool active)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
	struct e1000_phy_info *phy = &hw->phy;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
	u16 data;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
	ret_val = e1e_rphy(hw, IGP02E1000_PHY_POWER_MGMT, &data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
	if (!active) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
		data &= ~IGP02E1000_PM_D3_LPLU;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
		ret_val = e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
			return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
		/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
		 * LPLU and SmartSpeed are mutually exclusive.  LPLU is used
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
		 * during Dx states where the power conservation is most
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
		 * important.  During driver activity we should enable
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
		 * SmartSpeed, so performance is maintained.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
		 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
		if (phy->smart_speed == e1000_smart_speed_on) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
			ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
					   &data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
			if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
				return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
			data |= IGP01E1000_PSCFR_SMART_SPEED;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
			ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
					   data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
			if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
				return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
		} else if (phy->smart_speed == e1000_smart_speed_off) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
			ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
					   &data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
			if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
				return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
			data &= ~IGP01E1000_PSCFR_SMART_SPEED;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
			ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
					   data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
			if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
				return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
		}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
	} else if ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) ||
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
		   (phy->autoneg_advertised == E1000_ALL_NOT_GIG) ||
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
		   (phy->autoneg_advertised == E1000_ALL_10_SPEED)) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
		data |= IGP02E1000_PM_D3_LPLU;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
		ret_val = e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
			return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
		/* When LPLU is enabled, we should disable SmartSpeed */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
		ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG, &data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
			return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
		data &= ~IGP01E1000_PSCFR_SMART_SPEED;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
		ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG, data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
 *  e1000e_check_downshift - Checks whether a downshift in speed occurred
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
 *  Success returns 0, Failure returns 1
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
 *  A downshift is detected by querying the PHY link health.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
s32 e1000e_check_downshift(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
	struct e1000_phy_info *phy = &hw->phy;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
	u16 phy_data, offset, mask;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
	switch (phy->type) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
	case e1000_phy_m88:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
	case e1000_phy_gg82563:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
	case e1000_phy_bm:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
	case e1000_phy_82578:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
		offset	= M88E1000_PHY_SPEC_STATUS;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
		mask	= M88E1000_PSSR_DOWNSHIFT;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
		break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
	case e1000_phy_igp_2:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
	case e1000_phy_igp_3:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
		offset	= IGP01E1000_PHY_LINK_HEALTH;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
		mask	= IGP01E1000_PLHR_SS_DOWNGRADE;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
		break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
	default:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
		/* speed downshift not supported */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
		phy->speed_downgraded = false;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
		return 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
	ret_val = e1e_rphy(hw, offset, &phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
	if (!ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
		phy->speed_downgraded = (phy_data & mask);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
 *  e1000_check_polarity_m88 - Checks the polarity.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
 *  Success returns 0, Failure returns -E1000_ERR_PHY (-2)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
 *  Polarity is determined based on the PHY specific status register.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
s32 e1000_check_polarity_m88(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
	struct e1000_phy_info *phy = &hw->phy;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
	u16 data;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_STATUS, &data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
	if (!ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
		phy->cable_polarity = (data & M88E1000_PSSR_REV_POLARITY)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
				      ? e1000_rev_polarity_reversed
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
				      : e1000_rev_polarity_normal;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
 *  e1000_check_polarity_igp - Checks the polarity.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
 *  Success returns 0, Failure returns -E1000_ERR_PHY (-2)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
 *  Polarity is determined based on the PHY port status register, and the
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
 *  current speed (since there is no polarity at 100Mbps).
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
s32 e1000_check_polarity_igp(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
	struct e1000_phy_info *phy = &hw->phy;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
	u16 data, offset, mask;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
	/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
	 * Polarity is determined based on the speed of
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
	 * our connection.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
	 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
	ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_STATUS, &data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
	if ((data & IGP01E1000_PSSR_SPEED_MASK) ==
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
	    IGP01E1000_PSSR_SPEED_1000MBPS) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
		offset	= IGP01E1000_PHY_PCS_INIT_REG;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
		mask	= IGP01E1000_PHY_POLARITY_MASK;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
	} else {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
		/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
		 * This really only applies to 10Mbps since
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
		 * there is no polarity for 100Mbps (always 0).
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
		 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
		offset	= IGP01E1000_PHY_PORT_STATUS;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
		mask	= IGP01E1000_PSSR_POLARITY_REVERSED;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
	ret_val = e1e_rphy(hw, offset, &data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
	if (!ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
		phy->cable_polarity = (data & mask)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
				      ? e1000_rev_polarity_reversed
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
				      : e1000_rev_polarity_normal;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
 *  e1000_check_polarity_ife - Check cable polarity for IFE PHY
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
 *  Polarity is determined on the polarity reversal feature being enabled.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
s32 e1000_check_polarity_ife(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
	struct e1000_phy_info *phy = &hw->phy;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
	u16 phy_data, offset, mask;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
	/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
	 * Polarity is determined based on the reversal feature being enabled.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
	 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
	if (phy->polarity_correction) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
		offset = IFE_PHY_EXTENDED_STATUS_CONTROL;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
		mask = IFE_PESC_POLARITY_REVERSED;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
	} else {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
		offset = IFE_PHY_SPECIAL_CONTROL;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
		mask = IFE_PSC_FORCE_POLARITY;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
	ret_val = e1e_rphy(hw, offset, &phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
	if (!ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
		phy->cable_polarity = (phy_data & mask)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
		                       ? e1000_rev_polarity_reversed
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
		                       : e1000_rev_polarity_normal;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
 *  e1000_wait_autoneg - Wait for auto-neg completion
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
 *  Waits for auto-negotiation to complete or for the auto-negotiation time
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
 *  limit to expire, which ever happens first.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
static s32 e1000_wait_autoneg(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
	s32 ret_val = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
	u16 i, phy_status;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
	/* Break after autoneg completes or PHY_AUTO_NEG_LIMIT expires. */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
	for (i = PHY_AUTO_NEG_LIMIT; i > 0; i--) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
		ret_val = e1e_rphy(hw, PHY_STATUS, &phy_status);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
			break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
		ret_val = e1e_rphy(hw, PHY_STATUS, &phy_status);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
			break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
		if (phy_status & MII_SR_AUTONEG_COMPLETE)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
			break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
		msleep(100);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
	/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
	 * PHY_AUTO_NEG_TIME expiration doesn't guarantee auto-negotiation
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
	 * has completed.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
	 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
 *  e1000e_phy_has_link_generic - Polls PHY for link
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
 *  @iterations: number of times to poll for link
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
 *  @usec_interval: delay between polling attempts
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
 *  @success: pointer to whether polling was successful or not
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
 *  Polls the PHY status register for link, 'iterations' number of times.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
			       u32 usec_interval, bool *success)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
	s32 ret_val = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
	u16 i, phy_status;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
	for (i = 0; i < iterations; i++) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
		/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
		 * Some PHYs require the PHY_STATUS register to be read
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
		 * twice due to the link bit being sticky.  No harm doing
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
		 * it across the board.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
		 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
		ret_val = e1e_rphy(hw, PHY_STATUS, &phy_status);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
			/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
			 * If the first read fails, another entity may have
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
			 * ownership of the resources, wait and try again to
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
			 * see if they have relinquished the resources yet.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
			 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
			udelay(usec_interval);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
		ret_val = e1e_rphy(hw, PHY_STATUS, &phy_status);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
			break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
		if (phy_status & MII_SR_LINK_STATUS)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
			break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
		if (usec_interval >= 1000)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
			mdelay(usec_interval/1000);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
		else
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
			udelay(usec_interval);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
	*success = (i < iterations);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
 *  e1000e_get_cable_length_m88 - Determine cable length for m88 PHY
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
 *  Reads the PHY specific status register to retrieve the cable length
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
 *  information.  The cable length is determined by averaging the minimum and
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
 *  maximum values to get the "average" cable length.  The m88 PHY has four
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
 *  possible cable length values, which are:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
 *	Register Value		Cable Length
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
 *	0			< 50 meters
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
 *	1			50 - 80 meters
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
 *	2			80 - 110 meters
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
 *	3			110 - 140 meters
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
 *	4			> 140 meters
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
s32 e1000e_get_cable_length_m88(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
	struct e1000_phy_info *phy = &hw->phy;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
	u16 phy_data, index;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
	index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
	        M88E1000_PSSR_CABLE_LENGTH_SHIFT;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
	if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
		ret_val = -E1000_ERR_PHY;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
	phy->min_cable_length = e1000_m88_cable_length_table[index];
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
	phy->max_cable_length = e1000_m88_cable_length_table[index + 1];
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
	phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
out:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
 *  e1000e_get_cable_length_igp_2 - Determine cable length for igp2 PHY
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
 *  The automatic gain control (agc) normalizes the amplitude of the
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
 *  received signal, adjusting for the attenuation produced by the
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
 *  cable.  By reading the AGC registers, which represent the
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
 *  combination of coarse and fine gain value, the value can be put
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
 *  into a lookup table to obtain the approximate cable length
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
 *  for each channel.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
s32 e1000e_get_cable_length_igp_2(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
	struct e1000_phy_info *phy = &hw->phy;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
	u16 phy_data, i, agc_value = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
	u16 cur_agc_index, max_agc_index = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
	u16 min_agc_index = IGP02E1000_CABLE_LENGTH_TABLE_SIZE - 1;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
	u16 agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] =
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
							 {IGP02E1000_PHY_AGC_A,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
							  IGP02E1000_PHY_AGC_B,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
							  IGP02E1000_PHY_AGC_C,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
							  IGP02E1000_PHY_AGC_D};
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
	/* Read the AGC registers for all channels */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
	for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
		ret_val = e1e_rphy(hw, agc_reg_array[i], &phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
			return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
		/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
		 * Getting bits 15:9, which represent the combination of
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
		 * coarse and fine gain values.  The result is a number
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
		 * that can be put into the lookup table to obtain the
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
		 * approximate cable length.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
		 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
		cur_agc_index = (phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) &
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
				IGP02E1000_AGC_LENGTH_MASK;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
		/* Array index bound check. */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
		if ((cur_agc_index >= IGP02E1000_CABLE_LENGTH_TABLE_SIZE) ||
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
		    (cur_agc_index == 0))
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
			return -E1000_ERR_PHY;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
		/* Remove min & max AGC values from calculation. */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
		if (e1000_igp_2_cable_length_table[min_agc_index] >
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
		    e1000_igp_2_cable_length_table[cur_agc_index])
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
			min_agc_index = cur_agc_index;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
		if (e1000_igp_2_cable_length_table[max_agc_index] <
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
		    e1000_igp_2_cable_length_table[cur_agc_index])
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
			max_agc_index = cur_agc_index;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
		agc_value += e1000_igp_2_cable_length_table[cur_agc_index];
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
	agc_value -= (e1000_igp_2_cable_length_table[min_agc_index] +
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
		      e1000_igp_2_cable_length_table[max_agc_index]);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
	agc_value /= (IGP02E1000_PHY_CHANNEL_NUM - 2);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
	/* Calculate cable length with the error range of +/- 10 meters. */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
	phy->min_cable_length = ((agc_value - IGP02E1000_AGC_RANGE) > 0) ?
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
				 (agc_value - IGP02E1000_AGC_RANGE) : 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
	phy->max_cable_length = agc_value + IGP02E1000_AGC_RANGE;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
	phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
 *  e1000e_get_phy_info_m88 - Retrieve PHY information
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
 *  Valid for only copper links.  Read the PHY status register (sticky read)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
 *  to verify that link is up.  Read the PHY special control register to
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
 *  determine the polarity and 10base-T extended distance.  Read the PHY
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
 *  special status register to determine MDI/MDIx and current speed.  If
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
 *  speed is 1000, then determine cable length, local and remote receiver.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
s32 e1000e_get_phy_info_m88(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
	struct e1000_phy_info *phy = &hw->phy;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
	s32  ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
	u16 phy_data;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
	bool link;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
	if (phy->media_type != e1000_media_type_copper) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
		e_dbg("Phy info is only valid for copper media\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
		return -E1000_ERR_CONFIG;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
	ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
	if (!link) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
		e_dbg("Phy info is only valid if link is up\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
		return -E1000_ERR_CONFIG;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
	phy->polarity_correction = (phy_data &
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
				    M88E1000_PSCR_POLARITY_REVERSAL);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
	ret_val = e1000_check_polarity_m88(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
	phy->is_mdix = (phy_data & M88E1000_PSSR_MDIX);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
	if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
		ret_val = e1000_get_cable_length(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
			return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
		ret_val = e1e_rphy(hw, PHY_1000T_STATUS, &phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
			return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
		phy->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
				? e1000_1000t_rx_status_ok
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
				: e1000_1000t_rx_status_not_ok;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
		phy->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
				 ? e1000_1000t_rx_status_ok
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
				 : e1000_1000t_rx_status_not_ok;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
	} else {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
		/* Set values to "undefined" */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
		phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
		phy->local_rx = e1000_1000t_rx_status_undefined;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
		phy->remote_rx = e1000_1000t_rx_status_undefined;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
 *  e1000e_get_phy_info_igp - Retrieve igp PHY information
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
 *  Read PHY status to determine if link is up.  If link is up, then
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
 *  set/determine 10base-T extended distance and polarity correction.  Read
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
 *  PHY port status to determine MDI/MDIx and speed.  Based on the speed,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
 *  determine on the cable length, local and remote receiver.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
s32 e1000e_get_phy_info_igp(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
	struct e1000_phy_info *phy = &hw->phy;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
	u16 data;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
	bool link;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
	ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
	if (!link) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
		e_dbg("Phy info is only valid if link is up\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
		return -E1000_ERR_CONFIG;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
	phy->polarity_correction = true;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
	ret_val = e1000_check_polarity_igp(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
	ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_STATUS, &data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
	phy->is_mdix = (data & IGP01E1000_PSSR_MDIX);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
	if ((data & IGP01E1000_PSSR_SPEED_MASK) ==
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
	    IGP01E1000_PSSR_SPEED_1000MBPS) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
		ret_val = e1000_get_cable_length(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
			return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
		ret_val = e1e_rphy(hw, PHY_1000T_STATUS, &data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
			return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
		phy->local_rx = (data & SR_1000T_LOCAL_RX_STATUS)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
				? e1000_1000t_rx_status_ok
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
				: e1000_1000t_rx_status_not_ok;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
		phy->remote_rx = (data & SR_1000T_REMOTE_RX_STATUS)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
				 ? e1000_1000t_rx_status_ok
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
				 : e1000_1000t_rx_status_not_ok;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
	} else {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
		phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
		phy->local_rx = e1000_1000t_rx_status_undefined;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
		phy->remote_rx = e1000_1000t_rx_status_undefined;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
 *  e1000_get_phy_info_ife - Retrieves various IFE PHY states
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
 *  Populates "phy" structure with various feature states.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
s32 e1000_get_phy_info_ife(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
	struct e1000_phy_info *phy = &hw->phy;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
	u16 data;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
	bool link;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
	ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
	if (!link) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
		e_dbg("Phy info is only valid if link is up\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
		ret_val = -E1000_ERR_CONFIG;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
	ret_val = e1e_rphy(hw, IFE_PHY_SPECIAL_CONTROL, &data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
	phy->polarity_correction = (data & IFE_PSC_AUTO_POLARITY_DISABLE)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
	                           ? false : true;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
	if (phy->polarity_correction) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
		ret_val = e1000_check_polarity_ife(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
			goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
	} else {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
		/* Polarity is forced */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
		phy->cable_polarity = (data & IFE_PSC_FORCE_POLARITY)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
		                      ? e1000_rev_polarity_reversed
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
		                      : e1000_rev_polarity_normal;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
	ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, &data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
	phy->is_mdix = (data & IFE_PMC_MDIX_STATUS) ? true : false;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
	/* The following parameters are undefined for 10/100 operation. */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
	phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
	phy->local_rx = e1000_1000t_rx_status_undefined;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
	phy->remote_rx = e1000_1000t_rx_status_undefined;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
out:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
 *  e1000e_phy_sw_reset - PHY software reset
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
 *  Does a software reset of the PHY by reading the PHY control register and
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
 *  setting/write the control register reset bit to the PHY.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
s32 e1000e_phy_sw_reset(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
	u16 phy_ctrl;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
	ret_val = e1e_rphy(hw, PHY_CONTROL, &phy_ctrl);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
	phy_ctrl |= MII_CR_RESET;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
	ret_val = e1e_wphy(hw, PHY_CONTROL, phy_ctrl);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
	udelay(1);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
 *  e1000e_phy_hw_reset_generic - PHY hardware reset
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
 *  Verify the reset block is not blocking us from resetting.  Acquire
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
 *  semaphore (if necessary) and read/set/write the device control reset
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
 *  bit in the PHY.  Wait the appropriate delay time for the device to
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
 *  reset and release the semaphore (if necessary).
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
s32 e1000e_phy_hw_reset_generic(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
	struct e1000_phy_info *phy = &hw->phy;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
	u32 ctrl;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
	ret_val = e1000_check_reset_block(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
		return 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
	ret_val = phy->ops.acquire(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
	ctrl = er32(CTRL);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
	ew32(CTRL, ctrl | E1000_CTRL_PHY_RST);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
	e1e_flush();
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
	udelay(phy->reset_delay_us);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
	ew32(CTRL, ctrl);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
	e1e_flush();
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
	udelay(150);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
	phy->ops.release(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
	return e1000_get_phy_cfg_done(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
 *  e1000e_get_cfg_done - Generic configuration done
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
 *  Generic function to wait 10 milli-seconds for configuration to complete
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
 *  and return success.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
s32 e1000e_get_cfg_done(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
	mdelay(10);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
	return 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
 *  e1000e_phy_init_script_igp3 - Inits the IGP3 PHY
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
 *  Initializes a Intel Gigabit PHY3 when an EEPROM is not present.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
s32 e1000e_phy_init_script_igp3(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
	e_dbg("Running IGP 3 PHY init script\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
	/* PHY init IGP 3 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
	/* Enable rise/fall, 10-mode work in class-A */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
	e1e_wphy(hw, 0x2F5B, 0x9018);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
	/* Remove all caps from Replica path filter */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
	e1e_wphy(hw, 0x2F52, 0x0000);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
	/* Bias trimming for ADC, AFE and Driver (Default) */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
	e1e_wphy(hw, 0x2FB1, 0x8B24);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
	/* Increase Hybrid poly bias */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
	e1e_wphy(hw, 0x2FB2, 0xF8F0);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
	/* Add 4% to Tx amplitude in Gig mode */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
	e1e_wphy(hw, 0x2010, 0x10B0);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
	/* Disable trimming (TTT) */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
	e1e_wphy(hw, 0x2011, 0x0000);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
	/* Poly DC correction to 94.6% + 2% for all channels */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
	e1e_wphy(hw, 0x20DD, 0x249A);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
	/* ABS DC correction to 95.9% */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
	e1e_wphy(hw, 0x20DE, 0x00D3);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
	/* BG temp curve trim */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
	e1e_wphy(hw, 0x28B4, 0x04CE);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
	/* Increasing ADC OPAMP stage 1 currents to max */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
	e1e_wphy(hw, 0x2F70, 0x29E4);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
	/* Force 1000 ( required for enabling PHY regs configuration) */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
	e1e_wphy(hw, 0x0000, 0x0140);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
	/* Set upd_freq to 6 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
	e1e_wphy(hw, 0x1F30, 0x1606);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
	/* Disable NPDFE */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
	e1e_wphy(hw, 0x1F31, 0xB814);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
	/* Disable adaptive fixed FFE (Default) */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
	e1e_wphy(hw, 0x1F35, 0x002A);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
	/* Enable FFE hysteresis */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
	e1e_wphy(hw, 0x1F3E, 0x0067);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
	/* Fixed FFE for short cable lengths */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
	e1e_wphy(hw, 0x1F54, 0x0065);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
	/* Fixed FFE for medium cable lengths */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
	e1e_wphy(hw, 0x1F55, 0x002A);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
	/* Fixed FFE for long cable lengths */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
	e1e_wphy(hw, 0x1F56, 0x002A);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
	/* Enable Adaptive Clip Threshold */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
	e1e_wphy(hw, 0x1F72, 0x3FB0);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
	/* AHT reset limit to 1 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
	e1e_wphy(hw, 0x1F76, 0xC0FF);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
	/* Set AHT master delay to 127 msec */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
	e1e_wphy(hw, 0x1F77, 0x1DEC);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
	/* Set scan bits for AHT */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
	e1e_wphy(hw, 0x1F78, 0xF9EF);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
	/* Set AHT Preset bits */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
	e1e_wphy(hw, 0x1F79, 0x0210);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
	/* Change integ_factor of channel A to 3 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
	e1e_wphy(hw, 0x1895, 0x0003);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
	/* Change prop_factor of channels BCD to 8 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
	e1e_wphy(hw, 0x1796, 0x0008);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
	/* Change cg_icount + enable integbp for channels BCD */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
	e1e_wphy(hw, 0x1798, 0xD008);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
	/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
	 * Change cg_icount + enable integbp + change prop_factor_master
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
	 * to 8 for channel A
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
	 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
	e1e_wphy(hw, 0x1898, 0xD918);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
	/* Disable AHT in Slave mode on channel A */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
	e1e_wphy(hw, 0x187A, 0x0800);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
	/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
	 * Enable LPLU and disable AN to 1000 in non-D0a states,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
	 * Enable SPD+B2B
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
	 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
	e1e_wphy(hw, 0x0019, 0x008D);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
	/* Enable restart AN on an1000_dis change */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
	e1e_wphy(hw, 0x001B, 0x2080);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
	/* Enable wh_fifo read clock in 10/100 modes */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
	e1e_wphy(hw, 0x0014, 0x0045);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
	/* Restart AN, Speed selection is 1000 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
	e1e_wphy(hw, 0x0000, 0x1340);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
	return 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
/* Internal function pointers */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
 *  e1000_get_phy_cfg_done - Generic PHY configuration done
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
 *  Return success if silicon family did not implement a family specific
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
 *  get_cfg_done function.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
	if (hw->phy.ops.get_cfg_done)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
		return hw->phy.ops.get_cfg_done(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
	return 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
 *  e1000_phy_force_speed_duplex - Generic force PHY speed/duplex
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
 *  When the silicon family has not implemented a forced speed/duplex
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
 *  function for the PHY, simply return 0.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
	if (hw->phy.ops.force_speed_duplex)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
		return hw->phy.ops.force_speed_duplex(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
	return 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
 *  e1000e_get_phy_type_from_id - Get PHY type from id
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
 *  @phy_id: phy_id read from the phy
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
 *  Returns the phy type from the id.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
	enum e1000_phy_type phy_type = e1000_phy_unknown;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
	switch (phy_id) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
	case M88E1000_I_PHY_ID:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
	case M88E1000_E_PHY_ID:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
	case M88E1111_I_PHY_ID:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
	case M88E1011_I_PHY_ID:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
		phy_type = e1000_phy_m88;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
		break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
	case IGP01E1000_I_PHY_ID: /* IGP 1 & 2 share this */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
		phy_type = e1000_phy_igp_2;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
		break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
	case GG82563_E_PHY_ID:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
		phy_type = e1000_phy_gg82563;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
		break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
	case IGP03E1000_E_PHY_ID:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
		phy_type = e1000_phy_igp_3;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
		break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
	case IFE_E_PHY_ID:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
	case IFE_PLUS_E_PHY_ID:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
	case IFE_C_E_PHY_ID:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
		phy_type = e1000_phy_ife;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
		break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
	case BME1000_E_PHY_ID:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
	case BME1000_E_PHY_ID_R2:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
		phy_type = e1000_phy_bm;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
		break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
	case I82578_E_PHY_ID:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
		phy_type = e1000_phy_82578;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
		break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
	case I82577_E_PHY_ID:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
		phy_type = e1000_phy_82577;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
		break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
	case I82579_E_PHY_ID:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
		phy_type = e1000_phy_82579;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
		break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
	default:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
		phy_type = e1000_phy_unknown;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
		break;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
	return phy_type;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
 *  e1000e_determine_phy_address - Determines PHY address.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
 *  This uses a trial and error method to loop through possible PHY
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
 *  addresses. It tests each by reading the PHY ID registers and
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
 *  checking for a match.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
s32 e1000e_determine_phy_address(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
	s32 ret_val = -E1000_ERR_PHY_TYPE;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
	u32 phy_addr = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
	u32 i;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
	enum e1000_phy_type phy_type = e1000_phy_unknown;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
	hw->phy.id = phy_type;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
	for (phy_addr = 0; phy_addr < E1000_MAX_PHY_ADDR; phy_addr++) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
		hw->phy.addr = phy_addr;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
		i = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
		do {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
			e1000e_get_phy_id(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
			phy_type = e1000e_get_phy_type_from_id(hw->phy.id);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
			/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
			 * If phy_type is valid, break - we found our
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
			 * PHY address
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
			 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
			if (phy_type  != e1000_phy_unknown) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
				ret_val = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
				goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
			}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
			msleep(1);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
			i++;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
		} while (i < 10);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
out:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
 *  e1000_get_phy_addr_for_bm_page - Retrieve PHY page address
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
 *  @page: page to access
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
 *  Returns the phy address for the page requested.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
	u32 phy_addr = 2;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
	if ((page >= 768) || (page == 0 && reg == 25) || (reg == 31))
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
		phy_addr = 1;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
	return phy_addr;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
 *  e1000e_write_phy_reg_bm - Write BM PHY register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
 *  @offset: register offset to write to
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
 *  @data: data to write at register offset
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
 *  Acquires semaphore, if necessary, then writes the data to PHY register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
 *  at the offset.  Release any acquired semaphores before exiting.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
	u32 page_select = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
	u32 page = offset >> IGP_PAGE_SHIFT;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
	u32 page_shift = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
	ret_val = hw->phy.ops.acquire(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
	/* Page 800 works differently than the rest so it has its own func */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
	if (page == BM_WUC_PAGE) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
							 false);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
	hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
	if (offset > MAX_PHY_MULTI_PAGE_REG) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
		/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
		 * Page select is register 31 for phy address 1 and 22 for
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
		 * phy address 2 and 3. Page select is shifted only for
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
		 * phy address 1.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
		 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
		if (hw->phy.addr == 1) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
			page_shift = IGP_PAGE_SHIFT;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
			page_select = IGP01E1000_PHY_PAGE_SELECT;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
		} else {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
			page_shift = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
			page_select = BM_PHY_PAGE_SELECT;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
		}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
		/* Page is shifted left, PHY expects (page x 32) */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
		ret_val = e1000e_write_phy_reg_mdic(hw, page_select,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
		                                    (page << page_shift));
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
			goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
	ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
	                                    data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
out:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
	hw->phy.ops.release(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
 *  e1000e_read_phy_reg_bm - Read BM PHY register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
 *  @offset: register offset to be read
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
 *  @data: pointer to the read data
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
 *  Acquires semaphore, if necessary, then reads the PHY register at offset
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
 *  and storing the retrieved information in data.  Release any acquired
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
 *  semaphores before exiting.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
	u32 page_select = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
	u32 page = offset >> IGP_PAGE_SHIFT;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
	u32 page_shift = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
	ret_val = hw->phy.ops.acquire(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
	/* Page 800 works differently than the rest so it has its own func */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
	if (page == BM_WUC_PAGE) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
							 true);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
	hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
	if (offset > MAX_PHY_MULTI_PAGE_REG) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
		/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
		 * Page select is register 31 for phy address 1 and 22 for
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
		 * phy address 2 and 3. Page select is shifted only for
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
		 * phy address 1.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
		 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
		if (hw->phy.addr == 1) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
			page_shift = IGP_PAGE_SHIFT;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
			page_select = IGP01E1000_PHY_PAGE_SELECT;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
		} else {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
			page_shift = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
			page_select = BM_PHY_PAGE_SELECT;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
		}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
		/* Page is shifted left, PHY expects (page x 32) */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
		ret_val = e1000e_write_phy_reg_mdic(hw, page_select,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
		                                    (page << page_shift));
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
			goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
	ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
	                                   data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
out:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
	hw->phy.ops.release(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
 *  e1000e_read_phy_reg_bm2 - Read BM PHY register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
 *  @offset: register offset to be read
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
 *  @data: pointer to the read data
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
 *  Acquires semaphore, if necessary, then reads the PHY register at offset
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
 *  and storing the retrieved information in data.  Release any acquired
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
 *  semaphores before exiting.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
	u16 page = (u16)(offset >> IGP_PAGE_SHIFT);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
	ret_val = hw->phy.ops.acquire(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
	/* Page 800 works differently than the rest so it has its own func */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
	if (page == BM_WUC_PAGE) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
							 true);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
	hw->phy.addr = 1;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
	if (offset > MAX_PHY_MULTI_PAGE_REG) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
		/* Page is shifted left, PHY expects (page x 32) */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
		ret_val = e1000e_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
						    page);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
			goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
	ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
					   data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
out:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
	hw->phy.ops.release(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
 *  e1000e_write_phy_reg_bm2 - Write BM PHY register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
 *  @offset: register offset to write to
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
 *  @data: data to write at register offset
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
 *  Acquires semaphore, if necessary, then writes the data to PHY register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
 *  at the offset.  Release any acquired semaphores before exiting.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
	u16 page = (u16)(offset >> IGP_PAGE_SHIFT);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
	ret_val = hw->phy.ops.acquire(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
		return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
	/* Page 800 works differently than the rest so it has its own func */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
	if (page == BM_WUC_PAGE) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
							 false);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
	hw->phy.addr = 1;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
	if (offset > MAX_PHY_MULTI_PAGE_REG) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
		/* Page is shifted left, PHY expects (page x 32) */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
		ret_val = e1000e_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
						    page);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
			goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
	ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
					    data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
out:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
	hw->phy.ops.release(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
 *  e1000_access_phy_wakeup_reg_bm - Read BM PHY wakeup register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
 *  @offset: register offset to be read or written
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
 *  @data: pointer to the data to read or write
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
 *  @read: determines if operation is read or write
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
 *  Acquires semaphore, if necessary, then reads the PHY register at offset
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
 *  and storing the retrieved information in data.  Release any acquired
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
 *  semaphores before exiting. Note that procedure to read the wakeup
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
 *  registers are different. It works as such:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
 *  1) Set page 769, register 17, bit 2 = 1
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
 *  2) Set page to 800 for host (801 if we were manageability)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
 *  3) Write the address using the address opcode (0x11)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
 *  4) Read or write the data using the data opcode (0x12)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
 *  5) Restore 769_17.2 to its original value
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
 *  Assumes semaphore already acquired.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
					  u16 *data, bool read)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
	u16 reg = BM_PHY_REG_NUM(offset);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
	u16 phy_reg = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
	/* Gig must be disabled for MDIO accesses to page 800 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
	if ((hw->mac.type == e1000_pchlan) &&
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
	   (!(er32(PHY_CTRL) & E1000_PHY_CTRL_GBE_DISABLE)))
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
		e_dbg("Attempting to access page 800 while gig enabled.\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
	/* All operations in this function are phy address 1 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
	hw->phy.addr = 1;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
	/* Set page 769 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
	e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
	                          (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
	ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &phy_reg);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
	if (ret_val) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
		e_dbg("Could not read PHY page 769\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
	/* First clear bit 4 to avoid a power state change */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
	phy_reg &= ~(BM_WUC_HOST_WU_BIT);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
	ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
	if (ret_val) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
		e_dbg("Could not clear PHY page 769 bit 4\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
	/* Write bit 2 = 1, and clear bit 4 to 769_17 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
	ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
	                                    phy_reg | BM_WUC_ENABLE_BIT);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
	if (ret_val) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
		e_dbg("Could not write PHY page 769 bit 2\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
	/* Select page 800 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
	ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
	                                    (BM_WUC_PAGE << IGP_PAGE_SHIFT));
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
	/* Write the page 800 offset value using opcode 0x11 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
	ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ADDRESS_OPCODE, reg);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
	if (ret_val) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
		e_dbg("Could not write address opcode to page 800\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
	if (read) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
	        /* Read the page 800 value using opcode 0x12 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
		ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
		                                   data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
	} else {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
	        /* Write the page 800 value using opcode 0x12 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
		ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
						    *data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
	if (ret_val) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
		e_dbg("Could not access data value from page 800\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
	/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
	 * Restore 769_17.2 to its original value
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
	 * Set page 769
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
	 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
	e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
	                          (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
	/* Clear 769_17.2 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
	ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
	if (ret_val) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
		e_dbg("Could not clear PHY page 769 bit 2\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
out:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
 * e1000_power_up_phy_copper - Restore copper link in case of PHY power down
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
 * @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
 * In the case of a PHY power down to save power, or to turn off link during a
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
 * driver unload, or wake on lan is not enabled, restore the link to previous
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
 * settings.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
void e1000_power_up_phy_copper(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
	u16 mii_reg = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
	/* The PHY will retain its settings across a power down/up cycle */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
	e1e_rphy(hw, PHY_CONTROL, &mii_reg);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
	mii_reg &= ~MII_CR_POWER_DOWN;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
	e1e_wphy(hw, PHY_CONTROL, mii_reg);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
 * e1000_power_down_phy_copper - Restore copper link in case of PHY power down
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
 * @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
 * In the case of a PHY power down to save power, or to turn off link during a
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
 * driver unload, or wake on lan is not enabled, restore the link to previous
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
 * settings.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
void e1000_power_down_phy_copper(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
	u16 mii_reg = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
	/* The PHY will retain its settings across a power down/up cycle */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
	e1e_rphy(hw, PHY_CONTROL, &mii_reg);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
	mii_reg |= MII_CR_POWER_DOWN;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
	e1e_wphy(hw, PHY_CONTROL, mii_reg);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
	msleep(1);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
 *  e1000e_commit_phy - Soft PHY reset
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
 *  Performs a soft PHY reset on those that apply. This is a function pointer
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
 *  entry point called by drivers.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
s32 e1000e_commit_phy(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
	if (hw->phy.ops.commit)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
		return hw->phy.ops.commit(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
	return 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
 *  e1000_set_d0_lplu_state - Sets low power link up state for D0
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
 *  @active: boolean used to enable/disable lplu
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
 *  Success returns 0, Failure returns 1
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
 *  The low power link up (lplu) state is set to the power management level D0
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
 *  and SmartSpeed is disabled when active is true, else clear lplu for D0
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
 *  and enable Smartspeed.  LPLU and Smartspeed are mutually exclusive.  LPLU
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
 *  is used during Dx states where the power conservation is most important.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
 *  During driver activity, SmartSpeed should be enabled so performance is
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
 *  maintained.  This is a function pointer entry point called by drivers.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
	if (hw->phy.ops.set_d0_lplu_state)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
		return hw->phy.ops.set_d0_lplu_state(hw, active);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
	return 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
 *  __e1000_read_phy_reg_hv -  Read HV PHY register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
 *  @offset: register offset to be read
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
 *  @data: pointer to the read data
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
 *  @locked: semaphore has already been acquired or not
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
 *  Acquires semaphore, if necessary, then reads the PHY register at offset
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
 *  and stores the retrieved information in data.  Release any acquired
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
 *  semaphore before exiting.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
                                   bool locked)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
	u16 page = BM_PHY_REG_PAGE(offset);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
	u16 reg = BM_PHY_REG_NUM(offset);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
	if (!locked) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
		ret_val = hw->phy.ops.acquire(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
			return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
	/* Page 800 works differently than the rest so it has its own func */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
	if (page == BM_WUC_PAGE) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
		                                         data, true);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
	if (page > 0 && page < HV_INTC_FC_PAGE_START) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
		ret_val = e1000_access_phy_debug_regs_hv(hw, offset,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
		                                         data, true);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
	hw->phy.addr = e1000_get_phy_addr_for_hv_page(page);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
	if (page == HV_INTC_FC_PAGE_START)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
		page = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
	if (reg > MAX_PHY_MULTI_PAGE_REG) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
		u32 phy_addr = hw->phy.addr;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
		hw->phy.addr = 1;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
		/* Page is shifted left, PHY expects (page x 32) */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
		ret_val = e1000e_write_phy_reg_mdic(hw,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
					     IGP01E1000_PHY_PAGE_SELECT,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
					     (page << IGP_PAGE_SHIFT));
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
		hw->phy.addr = phy_addr;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
			goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
	ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
	                                  data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
out:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
	if (!locked)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
		hw->phy.ops.release(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2849
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
 *  e1000_read_phy_reg_hv -  Read HV PHY register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
 *  @offset: register offset to be read
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
 *  @data: pointer to the read data
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
 *  Acquires semaphore then reads the PHY register at offset and stores
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
 *  the retrieved information in data.  Release the acquired semaphore
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
 *  before exiting.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
	return __e1000_read_phy_reg_hv(hw, offset, data, false);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
 *  e1000_read_phy_reg_hv_locked -  Read HV PHY register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
 *  @offset: register offset to be read
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
 *  @data: pointer to the read data
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
 *  Reads the PHY register at offset and stores the retrieved information
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
 *  in data.  Assumes semaphore already acquired.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 *data)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
	return __e1000_read_phy_reg_hv(hw, offset, data, true);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
 *  __e1000_write_phy_reg_hv - Write HV PHY register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
 *  @offset: register offset to write to
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
 *  @data: data to write at register offset
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
 *  @locked: semaphore has already been acquired or not
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2888
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
 *  Acquires semaphore, if necessary, then writes the data to PHY register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2890
 *  at the offset.  Release any acquired semaphores before exiting.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
                                    bool locked)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
	u16 page = BM_PHY_REG_PAGE(offset);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
	u16 reg = BM_PHY_REG_NUM(offset);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
	if (!locked) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
		ret_val = hw->phy.ops.acquire(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
			return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
	/* Page 800 works differently than the rest so it has its own func */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
	if (page == BM_WUC_PAGE) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
		                                         &data, false);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
	if (page > 0 && page < HV_INTC_FC_PAGE_START) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
		ret_val = e1000_access_phy_debug_regs_hv(hw, offset,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
		                                         &data, false);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2918
	hw->phy.addr = e1000_get_phy_addr_for_hv_page(page);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
	if (page == HV_INTC_FC_PAGE_START)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
		page = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
	/*
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
	 * Workaround MDIO accesses being disabled after entering IEEE Power
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
	 * Down (whenever bit 11 of the PHY Control register is set)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
	 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
	if ((hw->phy.type == e1000_phy_82578) &&
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
	    (hw->phy.revision >= 1) &&
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
	    (hw->phy.addr == 2) &&
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
	    ((MAX_PHY_REG_ADDRESS & reg) == 0) &&
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
	    (data & (1 << 11))) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
		u16 data2 = 0x7EFF;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2933
		ret_val = e1000_access_phy_debug_regs_hv(hw, (1 << 6) | 0x3,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2934
		                                         &data2, false);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
			goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
	if (reg > MAX_PHY_MULTI_PAGE_REG) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
		u32 phy_addr = hw->phy.addr;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
		hw->phy.addr = 1;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
		/* Page is shifted left, PHY expects (page x 32) */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
		ret_val = e1000e_write_phy_reg_mdic(hw,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
					     IGP01E1000_PHY_PAGE_SELECT,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
					     (page << IGP_PAGE_SHIFT));
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
		hw->phy.addr = phy_addr;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2950
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
			goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
	ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
	                                  data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2957
out:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
	if (!locked)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
		hw->phy.ops.release(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
 *  e1000_write_phy_reg_hv - Write HV PHY register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
 *  @offset: register offset to write to
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
 *  @data: data to write at register offset
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
 *  Acquires semaphore then writes the data to PHY register at the offset.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
 *  Release the acquired semaphores before exiting.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
	return __e1000_write_phy_reg_hv(hw, offset, data, false);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
 *  e1000_write_phy_reg_hv_locked - Write HV PHY register
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
 *  @offset: register offset to write to
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
 *  @data: data to write at register offset
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
 *  Writes the data to PHY register at the offset.  Assumes semaphore
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
 *  already acquired.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 data)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
	return __e1000_write_phy_reg_hv(hw, offset, data, true);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2990
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
 *  e1000_get_phy_addr_for_hv_page - Get PHY adrress based on page
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
 *  @page: page to be accessed
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
static u32 e1000_get_phy_addr_for_hv_page(u32 page)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
	u32 phy_addr = 2;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
	if (page >= HV_INTC_FC_PAGE_START)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
		phy_addr = 1;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
	return phy_addr;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3006
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
 *  e1000_access_phy_debug_regs_hv - Read HV PHY vendor specific high registers
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
 *  @offset: register offset to be read or written
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
 *  @data: pointer to the data to be read or written
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
 *  @read: determines if operation is read or written
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
 *  Reads the PHY register at offset and stores the retreived information
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
 *  in data.  Assumes semaphore already acquired.  Note that the procedure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
 *  to read these regs uses the address port and data port to read/write.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
                                          u16 *data, bool read)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
	u32 addr_reg = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
	u32 data_reg = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
	/* This takes care of the difference with desktop vs mobile phy */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
	addr_reg = (hw->phy.type == e1000_phy_82578) ?
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
	           I82578_ADDR_REG : I82577_ADDR_REG;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
	data_reg = addr_reg + 1;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
	/* All operations in this function are phy address 2 */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
	hw->phy.addr = 2;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
	/* masking with 0x3F to remove the page from offset */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3033
	ret_val = e1000e_write_phy_reg_mdic(hw, addr_reg, (u16)offset & 0x3F);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
	if (ret_val) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
		e_dbg("Could not write PHY the HV address register\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
	/* Read or write the data value next */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
	if (read)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
		ret_val = e1000e_read_phy_reg_mdic(hw, data_reg, data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
	else
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
		ret_val = e1000e_write_phy_reg_mdic(hw, data_reg, *data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
	if (ret_val) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
		e_dbg("Could not read data value from HV data register\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3049
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
out:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
 *  e1000_link_stall_workaround_hv - Si workaround
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3056
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
 *  This function works around a Si bug where the link partner can get
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
 *  a link up indication before the PHY does.  If small packets are sent
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3060
 *  by the link partner they can be placed in the packet buffer without
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
 *  being properly accounted for by the PHY and will stall preventing
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
 *  further packets from being received.  The workaround is to clear the
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
 *  packet buffer after the PHY detects link up.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3066
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
	s32 ret_val = 0;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
	u16 data;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
	if (hw->phy.type != e1000_phy_82578)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
	/* Do not apply workaround if in PHY loopback bit 14 set */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
	hw->phy.ops.read_reg(hw, PHY_CONTROL, &data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
	if (data & PHY_CONTROL_LB)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
	/* check if link is up and at 1Gbps */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3079
	ret_val = hw->phy.ops.read_reg(hw, BM_CS_STATUS, &data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
	data &= BM_CS_STATUS_LINK_UP |
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
	        BM_CS_STATUS_RESOLVED |
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
	        BM_CS_STATUS_SPEED_MASK;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
	if (data != (BM_CS_STATUS_LINK_UP |
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
	             BM_CS_STATUS_RESOLVED |
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
	             BM_CS_STATUS_SPEED_1000))
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
	mdelay(200);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
	/* flush the packets in the fifo buffer */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
	ret_val = hw->phy.ops.write_reg(hw, HV_MUX_DATA_CTRL,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
	                                HV_MUX_DATA_CTRL_GEN_TO_MAC |
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
	                                HV_MUX_DATA_CTRL_FORCE_SPEED);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
	ret_val = hw->phy.ops.write_reg(hw, HV_MUX_DATA_CTRL,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
	                                HV_MUX_DATA_CTRL_GEN_TO_MAC);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
out:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
 *  e1000_check_polarity_82577 - Checks the polarity.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3111
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
 *  Success returns 0, Failure returns -E1000_ERR_PHY (-2)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
 *  Polarity is determined based on the PHY specific status register.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
s32 e1000_check_polarity_82577(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
	struct e1000_phy_info *phy = &hw->phy;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
	u16 data;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
	ret_val = phy->ops.read_reg(hw, I82577_PHY_STATUS_2, &data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3124
	if (!ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
		phy->cable_polarity = (data & I82577_PHY_STATUS2_REV_POLARITY)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
		                      ? e1000_rev_polarity_reversed
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
		                      : e1000_rev_polarity_normal;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
 *  e1000_phy_force_speed_duplex_82577 - Force speed/duplex for I82577 PHY
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
 *  Calls the PHY setup function to force speed and duplex.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3138
s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
	struct e1000_phy_info *phy = &hw->phy;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
	u16 phy_data;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
	bool link;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
	ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
	e1000e_phy_force_speed_duplex_setup(hw, &phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3150
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
	ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3153
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
	udelay(1);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
	if (phy->autoneg_wait_to_complete) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
		e_dbg("Waiting for forced speed/duplex link on 82577 phy\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
		ret_val = e1000e_phy_has_link_generic(hw,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
		                                     PHY_FORCE_LIMIT,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
		                                     100000,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
		                                     &link);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
			goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
		if (!link)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
			e_dbg("Link taking longer than expected.\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3170
		/* Try once more */
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
		ret_val = e1000e_phy_has_link_generic(hw,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3172
		                                     PHY_FORCE_LIMIT,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
		                                     100000,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
		                                     &link);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
			goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
out:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
 *  e1000_get_phy_info_82577 - Retrieve I82577 PHY information
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
 *  Read PHY status to determine if link is up.  If link is up, then
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
 *  set/determine 10base-T extended distance and polarity correction.  Read
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
 *  PHY port status to determine MDI/MDIx and speed.  Based on the speed,
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
 *  determine on the cable length, local and remote receiver.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
s32 e1000_get_phy_info_82577(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3194
	struct e1000_phy_info *phy = &hw->phy;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3195
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3196
	u16 data;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
	bool link;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3198
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
	ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
	if (!link) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
		e_dbg("Phy info is only valid if link is up\n");
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
		ret_val = -E1000_ERR_CONFIG;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
	phy->polarity_correction = true;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3211
	ret_val = e1000_check_polarity_82577(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3212
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
	ret_val = phy->ops.read_reg(hw, I82577_PHY_STATUS_2, &data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3217
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3218
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3219
	phy->is_mdix = (data & I82577_PHY_STATUS2_MDIX) ? true : false;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3220
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3221
	if ((data & I82577_PHY_STATUS2_SPEED_MASK) ==
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
	    I82577_PHY_STATUS2_SPEED_1000MBPS) {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
		ret_val = hw->phy.ops.get_cable_length(hw);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3224
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
			goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3227
		ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3228
		if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3229
			goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3230
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
		phy->local_rx = (data & SR_1000T_LOCAL_RX_STATUS)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
		                ? e1000_1000t_rx_status_ok
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3233
		                : e1000_1000t_rx_status_not_ok;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3234
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3235
		phy->remote_rx = (data & SR_1000T_REMOTE_RX_STATUS)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3236
		                 ? e1000_1000t_rx_status_ok
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3237
		                 : e1000_1000t_rx_status_not_ok;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3238
	} else {
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3239
		phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3240
		phy->local_rx = e1000_1000t_rx_status_undefined;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3241
		phy->remote_rx = e1000_1000t_rx_status_undefined;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3242
	}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3243
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3244
out:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3245
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3246
}
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3247
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3248
/**
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3249
 *  e1000_get_cable_length_82577 - Determine cable length for 82577 PHY
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3250
 *  @hw: pointer to the HW structure
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3251
 *
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3252
 * Reads the diagnostic status register and verifies result is valid before
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3253
 * placing it in the phy_cable_length field.
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3254
 **/
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3255
s32 e1000_get_cable_length_82577(struct e1000_hw *hw)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3256
{
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3257
	struct e1000_phy_info *phy = &hw->phy;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3258
	s32 ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3259
	u16 phy_data, length;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3260
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3261
	ret_val = phy->ops.read_reg(hw, I82577_PHY_DIAG_STATUS, &phy_data);
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3262
	if (ret_val)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3263
		goto out;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3264
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3265
	length = (phy_data & I82577_DSTATUS_CABLE_LENGTH) >>
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3266
	         I82577_DSTATUS_CABLE_LENGTH_SHIFT;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3267
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3268
	if (length == E1000_CABLE_LENGTH_UNDEFINED)
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3269
		ret_val = -E1000_ERR_PHY;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3270
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3271
	phy->cable_length = length;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3272
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3273
out:
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3274
	return ret_val;
d52848f0be04 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3275
}