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