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